Fix some styling & layout things and use events instead of imports

- No component should import SharkGame except App.svelte, except *as a type*
  - use props instead
- Add events for Log
- Make tab not use name but the actual tab instead
This commit is contained in:
Tobias Berger 2021-09-28 14:17:51 +02:00
parent 1ff92d152d
commit 416585e0da
13 changed files with 170 additions and 86 deletions

View file

@ -7,6 +7,6 @@
SharkGame.init(); SharkGame.init();
</script> </script>
<Header /> <Header title={SharkGame.title} />
<Wrapper /> <Wrapper game={SharkGame} />
<Footer /> <Footer />

View file

@ -7,13 +7,8 @@
<style lang="scss"> <style lang="scss">
footer { footer {
user-select: none; user-select: none;
pointer-events: none;
font-size: 80%; font-size: 80%;
color: var(--color-lighter); color: var(--color-lighter);
filter: brightness(130%); filter: brightness(130%);
> a {
pointer-events: initial;
}
} }
</style> </style>

View file

@ -1,16 +0,0 @@
<script lang="ts">
import { SharkGame } from "../shark/SharkGame";
import type { Tabs } from "../shark/Tabs";
export let currentTab: typeof Tabs.currentTab;
</script>
<div>
<svelte:component this={SharkGame.Tabs.Tabs[currentTab]} />
</div>
<style lang="scss">
div {
height: calc(100% - 2em);
}
</style>

View file

@ -1,5 +1,5 @@
<script lang="ts"> <script lang="ts">
import { SharkGame } from "../shark/SharkGame"; export let title: string;
const discordLink = "https://discord.gg/eYqApFkFPY"; const discordLink = "https://discord.gg/eYqApFkFPY";
@ -38,16 +38,16 @@
</script> </script>
<svelte:head> <svelte:head>
<title>{SharkGame.title}</title> <title>{title}</title>
</svelte:head> </svelte:head>
<header> <header id="header">
<ul id="main-header-buttons"> <ul id="main-header-buttons">
{#each Object.entries(mainHeaderButtons) as [name, onClick]} {#each Object.entries(mainHeaderButtons) as [name, onClick]}
<li><a on:click={onClick} href={"javascript:;"}>{name}</a></li> <li><a on:click={onClick} href={"javascript:;"}>{name}</a></li>
{/each} {/each}
</ul> </ul>
<span>{SharkGame.title}</span> <span>{title}</span>
<ul id="other-header-buttons"> <ul id="other-header-buttons">
{#each Object.entries(otherHeaderButtons) as [name, onClick]} {#each Object.entries(otherHeaderButtons) as [name, onClick]}
<li> <li>
@ -78,11 +78,6 @@
margin: 0; margin: 0;
padding: 0; padding: 0;
position: fixed;
top: 0;
left: 0;
right: 0;
pointer-events: none; pointer-events: none;
> span { > span {
@ -104,15 +99,6 @@
&:not(:first-child):before { &:not(:first-child):before {
content: " | "; content: " | ";
} }
> a:link,
> a:visited {
color: var(--color-lighter);
filter: none;
}
> a:hover {
filter: brightness(130%);
}
} }
&#main-header-buttons { &#main-header-buttons {

View file

@ -1,21 +1,34 @@
<svelte:options immutable /> <svelte:options immutable />
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from "svelte";
import { expoOut } from "svelte/easing"; import { expoOut } from "svelte/easing";
import type { Writable } from "svelte/store"; import type { Writable } from "svelte/store";
import { slide } from "svelte/transition"; import { slide } from "svelte/transition";
import { Message, MessageType } from "../shark/Message"; import type {
import { SharkGame } from "../shark/SharkGame"; AddMessageEvent,
ResetMessagesEvent,
Message,
} from "../shark/Message";
import { MessageType } from "../shark/Message";
export let messages: Writable<Message[]>; export let messages: Writable<Message[]>;
export let logLength: number;
const dispatch = createEventDispatcher<{
addMessage: AddMessageEvent;
resetLog: ResetMessagesEvent;
}>();
// Shorthand // Shorthand
function addMessage(message: string, messageType?: MessageType) { function addMessage(message: string, messageType?: MessageType) {
SharkGame.Log.addMessage(message, messageType); dispatch("addMessage", { message, messageType });
}
function resetMessages() {
dispatch("resetLog", { reset: true });
} }
$: logLength = SharkGame.Settings.logLength.current;
$: displayMessages = $messages.slice(-logLength).reverse(); $: displayMessages = $messages.slice(-logLength).reverse();
</script> </script>
@ -45,11 +58,7 @@
addMessage("error" + $messages.length, MessageType.error); addMessage("error" + $messages.length, MessageType.error);
}}>Add Error</button }}>Add Error</button
> >
<button <button on:click={resetMessages}>Clear log</button>
on:click={() => {
SharkGame.Log.reset();
}}>Clear log</button
>
<ol> <ol>
{#each displayMessages as message, i (message)} {#each displayMessages as message, i (message)}
{#if i < logLength} {#if i < logLength}
@ -81,6 +90,7 @@
> li { > li {
padding: 1em 0.4em; padding: 1em 0.4em;
overflow-wrap: break-word; overflow-wrap: break-word;
overflow-anchor: none;
&.odd { &.odd {
background-color: var(--color-med); background-color: var(--color-med);

View file

@ -1,21 +1,21 @@
<script lang="ts"> <script lang="ts">
import type { Tabs } from "../shark/Tabs"; import type { Tabs } from "../shark/Tabs";
export let tabs: typeof Tabs.Tabs; export let tabs: typeof Tabs.AllTabs;
export let selectedTab: typeof Tabs.currentTab; export let selectedTab: typeof Tabs.currentTab;
$: tabNames = Object.keys(tabs) as typeof selectedTab[]; $: tabEntries = Object.entries(tabs);
</script> </script>
<div> <div>
<ul> <ul>
{#each tabNames as tab} {#each tabEntries as [tabName, tab]}
<li> <li>
<a <a
on:click={() => { on:click={() => {
selectedTab = tab; selectedTab = tab;
}} }}
disabled={tab === selectedTab} disabled={tab === selectedTab}
href={"javascript:;"}>{tab}</a href={"javascript:;"}>{tabName}</a
> >
</li> </li>
{/each} {/each}
@ -55,16 +55,11 @@
content: " | "; content: " | ";
} }
> a { > a[disabled="false"] {
color: var(--color-lighter); text-decoration: none;
}
> a:not([disabled="true"]):hover {
filter: brightness(130%);
} }
> a[disabled="true"] { > a[disabled="true"] {
pointer-events: none; text-decoration: underline;
text-decoration: none;
color: var(--color-light);
} }
} }
} }

View file

@ -1,11 +1,16 @@
<script lang="ts"> <script lang="ts">
import { createEventDispatcher } from "svelte";
import type { HomeAction } from "../../shark/data/HomeActions"; import type { HomeAction } from "../../shark/data/HomeActions";
import { HomeActions } from "../../shark/data/HomeActions"; import { HomeActions } from "../../shark/data/HomeActions";
import { SharkGame } from "../../shark/SharkGame"; import { Resources } from "../../shark/data/Resources";
import type { AddMessageEvent } from "../../shark/Message";
const dispatch = createEventDispatcher<{ addMessage: AddMessageEvent }>();
function homeActionClick(homeAction: HomeAction) { function homeActionClick(homeAction: HomeAction) {
if (homeAction.effect.resource) { if (homeAction.effect.resource) {
const resources = SharkGame.Resources.getResources( const resources = Resources.getResources(
Object.keys(homeAction.effect.resource) Object.keys(homeAction.effect.resource)
); );
@ -17,11 +22,12 @@
} }
if (homeAction.outcomes) { if (homeAction.outcomes) {
SharkGame.Log.addMessage( dispatch("addMessage", {
message:
homeAction.outcomes[ homeAction.outcomes[
Math.floor(Math.random() * homeAction.outcomes.length) Math.floor(Math.random() * homeAction.outcomes.length)
] ],
); });
} }
} }
</script> </script>
@ -37,5 +43,6 @@
<style lang="scss"> <style lang="scss">
div { div {
display: flex; display: flex;
flex-direction: row;
} }
</style> </style>

View file

@ -1 +1,56 @@
Haha, Laboratory go <em>BRRRRRRRRRRRRRRR!</em> Haha, Laboratory go <em>BRRRRRRRRRRRRRRR!</em>
A bunch of empty lines:<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
This is because I wanted to test the scrollability of the content wrapper.
<br />
More lines:<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
Egg

View file

@ -1,22 +1,43 @@
<script lang="ts"> <script lang="ts">
import { SharkGame } from "../shark/SharkGame"; import type { AddMessageEvent } from "../shark/Message";
import Game from "./Game.svelte";
import type { SharkGame } from "../shark/SharkGame";
import Log from "./Log.svelte"; import Log from "./Log.svelte";
import ResourceTable from "./ResourceTable/ResourceTable.svelte"; import ResourceTable from "./ResourceTable/ResourceTable.svelte";
import TabSelector from "./TabSelector.svelte"; import TabSelector from "./TabSelector.svelte";
export let game: typeof SharkGame;
$: Game = game;
function handleAddMessage(event: CustomEvent<AddMessageEvent>) {
Game.Log.addMessage(event.detail.message, event.detail.messageType);
}
function handleResetLog() {
Game.Log.reset();
}
</script> </script>
<main> <main>
<div id="left-column"> <div id="left-column">
<ResourceTable bind:resources={SharkGame.Resources.Resources} /> <ResourceTable bind:resources={Game.Resources.Resources} />
<Log bind:messages={SharkGame.Log.messages} /> <Log
bind:logLength={Game.Settings.logLength.current}
bind:messages={Game.Log.messages}
on:addMessage={handleAddMessage}
on:resetLog={handleResetLog}
/>
</div> </div>
<div id="right-column"> <div id="right-column">
<TabSelector <TabSelector
bind:tabs={SharkGame.Tabs.Tabs} bind:tabs={Game.Tabs.AllTabs}
bind:selectedTab={SharkGame.Tabs.currentTab} bind:selectedTab={Game.Tabs.currentTab}
/> />
<Game bind:currentTab={SharkGame.Tabs.currentTab} /> <div id="tab-content">
<svelte:component
this={Game.Tabs.currentTab}
on:addMessage={handleAddMessage}
/>
</div>
</div> </div>
</main> </main>
@ -26,12 +47,12 @@
flex-direction: row; flex-direction: row;
background-color: var(--color-dark); background-color: var(--color-dark);
margin: 2em 0 0 0;
padding: 0; padding: 0;
height: 100%; // Subtract footer and header size
height: calc(100% - 2em - 3em);
overflow-y: scroll; overflow-y: hidden;
> #left-column { > #left-column {
height: 100%; height: 100%;
@ -41,8 +62,18 @@
} }
> #right-column { > #right-column {
height: 100%;
max-height: 100%;
width: 80%; width: 80%;
max-width: 80%; max-width: 80%;
> #tab-content {
width: 100%;
// Subtract the height of the TabSelector
height: calc(100% - 2em);
overflow-y: scroll;
}
} }
} }
</style> </style>

View file

@ -1,3 +1,6 @@
export type AddMessageEvent = { message: string; messageType?: MessageType };
export type ResetMessagesEvent = { reset: true };
export enum MessageType { export enum MessageType {
message = "message", message = "message",
warning = "warning", warning = "warning",

View file

@ -3,9 +3,10 @@ import Lab from "../components/Tabs/Lab.svelte";
import { StaticClass } from "./StaticClass"; import { StaticClass } from "./StaticClass";
export class Tabs extends StaticClass { export class Tabs extends StaticClass {
static readonly Tabs = { static readonly AllTabs = {
Home, Home,
Lab, Lab,
} as const; } as const;
static currentTab: keyof typeof Tabs.Tabs = "Home"; static currentTab: typeof Tabs.AllTabs[keyof typeof Tabs.AllTabs] =
Tabs.AllTabs.Home;
} }

View file

@ -7,7 +7,6 @@ export type HomeAction = {
}; };
outcomes: string[]; outcomes: string[];
multiOutcomes?: string[]; multiOutcomes?: string[];
helpText: string;
}; };
export class HomeActions extends StaticClass { export class HomeActions extends StaticClass {
@ -23,8 +22,6 @@ export class HomeActions extends StaticClass {
fish: 1, fish: 1,
}, },
}, },
cost: {},
prereq: {},
outcomes: [ outcomes: [
"Dropped the bass.", "Dropped the bass.",
"Ate a kipper. Wait. Hang on.", "Ate a kipper. Wait. Hang on.",
@ -67,7 +64,21 @@ export class HomeActions extends StaticClass {
"Ate a swedish fish.", "Ate a swedish fish.",
"Ate a goldfish.", "Ate a goldfish.",
], ],
helpText: "Use your natural shark prowess to find and catch a fish.", },
catchShark: {
name: "Catch shark",
effect: {
resource: {
shark: 1,
},
},
outcomes: [
"S h a r k",
"s.h.a.r.k.",
"shark",
"sharg",
"that was probably a shark",
],
}, },
}; };
} }

View file

@ -1,7 +1,8 @@
@use "./themes.scss"; @use "./themes.scss";
html { html {
height: calc(100vh - 2em - 3em); // Subtract height of header and footer
height: calc(100vh);
} }
body { body {
height: 100%; height: 100%;
@ -20,6 +21,9 @@ a {
&:active { &:active {
filter: brightness(135%); filter: brightness(135%);
} }
&[disabled="true"] {
pointer-events: none;
}
} }
button { button {
@ -29,6 +33,8 @@ button {
text-shadow: 0 0 2px black; text-shadow: 0 0 2px black;
color: white; color: white;
user-select: none;
&:hover { &:hover {
box-shadow: 0 0 2px 2px var(--color-lighter); box-shadow: 0 0 2px 2px var(--color-lighter);
} }