Skip to content

Commit

Permalink
Added a checkbox to PlayableMapPane's titlebar to dim inaccessible rooms
Browse files Browse the repository at this point in the history
Moved titlebar handling to each pane

Closes #7
  • Loading branch information
hopperelec committed Aug 21, 2024
1 parent acf8854 commit eb1d7a0
Show file tree
Hide file tree
Showing 16 changed files with 254 additions and 140 deletions.
30 changes: 30 additions & 0 deletions src/lib/components/split-panes/MinimizeButton.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<script lang="ts">
export let minimize: () => void;
</script>

<button type="button" on:click={minimize}>
<div>&#9473;</div>
</button>

<style>
div {
font-weight: bold;
padding: .1em;
border-radius: 25%;
aspect-ratio: 1 / 1;
line-height: 1em;
}
button {
margin-left: auto;
font-size: inherit;
background: none;
border: none;
padding: .15em;
cursor: pointer;
&:hover > div {
background-color: #fff;
}
}
</style>
67 changes: 9 additions & 58 deletions src/lib/components/split-panes/Pane.svelte
Original file line number Diff line number Diff line change
@@ -1,72 +1,23 @@
<script lang="ts">
import { Pane } from "svelte-splitpanes";
import type { DefinitionDashPaneProps } from "./types";
import type { PaneProps } from "./types";
export let props: DefinitionDashPaneProps;
export let props: PaneProps;
</script>

<Pane>
<div id="pane">
{#if props.showName || props.allowClosing}
<div id="bar">
{#if props.showName}
<span id="name">{props.name}</span>
{/if}
{#if props.allowClosing}
<button type="button" on:click={() => props.shown = !props.shown}>
<span>&#9473;</span>
</button>
{/if}
</div>
{/if}
<div id="component">
<svelte:component this={props.component} {...props.componentProps} bind:this={props.binding}/>
</div>
<div>
<svelte:component
this={props.component} bind:this={props.binding}
{...props.componentProps} minimize={() => props.shown = !props.shown}
/>
</div>
</Pane>

<style lang="scss">
#pane {
<style>
div {
display: flex;
flex-direction: column;
height: 100%;
}
#bar {
display: flex;
align-items: center;
justify-content: space-between;
border-bottom: 1px solid #aaa;
background: #d8d8d8;
font-family: "Segoe UI", Arial, sans-serif;
}
#name {
padding: 0 .5em;
}
button {
font-weight: bold;
background: none;
border: none;
aspect-ratio: 1 / 1;
line-height: 1em;
padding: .2em;
cursor: pointer;
& > span {
padding: .2em;
border-radius: 25%;
}
&:hover > span {
background-color: #fff;
}
}
#component {
position: relative;
flex-grow: 1;
overflow: auto; /* I'm not sure why but this fixes the height of SVGMap */
}
</style>
7 changes: 7 additions & 0 deletions src/lib/components/split-panes/PaneTitle.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<div id="title"><slot/></div>

<style>
#title {
padding: 0 .5em;
}
</style>
15 changes: 15 additions & 0 deletions src/lib/components/split-panes/PaneTitleBar.svelte
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
<div id="bar"><slot/></div>

<style>
#bar {
display: flex;
align-items: center;
border-bottom: 1px solid #aaa;
background: #d8d8d8;
font-family: "Segoe UI", Arial, sans-serif;
min-height: 1.5em;
height: 1.5em;
white-space: nowrap;
text-overflow: ellipsis;
}
</style>
12 changes: 4 additions & 8 deletions src/lib/components/split-panes/PanesTabBar.svelte
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
<script lang="ts">
import StatusBarSeparator from "$lib/components/status-bar/StatusBarSeparator.svelte";
import type { DefinitionDashPaneProps } from "./types";
import type { PaneProps } from "./types";
export let columnMode: boolean;
export let panes: DefinitionDashPaneProps[] | DefinitionDashPaneProps[][];
export let panes: PaneProps[] | PaneProps[][];
</script>

<div class="status-bar">
Expand All @@ -12,12 +12,8 @@ export let panes: DefinitionDashPaneProps[] | DefinitionDashPaneProps[][];
<ul id="tabs">
{#each panes.flat() as tab}
<StatusBarSeparator/>
<li class:open={tab.allowClosing && tab.shown}>
{#if tab.allowClosing}
<button type="button" on:click={() => tab.shown = !tab.shown}>{tab.name}</button>
{:else}
{tab.name}
{/if}
<li class:open={tab.shown}>
<button type="button" on:click={() => tab.shown = !tab.shown}>{tab.name}</button>
</li>
{/each}
</ul>
Expand Down
8 changes: 4 additions & 4 deletions src/lib/components/split-panes/SplitPanes.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@ import DefinitionDashPane from "$lib/components/split-panes/Pane.svelte";
import PanesTabBar from "$lib/components/split-panes/PanesTabBar.svelte";
import SplitpanesTheme from "$lib/components/split-panes/SplitpanesTheme.svelte";
import { Splitpanes } from "svelte-splitpanes";
import type { DefinitionDashPaneProps } from "./types";
import type { PaneProps } from "./types";
export let panes: DefinitionDashPaneProps[];
export let panes: PaneProps[];
export let columnMode = false;
export let showTabBar: "never" | "for-closing" | "always" = "for-closing";
export let showTabBar = true;
</script>

{#if showTabBar !== "never" && (showTabBar === "always" || panes.some(pane => pane.allowClosing))}
{#if showTabBar}
<PanesTabBar bind:columnMode={columnMode} panes={panes}/>
{/if}
<Splitpanes theme="" horizontal={columnMode}>
Expand Down
11 changes: 5 additions & 6 deletions src/lib/components/split-panes/TwoDimensionalSplitPanes.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,22 @@ import { Pane, Splitpanes } from "svelte-splitpanes";
import "$lib/styles/status-bar.css";
import PanesTabBar from "$lib/components/split-panes/PanesTabBar.svelte";
import DefinitionDashSplitPanes from "$lib/components/split-panes/SplitPanes.svelte";
import type { DefinitionDashPaneProps } from "$lib/components/split-panes/types";
import type { PaneProps } from "$lib/components/split-panes/types";
export let panes: DefinitionDashPaneProps[][];
export let panes: PaneProps[][];
export let columnMode = false;
export let showTabBar: "never" | "for-closing" | "always" = "for-closing";
export let showTabBar = true;
</script>

{#if showTabBar !== "never" && (showTabBar === "always" || panes.flat().some(pane => pane.allowClosing))}
{#if showTabBar}
<PanesTabBar bind:columnMode={columnMode} bind:panes={panes}/>
{/if}
<Splitpanes theme="" horizontal={!columnMode}>
{#each panes as group} <!-- Group is a column in column mode, and a row otherwise -->
{#if group.some(pane => pane.shown)}
<Pane>
<DefinitionDashSplitPanes bind:panes={group} {columnMode} showTabBar="never"/>
<DefinitionDashSplitPanes bind:panes={group} {columnMode} showTabBar={false}/>
</Pane>
{/if}
{/each}
</Splitpanes>

16 changes: 4 additions & 12 deletions src/lib/components/split-panes/types.ts
Original file line number Diff line number Diff line change
@@ -1,30 +1,22 @@
import type { ComponentProps, ComponentType, SvelteComponent } from "svelte";

export type DefinitionDashPaneProps<
T extends SvelteComponent = SvelteComponent,
> = {
export type PaneProps<T extends SvelteComponent = SvelteComponent> = {
name: string;
component: ComponentType<T>;
componentProps: ComponentProps<T>;
componentProps: Omit<ComponentProps<T>, "minimize">;
shown: boolean;
showName: boolean;
allowClosing: boolean;
binding?: T;
};
export function createPane<T extends SvelteComponent>(
name: string,
component: ComponentType<T>,
componentProps: ComponentProps<T>,
componentProps: Omit<ComponentProps<T>, "minimize">,
shown?: boolean,
showName?: boolean,
allowClosing?: boolean,
): DefinitionDashPaneProps<T> {
): PaneProps<T> {
return {
name,
component,
componentProps,
shown: !!shown,
showName: !!showName,
allowClosing: !!allowClosing,
};
}
41 changes: 6 additions & 35 deletions src/routes/(requires-login)/game/[gameId=id]/+page.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -3,23 +3,17 @@ import { page } from "$app/stores";
import { getChannel } from "$lib/ably-client";
import IconsPreloader from "$lib/components/preloaders/IconsPreloader.svelte";
import TwoDimensionalPanes from "$lib/components/split-panes/TwoDimensionalSplitPanes.svelte";
import decodeDoors from "$lib/decode-doors";
import { title } from "$lib/page-meta.js";
import { onMount } from "svelte";
import { type Writable, derived, writable } from "svelte/store";
import { derived, writable } from "svelte/store";
import type { PageData } from "./$types";
import AnswerPane from "./AnswerPane.svelte";
import PlayableMap from "./PlayableMapPane.svelte";
import LeaderboardPane from "./ReactiveLeaderboardPane.svelte";
import Shop from "./ShopPane.svelte";
import "$lib/styles/status-bar.css";
import {
type DefinitionDashPaneProps,
createPane,
} from "$lib/components/split-panes/types";
import { type PaneProps, createPane } from "$lib/components/split-panes/types";
import StatusBar from "$lib/components/status-bar/StatusBar.svelte";
import StatusBarSeparator from "$lib/components/status-bar/StatusBarSeparator.svelte";
import type { Doors } from "$lib/types";
import GuidePane from "./GuidePane.svelte";
title.set(undefined);
Expand All @@ -31,7 +25,6 @@ const currMove = writable(data.currMove);
let columnMode = true;
let ptsChangeContainer: HTMLElement;
const doors: Writable<Doors> = writable();
function addPtsChangeGlyph(amount: number) {
const elm = ptsChangeContainer.appendChild(document.createElement("span"));
Expand All @@ -50,15 +43,12 @@ const playableMap = createPane(
PlayableMap,
{
currUserId: data.userId,
mapImgURL: data.map.imgURL,
mapData: data.map,
players,
claimedRooms: data.claimedRooms,
currMove,
doors,
},
true,
true,
true,
);
const answerPane = createPane(
"Answer",
Expand All @@ -68,30 +58,19 @@ const answerPane = createPane(
currMove,
},
true,
true,
true,
);
let panes: DefinitionDashPaneProps[][] = [
let panes: PaneProps[][] = [
[playableMap, answerPane],
[
createPane(
"Shop",
Shop,
{ shopItems: data.shopItems, currPoints },
true,
true,
true,
),
createPane("Shop", Shop, { shopItems: data.shopItems, currPoints }, true),
createPane(
"Leaderboard",
LeaderboardPane,
{ currUserId: data.userId, players },
true,
true,
true,
),
createPane("Guide", GuidePane, {}, false, true, true),
createPane("Guide", GuidePane, {}, false),
],
];
Expand Down Expand Up @@ -146,14 +125,6 @@ $: if ($realtimeMessage) {
}
}
}
onMount(async () => {
doors.set(
await fetch(`/maps/${data.map.id}/doors`)
.then((response) => response.arrayBuffer())
.then(decodeDoors),
);
});
</script>

<div id="page-container">
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
<script lang="ts">
import MinimizeButton from "$lib/components/split-panes/MinimizeButton.svelte";
import PaneTitle from "$lib/components/split-panes/PaneTitle.svelte";
import PaneTitleBar from "$lib/components/split-panes/PaneTitleBar.svelte";
import type { Definition } from "$lib/types";
import type { Writable } from "svelte/store";
export let currQuestion: Definition | null;
export let currMove: Writable<unknown>;
export let minimize: () => void;
let answer = "";
let usageElm: HTMLElement;
Expand Down Expand Up @@ -57,6 +61,10 @@ function focus(elm: HTMLElement) {
}
</script>

<PaneTitleBar>
<PaneTitle>Answer</PaneTitle>
<MinimizeButton {minimize}/>
</PaneTitleBar>
<div class:loading={status === "loading"} class:has-question={currQuestion} class:no-question={!currQuestion}>
{#if currQuestion}
<input
Expand Down
13 changes: 13 additions & 0 deletions src/routes/(requires-login)/game/[gameId=id]/GuidePane.svelte
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
<script lang="ts">
import MinimizeButton from "$lib/components/split-panes/MinimizeButton.svelte";
import PaneTitle from "$lib/components/split-panes/PaneTitle.svelte";
import PaneTitleBar from "$lib/components/split-panes/PaneTitleBar.svelte";
export let minimize: () => void;
</script>

<PaneTitleBar>
<PaneTitle>Guide</PaneTitle>
<MinimizeButton {minimize}/>
</PaneTitleBar>

<p>In Definition Dash, your goal is to end the game with the most points. Each room in the map contains a point for you to collect.</p>
<p>You can move to a room by clicking on it, but you cannot finish the move until you correctly answer a question. For each question, you are given the definition of a term and you must identify the term being defined. Each question has a number of different accepted answers and the answers are not case-sensitive, however you are expected to spell the answers correctly.</p>
<p>Once you move to a room, you will collect the point from that room and that point will now be claimed meaning it can't be claimed (by you or anyone else) again.</p>
Expand Down
Loading

0 comments on commit eb1d7a0

Please sign in to comment.