[+] Implement game options

This commit is contained in:
Azalea 2024-04-02 00:07:50 -04:00
parent ba13bfd9ad
commit 876a0bd108
4 changed files with 73 additions and 13 deletions

View File

@ -133,6 +133,23 @@ input
transition: $transition transition: $transition
box-sizing: border-box box-sizing: border-box
input[type="checkbox"]
width: 1.2em
height: 1.2em
margin: 0
padding: 0
border: 1px solid $c-main
background-color: $ov-lighter
appearance: none
cursor: pointer
flex-shrink: 0
&:checked
background-color: $c-main
border-color: $c-main
label
cursor: pointer
input:focus, input:focus-visible input:focus, input:focus-visible
border: 1px solid $c-main border: 1px solid $c-main

View File

@ -157,6 +157,6 @@ export const DATA = {
export const SETTING = { export const SETTING = {
get: (): Promise<GameOption[]> => get: (): Promise<GameOption[]> =>
post('/api/v2/settings/get', {}), post('/api/v2/settings/get', {}),
set: (key: string, value: string) => set: (key: string, value: any) =>
post('/api/v2/settings/set', { key, value }), post('/api/v2/settings/set', { key, value: `${value}` }),
} }

View File

@ -2,8 +2,8 @@
<script lang="ts"> <script lang="ts">
import { slide, fade } from "svelte/transition"; import { slide, fade } from "svelte/transition";
import type { AquaNetUser } from "../../libs/generalTypes"; import type { AquaNetUser, GameOption } from "../../libs/generalTypes";
import { USER } from "../../libs/sdk"; import { SETTING, USER } from "../../libs/sdk";
import StatusOverlays from "../../components/StatusOverlays.svelte"; import StatusOverlays from "../../components/StatusOverlays.svelte";
import Icon from "@iconify/svelte"; import Icon from "@iconify/svelte";
import { pfp } from "../../libs/ui"; import { pfp } from "../../libs/ui";
@ -18,7 +18,7 @@
let tab = 0 let tab = 0
const tabs = [ 'profile', 'game' ] const tabs = [ 'profile', 'game' ]
const fields = [ const profileFields = [
[ 'displayName', "Display Name" ], [ 'displayName', "Display Name" ],
[ 'username', "Username" ], [ 'username', "Username" ],
[ 'password', "Password" ], [ 'password', "Password" ],
@ -26,14 +26,17 @@
[ 'profileBio', "Bio" ], [ 'profileBio', "Bio" ],
] ]
let gameFields: GameOption[] = []
// Fetch user data // Fetch user data
const getMe = () => USER.me().then(m => { const getMe = () => Promise.all([USER.me(), SETTING.get()]).then(([m, s]) => {
gameFields = s
me = m me = m
values = fields.map(([field]) => me[field as keyof AquaNetUser]) values = profileFields.map(([field]) => me[field as keyof AquaNetUser])
}).catch(e => error = e.message) }).catch(e => error = e.message)
getMe() getMe()
let values = Array(fields.length).fill('') let values = Array(profileFields.length).fill('')
let changed: string[] = [] let changed: string[] = []
let pfpField: HTMLInputElement let pfpField: HTMLInputElement
@ -46,6 +49,13 @@
}).catch(e => error = e.message).finally(() => submitting = "") }).catch(e => error = e.message).finally(() => submitting = "")
} }
function submitGameOption(field: string, value: any) {
if (submitting) return
submitting = field
SETTING.set(field, value).catch(e => error = e.message).finally(() => submitting = "")
}
function uploadPfp(file: File) { function uploadPfp(file: File) {
if (submitting) return if (submitting) return
submitting = 'profilePicture' submitting = 'profilePicture'
@ -78,7 +88,7 @@
{#if tab === 0} {#if tab === 0}
<!-- Tab 0: Profile settings --> <!-- Tab 0: Profile settings -->
<div out:fade={FADE_OUT} in:fade={FADE_IN}> <div out:fade={FADE_OUT} in:fade={FADE_IN} class="fields">
<div class="field"> <div class="field">
<label for="profile-upload">Profile Picture</label> <label for="profile-upload">Profile Picture</label>
<div> <div>
@ -97,7 +107,7 @@
on:change={() => pfpField.files && uploadPfp(pfpField.files[0])} /> on:change={() => pfpField.files && uploadPfp(pfpField.files[0])} />
</div> </div>
{#each fields as [field, name], i (field)} {#each profileFields as [field, name], i (field)}
<div class="field"> <div class="field">
<label for={field}>{name}</label> <label for={field}>{name}</label>
<div> <div>
@ -119,15 +129,47 @@
</div> </div>
{:else if tab === 1} {:else if tab === 1}
<!-- Tab 1: Game settings --> <!-- Tab 1: Game settings -->
<div out:fade={FADE_OUT} in:fade={FADE_IN}>Hello world</div> <div out:fade={FADE_OUT} in:fade={FADE_IN} class="fields">
{#each gameFields as field}
<div class="field">
{#if field.type === "Boolean"}
<div class="bool">
<input id={field.name} type="checkbox" bind:checked={field.value}
on:change={() => submitGameOption(field.key, !field.value)} />
<label for={field.name}>
<span class="name">{field.name}</span>
<span class="desc">{field.desc}</span>
</label>
</div>
{/if}
</div>
{/each}
</div>
{/if} {/if}
<StatusOverlays {error} loading={!me} /> <StatusOverlays {error} loading={!me || submitting} />
</main> </main>
<style lang="sass"> <style lang="sass">
@import "../../vars" @import "../../vars"
.fields
display: flex
flex-direction: column
gap: 12px
.bool
display: flex
align-items: center
gap: 1rem
label
display: flex
flex-direction: column
.desc
opacity: 0.6
.field .field
display: flex display: flex
flex-direction: column flex-direction: column
@ -135,7 +177,7 @@
label label
max-width: max-content max-width: max-content
> div > div:not(.bool)
display: flex display: flex
align-items: center align-items: center
gap: 1rem gap: 1rem

View File

@ -1,5 +1,6 @@
$font: Quicksand, Inter, LXGW Wenkai, Microsoft YaHei, -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, Avenir, Helvetica, Arial, sans-serif $font: Quicksand, Inter, LXGW Wenkai, Microsoft YaHei, -apple-system, BlinkMacSystemFont, "Segoe UI", system-ui, Avenir, Helvetica, Arial, sans-serif
$c-main: #b3c6ff $c-main: #b3c6ff
$c-sub: rgba(0, 0, 0, 0.77)
$c-good: #b3ffb9 $c-good: #b3ffb9
$c-darker: #646cff $c-darker: #646cff
$c-bg: #242424 $c-bg: #242424