Skip to content

Commit

Permalink
refactor: export encapsulated function from store
Browse files Browse the repository at this point in the history
export a function to create store object with methods and better logics
  • Loading branch information
moonlitgrace committed Dec 12, 2024
1 parent 8b1a3a3 commit cf6cd6f
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 34 deletions.
11 changes: 7 additions & 4 deletions frontend/src/lib/components/header.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@
import QuibbleTextLogo from '$lib/components/icons/logos/quibble_text.svelte';
import NotificationIcon from '$lib/components/icons/notification.svelte';
import Avatar from '$lib/components/ui/avatar.svelte';
import { open_modal } from '$lib/stores/modals.svelte';
import { get_auth_state } from '$lib/stores/auth.svelte';
import { createModalsStore } from '$lib/stores/modals.svelte';
import { createAuthStore } from '$lib/stores/auth.svelte';
const modalsStore = createModalsStore(),
authStore = createAuthStore();
</script>

<header
Expand Down Expand Up @@ -40,7 +43,7 @@
</label>
</div>
<div class="flex items-center gap-2">
{#if get_auth_state().is_authenticated}
{#if authStore.state.is_authenticated}
<button aria-label="Create Quibble" class="btn btn-primary h-10 px-3">
<coreicons-shape-plus variant="no-border" class="size-5"></coreicons-shape-plus>
<span class="text-sm font-semibold">Create</span>
Expand All @@ -57,7 +60,7 @@
{:else}
<button
class="btn btn-primary h-10 px-3 text-sm font-bold"
onclick={() => open_modal('auth')}
onclick={() => modalsStore.open('auth')}
>
Join In!
<coreicons-shape-log-in class="size-4"></coreicons-shape-log-in>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
import { onMount } from 'svelte';
import { enhance } from '$app/forms';
import type { SubmitFunction } from '@sveltejs/kit';
import { close_modal } from '$lib/stores/modals.svelte';
import { createModalsStore } from '$lib/stores/modals.svelte';
import { invalidateAll } from '$app/navigation';
// @ts-expect-error: too lazy to copy paste it
import daisyuiColorNames from 'daisyui/src/theming/colorNames';
Expand All @@ -22,14 +22,16 @@
let profiles = $state<Profile[]>([]);
const modalsStore = createModalsStore();
const handle_submit: SubmitFunction = async () => {
pending = true;
status_text = 'Setting up profile...';
return async () => {
// re-run load functions and close this modal
await invalidateAll();
close_modal('auth');
modalsStore.close('auth');
pending = false;
status_text = null;
Expand Down
8 changes: 5 additions & 3 deletions frontend/src/lib/components/modals/auth/index.svelte
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<script lang="ts">
import { close_modal, get_modals_state } from '$lib/stores/modals.svelte';
import { createModalsStore } from '$lib/stores/modals.svelte';
import type { FormsState, FormSubmitData, Forms } from './types';
import forms from './forms';
Expand All @@ -23,8 +23,10 @@
let dialog_element: HTMLDialogElement | undefined = undefined;
const modalsStore = createModalsStore();
$effect(() => {
if (get_modals_state().get('auth')) {
if (modalsStore.state.get('auth')) {
dialog_element?.showModal();
} else {
dialog_element?.close();
Expand All @@ -35,7 +37,7 @@
<dialog
class="modal modal-bottom sm:modal-middle"
bind:this={dialog_element}
onclose={() => close_modal('auth')}
onclose={() => modalsStore.close('auth')}
>
<div class="modal-box !w-[25rem]">
{#await current_form then Form}
Expand Down
25 changes: 16 additions & 9 deletions frontend/src/lib/stores/auth.svelte.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,26 @@ import type { Nullable } from '$lib/types/shared';

type Profile = components['schemas']['Profile'];

const auth_state = $state<{
type AuthState = {
is_authenticated: boolean;
profile: Nullable<Profile>;
}>({
};

let auth_state = $state<AuthState>({

Check failure on line 11 in frontend/src/lib/stores/auth.svelte.ts

View workflow job for this annotation

GitHub Actions / lint

'auth_state' is never reassigned. Use 'const' instead
is_authenticated: false,
profile: null
});

export function get_auth_state() {
return auth_state;
}

export function set_auth_state(new_state: Partial<typeof auth_state>) {
// auth_state = { ...auth_state, ...new_state }
Object.assign(auth_state, new_state);
export function createAuthStore() {
return {
get state() {
return auth_state;
},
update(new_state: Partial<AuthState>) {
// spreading doesnt work because it creates a new reference
// which leads to infinite loop of effects
// auth_state = { ...auth_state, ...new_state }
Object.assign(auth_state, new_state);
}
};
}
29 changes: 15 additions & 14 deletions frontend/src/lib/stores/modals.svelte.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,19 @@ const modals_state = $state(
new SvelteMap<IModals, boolean>(modals.map((item) => [item, false]))
);

export function get_modals_state() {
return modals_state;
}

export function open_modal(modal: IModals) {
// close all modals first
modals_state.keys().forEach((key) => {
modals_state.set(key, false);
});
modals_state.set(modal, true);
}

export function close_modal(modal: IModals) {
modals_state.set(modal, false);
export function createModalsStore() {
return {
get state() {
return modals_state;
},
open(modal: IModals) {
modals_state.keys().forEach((key) => {
modals_state.set(key, false);
});
modals_state.set(modal, true);
},
close(modal: IModals) {
modals_state.set(modal, false);
}
};
}
6 changes: 4 additions & 2 deletions frontend/src/routes/+layout.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,17 @@
import Header from '$lib/components/header.svelte';
import Sidebar from '$lib/components/sidebar.svelte';
import Modals from '$lib/components/modals/index.svelte';
import { set_auth_state } from '$lib/stores/auth.svelte';
import { createAuthStore } from '$lib/stores/auth.svelte';
import type { components } from '$lib/clients/v1';
type Profile = components['schemas']['Profile'];
let { children, data }: { children: Snippet; data: { profile: Profile } } = $props();
const authStore = createAuthStore();
$effect.pre(() => {
set_auth_state({
authStore.update({
profile: data.profile,
is_authenticated: !!data.profile
});
Expand Down

0 comments on commit cf6cd6f

Please sign in to comment.