You've already forked obsidian-visualiser
Add back Loading Indicator, rework children caching, small visual improvement on character sheet and config management.
This commit is contained in:
13
app/app.vue
13
app/app.vue
@@ -1,13 +1,12 @@
|
||||
<template>
|
||||
<div class="text-light-100 dark:text-dark-100 flex bg-light-0 dark:bg-dark-0 h-screen overflow-hidden">
|
||||
<NuxtRouteAnnouncer/>
|
||||
<TooltipProvider>
|
||||
<NuxtLayout>
|
||||
<div class="xl:px-12 xl:py-8 lg:px-8 lg:py-6 px-6 py-3 flex flex-1 justify-center overflow-auto max-h-full max-w-full relative" id="mainContainer">
|
||||
<NuxtPage />
|
||||
</div>
|
||||
</NuxtLayout>
|
||||
</TooltipProvider>
|
||||
<NuxtLoadingIndicator :throttle="50"/>
|
||||
<NuxtLayout>
|
||||
<div class="xl:px-12 xl:py-8 lg:px-8 lg:py-6 px-6 py-3 flex flex-1 justify-center overflow-auto max-h-full max-w-full relative" id="mainContainer">
|
||||
<NuxtPage />
|
||||
</div>
|
||||
</NuxtLayout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ function create()
|
||||
useRequestFetch()('/api/campaign', {
|
||||
method: 'POST',
|
||||
body: { name: 'Margooning', public_notes: '', dm_notes: '', settings: {} },
|
||||
}).then(() => Toaster.add({ duration: 8000, content: 'Campagne créée', type: 'info' })).catch((e) => Toaster.add({ duration: 8000, title: 'Une erreur est survenue', content: e, type: 'error' }))
|
||||
}).then((result) => Toaster.add({ duration: 8000, content: 'Campagne créée', type: 'info' })).catch((e) => Toaster.add({ duration: 8000, title: 'Une erreur est survenue', content: e, type: 'error' }))
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -87,20 +87,6 @@ function create()
|
||||
</AlertDialogRoot>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col w-[360px] border border-light-35 dark:border-dark-35" v-for="campaign of campaigns.filter(e => e.status === 'ARCHIVED')">
|
||||
<NuxtLink :to="{ name: 'campaign-id', params: { id: campaign.id } }" class="group bg-light-10 dark:bg-dark-10 border-b border-light-35 dark:border-dark-35 p-2 flex flex-col gap-2">
|
||||
<div class="flex flex-row gap-8 ps-4 items-center">
|
||||
<div class="flex flex-1 flex-col gap-2 justify-center">
|
||||
<span class="text-lg font-bold group-hover:text-accent-blue">{{ campaign.name }}</span>
|
||||
<span class="border-b w-full border-light-50 dark:border-dark-50"></span>
|
||||
<div class="flex flex-row flex-1 items-stretch gap-4">
|
||||
<span class="text-sm">{{ campaign.members.length }} joueur{{ campaign.members.length === 1 ? '' : 's' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rounded-full w-[96px] h-[96px] border border-light-50 dark:border-dark-50 bg-light-100 dark:bg-dark-100 !bg-opacity-10"></div>
|
||||
</div>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
<div v-if="archives && archives.length > 0" class="flex flex-row w-full gap-8 justify-center items-center"><span class="border-t border-light-35 dark:border-dark-35 flex-1"></span><span class="text-lg font-semibold">Archives</span><span class="border-t border-light-35 dark:border-dark-35 flex-1"></span></div>
|
||||
<div v-if="archives && archives.length > 0" class="grid p-6 2xl:grid-cols-3 lg:grid-cols-2 grid-cols-1 gap-4 w-full">
|
||||
@@ -136,20 +122,6 @@ function create()
|
||||
</AlertDialogRoot>
|
||||
</div>
|
||||
</div>
|
||||
<div class="flex flex-col w-[360px] border border-light-35 dark:border-dark-35" v-for="campaign of campaigns.filter(e => e.status === 'ARCHIVED')">
|
||||
<NuxtLink :to="{ name: 'campaign-id', params: { id: campaign.id } }" class="group bg-light-10 dark:bg-dark-10 border-b border-light-35 dark:border-dark-35 p-2 flex flex-col gap-2">
|
||||
<div class="flex flex-row gap-8 ps-4 items-center">
|
||||
<div class="flex flex-1 flex-col gap-2 justify-center">
|
||||
<span class="text-lg font-bold group-hover:text-accent-blue">{{ campaign.name }}</span>
|
||||
<span class="border-b w-full border-light-50 dark:border-dark-50"></span>
|
||||
<div class="flex flex-row flex-1 items-stretch gap-4">
|
||||
<span class="text-sm">{{ campaign.members.length }} joueur{{ campaign.members.length === 1 ? '' : 's' }}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="rounded-full w-[96px] h-[96px] border border-light-50 dark:border-dark-50 bg-light-100 dark:bg-dark-100 !bg-opacity-10"></div>
|
||||
</div>
|
||||
</NuxtLink>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div v-else class="flex flex-col gap-2 items-center flex-1">
|
||||
|
||||
33
app/types/character.d.ts
vendored
33
app/types/character.d.ts
vendored
@@ -1,4 +1,4 @@
|
||||
import type { MAIN_STATS, ABILITIES, LEVELS, TRAINING_LEVELS, SPELL_TYPES, CATEGORIES, SPELL_ELEMENTS, ALIGNMENTS, RESISTANCES, DAMAGE_TYPES, WEAPON_TYPES } from "#shared/character.util";
|
||||
import type { MAIN_STATS, ABILITIES, LEVELS, TRAINING_LEVELS, SPELL_TYPES, CATEGORIES, SPELL_ELEMENTS, ALIGNMENTS, RESISTANCES, DAMAGE_TYPES, WEAPON_TYPES, PropertySum, ITEM_BUFFER_KEYS } from "#shared/character.util";
|
||||
import type { Localized } from "../types/general";
|
||||
|
||||
export type MainStat = typeof MAIN_STATS[number];
|
||||
@@ -57,11 +57,16 @@ export type CharacterVariables = {
|
||||
|
||||
money: number;
|
||||
};
|
||||
export type TreeStructure = {
|
||||
|
||||
name: string;
|
||||
};
|
||||
type CommonState = {
|
||||
capacity?: number;
|
||||
powercost?: number;
|
||||
};
|
||||
type ArmorState = { health?: number };
|
||||
type StateBufferKeys = typeof ITEM_BUFFER_KEYS[number];
|
||||
type ArmorState = { loss: number, health?: number, absorb?: { flat?: number, percent?: number } };
|
||||
type WeaponState = { attack?: number | string, hit?: number };
|
||||
type WondrousState = { };
|
||||
type MundaneState = { };
|
||||
@@ -72,11 +77,12 @@ type ItemState = {
|
||||
charges?: number;
|
||||
equipped?: boolean;
|
||||
state?: (ArmorState | WeaponState | WondrousState | MundaneState) & CommonState;
|
||||
buffer?: Partial<Record<StateBufferKeys, PropertySum>>;
|
||||
};
|
||||
export type CharacterConfig = {
|
||||
peoples: Record<string, RaceConfig>;
|
||||
training: Record<MainStat, Record<TrainingLevel, FeatureID[]>>;
|
||||
spells: Record<string, SpellConfig | ArtConfig>;
|
||||
spells: Record<string, SpellConfig>;
|
||||
aspects: Record<string, AspectConfig>;
|
||||
features: Record<FeatureID, Feature>;
|
||||
enchantments: Record<string, EnchantementConfig>;
|
||||
@@ -86,11 +92,12 @@ export type CharacterConfig = {
|
||||
freeaction: Record<string, { id: string, name: string, description: string }>;
|
||||
passive: Record<string, { id: string, name: string, description: string }>;
|
||||
texts: Record<i18nID, Localized>;
|
||||
trees: Record<string, TreeStructure>;
|
||||
|
||||
//Each of these groups extend an existing feature as they all use the same properties
|
||||
sickness: Record<FeatureID, { stage: number }>; //TODO
|
||||
poisons: Record<FeatureID, { difficulty: number, efficienty: number, solubility: number }>; //TODO
|
||||
dedications: Record<FeatureID, { id: string, name: string, description: i18nID, effect: FeatureID[], requirement: Array<{ stat: MainStat, amount: number }> }>; //TODO
|
||||
sickness: Record<FeatureID, { name: string, stage: number }>; //TODO
|
||||
poisons: Record<FeatureID, { name: string, difficulty: number, efficienty: number, solubility: number }>; //TODO
|
||||
dedications: Record<FeatureID, { name: string, requirement: Array<{ stat: MainStat, amount: number }> }>; //TODO
|
||||
};
|
||||
export type EnchantementConfig = {
|
||||
id: string;
|
||||
@@ -142,7 +149,7 @@ export type SpellConfig = {
|
||||
id: string;
|
||||
name: string; //TODO -> TextID
|
||||
rank: 1 | 2 | 3 | 4;
|
||||
type: Exclude<SpellType, "arts">;
|
||||
type: SpellType;
|
||||
cost: number;
|
||||
speed: "action" | "reaction" | number;
|
||||
elements: Array<SpellElement>;
|
||||
@@ -191,7 +198,7 @@ export type FeatureEquipment = {
|
||||
id: FeatureID;
|
||||
category: "value";
|
||||
operation: "add" | "set" | "min";
|
||||
property: 'weapon/damage/value' | 'armor/health' | 'armor/absorb/flat' | 'armor/absorb/percent';
|
||||
property: StateBufferKeys;
|
||||
value: number | `modifier/${MainStat}` | false;
|
||||
}
|
||||
export type FeatureList = {
|
||||
@@ -228,13 +235,15 @@ export type CompiledCharacter = {
|
||||
race: string;
|
||||
spellslots: number; //Max
|
||||
artslots: number; //Max
|
||||
spellranks: Record<SpellType, 0 | 1 | 2 | 3>;
|
||||
spellranks: Record<SpellType | 'arts', 0 | 1 | 2 | 3>;
|
||||
aspect: {
|
||||
id: string,
|
||||
amount: number;
|
||||
duration: number;
|
||||
bonus: number;
|
||||
shift_bonus: number;
|
||||
tier: 0 | 1 | 2;
|
||||
|
||||
bonus?: Partial<CompiledCharacter['bonus']>;
|
||||
};
|
||||
speed: number | false;
|
||||
capacity: number | false;
|
||||
@@ -269,13 +278,13 @@ export type CompiledCharacter = {
|
||||
defense: Partial<Record<MainStat, number>>; //Defense aux jets de resistance
|
||||
abilities: Partial<Record<Ability, number>>;
|
||||
spells: {
|
||||
type: Partial<Record<SpellType, number>>;
|
||||
type: Partial<Record<SpellType | 'arts', number>>;
|
||||
rank: Partial<Record<1 | 2 | 3 | 4, number>>;
|
||||
elements: Partial<Record<SpellElement, number>>;
|
||||
};
|
||||
weapon: Partial<Record<WeaponType, number>>;
|
||||
resistance: Partial<Record<Resistance, number>>; //Bonus à l'attaque
|
||||
}; //Any special bonus goes here
|
||||
resistance: Partial<Record<Resistance, number>>; //Bonus à l'attaque
|
||||
|
||||
craft: { level: number, bonus: number };
|
||||
|
||||
|
||||
Reference in New Issue
Block a user