Skip to content

Commit

Permalink
fix: player & xp sections of builder are collapsible
Browse files Browse the repository at this point in the history
  • Loading branch information
valentine195 committed May 2, 2023
1 parent d6d2bee commit 8505873
Show file tree
Hide file tree
Showing 3 changed files with 223 additions and 112 deletions.
67 changes: 67 additions & 0 deletions src/builder/view/party/Collapsible.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
<script lang="ts">
export let open: boolean;
</script>

<details {open} on:toggle>
<summary>
<slot name="title" />
<div class="collapser">
<div class="handle" />
</div>
</summary>
<slot name="content" />
</details>

<style scoped>
details > summary {
outline: none;
display: flex !important;
align-items: center;
justify-content: space-between;
gap: 0.25rem;
list-style: none !important;
list-style-type: none !important;
min-height: 1rem;
border-top-left-radius: 0.1rem;
border-top-right-radius: 0.1rem;
cursor: pointer;
position: relative;
margin-bottom: 1rem;
}
details > summary::-webkit-details-marker,
details > summary::marker {
display: none !important;
}
details > summary > .collapser {
position: relative;
display: flex;
align-items: center;
}
details > summary .collapser > .handle {
transform: rotate(0deg);
transition: transform 0.25s;
background-color: currentColor;
-webkit-mask-repeat: no-repeat;
mask-repeat: no-repeat;
-webkit-mask-size: contain;
mask-size: contain;
-webkit-mask-image: var(--admonition-details-icon);
mask-image: var(--admonition-details-icon);
width: 20px;
height: 20px;
}
details[open] > summary .collapser > .handle {
transform: rotate(90deg);
}
details > summary {
border-bottom: 1px solid var(--background-modifier-border);
}
details > summary {
border-bottom: 1px solid var(--background-modifier-border);
}
</style>
97 changes: 59 additions & 38 deletions src/builder/view/party/Experience.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,18 @@
import { players } from "../../stores/players";
import { MODIFIERS_BY_COUNT, MODIFIER_THRESHOLDS } from "../../constants";
import { DEFAULT_UNDEFINED, XP_PER_CR } from "src/utils";
import { getContext } from "svelte";
import Collapsible from "./Collapsible.svelte";
const plugin = getContext("plugin");
if (!plugin.data.builder) {
plugin.data.builder = {
sidebarIcon: true,
showParty: true,
showXP: true
};
}
const open = plugin.data.builder.showXP;
const { thresholds, modifier: playerModifier } = players;
$: count = ([...$encounter.values()] ?? []).reduce((a, b) => {
Expand Down Expand Up @@ -47,48 +58,58 @@
</script>

<div class="xp-container">
<h5>Experience</h5>
<div class="xp">
<div class="encounter-difficulty">
<div class="difficulty container">
<strong class="header">Difficulty</strong>
<span>
{difficulty}
</span>
</div>
<div class="total container">
<strong class="header">XP</strong>
<span>
{xp ? xp.toLocaleString() : DEFAULT_UNDEFINED}
</span>
<Collapsible
{open}
on:toggle={() =>
(plugin.data.builder.showXP = !plugin.data.builder.showXP)}
>
<h5 slot="title">Experience</h5>
<div slot="content">
<div class="xp">
<div class="encounter-difficulty">
<div class="difficulty container">
<strong class="header">Difficulty</strong>
<span>
{difficulty}
</span>
</div>
<div class="total container">
<strong class="header">XP</strong>
<span>
{xp ? xp.toLocaleString() : DEFAULT_UNDEFINED}
</span>
</div>
<div class="adjusted container">
<strong class="header">Adjusted</strong>
<span>
{adjXP ? adjXP.toLocaleString() : DEFAULT_UNDEFINED}
</span>
</div>
</div>
<div class="thresholds">
{#each EXPERIENCE_THRESHOLDS as level}
<div
class="experience-threshold {level.toLowerCase()} container"
>
<strong class="experience-name header"
>{level}</strong
>
<span class="experience-amount">
{$thresholds[level].toLocaleString()} XP
</span>
</div>
{/each}
</div>
<br />
</div>
<div class="adjusted container">
<strong class="header">Adjusted</strong>
<span>
{adjXP ? adjXP.toLocaleString() : DEFAULT_UNDEFINED}
<div class="budget">
<h5 class="experience-name">Daily budget</h5>
<span class="experience-amount">
{$thresholds.Daily.toLocaleString()} XP
</span>
</div>
</div>
<div class="thresholds">
{#each EXPERIENCE_THRESHOLDS as level}
<div
class="experience-threshold {level.toLowerCase()} container"
>
<strong class="experience-name header">{level}</strong>
<span class="experience-amount">
{$thresholds[level].toLocaleString()} XP
</span>
</div>
{/each}
</div>
<br />
</div>
<div class="budget">
<h5 class="experience-name">Daily budget</h5>
<span class="experience-amount">
{$thresholds.Daily.toLocaleString()} XP
</span>
</div>
</Collapsible>
</div>

<style scoped>
Expand Down
171 changes: 97 additions & 74 deletions src/builder/view/party/Party.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,19 @@
import { players } from "../../stores/players";
import Experience from "./Experience.svelte";
import Collapsible from "./Collapsible.svelte";
const { party, generics } = players;
const plugin = getContext("plugin");
if (!plugin.data.builder) {
plugin.data.builder = {
sidebarIcon: true,
showParty: true,
showXP: true
};
}
const open = plugin.data.builder.showParty;
const defaultParty = plugin.data.defaultParty;
const parties = plugin.data.parties;
Expand Down Expand Up @@ -81,90 +90,104 @@
</script>

<div class="players-container">
<h5 class="player-header">Players</h5>
<div class="party">
{#if parties.length}
<div use:partyDropdown />
{/if}
</div>

<div class="players">
{#each $party as player (player.name)}
<div class="player" class:disabled={!player.enabled}>
<span class="player-name">{player.name}</span>
<div class="player-right">
<span>{player.level}</span>
<div
class="clickable-icon setting-editor-extra-setting-button"
aria-label={player.enabled ? "Disable" : "Enable"}
on:click={() => players.toggleEnabled(player)}
>
{#if player.enabled}
<div use:disable />
{:else}
<div use:enable />
{/if}
</div>
</div>
<Collapsible
{open}
on:toggle={() =>
(plugin.data.builder.showParty = !plugin.data.builder.showParty)}
>
<h5 class="player-header" slot="title">Players</h5>
<div slot="content">
<div class="party">
{#if parties.length}
<div use:partyDropdown />
{/if}
</div>
{/each}
{#each $generics as player, index}
<div class="player" class:disabled={!player.enabled}>
<input
type="number"
value={player.count}
on:input={(evt) =>
players.set(player, Number(evt.currentTarget.value))}
min="1"
/>
<span>Player(s)</span>
<div use:crossIcon />

<span>Level</span>
<input
type="number"
value={player.level}
on:input={(evt) =>
players.setLevel(
player,
Number(evt.currentTarget.value)
)}
min="1"
/>
<div class="player-right">
<div
class="clickable-icon setting-editor-extra-setting-button"
aria-label={player.enabled ? "Disable" : "Enable"}
on:click={() => players.toggleEnabled(player)}
>
{#if player.enabled}
<div use:disable />
{:else}
<div use:enable />
{/if}
</div>

<div class="players">
{#each $party as player (player.name)}
<div class="player" class:disabled={!player.enabled}>
<span class="player-name">{player.name}</span>
<div class="player-right">
<span>{player.level}</span>
<div
class="clickable-icon setting-editor-extra-setting-button"
aria-label={player.enabled
? "Disable"
: "Enable"}
on:click={() => players.toggleEnabled(player)}
>
{#if player.enabled}
<div use:disable />
{:else}
<div use:enable />
{/if}
</div>
</div>
</div>
{/each}
{#each $generics as player, index}
<div class="player" class:disabled={!player.enabled}>
<input
type="number"
value={player.count}
on:input={(evt) =>
players.set(
player,
Number(evt.currentTarget.value)
)}
min="1"
/>
<span>Player(s)</span>
<div use:crossIcon />

<span>Level</span>
<input
type="number"
value={player.level}
on:input={(evt) =>
players.setLevel(
player,
Number(evt.currentTarget.value)
)}
min="1"
/>
<div class="player-right">
<div
class="clickable-icon setting-editor-extra-setting-button"
aria-label={player.enabled
? "Disable"
: "Enable"}
on:click={() => players.toggleEnabled(player)}
>
{#if player.enabled}
<div use:disable />
{:else}
<div use:enable />
{/if}
</div>

<div
class="clickable-icon setting-editor-extra-setting-button"
on:click={() => players.remove(player)}
>
<div use:removeIcon />
</div>
</div>
</div>
{/each}
<div class="add-player">
<div
class="clickable-icon setting-editor-extra-setting-button"
on:click={() => players.remove(player)}
>
<div use:removeIcon />
</div>
on:click={add}
use:addIcon
/>
</div>
</div>
{/each}
<div class="add-player">
<div
class="clickable-icon setting-editor-extra-setting-button"
on:click={add}
use:addIcon
/>
</div>
</div>
</Collapsible>
</div>

<style scoped>
.players {
display: flex;
flex-flow: column;
Expand Down

0 comments on commit 8505873

Please sign in to comment.