geoidesic
geoidesic
TTyphonJS
Created by geoidesic on 12/24/2024 in #typhonjs-runtime
Can the application to respond reactively to game.combat?
I tried this:
{{#if game.combat}}
<span class="ml-sm">
<Badge type="{{badgeType item}}">{{remaining item}}</Badge>
</span>
{{/if}}
{{#if game.combat}}
<span class="ml-sm">
<Badge type="{{badgeType item}}">{{remaining item}}</Badge>
</span>
{{/if}}
But it's not reactive. I also tried:
<script>
$: isCombat = game.combat
<script>
<template>
{{#if isCombat}}
<span class="ml-sm">
<Badge type="{{badgeType item}}">{{remaining item}}</Badge>
</span>
{{/if}}
</template>
<script>
$: isCombat = game.combat
<script>
<template>
{{#if isCombat}}
<span class="ml-sm">
<Badge type="{{badgeType item}}">{{remaining item}}</Badge>
</span>
{{/if}}
</template>
And also tried with game.combat.active, which provides a boolean value, but still not reactively.
22 replies
TTyphonJS
Created by geoidesic on 12/15/2024 in #typhonjs-runtime
TJS ChatMessage doesn't include the standard chat header
I'm having a weird problem (as usual for me) where in this paraticular system, chat messages that use a Svelte template are being generated without the standard header (i.e. time ago and trash can for deletion). I had it working fine in another system, ported it over to this system and now it's excluding the headers and I can't for the life of me figure out why. Any clues?
2 replies
TTyphonJS
Created by geoidesic on 12/14/2024 in #typhonjs-runtime
Get dynamic application width
I think there was a way to do this? I had a look at essential-svelte-esm but couldn't quite grok how to access application width from within my svelte app shell?
5 replies
TTyphonJS
Created by geoidesic on 11/29/2024 in #typhonjs-runtime
Can't open more than one character sheet at a time
I'm having some trouble figuring out what's causing this behaviour. Any clues?
foundry.js:655 Error: An error occurred while rendering FF15ActorSheet 27. Cannot read properties of undefined (reading 'parentElement')
at Hooks.onError (foundry.js:654:24)
at 🎁call_wrapped [as call_wrapped] (libWrapper-wrapper.js:507:22)
at 🎁Hooks.onError#lib-wrapper (listeners.js:138:11)
at 🎁Hooks.onError#0 (libWrapper-wrapper.js:187:52)
at foundry.js:5795:13
Caused by: TypeError: Cannot read properties of undefined (reading 'parentElement')
at FF15ActorSheet._activateCoreListeners (foundry.js:6100:43)
at FF15ActorSheet._activateCoreListeners (SvelteApplication.js:229:13)
at FF15ActorSheet._render (foundry.js:5866:10)
at async FF15ActorSheet._render (SvelteApplication.js:886:7)
foundry.js:655 Error: An error occurred while rendering FF15ActorSheet 27. Cannot read properties of undefined (reading 'parentElement')
at Hooks.onError (foundry.js:654:24)
at 🎁call_wrapped [as call_wrapped] (libWrapper-wrapper.js:507:22)
at 🎁Hooks.onError#lib-wrapper (listeners.js:138:11)
at 🎁Hooks.onError#0 (libWrapper-wrapper.js:187:52)
at foundry.js:5795:13
Caused by: TypeError: Cannot read properties of undefined (reading 'parentElement')
at FF15ActorSheet._activateCoreListeners (foundry.js:6100:43)
at FF15ActorSheet._activateCoreListeners (SvelteApplication.js:229:13)
at FF15ActorSheet._render (foundry.js:5866:10)
at async FF15ActorSheet._render (SvelteApplication.js:886:7)
10 replies
TTyphonJS
Created by geoidesic on 10/15/2024 in #typhonjs-runtime
Is there any way to avoid 'game' is not defined lint error for vite build?
7:09:30 PM [vite-plugin-svelte] /Users/noeldacosta/code/foundryvtt-final-fantasy/src/components/organisms/item/shared/EffectsTab.svelte:172:768 'game' is not defined
170:
7:09:30 PM [vite-plugin-svelte] /Users/noeldacosta/code/foundryvtt-final-fantasy/src/components/organisms/item/shared/EffectsTab.svelte:172:768 'game' is not defined
170:
8 replies
TTyphonJS
Created by geoidesic on 9/26/2024 in #typhonjs-runtime
TJSGameSettings doesn't respect `onChange` option?
So if I have a standard settings registration:
function dontShowWelcome() {
game.settings.register(MODULE_ID, 'dontShowWelcome', {
name: game.i18n.localize('GAS.Setting.DontShowWelcome.Name'),
hint: game.i18n.localize('GAS.Setting.DontShowWelcome.Hint'),
scope: 'user',
config: true,
default: false,
type: Boolean,
onChange: () => {
alert('o');
}
});
function dontShowWelcome() {
game.settings.register(MODULE_ID, 'dontShowWelcome', {
name: game.i18n.localize('GAS.Setting.DontShowWelcome.Name'),
hint: game.i18n.localize('GAS.Setting.DontShowWelcome.Hint'),
scope: 'user',
config: true,
default: false,
type: Boolean,
onChange: () => {
alert('o');
}
});
The alert will trigger. However, if I wrap a setting via TJSGameSettings it won't trigger the onChange hook. E.g.
class trackerSettings extends TJSGameSettings {
this.register({
namespace,
key: "enable-tracker",
options: {
name: game.i18n.localize('Name'),
hint: game.i18n.localize('Hint'),
scope: "world",
config: true,
type: Boolean,
default: true,
onchange: () => {
alert('o');
}
}
});
class trackerSettings extends TJSGameSettings {
this.register({
namespace,
key: "enable-tracker",
options: {
name: game.i18n.localize('Name'),
hint: game.i18n.localize('Hint'),
scope: "world",
config: true,
type: Boolean,
default: true,
onchange: () => {
alert('o');
}
}
});
Am I doing it wrong?
3 replies
TTyphonJS
Created by geoidesic on 8/10/2024 in #typhonjs-runtime
How can I respond to the _onDrop event in the shell?
I'm working with a SvelteApplication. I can edit the _onDrop method on the sheet but how do I react to it in the svelte shell?
30 replies
TTyphonJS
Created by geoidesic on 8/1/2024 in #typhonjs-runtime
What's the best way to control default header items in a TJS application window?
No description
27 replies
TTyphonJS
Created by geoidesic on 7/24/2024 in #typhonjs-runtime
[vite] warning: Could not resolve import "#runtime/svelte/component/core"
I haven't seen this error before. WelcomeAppShell.svelte
import { ApplicationShell } from '#runtime/svelte/component/core';
import { ApplicationShell } from '#runtime/svelte/component/core';
Foundry v12, developing a new system. Any clues?
18 replies
TTyphonJS
Created by geoidesic on 6/28/2024 in #typhonjs-runtime
$actor.toObject() for a TJSDocument isn't reactive
I'm creating an actor in memory and assigning that to the TJSDocument on my application
export default class PCApplication extends SvelteApplication
{
/**
* Document store that monitors updates to any assigned document.
*
* @type {TJSDocument<foundry.abstract.Document>}
*/
#documentStore = new TJSDocument(void 0, { delete: this.close.bind(this) });

constructor(object) {
super(object);

// Define document store property
Object.defineProperty(this.reactive, "document", {
get: () => this.#documentStore.get(),
set: (document) => {
this.#documentStore.set(document);
},
});
this.reactive.document = object;
}

static get defaultOptions() {
const title = this.title;
return foundry.utils.mergeObject(super.defaultOptions, {
id: 'foundryvtt-actor-studio-pc-sheet',
title: game.i18n.localize('GAS.ActorStudio')+' - '+game.i18n.localize('GAS.PCTitle'),
classes: ['gas-actor-studio'],
width: 650,
height: 600,
headerIcon: 'modules/foundryvtt-actor-studio/assets/actor-studio-logo-dragon-white.svg',
minWidth: 500,
padding: 0,
resizable: true,
focusAuto: false,
minimizable: true,
svelte: {
class: PCAppShell,
target: document.body,
props: function () {
return { documentStore: this.#documentStore, document: this.reactive.document };
},
},
});
}
export default class PCApplication extends SvelteApplication
{
/**
* Document store that monitors updates to any assigned document.
*
* @type {TJSDocument<foundry.abstract.Document>}
*/
#documentStore = new TJSDocument(void 0, { delete: this.close.bind(this) });

constructor(object) {
super(object);

// Define document store property
Object.defineProperty(this.reactive, "document", {
get: () => this.#documentStore.get(),
set: (document) => {
this.#documentStore.set(document);
},
});
this.reactive.document = object;
}

static get defaultOptions() {
const title = this.title;
return foundry.utils.mergeObject(super.defaultOptions, {
id: 'foundryvtt-actor-studio-pc-sheet',
title: game.i18n.localize('GAS.ActorStudio')+' - '+game.i18n.localize('GAS.PCTitle'),
classes: ['gas-actor-studio'],
width: 650,
height: 600,
headerIcon: 'modules/foundryvtt-actor-studio/assets/actor-studio-logo-dragon-white.svg',
minWidth: 500,
padding: 0,
resizable: true,
focusAuto: false,
minimizable: true,
svelte: {
class: PCAppShell,
target: document.body,
props: function () {
return { documentStore: this.#documentStore, document: this.reactive.document };
},
},
});
}
Then to open the application:
new PCApplication(new Actor.implementation({ name: 'Name1', folder: folderName, type: actorType })).render(true, { focus: true });
new PCApplication(new Actor.implementation({ name: 'Name1', folder: folderName, type: actorType })).render(true, { focus: true });
PCAppShell does:
export let documentStore;
setContext("#doc", documentStore);
export let documentStore;
setContext("#doc", documentStore);
Then later in another componentI do this:
const doc = getContext('#doc')
$doc.name = "Name2"
console.log($doc.name) //<-- outputs "Name2"
console.log($doc.toObject().name) //<-- outputs "Name1", which is unexpected.
const doc = getContext('#doc')
$doc.name = "Name2"
console.log($doc.name) //<-- outputs "Name2"
console.log($doc.toObject().name) //<-- outputs "Name1", which is unexpected.
4 replies
TTyphonJS
Created by geoidesic on 6/21/2024 in #typhonjs-runtime
v12 seems to break item reactivity for createFilterQuery
I've been trying out my system on v12. Something I notice is that some of my reactive components are no longer reactive. Specifically where I've used createFilterQuery. I don't get any errors but when the items in the wildcard list are changed, the view doesn't update. I mean the filter select still works reactively but if any of the values of the items in the list are altered, or if the core list changes (e.g. item is added or deleted from the original unfiltered list) those changes aren't reactively rendered. I don't understand why that might be but I've tested the same code in both v11 and v12 and it's working in v11. My svelte component looks something like this:
$: typeSearch.set(typeFilterValue);
$: items = [...$wildcard];

/** @type {import('@typhonjs-fvtt/runtime/svelte/store').DynMapReducer<string, Item>} */
const wildcard = doc.embedded.create(Item, {
name: "wildcard",
filters: [nameSearch, typeSearch],
sort: (a, b) => a.name.localeCompare(b.name),
});
$: typeSearch.set(typeFilterValue);
$: items = [...$wildcard];

/** @type {import('@typhonjs-fvtt/runtime/svelte/store').DynMapReducer<string, Item>} */
const wildcard = doc.embedded.create(Item, {
name: "wildcard",
filters: [nameSearch, typeSearch],
sort: (a, b) => a.name.localeCompare(b.name),
});
<template>
<Select options {typeFilterOptions} bind:value={typeFilterValue} />
{#each items as item (item.id)}
.. various item properties
{/each}
<template>
<Select options {typeFilterOptions} bind:value={typeFilterValue} />
{#each items as item (item.id)}
.. various item properties
{/each}
It might not precisely be to do with createFilterQuery. I'm not sure yet why it's happening, but certainly, what was working in v11 is not working in v12.
4 replies
TTyphonJS
Created by geoidesic on 6/19/2024 in #typhonjs-runtime
How to avoid Foundry Globals from causing vite build warnings?
I'm getting a lot of warnings from vite-plugin-svelte for foundry globals like TextEditor.enrichHTML(item.system.description.value || '') . Any idea how I can make it ignore those or register them? E.g.:
1:00:29 PM [vite-plugin-svelte] /Users/me/path/ItemGrant.svelte:35:153 'TextEditor' is not defined
1:00:29 PM [vite-plugin-svelte] /Users/me/path/ItemGrant.svelte:35:153 'TextEditor' is not defined
26 replies
TTyphonJS
Created by geoidesic on 6/15/2024 in #typhonjs-runtime
Dynamic Imports work on dev server but not in build?
I'm having something weird. I'm doing dynamic async imports for certain dynamic components. It's working just find when run via a dev server (e.g. npm run dev) but once I build it, then the imports break. From the error message it seems that the import is done via URL, rather than via code. The URL exists and is browsable in the dev server, but not once built. Am I doing it wrong? Or are dynamic imports not available to the build? E.g.
const importComponent = async (importPath, componentName) => {
const { default: Component } = await import(
/* @vite-ignore */ `../${importPath}${componentName}.svelte`
);
return Component;
};

let importPath;

<div class="tab-content">
{#each tabs as tab}
{#if tab.id === activeTab}
{#if typeof tab.component === 'object'}
<svelte:component this={tab.component} />
{/if}
{#if typeof tab.component === 'string' && importPath}
{#await importComponent(importPath, tab.component)}
<i class="spinner fas fa-circle-notch fa-spin"></i>
{:then Component}
<svelte:component this={Component} />
{:catch error}
<p>Error loading component: {error.message}</p>
{/await}
{/if}
{/if}
{/each}
</div>
</div>
const importComponent = async (importPath, componentName) => {
const { default: Component } = await import(
/* @vite-ignore */ `../${importPath}${componentName}.svelte`
);
return Component;
};

let importPath;

<div class="tab-content">
{#each tabs as tab}
{#if tab.id === activeTab}
{#if typeof tab.component === 'object'}
<svelte:component this={tab.component} />
{/if}
{#if typeof tab.component === 'string' && importPath}
{#await importComponent(importPath, tab.component)}
<i class="spinner fas fa-circle-notch fa-spin"></i>
{:then Component}
<svelte:component this={Component} />
{:catch error}
<p>Error loading component: {error.message}</p>
{/await}
{/if}
{/if}
{/each}
</div>
</div>
So this works if I run the dev server. It seems to find it via URL:
http://localhost:30001/modules/foundryvtt-my-module/components/organisms/dnd5e/Tabs/Abilities.svelte
http://localhost:30001/modules/foundryvtt-my-module/components/organisms/dnd5e/Tabs/Abilities.svelte
However, once built, the path it looks for changes, leaving out the module id and reporting a 404:
http://localhost:3000/modules/components/organisms/dnd5e/Tabs/Abilities.svelte
http://localhost:3000/modules/components/organisms/dnd5e/Tabs/Abilities.svelte
Even if I correct the ommssion in the URL manually I still see a 404 Any ideas?
22 replies
TTyphonJS
Created by geoidesic on 6/10/2024 in #typhonjs-runtime
Can I use markdown with TJSProseMirror?
No description
2 replies
TTyphonJS
Created by geoidesic on 5/31/2024 in #typhonjs-runtime
What's the TJS way to extend FormApplication?
Specifically I want a custom type to register a component via game.settings.register e.g. a multi-select or checkbox list. E.g. I currently have this:
game.settings.registerMenu(MODULE_ID, SettingKeys.SOURCES, {
name: 'compendiums'),
label: 'Compendiums'),
icon: 'fas fa-atlas',
type: CompendiumSourcesSubmenu,
restricted: true,
});
game.settings.registerMenu(MODULE_ID, SettingKeys.SOURCES, {
name: 'compendiums'),
label: 'Compendiums'),
icon: 'fas fa-atlas',
type: CompendiumSourcesSubmenu,
restricted: true,
});
But I would like that CompendiumSourcesSubmenu to be a svelte component, rather than the TypeScript / Handlebars extension to FormApplication that it currently is (as it has been ported from an existing module)
9 replies
TTyphonJS
Created by geoidesic on 5/23/2024 in #typhonjs-runtime
dnd5e reactivity with race.advancement.byID
I'm having trouble when fetching a race byUuid with one particular reactive var:
const selectHandler = async (option) => {
race = await fromUuid(option);
console.log(source); //<-- works
console.log(adv); //<-- undefined
console.log(race.advancement.byId); //<-- works
}
$: source = race?.system?.source;
$: adv = race?.advancement?.byId;
const selectHandler = async (option) => {
race = await fromUuid(option);
console.log(source); //<-- works
console.log(adv); //<-- undefined
console.log(race.advancement.byId); //<-- works
}
$: source = race?.system?.source;
$: adv = race?.advancement?.byId;
Any ideas? Why adv is undefined? (The only special thing about byId is that it's a getter)
7 replies
TTyphonJS
Created by geoidesic on 5/21/2024 in #typhonjs-runtime
Error in $doc.update()?
I'm not quite sure if I'm doing it wrong. The error I'm getting is:
foundry.js:13637 Uncaught (in promise) Error: You must provide an _id for every object in the update data Array.
at #preUpdateDocumentArray (foundry.js:13637:32)
at ClientDatabaseBackend._updateDocuments (foundry.js:13449:73)
at ClientDatabaseBackend.update (commons.js:8677:19)
at async Actor5e.updateDocuments (commons.js:8001:23)
at async Actor5e.update (commons.js:8098:23)
foundry.js:13637 Uncaught (in promise) Error: You must provide an _id for every object in the update data Array.
at #preUpdateDocumentArray (foundry.js:13637:32)
at ClientDatabaseBackend._updateDocuments (foundry.js:13449:73)
at ClientDatabaseBackend.update (commons.js:8677:19)
at async Actor5e.updateDocuments (commons.js:8001:23)
at async Actor5e.update (commons.js:8098:23)
Here's the component
<script>
import { log, update } from "~/src/helpers/Utility";
import { Timing } from "@typhonjs-fvtt/runtime/util";
import { createEventDispatcher, getContext, onDestroy, onMount } from "svelte";

export let document = false;

const dispatch = createEventDispatcher();
const doc = document || getContext("#doc");
const updateDebounce = (path) => Timing.debounce($doc.update({[path]: event.target.value }), 300);

$: systemAbilities = game.system.config.abilities
$: systemAbilitiesArray = Object.entries(systemAbilities);

</script>

<template lang="pug">
.attribute-entry.mt-sm
+each("systemAbilitiesArray as ability, index")
.flexrow.mb-sm
.flex1 {ability[1].label}
.flex3.right
input(type="number" value="{$doc.system.abilities[ability[1].abbreviation].value}" on:input="{updateDebounce(`system.abilities.${ability[1].abbreviation}.value`)}" style="width: 40px")

</template>
<script>
import { log, update } from "~/src/helpers/Utility";
import { Timing } from "@typhonjs-fvtt/runtime/util";
import { createEventDispatcher, getContext, onDestroy, onMount } from "svelte";

export let document = false;

const dispatch = createEventDispatcher();
const doc = document || getContext("#doc");
const updateDebounce = (path) => Timing.debounce($doc.update({[path]: event.target.value }), 300);

$: systemAbilities = game.system.config.abilities
$: systemAbilitiesArray = Object.entries(systemAbilities);

</script>

<template lang="pug">
.attribute-entry.mt-sm
+each("systemAbilitiesArray as ability, index")
.flexrow.mb-sm
.flex1 {ability[1].label}
.flex3.right
input(type="number" value="{$doc.system.abilities[ability[1].abbreviation].value}" on:input="{updateDebounce(`system.abilities.${ability[1].abbreviation}.value`)}" style="width: 40px")

</template>
Normally (e.g. in my system, as opposed to this module) $doc.update() just works for me. I haven't seen this _id error before. It seems weird because update is being called on $doc, which is a TJSDocument instance of the actor, so it has the _id already I would expect.
5 replies
TTyphonJS
Created by geoidesic on 5/11/2024 in #typhonjs-runtime
local link of the runtime
Because the current runtime has some build issues and also because I am trying to debug something (i.e. application css overflow), I would like to be able to edit the runtime. I tried editing the runtime in node_modules but changes weren't seen (even after clearing vite-cache. Yarn offers yarn patch and yarn link which are potential solutions. However, when I tried to git clone [email protected]:typhonjs-fvtt-lib/typhonjs.git I got confused because it does not contain the same folders / files as in node_modules @typhonjs-fvtt/runtime. So the question is how do I get a local, editable copy of the runtime linked to my local module for debugging? Specifically I want to edit and debug in @typhonjs-fvtt/runtime/_dist/svelte/component/core/application/ApplicationShell
7 replies
TTyphonJS
Created by geoidesic on 5/10/2024 in #typhonjs-runtime
importing from the runtime
I see this in the template-svelte-esm example:
import { ApplicationShell } from '#runtime/svelte/component/core';
import { ApplicationShell } from '#runtime/svelte/component/core';
I'm not familiar with this syntax – i.e. the # here in the path. What does it mean and what enables it? I looked in vite.config.js and the # symbol doesn't appear in that file. I also couldn't find anything about that being standard sugar for ESM6 syntax.
5 replies
TTyphonJS
Created by geoidesic on 5/10/2024 in #typhonjs-runtime
lang localization in svelte template?
So far I've only managed to do this via data-tooltip, which picks up the localization string magically (presumably a FoundryVTT feature). What's the best way to use localization strings in a TJS-inspired svelte template directly? I tried this:
export const lang = game.i18n.localize;

<header> {lang("MY.langstring")} </header>
export const lang = game.i18n.localize;

<header> {lang("MY.langstring")} </header>
... but no go
33 replies