Remember that stores exist

This commit is contained in:
Tobias Berger 2021-09-27 14:36:40 +02:00
parent d246a94f42
commit 7e04b635cd
6 changed files with 119 additions and 84 deletions

View file

@ -81,6 +81,10 @@
pointer-events: none; pointer-events: none;
> span {
font-weight: bold;
}
> ul { > ul {
text-align: center; text-align: center;
font-weight: bold; font-weight: bold;

View file

@ -1,45 +1,45 @@
<svelte:options immutable />
<script lang="ts"> <script lang="ts">
import type { Writable } from "svelte/store";
import { Message, MessageType } from "../shark/Message"; import { Message, MessageType } from "../shark/Message";
import { SharkGame } from "../shark/SharkGame"; import { SharkGame } from "../shark/SharkGame";
export let messages: Message[]; export let messages: Writable<Message[]>;
function addMessage( // Shorthand
message: string, function addMessage(message: string, messageType?: MessageType) {
messageType: MessageType = MessageType.message SharkGame.Log.addMessage(message, messageType);
) {
messages = [...messages, new Message(message, messageType)];
} }
$: logLength = SharkGame.Settings.logLength.current; $: logLength = SharkGame.Settings.logLength.current;
$: displaymessages = messages.slice(-logLength).reverse(); $: displayMessages = $messages.slice(-logLength).reverse();
</script> </script>
<div id="log"> <div id="log">
<button <button
on:click={() => { on:click={() => {
addMessage("message" + messages.length); addMessage("message" + $messages.length);
}}>Add Message</button }}>Add Message</button
> >
<button <button
on:click={() => { on:click={() => {
addMessage("warn" + messages.length, MessageType.warning); addMessage("warn" + $messages.length, MessageType.warning);
}}>Add Warning</button }}>Add Warning</button
> >
<button <button
on:click={() => { on:click={() => {
addMessage("error" + messages.length, MessageType.error); addMessage("error" + $messages.length, MessageType.error);
}}>Add Error</button }}>Add Error</button
> >
<button <button
on:click={() => { on:click={() => {
Message.even = true; SharkGame.Log.reset();
messages = [];
addMessage("Log cleared");
}}>Clear log</button }}>Clear log</button
> >
<ol> <ol>
{#each displaymessages as message, i} {#each displayMessages as message, i}
{#if i < logLength} {#if i < logLength}
<li class={(message.isEven ? "even" : "odd") + " " + message.type}> <li class={(message.isEven ? "even" : "odd") + " " + message.type}>
{message} {message}

View file

@ -0,0 +1,48 @@
<svelte:options immutable />
<script lang="ts">
import type { ResourceEntry } from "./ResourceTable.svelte";
export let categoryName: string;
export let collapsed: boolean;
export let resources: ResourceEntry[];
</script>
<tr on:click class="subhead" tabindex="0" role="button">
<td>{collapsed ? "▲" : "▼"}</td>
<td colspan="3"><h4>{categoryName}</h4> </td>
</tr>
{#if !collapsed}
{#each resources as [resourceName, resource], index}
<tr class={index % 2 === 0 ? "even" : "odd"}>
<td colspan="2">{resourceName}</td>
<td>{resource.amount}</td>
<td>{Math.round(100 * resource.change) / 100}/s</td>
</tr>
{/each}
{/if}
<style lang="scss">
tr {
&.even {
background-color: var(--color-med);
}
&.odd {
background-color: var(--color-light);
}
&.subhead {
cursor: pointer;
user-select: none;
background-color: var(--color-dark);
border: 1px solid var(--color-lighter);
> td > h4 {
margin: 0.3em;
}
&:hover > td > h4 {
text-shadow: 0 0 8px var(--color-lighter);
}
}
}
</style>

View file

@ -1,4 +1,7 @@
<script lang="ts"> <svelte:options immutable={true} />
<script context="module" lang="ts">
export type ResourceEntry = [string, typeof TEST_RESOURCES["Shark"]];
const TEST_RESOURCES = { const TEST_RESOURCES = {
Shark: { Shark: {
amount: 100, amount: 100,
@ -51,31 +54,38 @@
change: (Math.random() - 0.5) * 30, change: (Math.random() - 0.5) * 30,
}, },
}; };
</script>
<script lang="ts">
import ResourceGroup from "./ResourceGroup.svelte";
let collapsed: string[] = []; let collapsed: string[] = [];
$: grouped = Object.entries(resourceGroups()); $: groups = resourceGroups();
type Entry = [string, typeof TEST_RESOURCES["Shark"]];
function resourceGroups() { function resourceGroups() {
return Object.entries(TEST_RESOURCES).reduce( return Object.entries(
(reduced: { [key: string]: Entry[] }, [resourceName, resource]) => { Object.entries(TEST_RESOURCES).reduce(
if (reduced[resource.category] === undefined) { (
reduced[resource.category] = []; reduced: { [key: string]: ResourceEntry[] },
} [resourceName, resource]
reduced[resource.category] = [ ) => {
...reduced[resource.category], if (reduced[resource.category] === undefined) {
[resourceName, resource], reduced[resource.category] = [];
]; }
reduced[resource.category] = [
...reduced[resource.category],
[resourceName, resource],
];
return reduced; return reduced;
}, },
{} {}
)
); );
} }
function toggleCollapsed(categoryName: string) { function toggleCollapsed(categoryName: string) {
if (collapsed.includes(categoryName)) { if (collapsed.includes(categoryName)) {
collapsed = collapsed.filter((group) => group !== categoryName); collapsed = collapsed.filter((category) => category !== categoryName);
} else { } else {
collapsed = [...collapsed, categoryName]; collapsed = [...collapsed, categoryName];
} }
@ -91,25 +101,13 @@
<col style="width: 20%;" /> <col style="width: 20%;" />
</colgroup> </colgroup>
<tbody> <tbody>
{#each grouped as [categoryName, resources]} {#each groups as [categoryName, resources]}
<tr <ResourceGroup
on:click={() => toggleCollapsed(categoryName)} on:click={() => toggleCollapsed(categoryName)}
class="subhead" {categoryName}
tabindex="0" {resources}
role="button" collapsed={collapsed.includes(categoryName)}
> />
<td>{collapsed.includes(categoryName) ? "▲" : "▼"}</td>
<td colspan="3"><h4>{categoryName}</h4> </td>
</tr>
{#if !collapsed.includes(categoryName)}
{#each resources as [resourceName, resource], index}
<tr class={index % 2 === 0 ? "even" : "odd"}>
<td colspan="2">{resourceName}</td>
<td>{resource.amount}</td>
<td>{Math.round(100 * resource.change) / 100}/s</td>
</tr>
{/each}
{/if}
{/each} {/each}
</tbody> </tbody>
</table> </table>
@ -126,32 +124,6 @@
> table { > table {
width: 100%; width: 100%;
border-collapse: collapse; border-collapse: collapse;
> tbody {
> tr {
&.even {
background-color: var(--color-med);
}
&.odd {
background-color: var(--color-light);
}
&.subhead {
cursor: pointer;
user-select: none;
background-color: var(--color-dark);
border: 1px solid var(--color-lighter);
> td > h4 {
margin: 0.3em;
}
&:hover > td > h4 {
text-shadow: 0 0 8px var(--color-lighter);
}
}
}
}
} }
} }
</style> </style>

View file

@ -1,7 +1,7 @@
<script lang="ts"> <script lang="ts">
import { SharkGame } from "../shark/SharkGame"; import { SharkGame } from "../shark/SharkGame";
import Log from "./Log.svelte"; import Log from "./Log.svelte";
import ResourceTable from "./ResourceTable.svelte"; import ResourceTable from "./ResourceTable/ResourceTable.svelte";
</script> </script>
<main> <main>

View file

@ -1,15 +1,26 @@
import type { Message } from "./Message"; import { writable } from "svelte/store";
import { SharkGame } from "./SharkGame";
import { Message, MessageType } from "./Message";
import { Settings } from "./Settings";
import { StaticClass } from "./StaticClass"; import { StaticClass } from "./StaticClass";
export class Log extends StaticClass { export class Log extends StaticClass {
static #messages: Message[] = []; static messages = writable<Message[]>([]);
static get messages(): Message[] {
return this.#messages; static addMessage(
} message: string,
static set messages(messages: Message[]) { messageType: MessageType = MessageType.message
this.#messages = messages.slice( ): void {
-Math.max(...SharkGame.Settings.logLength.options) this.messages.update((oldMessages) =>
[...oldMessages, new Message(message, messageType)].slice(
-Math.max(...Settings.logLength.options)
)
); );
} }
static reset(): void {
Message.even = true;
this.messages.set([]);
this.addMessage("Log cleared");
}
} }