224 lines
4.4 KiB
Svelte
224 lines
4.4 KiB
Svelte
<script lang="ts">
|
|
import ShipDesigner from "../../components/modals/ShipDesigner.svelte";
|
|
import OptionInfo from "../../components/modals/OptionInfo.svelte";
|
|
import SciFiCheckbox from "../../components/SciFi-Checkbox.svelte";
|
|
import SciFiButton from "../../components/SciFi-Button.svelte";
|
|
import { ILobbyInfo, Status, gameOptions } from "common";
|
|
import Player from "../../components/Player.svelte";
|
|
import { isHost, players } from "../../stores";
|
|
import { socket } from "../../main";
|
|
import { onMount } from "svelte";
|
|
|
|
function handleLobbyInfo(data: ILobbyInfo) {
|
|
if (data.status == Status.Success) {
|
|
for (const player of data.players) {
|
|
$players[player.id] = player;
|
|
}
|
|
} else {
|
|
console.table(data);
|
|
};
|
|
};
|
|
|
|
onMount(() => {
|
|
socket.on(`res:lobby.info`, handleLobbyInfo);
|
|
return () => {
|
|
socket.off(`res:lobby.info`);
|
|
};
|
|
});
|
|
|
|
function tempButtonHandler() {};
|
|
|
|
// The modals that can appear in the lobby
|
|
const modal = {
|
|
options: false,
|
|
shipDesigner: false,
|
|
};
|
|
|
|
$: visibleOptions = gameOptions.filter(x => !x.hidden);
|
|
|
|
/** Copies the game link to clipboard for easy sharing */
|
|
function copyLinkToClipboard() {
|
|
navigator.clipboard.writeText(window.location.href);
|
|
};
|
|
|
|
/**
|
|
* What gets called when the host toggles one of the options in the lobby so
|
|
* that the other players can see the change happen on their screen.
|
|
*/
|
|
function toggleOption(e: CustomEvent<string>) {
|
|
let option = visibleOptions.find(x => x.id == e.detail);
|
|
console.debug(`Toggled option: ${option.name}`);
|
|
|
|
// TODO: Send websocket event to server
|
|
};
|
|
</script>
|
|
|
|
<OptionInfo
|
|
open="{modal.options}"
|
|
{visibleOptions}
|
|
on:close="{_ => modal.options = false}"
|
|
/>
|
|
<ShipDesigner
|
|
open="{modal.shipDesigner}"
|
|
on:selectColour="{tempButtonHandler}"
|
|
on:close="{_ => modal.shipDesigner = false}"
|
|
/>
|
|
|
|
<main>
|
|
<div>
|
|
<h1>Gravwell</h1>
|
|
<SciFiButton
|
|
width="69%"
|
|
on:click={copyLinkToClipboard}
|
|
>
|
|
Copy Game Link
|
|
</SciFiButton>
|
|
<div class="sci-fi-box">
|
|
<h2>Players</h2>
|
|
<div class="player-box">
|
|
{#each Object.entries($players) as [id, p], i (id)}
|
|
<Player
|
|
name="{p.name}"
|
|
colour="{p.colour}"
|
|
on:changeColour="{_ => modal.shipDesigner = true}"
|
|
/>
|
|
{#if i == 1}
|
|
<div class="divider"></div>
|
|
{/if}
|
|
{/each}
|
|
</div>
|
|
</div>
|
|
<div class="sci-fi-box">
|
|
<div class="info-button-container">
|
|
<SciFiButton
|
|
on:click={_ => modal.options = true}
|
|
height="60px"
|
|
width="60px"
|
|
>
|
|
<div style="display: flex; align-items: center; justify-content: center;">
|
|
<span class="material-icons">help_outline</span>
|
|
</div>
|
|
</SciFiButton>
|
|
</div>
|
|
<h2>Options</h2>
|
|
<div class="options-box">
|
|
{#each visibleOptions as option}
|
|
<div>
|
|
<SciFiCheckbox
|
|
name="{option.name}"
|
|
id="{option.id}"
|
|
disabled="{!$isHost}"
|
|
bind:state="{option.active}"
|
|
on:toggle="{toggleOption}"
|
|
>
|
|
{option.name}
|
|
</SciFiCheckbox>
|
|
</div>
|
|
{/each}
|
|
</div>
|
|
</div>
|
|
<div class="flex-row">
|
|
<SciFiButton
|
|
title="Starts the game"
|
|
on:click={tempButtonHandler}
|
|
>
|
|
Start Game
|
|
</SciFiButton>
|
|
<SciFiButton
|
|
title="Delete the lobby, preventing further games from being played"
|
|
background="#ff0000"
|
|
on:click={tempButtonHandler}
|
|
>
|
|
Delete Game
|
|
</SciFiButton>
|
|
</div>
|
|
</div>
|
|
</main>
|
|
|
|
<style lang="scss">
|
|
main {
|
|
color: #FFFFFF;
|
|
width: 100%;
|
|
height: 100%;
|
|
text-align: center;
|
|
display: flex;
|
|
justify-content: center;
|
|
}
|
|
|
|
h1 {
|
|
font-size: 4rem;
|
|
font-weight: 100;
|
|
line-height: 1.1;
|
|
}
|
|
|
|
|
|
.sci-fi-box {
|
|
border-radius: 10px;
|
|
border-width: 2px;
|
|
border-style: solid;
|
|
border-color: white;
|
|
margin: 5px;
|
|
background: rgba(0, 0, 0, 0.5);
|
|
position: relative;
|
|
|
|
h2 {
|
|
margin: 10px 0px;
|
|
}
|
|
}
|
|
|
|
.player-box {
|
|
display: flex;
|
|
flex-wrap: wrap;
|
|
justify-content: center;
|
|
|
|
> .divider {
|
|
width: 100%;
|
|
}
|
|
|
|
> :global(div) {
|
|
flex-grow: 1;
|
|
}
|
|
}
|
|
|
|
.options-box {
|
|
padding-bottom: 5px;
|
|
display: flex;
|
|
justify-content: space-evenly;
|
|
flex-wrap: wrap;
|
|
|
|
> div {
|
|
background: rgba(255, 255, 255, 0.1);
|
|
border-radius: 5px;
|
|
padding: 3px 7px;
|
|
margin: 5px 5px 10px 5px;
|
|
}
|
|
|
|
> div:first-child {
|
|
margin-left: 10px;
|
|
}
|
|
> div:last-child {
|
|
margin-right: 10px;
|
|
}
|
|
}
|
|
|
|
.info-button-container {
|
|
position: absolute;
|
|
top: -2px;
|
|
right: -2px;
|
|
}
|
|
|
|
.flex-row {
|
|
display: flex;
|
|
align-items: center;
|
|
justify-content: center;
|
|
}
|
|
.flex-row > :global(div) {
|
|
flex-grow: 1;
|
|
}
|
|
|
|
@media (min-width: 480px) {
|
|
h1 {
|
|
max-width: none;
|
|
}
|
|
}
|
|
</style>
|