From d16e3174072bb7d73f42f10eb0a97caa740b4f65 Mon Sep 17 00:00:00 2001 From: "s0wlz (Matthias Puchstein)" Date: Sun, 1 Mar 2026 19:47:14 +0100 Subject: [PATCH] [refactor] finalised the implementation of the countdown.store.ts --- .../countdown/state/countdown.store.ts | 139 +++++++++++++----- 1 file changed, 106 insertions(+), 33 deletions(-) diff --git a/src/features/countdown/state/countdown.store.ts b/src/features/countdown/state/countdown.store.ts index 6823ba5..5fc52ab 100644 --- a/src/features/countdown/state/countdown.store.ts +++ b/src/features/countdown/state/countdown.store.ts @@ -1,8 +1,14 @@ -//TODO: Implement countdown store - import type {CountdownSnapshot} from "../model/countdown.types"; -import {writable} from "svelte/store"; -import {createCountdown, listCountdowns} from "../api/countdown.client"; +import {get, writable} from "svelte/store"; +import { + createCountdown, + deleteCountdown, + listCountdowns, + pauseCountdown, + resetCountdown, + resumeCountdown, + startCountdown +} from "../api/countdown.client"; import type {Duration} from "../../../shared/time/duration"; @@ -22,7 +28,7 @@ const initialStateStore: CountdownStateStore = { error: null, }; -const {subscribe} = writable(initialStateStore); +const {subscribe, update} = writable(initialStateStore); function resolveSelected(items: CountdownSnapshot[], selectedId: number | null): CountdownSnapshot | null { return selectedId === null @@ -30,49 +36,116 @@ function resolveSelected(items: CountdownSnapshot[], selectedId: number | null): : items.find((x) => x.id === selectedId) ?? null; } -export function loadList() { - initialStateStore.loading = true; - listCountdowns().then((items) => { - initialStateStore.items = items; - initialStateStore.selectedId = initialStateStore.selectedId === null - ? (items.length > 0 ? items[0].id : null) - : initialStateStore.selectedId; - initialStateStore.selected = resolveSelected(items, initialStateStore.selectedId); - initialStateStore.loading = false; - }); +function getSelectedIdOrThrow(): number { + const selectedId = get(countdownStore).selectedId; + if (selectedId === null) + throw new Error("No selected countdown"); + return selectedId; } -export function select(id: number) { - initialStateStore.selectedId = id; - initialStateStore.selected = resolveSelected(initialStateStore.items, id); +async function actionOnSelected(action: ((id: number) => Promise)): Promise { + update((state) => ({...state, loading: true, error: null})); + try { + const selectedId = getSelectedIdOrThrow(); + await action(selectedId); + await loadList(); + } catch (error) { + update((state) => { + const e_msg = error instanceof Error ? error.message : String(error); + return {...state, error: e_msg} + }); + } finally { + update((state) => ({...state, loading: false})); + } } -export function create(label: string, duration: Duration) { - createCountdown(label, duration).then((id) => { - loadList(); - initialStateStore.selectedId = id; - initialStateStore.selected = resolveSelected(initialStateStore.items, id); - }) +export async function loadList() { + update((state) => ({...state, loading: true, error: null})); + try { + const items = await listCountdowns(); + update((state) => ({...state, items})); + } catch (error) { + update((state) => { + const e_msg = error instanceof Error ? error.message : String(error); + return {...state, error: e_msg} + }); + } finally { + update((state) => ({...state, loading: false})); + } } -export function startSelected() { - +export async function select(id: number) { + update((state) => ({...state, loading: true, error: null})); + try { + await loadList(); + update((state) => { + const selected = resolveSelected(state.items, id); + return { + ...state, + selectedId: id, + selected: selected, + error: selected === null ? "Selected countdown not found" : null + }; + }); + } catch (error) { + update((state) => { + const e_msg = error instanceof Error ? error.message : String(error); + return {...state, error: e_msg} + }); + } finally { + update((state) => ({...state, loading: false})); + } } -export function resumeSelected() { - +export async function create(label: string, duration: Duration) { + update((state) => ({...state, loading: true, error: null})); + try { + const nId = await createCountdown(label, duration); + await select(nId); + } catch (error) { + update((state) => { + const e_msg = error instanceof Error ? error.message : String(error); + return {...state, error: e_msg} + }); + } finally { + update((state) => ({...state, loading: false})); + } } -export function pauseSelected() { - +export async function deleteSelected() { + update((state) => ({...state, loading: true, error: null})); + try { + const selectedId = getSelectedIdOrThrow(); + const items = get(countdownStore).items; + let nId = items.findIndex((x) => x.id === selectedId) - 1; + nId = nId < 0 ? 0 : nId == 0 ? 1 : 0; + nId = items[nId].id; + await deleteCountdown(selectedId); + await select(nId) + } catch (error) { + update((state) => { + const e_msg = error instanceof Error ? error.message : String(error); + return {...state, error: e_msg} + }); + } finally { + update((state) => ({...state, loading: false})); + } } -export function resetSelected() { - +export async function startSelected() { + await actionOnSelected(startCountdown); } -export function deleteSelected() { +export async function resumeSelected() { + await actionOnSelected(resumeCountdown); +} +export async function pauseSelected() { + await actionOnSelected(pauseCountdown); +} + +export async function resetSelected() { + await actionOnSelected(resetCountdown); } export const countdownStore = {