style: run prettier
Some checks failed
TrafficCue CI / check (push) Successful in 1m35s
TrafficCue CI / build (push) Failing after 8m45s
TrafficCue CI / build-android (push) Failing after 12m44s

This commit is contained in:
2025-09-27 19:48:28 +02:00
parent 243d5c6437
commit 533f358a65
5 changed files with 90 additions and 39 deletions

View File

@ -10,7 +10,7 @@
} from "@lucide/svelte";
import Button, { buttonVariants } from "../ui/button/button.svelte";
import {
addVehicle,
addVehicle,
isValidFuel,
selectVehicle,
type Vehicle,

View File

@ -5,7 +5,7 @@ export const hazards: Hazard[] = $state([]);
export async function fetchHazards() {
if (!location.available) return;
if (!await hasCapability("hazards")) return;
if (!(await hasCapability("hazards"))) return;
const newHazards = await getHazards(
{ lat: location.lat, lon: location.lng },
100,

View File

@ -1,6 +1,6 @@
<script>
import {
CloudUploadIcon,
CloudUploadIcon,
HandIcon,
MapIcon,
PackageMinusIcon,

View File

@ -46,25 +46,27 @@ interface TCDB extends DBSchema {
export const db = await openDB<TCDB>("tc", 1, {
upgrade(db, _oldVersion, _newVersion, _transaction, _event) {
if(!db.objectStoreNames.contains("stores")) {
if (!db.objectStoreNames.contains("stores")) {
const store = db.createObjectStore("stores", { keyPath: "id" });
store.createIndex("by-type", "type");
store.createIndex("by-owner", "owner_id");
store.createIndex("by-type-and-owner", ["type", "owner_id"]);
store.createIndex("by-name-and-type", ["name", "type"]);
}
if(!db.objectStoreNames.contains("changes")) {
if (!db.objectStoreNames.contains("changes")) {
db.createObjectStore("changes", { keyPath: "id" });
}
}
})
},
});
const eventTarget = new EventTarget();
export async function trySync() {
const pingResult = await ping();
if(!pingResult) {
console.warn("[STORES] [trySync] LNV server is not reachable, skipping sync");
if (!pingResult) {
console.warn(
"[STORES] [trySync] LNV server is not reachable, skipping sync",
);
return { success: false, message: "LNV server is not reachable" };
}
await syncStores();
@ -72,38 +74,58 @@ export async function trySync() {
}
export async function syncStores() {
if(!(await hasCapability("stores"))) {
if (!(await hasCapability("stores"))) {
return;
}
const changes = await Promise.all(await db.getAll("changes").then(changes => changes.map(async change => {
const storeData = await db.get("stores", change.id);
return { id: change.id, operation: change.operation, data: storeData?.data || null, modified_at: storeData?.modified_at || new Date().toISOString(), type: storeData?.type || "location", name: storeData?.name || "" };
})));
const stores = await db.getAll("stores").then(stores => stores.map(store => ({ id: store.id, modified_at: store.modified_at })));
const changes = await Promise.all(
await db.getAll("changes").then((changes) =>
changes.map(async (change) => {
const storeData = await db.get("stores", change.id);
return {
id: change.id,
operation: change.operation,
data: storeData?.data || null,
modified_at: storeData?.modified_at || new Date().toISOString(),
type: storeData?.type || "location",
name: storeData?.name || "",
};
}),
),
);
const stores = await db
.getAll("stores")
.then((stores) =>
stores.map((store) => ({ id: store.id, modified_at: store.modified_at })),
);
const res = await authFetch(LNV_SERVER + "/stores/sync", {
method: "POST",
headers: {
"Content-Type": "application/json"
"Content-Type": "application/json",
},
body: JSON.stringify({
changes,
stores
})
})
if(!res.ok) {
console.error("[STORES] [syncStores] Failed to sync stores:", await res.text());
stores,
}),
});
if (!res.ok) {
console.error(
"[STORES] [syncStores] Failed to sync stores:",
await res.text(),
);
return;
}
const data = await res.json() as { changes: Store[]; };
const data = (await res.json()) as { changes: Store[] };
const tx = db.transaction(["stores", "changes"], "readwrite");
// Apply all changes the server sent us
for(const store of data.changes) {
if(store.data === null) {
for (const store of data.changes) {
if (store.data === null) {
await tx.objectStore("stores").delete(store.id);
} else {
await tx.objectStore("stores").put(store);
}
eventTarget.dispatchEvent(new CustomEvent("store-updated", { detail: store }) );
eventTarget.dispatchEvent(
new CustomEvent("store-updated", { detail: store }),
);
}
// Delete all changes
await tx.objectStore("changes").clear();
@ -118,21 +140,26 @@ async function createStore(info: StoreInfo, data: object) {
type: info.type,
owner_id: "", // TODO
data: JSON.stringify(data),
modified_at: new Date().toISOString()
modified_at: new Date().toISOString(),
};
const tx = db.transaction(["stores", "changes"], "readwrite");
await tx.objectStore("stores").add(store);
await tx.objectStore("changes").add({ id, operation: "create" });
await tx.done;
eventTarget.dispatchEvent(new CustomEvent("store-updated", { detail: store }) );
eventTarget.dispatchEvent(
new CustomEvent("store-updated", { detail: store }),
);
await trySync();
return store;
}
export async function updateStore(info: StoreInfo, data: object | null) {
const store = await db.getFromIndex("stores", "by-name-and-type", [info.name, info.type]);
const store = await db.getFromIndex("stores", "by-name-and-type", [
info.name,
info.type,
]);
if (!store) {
if(data === null) return;
if (data === null) return;
return await createStore(info, data);
}
// Update the store data
@ -142,7 +169,9 @@ export async function updateStore(info: StoreInfo, data: object | null) {
await tx.objectStore("stores").put(store);
await tx.objectStore("changes").add({ id: store.id, operation: "update" });
await tx.done;
eventTarget.dispatchEvent(new CustomEvent("store-updated", { detail: store }) );
eventTarget.dispatchEvent(
new CustomEvent("store-updated", { detail: store }),
);
await trySync();
return store;
}
@ -166,19 +195,33 @@ export async function updateStore(info: StoreInfo, data: object | null) {
// return state;
// }
export function stores<T extends object>(type: StoreType): WrappedValue<StoreValue<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) {
if (updatedStore.type === type) {
const stores = await db.getAllFromIndex("stores", "by-type", type);
state.splice(0, state.length, ...(stores.map(store => ({ ...store, data: JSON.parse(store.data) as T })).filter(store => store.data !== 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 => ({ ...store, data: JSON.parse(store.data) as T })).filter(store => store.data !== 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() {
@ -186,6 +229,6 @@ export function stores<T extends object>(type: StoreType): WrappedValue<StoreVal
},
set current(newValue: StoreValue<T>[]) {
state.splice(0, state.length, ...newValue);
}
}
},
};
}

View File

@ -1,5 +1,10 @@
import { m } from "$lang/messages";
import { stores, updateStore, type StoreValue, type WrappedValue } from "$lib/services/stores.svelte";
import {
stores,
updateStore,
type StoreValue,
type WrappedValue,
} from "$lib/services/stores.svelte";
/*
Valhalla costing:
@ -80,7 +85,8 @@ export const selectedVehicleIdx: StateValue<number | null> = $state({
});
export const selectedVehicle: () => Vehicle | null = () => {
return (
vehicles.current[selectedVehicleIdx.v !== null ? selectedVehicleIdx.v : 0]?.data ?? null
vehicles.current[selectedVehicleIdx.v !== null ? selectedVehicleIdx.v : 0]
?.data ?? null
);
};
@ -100,7 +106,9 @@ export function selectVehicle(vehicle: Vehicle | null) {
if (vehicle == null) {
selectedVehicleIdx.v = null;
} else {
selectedVehicleIdx.v = vehicles.current.findIndex((v) => v.name === vehicle.name);
selectedVehicleIdx.v = vehicles.current.findIndex(
(v) => v.name === vehicle.name,
);
if (selectedVehicleIdx.v === -1) {
selectedVehicleIdx.v = null;
}