feat(stores): sync vehicles
Some checks failed
TrafficCue CI / check (push) Failing after 1m32s
TrafficCue CI / build (push) Failing after 8m32s
TrafficCue CI / build-android (push) Failing after 13m18s

This commit is contained in:
2025-09-27 13:28:52 +02:00
parent b712966cf7
commit b78f1aab06
4 changed files with 34 additions and 27 deletions

View File

@ -10,10 +10,9 @@
} from "@lucide/svelte";
import Button, { buttonVariants } from "../ui/button/button.svelte";
import {
addVehicle,
isValidFuel,
selectVehicle,
setVehicles,
vehicles,
type Vehicle,
type VehicleType,
} from "$lib/vehicles/vehicles.svelte";
@ -183,9 +182,10 @@
alert(m["vehicles.add.errors.select-fuel"]());
return;
}
setVehicles([...vehicles, vehicle]);
// setVehicles([...vehicles.current, vehicle]);
addVehicle(vehicle);
selectVehicle(vehicle);
location.reload(); // TODO
// location.reload(); // TODO
}}
>
<SaveIcon />

View File

@ -55,18 +55,18 @@
>
</Drawer.Header>
<div class="p-4 pt-0 flex flex-col gap-2">
{#each vehicles as vehicle (vehicle.name)}
{#each vehicles.current as vehicle (vehicle.name)}
<Button
variant={selectedVehicle() === vehicle ? "default" : "secondary"}
variant={selectedVehicle() === vehicle.data ? "default" : "secondary"}
class="w-full p-5"
onclick={() => {
selectVehicle(vehicle);
selectVehicle(vehicle.data);
open = false;
}}
>
{@const Icon = getVehicleIcon(vehicle.type)}
{@const Icon = getVehicleIcon(vehicle.data.type)}
<Icon />
{vehicle.name}
{vehicle.data.name}
</Button>
{/each}

View File

@ -17,6 +17,12 @@ export interface StoreInfo {
name: string;
type: StoreType;
}
export interface WrappedValue<T> {
current: T;
}
export type StoreValue<T> = {
data: T;
} & Omit<Store, "data">;
interface TCDB extends DBSchema {
stores: {
@ -145,25 +151,25 @@ export async function updateStore(info: StoreInfo, data: object | null) {
// return state;
// }
export function stores<T extends object>(type: StoreType) {
const state = $state<T[]>([]);
export function stores<T extends object>(type: StoreType): WrappedValue<StoreValue<T>[]> {
const state = $state<StoreValue<T>[]>([]);
eventTarget.addEventListener("store-updated", async (event) => {
const customEvent = event as CustomEvent;
const updatedStore = customEvent.detail as Store;
if(updatedStore.type === type) {
const stores = await db.getAllFromIndex("stores", "by-type", type);
state.splice(0, state.length, ...(stores.map(store => JSON.parse(store.data) as T).filter(store => store !== null)));
state.splice(0, state.length, ...(stores.map(store => ({ ...store, data: JSON.parse(store.data) as T })).filter(store => store.data !== null)));
}
});
(async () => {
const stores = await db.getAllFromIndex("stores", "by-type", type);
state.splice(0, state.length, ...(stores.map(store => JSON.parse(store.data) as T).filter(store => store !== null)));
state.splice(0, state.length, ...(stores.map(store => ({ ...store, data: JSON.parse(store.data) as T })).filter(store => store.data !== null)));
})();
return {
get current() {
return state;
},
set current(newValue: T[]) {
set current(newValue: StoreValue<T>[]) {
state.splice(0, state.length, ...newValue);
}
}

View File

@ -1,4 +1,5 @@
import { m } from "$lang/messages";
import { stores, updateStore, type StoreValue, type WrappedValue } from "$lib/services/stores.svelte";
/*
Valhalla costing:
@ -71,11 +72,7 @@ export const DefaultVehicle: Vehicle = {
interface StateValue<T> {
v: T;
}
export const vehicles: Vehicle[] = $state(
localStorage.getItem("vehicles")
? JSON.parse(localStorage.getItem("vehicles")!)
: [],
);
export const vehicles: WrappedValue<StoreValue<Vehicle>[]> = stores("vehicle");
export const selectedVehicleIdx: StateValue<number | null> = $state({
v: localStorage.getItem("selectedVehicle")
? parseInt(localStorage.getItem("selectedVehicle")!)
@ -83,23 +80,27 @@ export const selectedVehicleIdx: StateValue<number | null> = $state({
});
export const selectedVehicle: () => Vehicle | null = () => {
return (
vehicles[selectedVehicleIdx.v !== null ? selectedVehicleIdx.v : 0] || null
vehicles.current[selectedVehicleIdx.v !== null ? selectedVehicleIdx.v : 0]?.data ?? null
);
};
export function setVehicles(_vehicles: Vehicle[]) {
// vehicles = _vehicles;
// Hack to update without reassigning the array
vehicles.length = 0;
_vehicles.forEach((vehicle) => vehicles.push(vehicle));
localStorage.setItem("vehicles", JSON.stringify(vehicles));
// export function setVehicles(_vehicles: Vehicle[]) {
// // vehicles = _vehicles;
// // Hack to update without reassigning the array
// vehicles.current.length = 0;
// // _vehicles.forEach((vehicle) => vehicles.current.push({ data: vehicle }));
// // localStorage.setItem("vehicles", JSON.stringify(vehicles));
// }
export async function addVehicle(vehicle: Vehicle) {
await updateStore({ name: vehicle.name, type: "vehicle" }, vehicle);
}
export function selectVehicle(vehicle: Vehicle | null) {
if (vehicle == null) {
selectedVehicleIdx.v = null;
} else {
selectedVehicleIdx.v = vehicles.findIndex((v) => v.name === vehicle.name);
selectedVehicleIdx.v = vehicles.current.findIndex((v) => v.name === vehicle.name);
if (selectedVehicleIdx.v === -1) {
selectedVehicleIdx.v = null;
}