You've already forked obsidian-visualiser
Add spell picker in the character sheet
This commit is contained in:
@@ -3,11 +3,15 @@ import characterConfig from '#shared/character-config.json';
|
||||
import { Icon } from '@iconify/vue/dist/iconify.js';
|
||||
import PreviewA from '~/components/prose/PreviewA.vue';
|
||||
import { clamp } from '#shared/general.util';
|
||||
import type { SpellConfig } from '~/types/character';
|
||||
import type { CompiledCharacter, SpellConfig } from '~/types/character';
|
||||
import type { CharacterConfig } from '~/types/character';
|
||||
import { abilityTexts, CharacterCompiler, defaultCharacter, elementTexts, spellTypeTexts } from '~/shared/character.util';
|
||||
import { getText } from '~/shared/i18n';
|
||||
import { fakeA } from '~/shared/proses';
|
||||
import { abilityTexts, CharacterCompiler, defaultCharacter, elementTexts, spellTypeTexts } from '#shared/character.util';
|
||||
import { getText } from '#shared/i18n';
|
||||
import { fakeA } from '#shared/proses';
|
||||
import { div, dom, icon, text } from '#shared/dom.util';
|
||||
import markdown from '#shared/markdown.util';
|
||||
import { button, foldable } from '#shared/components.util';
|
||||
import { fullblocker, tooltip } from '~/shared/floating.util';
|
||||
|
||||
const config = characterConfig as CharacterConfig;
|
||||
|
||||
@@ -16,7 +20,7 @@ const { user } = useUserSession();
|
||||
|
||||
const { data, status, error } = await useFetch(`/api/character/${id}`);
|
||||
const compiler = new CharacterCompiler(data.value ?? defaultCharacter);
|
||||
const character = ref(compiler.compiled);
|
||||
const character = ref<CompiledCharacter>(compiler.compiled);
|
||||
/*
|
||||
text-light-red dark:text-dark-red border-light-red dark:border-dark-red bg-light-red dark:bg-dark-red
|
||||
text-light-blue dark:text-dark-blue border-light-blue dark:border-dark-blue bg-light-blue dark:bg-dark-blue
|
||||
@@ -29,9 +33,71 @@ text-light-yellow dark:text-dark-yellow border-light-yellow dark:border-dark-yel
|
||||
text-light-purple dark:text-dark-purple border-light-purple dark:border-dark-purple bg-light-purple dark:bg-dark-purple
|
||||
*/
|
||||
|
||||
function manageSpell()
|
||||
{
|
||||
function openSpellPanel() {
|
||||
const availableSpells = Object.values(config.spells).filter(spell => {
|
||||
if (spell.rank === 4) return false;
|
||||
if (character.value.spellranks[spell.type] < spell.rank) return false;
|
||||
return true;
|
||||
});
|
||||
|
||||
const textAmount = text(character.value.variables.spells.length.toString()), textMax = text(character.value.spellslots.toString());
|
||||
const container = div("border-light-35 dark:border-dark-35 bg-light-10 dark:bg-dark-10 border-l absolute top-0 bottom-0 right-0 w-[10%] data-[state=active]:w-1/2 flex flex-col gap-4 text-light-100 dark:text-dark-100 p-8 transition-[width] transition-delay-[150ms]", [
|
||||
div("flex flex-row justify-between items-center mb-4", [
|
||||
dom("h2", { class: "text-xl font-bold", text: "Ajouter un sort" }),
|
||||
div('flex flex-row gap-4 items-center', [ dom('span', { class: 'italic text-light-70 dark:text-dark-70 text-sm' }, [ textAmount, text(' / '), textMax, text(' sorts maitrisés') ]), tooltip(button(icon("radix-icons:cross-1", { width: 20, height: 20 }), () => {
|
||||
setTimeout(blocker.close, 150);
|
||||
container.setAttribute('data-state', 'inactive');
|
||||
}, "p-1"), "Fermer", "left") ])
|
||||
]),
|
||||
div('flex flex-col divide-y *:py-2 -my-2 overflow-y-auto', availableSpells.map(spell => {
|
||||
let state = character.value.lists.spells?.includes(spell.id) ? 'given' : character.value.variables.spells.includes(spell.id) ? 'choosen' : 'empty';
|
||||
const toggleText = text(state === 'choosen' ? 'Supprimer' : state === 'given' ? 'Inné' : 'Ajouter'), toggleButton = button(toggleText, () => {
|
||||
if(state === 'choosen')
|
||||
{
|
||||
compiler.variable('spells', character.value.variables.spells.filter(e => e !== spell.id));
|
||||
state = 'empty';
|
||||
}
|
||||
else if(state === 'empty')
|
||||
{
|
||||
compiler.variable('spells', [...character.value.variables.spells, spell.id]);
|
||||
state = 'choosen';
|
||||
}
|
||||
character.value = compiler.compiled;
|
||||
toggleText.textContent = state === 'choosen' ? 'Supprimer' : state === 'given' ? 'Inné' : 'Ajouter';
|
||||
textAmount.textContent = character.value.variables.spells.length.toString();
|
||||
}, "px-2 py-1 text-sm font-normal");
|
||||
toggleButton.disabled = state === 'given';
|
||||
return foldable(() => [
|
||||
markdown(spell.effect),
|
||||
], [ div("flex flex-row justify-between gap-2", [
|
||||
dom("span", { class: "text-lg font-bold", text: spell.name }),
|
||||
div("flex flex-row items-center gap-6", [
|
||||
div("flex flex-row text-sm gap-2",
|
||||
spell.elements.map(el =>
|
||||
dom("span", {
|
||||
class: [`border !border-opacity-50 rounded-full !bg-opacity-20 px-2 py-px`, elementTexts[el].class],
|
||||
text: elementTexts[el].text
|
||||
})
|
||||
)
|
||||
),
|
||||
div("flex flex-row text-sm gap-1", [
|
||||
...(spell.rank !== 4 ? [
|
||||
dom("span", { text: `Rang ${spell.rank}` }),
|
||||
text("/"),
|
||||
dom("span", { text: spellTypeTexts[spell.type] }),
|
||||
text("/")
|
||||
] : []),
|
||||
dom("span", { text: `${spell.cost} mana` }),
|
||||
text("/"),
|
||||
dom("span", { text: typeof spell.speed === "string" ? spell.speed : `${spell.speed} minutes` })
|
||||
]),
|
||||
toggleButton,
|
||||
]),
|
||||
]) ], { open: false, class: { container: "px-2 flex flex-col border-light-35 dark:border-dark-35", content: 'py-2' } });
|
||||
}))
|
||||
]);
|
||||
const blocker = fullblocker([ container ], { closeWhenOutside: true });
|
||||
setTimeout(() => container.setAttribute('data-state', 'active'), 1);
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -162,7 +228,7 @@ function manageSpell()
|
||||
</TabsContent>
|
||||
<TabsContent v-if="character.spellslots > 0" value="spells" class="overflow-y-auto max-h-full">
|
||||
<div class="flex flex-1 flex-col ps-8 gap-4 py-2">
|
||||
<div class="flex flex-1 justify-between items-baseline px-2"><div></div><div class="flex gap-4 items-baseline"><span class="italic text-light-70 dark:text-dark-70 text-sm">{{ character.variables.spells.length }} / {{ character.spellslots }} sorts maitrisés</span><Button class="!font-normal" @click="manageSpell">Modifier</Button></div></div>
|
||||
<div class="flex flex-1 justify-between items-baseline px-2"><div></div><div class="flex gap-4 items-baseline"><span class="italic text-light-70 dark:text-dark-70 text-sm">{{ character.variables.spells.length }} / {{ character.spellslots }} sorts maitrisés</span><Button class="!font-normal" @click="openSpellPanel">Modifier</Button></div></div>
|
||||
<div class="flex flex-col" v-if="[...(character.lists.spells ?? []), ...character.variables.spells].length > 0">
|
||||
<div class="pb-4 px-2 mt-4 border-b last:border-none border-light-30 dark:border-dark-30 flex flex-col" v-for="spell of [...(character.lists.spells ?? []), ...character.variables.spells].map(e => config.spells.find((f: SpellConfig) => f.id === e)).filter(e => !!e)">
|
||||
<div class="flex flex-row justify-between">
|
||||
|
||||
Reference in New Issue
Block a user