ND
Nekro Darkmoon209d ago
<script>
import { getContext, onDestroy } from "svelte";

import { ApplicationShell } from "#runtime/svelte/component/core";
import { TJSDocument } from "#runtime/svelte/store/fvtt/document";
import { DynMapReducer } from "#runtime/svelte/store/reducer";
import { TJSInput } from "#standard/component";

import CompendiumFilters from "../components/CompendiumFilters.svelte";
import CompendiumItemList from "../components/CompendiumItemList.svelte";
import Spinner from "../components/Spinner.svelte";

import {
addTJSDocumentSearchFilter,
removeSearchFilter,
} from "../handlers/handleSearchFilter";

async function getDocuments(docList) {
// Sort the documents into alphabetical order
docList.sort((a, b) => a.name.localeCompare(b.name));

const validDocs = new Map();

// Create a TJSDocument for each document in the compendium. Filter out invalid docs.
await Promise.all(
docList.map(async ({ _id, uuid }) => {
const doc = new TJSDocument();
const setSuccessfully = await doc.setFromUUID(uuid);

if (setSuccessfully) validDocs.set(_id, doc);
})
);

return validDocs;
}

export let { compendiumType, document, sheet } =
getContext("#external").application;

export let elementRoot;

let reducer = new DynMapReducer();
let loading = true;

const searchInput = addTJSDocumentSearchFilter(reducer);
onDestroy(() => removeSearchFilter(reducer));

// Fake an async operation in svelte to get around the fact that we can't await in the script tag
Promise.resolve(getDocuments([...document.index])).then((docs) => {
reducer.setData(docs, true);
reducer.index.update();
loading = false;
});
</script>

<ApplicationShell bind:elementRoot>
<main>
<CompendiumFilters {compendiumType} />

<div class="search-field">
<TJSInput
input={searchInput}
--tjs-input-placeholder-color="#555"
--tjs-input-text-margin="0"
--tjs-input-text-width="100%"
/>
</div>

{#if loading}
<div class="spinner-wrapper">
<Spinner />
</div>
{:else}
<CompendiumItemList documents={[...$reducer]} {compendiumType} />
{/if}
</main>
</ApplicationShell>
<script>
import { getContext, onDestroy } from "svelte";

import { ApplicationShell } from "#runtime/svelte/component/core";
import { TJSDocument } from "#runtime/svelte/store/fvtt/document";
import { DynMapReducer } from "#runtime/svelte/store/reducer";
import { TJSInput } from "#standard/component";

import CompendiumFilters from "../components/CompendiumFilters.svelte";
import CompendiumItemList from "../components/CompendiumItemList.svelte";
import Spinner from "../components/Spinner.svelte";

import {
addTJSDocumentSearchFilter,
removeSearchFilter,
} from "../handlers/handleSearchFilter";

async function getDocuments(docList) {
// Sort the documents into alphabetical order
docList.sort((a, b) => a.name.localeCompare(b.name));

const validDocs = new Map();

// Create a TJSDocument for each document in the compendium. Filter out invalid docs.
await Promise.all(
docList.map(async ({ _id, uuid }) => {
const doc = new TJSDocument();
const setSuccessfully = await doc.setFromUUID(uuid);

if (setSuccessfully) validDocs.set(_id, doc);
})
);

return validDocs;
}

export let { compendiumType, document, sheet } =
getContext("#external").application;

export let elementRoot;

let reducer = new DynMapReducer();
let loading = true;

const searchInput = addTJSDocumentSearchFilter(reducer);
onDestroy(() => removeSearchFilter(reducer));

// Fake an async operation in svelte to get around the fact that we can't await in the script tag
Promise.resolve(getDocuments([...document.index])).then((docs) => {
reducer.setData(docs, true);
reducer.index.update();
loading = false;
});
</script>

<ApplicationShell bind:elementRoot>
<main>
<CompendiumFilters {compendiumType} />

<div class="search-field">
<TJSInput
input={searchInput}
--tjs-input-placeholder-color="#555"
--tjs-input-text-margin="0"
--tjs-input-text-width="100%"
/>
</div>

{#if loading}
<div class="spinner-wrapper">
<Spinner />
</div>
{:else}
<CompendiumItemList documents={[...$reducer]} {compendiumType} />
{/if}
</main>
</ApplicationShell>
So this would be our current usecase which is to get a list of all the available documents from a compendium I guess in this particular use case we don't really need the documents to be reactive since compendium don't really change. But we have other bits in the system that are a collection of different documents that need to keep track of changing data.
TM
TyphonJS (Michael)208d ago
This definitely brings up a possible inclusion of more utility helpers to TRL for compendium access as there is nothing available currently. As you mention quite likely wrapping each underlying compendium document in a TJSDocument instance is not necessary. Figuring out the best way to proceed w/ dynamic reducers (reactive embedded collections, etc.) and reactive document content for all documents being reduced will be interesting given the general constraints imposed by the Foundry core platform. Avoiding heavyweight / potentially error prone solutions (dangling listeners) is relatively tough or at least needs quite a bit of testing.
ND
Nekro Darkmoon208d ago
yeah
TM
TyphonJS (Michael)208d ago
I definitely appreciate the exploration angle w/ all of this I'd like to start rounding out convenience / helper code particularly for system devs in the Oct - Dec TRL dev push. In Auckland airport so back home soon; a couple of days until things start in earnest. If you have the time to catalog these general patterns across your system efforts it's something; I'd like to get a list of use cases for potential easy to use solutions.
ND
Nekro Darkmoon208d ago
Can try to that 😄 Currently trying to use SvelteApplication to set up something of a placeableHud 🤔
TM
TyphonJS (Michael)208d ago
Hmm.. Certainly check out the Position Basic demo using EmptyApplicationShell (I think) but that sounds a bit challenging if trying to sync up w/ canvas position around / near a token. IE canvas pans being pretty hard to accommodate; much easier w/out canvas movement.
ND
Nekro Darkmoon208d ago
currently I only need it to be in one position
ND
Nekro Darkmoon208d ago
I've had good luck with using the chat message rendering technique to modify the effects panel with svelte
No description
ND
Nekro Darkmoon208d ago
but for my current purposes there's no existing element already being rendered so that approach is not quite feasible. I could potentiall render an empty element and hook into that but I'd like to try to use a base application if possible for this one
TM
TyphonJS (Michael)208d ago
Yeah this demo in essential-svelte-esm likely is relevant if going for a full SvelteApplication approach. https://github.com/typhonjs-fvtt-demo/essential-svelte-esm/tree/main/src/view/position/basic-overlay
ND
Nekro Darkmoon208d ago
👌 ty ah EmptyApplicationShell is what I needed 😄
TM
TyphonJS (Michael)208d ago
Also don't overlook TJSContextMenu / use a single custom component in the data defined menu if creating a unique hud / menu that should automatically handle closing when focus is lost. This would be something responding to a click of a token HUD button. https://github.com/typhonjs-fvtt-lib/svelte-standard/blob/main/src/application/TJSContextMenu.js
ND
Nekro Darkmoon208d ago
I've not yet gotten the chance or had the need to use a ContextMenu but hopefully in the future 🤞 I have however used TJSMenu a lot 😄 I think the only problem I have with it though is that its hard to run an inspect element on it cz it loses focus and closes as soon as I click the inspect button 🤣
TM
TyphonJS (Michael)208d ago
Very similar, but could be used potentially for a button press of a token HUD; not actually for context clicking.
ND
Nekro Darkmoon208d ago
true
TM
TyphonJS (Michael)208d ago
As long as you are doing production builds you could modify the associated component and comment out this line temporarily: https://github.com/typhonjs-fvtt-lib/svelte-standard/blob/main/src/component/standard/menu/context/TJSContextMenuImpl.svelte / line 387 needs to be commented out.
ND
Nekro Darkmoon208d ago
🤔 that should help a lot ❤️ tyvm Btw can I use TJSPosition to track the position of a non svelte app 🤔 I've been doing new TJSPosition(document.querySelector('#ui-right')) but all the values in it are null
TM
TyphonJS (Michael)208d ago
I assume the #ui-right is the Foundry containing div for the sidebar. That is not what TJSPosition is for exactly especially since #ui-right is a div controlled by static CSS. It controls inline styles, but doesn't monitor things. There is a Svelte action for optimized resize observation, but not separated to use independently of the action. Basically, you'll need to use a ResizeObserver instance / build a custom solution for non-Svelte usage. You can get some ideas from the action: https://github.com/typhonjs-svelte/runtime-base/blob/main/src/svelte/action/dom/resizeObserver.js
ND
Nekro Darkmoon208d ago
hmmm i'll chck it out
TM
TyphonJS (Michael)208d ago
Should be import { resizeObserver } from '#runtime/svelte/action/dom';
ND
Nekro Darkmoon208d ago
const sidebarHook = Hooks.on("collapseSidebar", () => {
sidebarStartPosition = getRightPosition();
});

function getRightPosition() {
const uiRight = document.querySelector("#ui-right");
const uiRightRect = uiRight.getBoundingClientRect();
return uiRightRect.left;
}

onDestroy(() => {
console.log("Destroying A5EEffectsPanel");
Hooks.off("collapseSidebar", sidebarHook);
});

let sidebarStartPosition = getRightPosition();

const position = application.position;
const panelWidth = position.stores.width;
position.stores.top.set(20);

$: position.stores.left.set(sidebarStartPosition - $panelWidth - 5);
const sidebarHook = Hooks.on("collapseSidebar", () => {
sidebarStartPosition = getRightPosition();
});

function getRightPosition() {
const uiRight = document.querySelector("#ui-right");
const uiRightRect = uiRight.getBoundingClientRect();
return uiRightRect.left;
}

onDestroy(() => {
console.log("Destroying A5EEffectsPanel");
Hooks.off("collapseSidebar", sidebarHook);
});

let sidebarStartPosition = getRightPosition();

const position = application.position;
const panelWidth = position.stores.width;
position.stores.top.set(20);

$: position.stores.left.set(sidebarStartPosition - $panelWidth - 5);
This was the solution I came up with earlier going to try to see if the resizeObserver will work better but yeah we've been trying to fit svelte in whereever possible 🤣
ND
Nekro Darkmoon208d ago
No description
TM
TyphonJS (Michael)208d ago
What are you attempting to do w/ the sidebar constraints?
ND
Nekro Darkmoon208d ago
ND
Nekro Darkmoon208d ago
essentially having it stick to the sidebar imo there are 3 major hurdles I have to tackle for this project - Rendering the empty application ✅ - Sticking the rendered application to the left of the sidebar ❓ - Having a TJS document for the selected token and having it automatically change on selecting a different token
TM
TyphonJS (Michael)208d ago
So in FQL I have an app dock to the sidebar; this is the quest tracker. With TJSPosition you can set a "validator". I haven't updated this code in over a year as it was the initial porting test to TRL, but the early TRL solution for defining this validator is here and should help: https://github.com/typhonjs-fvtt/typhonjs-quest-log/blob/master/src/view/tracker2/PositionValidator.js And you can see usage in the constructor here which all still works given import statements are wrong for latest TRL: https://github.com/typhonjs-fvtt/typhonjs-quest-log/blob/master/src/view/tracker2/QuestTrackerApp.js So with TJSPosition you can do some really fancy things that I'm sure just myself is aware about. Alas kind of hard to provide this kind of solution for Foundry as it would take a lot of work to make it play nice between different packages.
ND
Nekro Darkmoon208d ago
hmmm interesting
Want results from more Discord servers?
Add your server
More Posts
Is there a way to export the quest log?I'm trying to setup a world for the PF2E Beginner Box but right now I working in a beta testing worFabricate@MisterPotts. Just starting a forum post to keep track of the conversation. > Fabricate doesn't maSvelte 5 TJSDocument PrototypeGreets @FVTT ▹ Developer. As some of you might have seen there is a bit of paradigm shift that is Funky interaction with fokus managementTJS's Focus Management is creating fun issues for me again. focusKeep = true causes my drag and dropHow to get rid of funky Prosemirror overlapHi. I'm getting some overlap with Prosemirror (see image) any ideas how to avoid that? ``` "@tyFQL / TextEditor enrichment issueFrom @ooblekie: > can anyone give me a hand as to why the text keeps coming up as object promise inTJSDocument not working properly with Module Sub-Types (Data Models)In Foundry, modules can define a [Sub-Types](<https://foundryvtt.com/article/module-sub-types/>) usiTRL `0.1.2` - Fine Tuning releaseGreets @FVTT ▹ Developer! I have just released a fine tuning release that brings a few more featureEmbed a DropDown/MenuList made with SvelteHello again! 😄 I've been pondering creating a second module for Foundry and a few questions poppedSlide Animations for SvelteApplicationI'd like my window ( which is an EmptyApplicationShell ) to play a slide-in animation when open andBug: Multiple ProseMirror editors on same svelte component do not save properlySimple reproduction in a foundry world with at least one actor defined: ``` <svelte:options accessorSystem Works in Dev Mode but not after buildAfter updating to 0.1.1, I noticed something odd happening. The TITAN system now seems to work whenError building after updating to TRL 0.1.1Recently updated the TITAN system to TRL 0.1.1, but when I `npm run build` it errors out. Not sure wTJSApplication Character Sheet odd behavior with unlinked tokensHas anyone else experienced weird when using a TJSApplication as a character sheet with unlinked tokTJSDocumentCollection best practices?Hi! I've got a little component I'm using whose purpose is basically to just show a tiny preview of Release `TRL 0.1.1` - Patch releaseGreets @FVTT ▹ Developer! I have just released a patch / fix release that fixes a small oversight iUncaught TypeError: $storeElementRoot is undefinedHi! Encountering the following error when trying to resize an application based on a TJSApplicationSPopcorn InitiativeJust opening a forum post to track @gerark progress w/ TRL & Svelte + an initial idea of implementinToken Action HUDLet's continue chatting about TAH here to keep track of discussion @larkinaboutPostcssConfig seem not workin with 0.1.0@mleahy sorry to bother i'm trying to use the postccs feature of the @typhonjs-fvtt/runtime on the