Compare commits

..

24 commits

Author SHA1 Message Date
211b9b3135 Update version to 3.0.2 in the manifest 2026-05-10 23:46:31 -06:00
8cadd8318b Add some TAF-specific links into the settings sidebar 2026-05-10 23:45:00 -06:00
849da4bb54 Add dev-only hook to remove the core software update notification because it annoys me 2026-05-10 15:07:04 -06:00
500eabc755 Fix the deprecation warning in v14 & hide the context menu options in v13 correctly 2026-05-10 14:56:28 -06:00
b36fe27182 Fix the issue with ContextMenus being completely non-functional in v13 (closes #91) 2026-05-07 18:05:00 -06:00
9177b7cc2d Remove the web-only files from the wiki archive 2026-05-06 16:18:23 -06:00
288f3a54b5 Update system version in the manifest 2026-05-06 16:11:02 -06:00
dddad7f55d Fix actor creation throwing an error (closes #89) 2026-05-06 16:10:34 -06:00
a34525f05e Remove useless command from the wiki portion of my action 2026-05-05 17:56:20 -06:00
786cb7f5ec Remove unused CDN URL environment variable 2026-05-03 15:45:52 -06:00
9527cd972e Tweak comment in data model 2026-05-03 00:09:24 -06:00
504a91bb9c Add way to set default attributes now that we no longer have the AttributeManager (closes #83) 2026-05-02 20:51:05 -06:00
a9567c200a Add the macro trigger into the Items tab, and localize the trigger button for attributes (closes #85) 2026-05-02 20:27:15 -06:00
a55748d6fc Remove log that slipped through the cracks 2026-05-02 19:28:13 -06:00
77413687e9 Make the generic Item subtype actually provide the speaker data to the macro 2026-05-02 19:28:03 -06:00
c6d3c094b8 Add an extra paragraph to the Macro deletion dialog in order to tell people how many items use that macro (closes #81) 2026-05-02 19:23:20 -06:00
74d881c3df Fix a bug where the actor context was not being correctly called unless the user had an actor assigned to them 2026-05-02 18:56:23 -06:00
5b59956016 Implement the light mode using Forgejo's colour pallete (closes #51) 2026-05-02 18:35:59 -06:00
749d442bd8 Update the QueryStatus app theme (closes #61) 2026-05-01 15:26:57 -06:00
6723e0d25f Add a different default image for attribute items so they stand out a bit more in the item tab 2026-04-29 22:12:18 -06:00
a30d68a327 Lint and fix undefined reference error 2026-04-29 21:38:07 -06:00
fe0a21f0ca Merge pull request 'Update the theming for Actor sheets' (#80) from theming/actor-sheet into main
Reviewed-on: #80
2026-04-30 01:57:12 +00:00
c090daa2aa Improve the chat message handling to make it so that the flavour can be properly updated if you include @active roll data 2026-04-29 19:53:39 -06:00
0fb10b7ae2 Prevent early returning in the taf.getRollData hook 2026-04-29 19:51:56 -06:00
27 changed files with 513 additions and 57 deletions

View file

@ -43,7 +43,6 @@ jobs:
run: node scripts/src/createForgejoRelease.mjs run: node scripts/src/createForgejoRelease.mjs
env: env:
TAG: "v${{steps.version.outputs.version}}" TAG: "v${{steps.version.outputs.version}}"
CDN_URL: "${{vars.CDN_URL}}"
wiki-release-artifact: wiki-release-artifact:
name: "Add Wiki to Release" name: "Add Wiki to Release"
@ -65,10 +64,10 @@ jobs:
token: ${{forgejo.token}} token: ${{forgejo.token}}
- name: "Install dependencies" - name: "Install dependencies"
run: "pwd; npm i" run: "npm i"
- name: "Remove development folders" - name: "Remove development/web folders"
run: "rm -rf .git .vscode" run: "rm -rf .git .vscode _*"
working-directory: "wiki" working-directory: "wiki"
- name: "Compress wiki folder" - name: "Compress wiki folder"

1
dev/dev.mjs Normal file
View file

@ -0,0 +1 @@
import "./hooks/renderSettings.mjs";

View file

@ -0,0 +1,5 @@
Hooks.on(`renderSettings`, (app, html, ctx, options) => {
/** @type {HTMLElement|undefined} */
const coreUpdateTooltip = html.querySelector(`.build .value a`);
coreUpdateTooltip?.remove();
});

View file

@ -64,6 +64,14 @@
"edit": "Edit", "edit": "Edit",
"resizable": "Resizable", "resizable": "Resizable",
"not-resizable": "Not Resizable", "not-resizable": "Not Resizable",
"macro-is-in-use": "The Macro is used by {count} items/attributes in the world or Actors, the items will lose their ability to use the macro.",
"roll": "Roll",
"use": "Use",
"version": "Version {version}",
"whats-new": "What's New",
"releases": "Releases",
"wiki": "Wiki",
"issues": "Issues",
"item": { "item": {
"weight": "Weight", "weight": "Weight",
"quantity": "Quantity", "quantity": "Quantity",
@ -88,6 +96,7 @@
"invalid-input-type": "Invalid input type provided: {type}" "invalid-input-type": "Invalid input type provided: {type}"
}, },
"PlayerSheet": { "PlayerSheet": {
"save-attributes-as-defaults": "Save Attributes as Defaults",
"create-item": "Create Embedded Item", "create-item": "Create Embedded Item",
"current-value": "Current value", "current-value": "Current value",
"max-value": "Maximum value", "max-value": "Maximum value",

View file

@ -1,9 +1,10 @@
import { __ID__, filePath } from "../consts.mjs"; import { __ID__, filePath } from "../consts.mjs";
import { deleteItemFromElement, editItemFromElement } from "./utils.mjs"; import { createContextMenuOption, deleteItemFromElement, editItemFromElement } from "./utils.mjs";
import { config } from "../config.mjs"; import { config } from "../config.mjs";
import { Logger } from "../utils/Logger.mjs"; import { Logger } from "../utils/Logger.mjs";
import { TAFDocumentSheetConfig } from "./TAFDocumentSheetConfig.mjs"; import { TAFDocumentSheetConfig } from "./overrides/TAFDocumentSheetConfig.mjs";
import { TAFDocumentSheetMixin } from "./mixins/TAFDocumentSheetMixin.mjs"; import { TAFDocumentSheetMixin } from "./mixins/TAFDocumentSheetMixin.mjs";
import { TAFActor } from "../documents/Actor.mjs";
const { HandlebarsApplicationMixin } = foundry.applications.api; const { HandlebarsApplicationMixin } = foundry.applications.api;
const { ActorSheetV2 } = foundry.applications.sheets; const { ActorSheetV2 } = foundry.applications.sheets;
@ -38,6 +39,7 @@ export class PlayerSheet extends
configureSheet: this.#configureSheet, configureSheet: this.#configureSheet,
toggleExpand: this.#toggleExpand, toggleExpand: this.#toggleExpand,
executeTrigger: this.#executeTrigger, executeTrigger: this.#executeTrigger,
saveDefaultAttrs: this.#saveDefaultAttrs,
}, },
}; };
@ -193,6 +195,12 @@ export class PlayerSheet extends
const controls = super._getHeaderControls(); const controls = super._getHeaderControls();
controls.push( controls.push(
{
icon: `fa-solid fa-globe`,
label: `taf.Apps.PlayerSheet.save-attributes-as-defaults`,
action: `saveDefaultAttrs`,
visible: () => game.user.isGM,
},
{ {
icon: `fa-solid fa-suitcase`, icon: `fa-solid fa-suitcase`,
label: `taf.Apps.PlayerSheet.create-item`, label: `taf.Apps.PlayerSheet.create-item`,
@ -218,24 +226,24 @@ export class PlayerSheet extends
this.element, this.element,
`[data-item-uuid]`, `[data-item-uuid]`,
[ [
{ createContextMenuOption({
label: _loc(`taf.misc.edit`), label: _loc(`taf.misc.edit`),
condition: (el) => { visible: (el) => {
const itemUuid = el.dataset.itemUuid; const itemUuid = el.dataset.itemUuid;
const itemExists = itemUuid != null && itemUuid !== ``; const itemExists = itemUuid != null && itemUuid !== ``;
return this.isEditable && itemExists; return this.isEditable && itemExists;
}, },
onClick: editItemFromElement, onClick: editItemFromElement,
}, }),
{ createContextMenuOption({
label: _loc(`taf.misc.delete`), label: _loc(`taf.misc.delete`),
condition: (el) => { visible: (el) => {
const itemUuid = el.dataset.itemUuid; const itemUuid = el.dataset.itemUuid;
const itemExists = itemUuid != null && itemUuid !== ``; const itemExists = itemUuid != null && itemUuid !== ``;
return this.isEditable && itemExists; return this.isEditable && itemExists;
}, },
onClick: deleteItemFromElement, onClick: deleteItemFromElement,
}, }),
], ],
{ jQuery: false, fixed: true }, { jQuery: false, fixed: true },
); );
@ -382,6 +390,7 @@ export class PlayerSheet extends
weight: config.weightFormatter(item.system.quantifiedWeight), weight: config.weightFormatter(item.system.quantifiedWeight),
isExpanded: this.#expandedItems.has(item.uuid), isExpanded: this.#expandedItems.has(item.uuid),
canExpand: item.system.description.length > 0, canExpand: item.system.description.length > 0,
trigger: item.system.trigger,
}; };
ctx.description = ``; ctx.description = ``;
@ -474,5 +483,15 @@ export class PlayerSheet extends
const item = await fromUuid(itemUuid); const item = await fromUuid(itemUuid);
await item?.system.execute?.(); await item?.system.execute?.();
}; };
/**
* Saves the Actor's current attribute items into the world setting for newly
* created Actors to have the same attribute list.
*
* @this {PlayerSheet}
*/
static async #saveDefaultAttrs() {
TAFActor.setDefaultAttributes(this.actor);
};
// #endregion Actions // #endregion Actions
}; };

View file

@ -1,6 +1,6 @@
import { __ID__, filePath } from "../consts.mjs"; import { __ID__, filePath } from "../../consts.mjs";
import { getDefaultSizing } from "../utils/getSizing.mjs"; import { getDefaultSizing } from "../../utils/getSizing.mjs";
import { localizer } from "../utils/localizer.mjs"; import { localizer } from "../../utils/localizer.mjs";
const { diffObject, expandObject, flattenObject } = foundry.utils; const { diffObject, expandObject, flattenObject } = foundry.utils;
const { DocumentSheetConfig } = foundry.applications.apps; const { DocumentSheetConfig } = foundry.applications.apps;

View file

@ -0,0 +1,30 @@
import { filePath } from "../../consts.mjs";
const { renderTemplate } = foundry.applications.handlebars;
const { Settings } = foundry.applications.sidebar.tabs;
export class TAFSettingsSidebar extends Settings {
// #region Lifecycle
async _onRender() {
// remove the row from the HTML
const systemRow = this.element.querySelector(`.info .system`);
systemRow?.remove();
// add the more customized system info into the sidebar
const systemBlock = this.element.querySelector(`section.system`);
if (!systemBlock) {
const htmlString = await renderTemplate(
filePath(`templates/settings-sidebar-addition.hbs`),
{ system: game.system, },
);
const temp = document.createElement(`div`);
temp.innerHTML = htmlString;
const rendered = temp.firstChild;
const info = this.element.querySelector(`section.info`);
info.insertAdjacentElement(`afterend`, rendered);
};
};
// #endregion Lifecycle
};

View file

@ -3,6 +3,25 @@ This file contains utility methods used by Applications in order to be
DRYer DRYer
*/ */
/**
* A helper function that takes a v14-compatible ContextMenuEntry option
* and adjusts it for v13 if required
*
* @param {ContextMenuEntry} option The v14+ compatible menu entry option
* @returns {ContextMenuEntry} The v14+ or <v13 menu option object
*/
export function createContextMenuOption(option) {
if (game.release.generation < 14) {
return {
name: option.label,
condition: option.visible,
callback: (target) => option.onClick(null, target),
};
};
return option;
};
/** /**
* @param {Event} _event The click event * @param {Event} _event The click event
* @param {HTMLElement} target The element to operate on * @param {HTMLElement} target The element to operate on

View file

@ -1,7 +1,7 @@
import { __ID__ } from "../../consts.mjs"; import { __ID__ } from "../../consts.mjs";
export class PlayerData extends foundry.abstract.TypeDataModel { export class PlayerData extends foundry.abstract.TypeDataModel {
// #region Schema // MARK: Schema
static defineSchema() { static defineSchema() {
const fields = foundry.data.fields; const fields = foundry.data.fields;
return { return {
@ -18,7 +18,6 @@ export class PlayerData extends foundry.abstract.TypeDataModel {
attr: new fields.ObjectField({ persisted: false, initial: {} }), attr: new fields.ObjectField({ persisted: false, initial: {} }),
}; };
}; };
// #endregion Schema
// #region Lifecycle // #region Lifecycle
/** /**

View file

@ -136,16 +136,40 @@ export class AttributeItemData extends foundry.abstract.TypeDataModel {
// Provide the chat-specific context when required // Provide the chat-specific context when required
if (macro.type === `chat`) { if (macro.type === `chat`) {
const extraContext = {
name: this.parent.name,
min: this.min,
value: this.value,
max: this.max,
};
Hooks.once(`taf.getRollData`, (data) => { Hooks.once(`taf.getRollData`, (data) => {
data.active = { data.active = extraContext;
min: this.min, });
value: this.value,
max: this.max, // Apply any roll data additions to the message flavour as well
// since that doesn't get formatted by the ChatLog
Hooks.once(`preCreateChatMessage`, (message) => {
if (message.flavor.includes(`@active`)) {
const flavor = message.flavor.replaceAll(
/@active\.(\w+)/g,
(fullMatch, key) => {
return extraContext[key] || fullMatch;
},
);
message.updateSource({ flavor });
}; };
}); });
}; };
await macro?.execute({ item: this.parent }); // Get the speaker so that Foundry has the correct context to be able to call
// the Actor's getData method, letting us augment the context dynamically for
// the @active roll context
const speaker = foundry.documents.ChatMessage.implementation.getSpeaker({
actor: this.parent.parent,
});
await macro?.execute({ item: this.parent, speaker });
}; };
// #endregion Methods // #endregion Methods
}; };

View file

@ -59,15 +59,39 @@ export class GenericItemData extends foundry.abstract.TypeDataModel {
// Provide the chat-specific context when required // Provide the chat-specific context when required
if (macro.type === `chat`) { if (macro.type === `chat`) {
const extraContext = {
name: this.parent.name,
quantity: this.quantity,
equipped: this.equipped ? 1 : 0,
};
Hooks.once(`taf.getRollData`, (data) => { Hooks.once(`taf.getRollData`, (data) => {
data.active = { data.active = extraContext;
quantity: this.quantity, });
equipped: this.equipped ? 1 : 0,
// Apply any roll data additions to the message flavour as well
// since that doesn't get formatted by the ChatLog
Hooks.once(`preCreateChatMessage`, (message) => {
if (message.flavor.includes(`@active`)) {
const flavor = message.flavor.replaceAll(
/@active\.(\w+)/g,
(fullMatch, key) => {
return extraContext[key] || fullMatch;
},
);
message.updateSource({ flavor });
}; };
}); });
}; };
await macro?.execute({ item }); // Get the speaker so that Foundry has the correct context to be able to call
// the Actor's getData method, letting us augment the context dynamically for
// the @active roll context
const speaker = foundry.documents.ChatMessage.implementation.getSpeaker({
actor: this.parent.parent,
});
await macro?.execute({ item: this.parent, speaker });
}; };
// #endregion Methods // #endregion Methods
}; };

View file

@ -71,7 +71,7 @@ export class TAFActor extends Actor {
...this.system.attr, ...this.system.attr,
}; };
Hooks.call(`taf.getRollData`, data, this); Hooks.callAll(`taf.getRollData`, data, this);
return data; return data;
}; };
@ -130,8 +130,11 @@ export class TAFActor extends Actor {
* This checks and performs all data migrations that the system requires, some * This checks and performs all data migrations that the system requires, some
* of these are one-time only migrations, others of them will happen every time * of these are one-time only migrations, others of them will happen every time
* an Actor is updated. * an Actor is updated.
*
* The defaulting of options is provided to ensure that the migration doesn't
* cause errors in Foundry v13
*/ */
static migrateData(data, options) { static migrateData(data, options = {}) {
this.#migrateToAttributeItems(data, options); this.#migrateToAttributeItems(data, options);
return super.migrateData(data, options); return super.migrateData(data, options);
}; };
@ -155,4 +158,30 @@ export class TAFActor extends Actor {
}; };
}; };
// #endregion Data Migration // #endregion Data Migration
// #region Static API
/**
* Sets the default attributes that are created when a new Actor is created,
* this uses all of the existing values that are a part of the items, it does
* not prompt for default values.
*/
static async setDefaultAttributes(actor) {
if (!game.user.isGM) { return };
const minifiedData = [];
const attrs = actor.itemTypes.attribute ?? [];
for (const attr of attrs) {
const raw = attr.toObject();
minifiedData.push({
img: raw.img, // doesn't really matter but ¯\_(ツ)_/¯
name: raw.name,
type: raw.type,
system: raw.system,
});
};
game.settings.set(__ID__, `actorDefaultAttributes`, minifiedData);
ui.notifications.success(_loc(`taf.notifs.success.saved-default-attributes`));
};
// #endregion Static API
}; };

View file

@ -0,0 +1,8 @@
export class TAFItem extends foundry.documents.Item {
static getDefaultArtwork(itemData) {
switch (itemData.type) {
case `attribute`: return { img: `icons/svg/jump.svg` };
};
return super.getDefaultArtwork(itemData);
};
};

View file

@ -0,0 +1,38 @@
export class TAFMacro extends foundry.documents.Macro {
async deleteDialog(options, operation) {
const itemsUsingMacro = new Set();
// Check Items on Actors
game.actors.forEach(actor => {
actor.items.forEach(item => {
if (item.system.trigger === this.uuid) {
itemsUsingMacro.add(item.uuid);
};
});
});
// Check World Items
game.items.forEach(item => {
if (item.system.trigger === this.uuid) {
itemsUsingMacro.add(item.uuid);
};
});
// Modify the dialog arguments
const type = _loc(this.constructor.metadata.label);
const question = _loc(`COMMON.AreYouSure`);
const warning = _loc(`SIDEBAR.DeleteWarning`, { type });
let content = `<p style="margin: 0;"><strong>${question}</strong> ${warning}</p>`;
if (itemsUsingMacro.size) {
const extraInfo = _loc(
`taf.misc.macro-is-in-use`,
{ count: itemsUsingMacro.size },
);
content += `<p style="margin: 0;">${extraInfo}</p>`;
};
options.content = content;
return super.deleteDialog(options, operation);
};
};

View file

@ -13,6 +13,8 @@ import { PlayerData } from "../data/Actor/player.mjs";
// Documents // Documents
import { TAFActor } from "../documents/Actor.mjs"; import { TAFActor } from "../documents/Actor.mjs";
import { TAFCombatant } from "../documents/Combatant.mjs"; import { TAFCombatant } from "../documents/Combatant.mjs";
import { TAFItem } from "../documents/Item.mjs";
import { TAFMacro } from "../documents/Macro.mjs";
import { TAFTokenDocument } from "../documents/Token.mjs"; import { TAFTokenDocument } from "../documents/Token.mjs";
// Settings // Settings
@ -24,14 +26,17 @@ import helpers from "../handlebarsHelpers/_index.mjs";
import { Logger } from "../utils/Logger.mjs"; import { Logger } from "../utils/Logger.mjs";
import { registerCustomComponents } from "../apps/elements/_index.mjs"; import { registerCustomComponents } from "../apps/elements/_index.mjs";
import { registerSockets } from "../sockets/_index.mjs"; import { registerSockets } from "../sockets/_index.mjs";
import { TAFSettingsSidebar } from "../apps/overrides/TAFSettingsSidebar.mjs";
Hooks.on(`init`, () => { Hooks.on(`init`, () => {
Logger.debug(`Initializing`); Logger.debug(`Initializing`);
// #region Documents // #region Documents
CONFIG.Token.documentClass = TAFTokenDocument;
CONFIG.Actor.documentClass = TAFActor; CONFIG.Actor.documentClass = TAFActor;
CONFIG.Combatant.documentClass = TAFCombatant; CONFIG.Combatant.documentClass = TAFCombatant;
CONFIG.Item.documentClass = TAFItem;
CONFIG.Macro.documentClass = TAFMacro;
CONFIG.Token.documentClass = TAFTokenDocument;
// #endregion Documents // #endregion Documents
// #region Data Models // #region Data Models
@ -40,6 +45,10 @@ Hooks.on(`init`, () => {
CONFIG.Item.dataModels.attribute = AttributeItemData; CONFIG.Item.dataModels.attribute = AttributeItemData;
// #endregion Data Models // #endregion Data Models
// #region App Overrides
CONFIG.ui.settings = TAFSettingsSidebar;
// #endregion App Overrides
// #region Sheets // #region Sheets
foundry.documents.collections.Actors.registerSheet( foundry.documents.collections.Actors.registerSheet(
__ID__, __ID__,

View file

@ -135,8 +135,8 @@
margin-bottom: 0; margin-bottom: 0;
.summary { .summary {
display: grid; display: flex;
grid-template-columns: min-content auto 1fr 50px auto; flex-direction: row;
align-items: center; align-items: center;
gap: 8px; gap: 8px;
background: var(--item-card-header-background); background: var(--item-card-header-background);
@ -154,6 +154,7 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
gap: 4px; gap: 4px;
flex-grow: 1;
} }
.name { .name {
@ -164,10 +165,15 @@
opacity: 90%; opacity: 90%;
} }
input {
width: 50px;
}
input, button { input, button {
background: var(--item-card-header-input-background); background: var(--item-card-header-input-background);
color: var(--item-card-header-input-colour); color: var(--item-card-header-input-colour);
text-align: center; text-align: center;
height: 32px;
&:disabled { &:disabled {
color: var(--item-card-header-disabled-input-colour); color: var(--item-card-header-disabled-input-colour);
@ -175,14 +181,17 @@
} }
} }
.expand-button { button {
border: none; border: none;
aspect-ratio: 1;
&:focus-visible { &:focus-visible {
filter: brightness(150%); filter: brightness(150%);
outline: none; outline: none;
} }
}
.expand-button {
aspect-ratio: 1;
&[data-expanded="true"] { &[data-expanded="true"] {
rotate: 180deg; rotate: 180deg;

View file

@ -1,4 +1,9 @@
.taf.QueryStatus { .taf.QueryStatus {
> .window-content {
color: var(--query-status-colour);
background: var(--query-status-background);
}
.user-list { .user-list {
display: flex; display: flex;
flex-direction: column; flex-direction: column;
@ -11,7 +16,8 @@
display: flex; display: flex;
flex-direction: column; flex-direction: column;
margin: 0; margin: 0;
border: 1px solid rebeccapurple; color: var(--query-status-user-colour);
background: var(--query-status-user-background);
border-radius: 4px; border-radius: 4px;
padding: 4px 8px; padding: 4px 8px;
@ -22,6 +28,19 @@
/* Same height as the icons used for loading/disconnected */ /* Same height as the icons used for loading/disconnected */
height: 35px; height: 35px;
} }
button {
color: var(--query-status-user-button-colour);
background: var(--query-status-user-button-background);
&:hover {
background: var(--query-status-user-button-hover-background);
}
&:focus-visible {
border-color: var(--query-status-user-button-focus);
}
}
} }
} }
@ -29,5 +48,23 @@
display: grid; display: grid;
grid-template-columns: 1fr 1fr; grid-template-columns: 1fr 1fr;
gap: 1rem; gap: 1rem;
button {
color: var(--query-status-control-colour);
background: var(--query-status-control-background);
&:hover {
background: var(--query-status-control-hover-background);
}
&:focus-visible {
border-color: var(--query-status-control-focus);
}
}
}
button {
border: 2px solid transparent;
outline: none;
} }
} }

View file

@ -0,0 +1,29 @@
#settings > .system {
.version-info {
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
gap: 8px;
.whats-new {
font-size: smaller;
}
}
.links {
display: flex;
justify-content: center;
align-items: center;
flex-direction: row;
flex-wrap: wrap;
gap: 8px;
list-style-type: none;
padding: 0;
margin: 0;
li {
margin: 0;
}
}
}

View file

@ -3,7 +3,6 @@
display: inline flex; display: inline flex;
color: var(--chip-colour); color: var(--chip-colour);
background: var(--chip-background); background: var(--chip-background);
border: 1px solid var(--chip-border-colour);
border-radius: 4px; border-radius: 4px;
.key { .key {

View file

@ -1,7 +1,7 @@
.taf > .window-content prose-mirror { .taf > .window-content prose-mirror {
color: var(--prosemirror-colour); color: var(--prosemirror-colour);
--table-row-color-odd: var(--steel-550); --table-row-color-odd: var(--prosemirror-table-row-color-odd);
--table-row-color-even: var(--steel-600); --table-row-color-even: var(--prosemirror-table-row-color-even);
background: var(--prosemirror-background); background: var(--prosemirror-background);
gap: 0; gap: 0;
@ -44,12 +44,12 @@
pre:has(> code), code:not(pre > code) { pre:has(> code), code:not(pre > code) {
padding: 4px 6px; padding: 4px 6px;
background: var(--steel-700); background: var(--prosemirror-code-background);
color: var(--steel-200); color: var(--prosemirror-code-colour);
} }
blockquote { blockquote {
color: inherit; color: inherit;
border-left: 2px solid var(--steel-200); border-left: 2px solid var(--prosemirror-blockquote-border);
} }
} }

View file

@ -31,3 +31,4 @@
@import url("./Apps/PlayerSheet.css") layer(apps); @import url("./Apps/PlayerSheet.css") layer(apps);
@import url("./Apps/QueryStatus.css") layer(apps); @import url("./Apps/QueryStatus.css") layer(apps);
@import url("./Apps/TAFDocumentSheetConfig.css") layer(apps); @import url("./Apps/TAFDocumentSheetConfig.css") layer(apps);
@import url("./Apps/TAFSettingsSidebar.css") layer(apps);

View file

@ -7,6 +7,11 @@
--prosemirror-menu-colour: var(--steel-100); --prosemirror-menu-colour: var(--steel-100);
--prosemirror-menu-background: var(--steel-750); --prosemirror-menu-background: var(--steel-750);
--prosemirror-divider-colour: var(--steel-250); --prosemirror-divider-colour: var(--steel-250);
--prosemirror-table-row-color-odd: var(--steel-550);
--prosemirror-table-row-color-even: var(--steel-600);
--prosemirror-code-colour: var(--steel-200);
--prosemirror-code-background: var(--steel-700);
--prosemirror-blockquote-border: var(--steel-200);
--spinner-outer-colour: white; --spinner-outer-colour: white;
--spinner-inner-colour: #FF3D00; --spinner-inner-colour: #FF3D00;
@ -81,10 +86,23 @@
--attribute-sheet-toggle-slider-enabled-colour: var(--item-sheet-toggle-slider-enabled-colour); --attribute-sheet-toggle-slider-enabled-colour: var(--item-sheet-toggle-slider-enabled-colour);
--attribute-sheet-toggle-slider-disabled-colour: var(--item-sheet-toggle-slider-disabled-colour); --attribute-sheet-toggle-slider-disabled-colour: var(--item-sheet-toggle-slider-disabled-colour);
/* Query Status App Variables */
--query-status-colour: var(--steel-100);
--query-status-background: var(--steel-800);
--query-status-user-colour: var(--steel-100);
--query-status-user-background: var(--steel-700);
--query-status-user-button-colour: var(--steel-100);
--query-status-user-button-background: var(--steel-600);
--query-status-user-button-focus: var(--zinc-100);
--query-status-user-button-hover-background: var(--steel-650);
--query-status-control-colour: var(--steel-100);
--query-status-control-background: var(--steel-600);
--query-status-control-focus: var(--zinc-100);
--query-status-control-hover-background: var(--steel-650);
/* Chip Variables */ /* Chip Variables */
--chip-colour: #fff7ed; --chip-colour: var(--steel-100);
--chip-background: #2b3642; --chip-background: var(--steel-600);
--chip-value-colour: #fff7ed; --chip-value-colour: var(--steel-100);
--chip-value-background: #10161d; --chip-value-background: var(--steel-500);
--chip-border-colour: var(--chip-value-background);
} }

View file

@ -1,16 +1,108 @@
.theme-light { .theme-light {
--prosemirror-background: white; /* Prose Mirror Elements */
--prosemirror-colour: var(--zinc-700);
--prosemirror-background: var(--zinc-300);
--prosemirror-toggle-background: var(--zinc-350);
--prosemirror-toggle-hover-background: var(--zinc-400);
--prosemirror-menu-colour: var(--zinc-700);
--prosemirror-menu-background: var(--zinc-350);
--prosemirror-divider-colour: var(--zinc-600);
--prosemirror-table-row-color-odd: var(--zinc-350);
--prosemirror-table-row-color-even: var(--zinc-400);
--prosemirror-code-colour: var(--zinc-800);
--prosemirror-code-background: var(--zinc-400);
--prosemirror-blockquote-border: var(--zinc-500);
--spinner-outer-colour: black; --spinner-outer-colour: var(--steel-600);
--spinner-inner-colour: #FF3D00; --spinner-inner-colour: #FF3D00;
--tab-button-active: rebeccapurple; --toggle-background-colour: var(--zinc-350);
--tab-button-hover-bg: var(--color-light-3); --toggle-slider-unchecked-colour: red;
--toggle-slider-checked-colour: green;
--tab-nav-divider-colour: var(--zinc-300);
--tab-button-colour: var(--zinc-550);
--tab-button-focus-colour: var(--zinc-750);
--tab-button-hover-colour: var(--zinc-800);
--tab-button-active-colour: var(--zinc-900);
/* Actor Sheet Variables */
--actor-sheet-colour: var(--zinc-800);
--actor-sheet-background: var(--zinc-200);
--actor-sheet-divider-colour: var(--zinc-300);
--actor-sheet-header-colour: var(--zinc-800);
--actor-sheet-header-background:var(--zinc-100);
--actor-sheet-header-input-colour: var(--zinc-800);
--actor-sheet-header-input-background: var(--zinc-250);
--inventory-summary-colour: var(--zinc-600);
--inventory-summary-background: var(--zinc-100);
--inventory-input-colour: var(--zinc-700);
--inventory-input-background: var(--zinc-250);
--inventory-input-disabled-colour: var(--zinc-500);
--embedded-list-header-colour: var(--inventory-summary-colour);
--embedded-list-header-background: var(--inventory-summary-background);
--embedded-list-header-input-colour: var(--inventory-input-colour);
--embedded-list-header-input-background: var(--inventory-input-background);
--attribute-colour: var(--zinc-700);
--attribute-background: var(--zinc-300);
--attribute-input-colour: var(--zinc-700);
--attribute-input-background: var(--zinc-350);
--attribute-input-focus-colour: var(--zinc-700);
--attribute-button-active-background: var(--zinc-400);
--attribute-disabled-input-colour: var(--zinc-500);
--item-card-colour: var(--zinc-800);
--item-card-background: var(--zinc-300);
--item-card-header-colour: var(--zinc-800);
--item-card-header-background: var(--zinc-300);
--item-card-header-input-colour: var(--zinc-700);
--item-card-header-input-background: var(--zinc-350);
--item-card-header-input-focus-colour: var(--zinc-700);
--item-card-header-disabled-input-colour: var(--zinc-700);
/* Item Sheet Variables */
--item-sheet-colour: var(--zinc-800);
--item-sheet-background: var(--zinc-200);
--item-sheet-divider-colour: var(--zinc-300);
--item-sheet-input-colour: var(--zinc-800);
--item-sheet-input-background: var(--zinc-300);
--item-sheet-toggle-slider-enabled-colour: green;
--item-sheet-toggle-slider-disabled-colour: red;
--item-sheet-description-menu-colour: var(--zinc-800);
--item-sheet-description-menu-background: var(--zinc-350);
--item-sheet-description-content-background: var(--zinc-300);
/* Attribute Sheet Variables */
--attribute-sheet-colour: var(--item-sheet-colour);
--attribute-sheet-background: var(--item-sheet-background);
--attribute-sheet-divider-colour: var(--item-sheet-divider);
--attribute-sheet-hint-colour: var(--zinc-550);
--attribute-sheet-input-colour: var(--item-sheet-input-colour);
--attribute-sheet-input-background: var(--item-sheet-input-background);
--attribute-sheet-disabled-input-colour: var(--zinc-550);
--attribute-sheet-toggle-slider-enabled-colour: var(--item-sheet-toggle-slider-enabled-colour);
--attribute-sheet-toggle-slider-disabled-colour: var(--item-sheet-toggle-slider-disabled-colour);
/* Query Status App Variables */
--query-status-colour: var(--zinc-800);
--query-status-background: var(--zinc-200);
--query-status-user-colour: var(--zinc-800);
--query-status-user-background: var(--zinc-300);
--query-status-user-button-colour: var(--steel-700);
--query-status-user-button-background: var(--zinc-350);
--query-status-user-button-focus: var(--steel-700);
--query-status-user-button-hover-background: var(--zinc-400);
--query-status-control-colour: var(--steel-700);
--query-status-control-background: var(--zinc-350);
--query-status-control-focus: var(--steel-700);
--query-status-control-hover-background: var(--zinc-400);
/* Chip Variables */ /* Chip Variables */
--chip-colour: #18181b; --chip-colour: ;
--chip-background: #fafafa; --chip-background: ;
--chip-value-colour: #18181b; --chip-value-colour: ;
--chip-value-background: #d4d4d8aa; --chip-value-background: ;
--chip-border-colour: var(--chip-value-background);
} }

View file

@ -2,7 +2,7 @@
"id": "taf", "id": "taf",
"title": "Text-Based Actors", "title": "Text-Based Actors",
"description": "An intentionally minimalist system that enables you to play rules-light games without getting in your way!", "description": "An intentionally minimalist system that enables you to play rules-light games without getting in your way!",
"version": "3.0.0", "version": "3.0.2",
"download": "", "download": "",
"manifest": "", "manifest": "",
"url": "https://git.varify.ca/Foundry/taf", "url": "https://git.varify.ca/Foundry/taf",
@ -15,7 +15,8 @@
{ "name": "Oliver" } { "name": "Oliver" }
], ],
"esmodules": [ "esmodules": [
"module/main.mjs" "module/main.mjs",
"dev/dev.mjs"
], ],
"styles": [ "styles": [
{ {
@ -54,6 +55,7 @@
}, },
"socket": true, "socket": true,
"flags": { "flags": {
"forgejo_api": "https://git.varify.ca/api/v1",
"hotReload": { "hotReload": {
"extensions": ["css", "hbs", "json", "js", "mjs", "svg"], "extensions": ["css", "hbs", "json", "js", "mjs", "svg"],
"paths": ["templates", "langs", "styles", "module", "assets"] "paths": ["templates", "langs", "styles", "module", "assets"]

View file

@ -10,7 +10,7 @@
type="button" type="button"
data-action="executeTrigger" data-action="executeTrigger"
> >
Roll {{ localize "taf.misc.roll" }}
</button> </button>
{{/if}} {{/if}}
<input <input

View file

@ -18,6 +18,14 @@
<span class="name">{{ name }}</span> <span class="name">{{ name }}</span>
<span class="subtitle">{{ weight }}</span> <span class="subtitle">{{ weight }}</span>
</div> </div>
{{#if trigger}}
<button
type="button"
data-action="executeTrigger"
>
{{ localize "taf.misc.use" }}
</button>
{{/if}}
<input <input
id="{{uuid}}-quantity" id="{{uuid}}-quantity"
type="number" type="number"

View file

@ -0,0 +1,48 @@
<section class="system flexcol">
<h4 class="divider">
{{ system.title }}
</h4>
<div class="version-info">
<span class="version">
{{localize "taf.misc.version" version=system.version}}
</span>
<a
href="{{ system.url }}/releases/tag/v{{ system.version }}"
class="whats-new"
target="_blank"
rel="noopener noreferrer"
style="font-size: smaller"
>
{{localize "taf.misc.whats-new"}}
</a>
</div>
<ul class="links">
<li>
<a
href="{{ system.url }}/releases"
target="_blank"
rel="noopener noreferrer"
>
{{localize "taf.misc.releases"}}
</a>
</li>
<li>
<a
href="{{ system.url }}/wiki"
target="_blank"
rel="noopener noreferrer"
>
{{localize "taf.misc.wiki"}}
</a>
</li>
<li>
<a
href="{{ system.url }}/issues"
target="_blank"
rel="noopener noreferrer"
>
{{localize "taf.misc.issues"}}
</a>
</li>
</ul>
</section>