diff --git a/apps/main/src/lib/domains/mobile/mobile.remote.ts b/apps/main/src/lib/domains/mobile/mobile.remote.ts index bbb43a2..92e258a 100644 --- a/apps/main/src/lib/domains/mobile/mobile.remote.ts +++ b/apps/main/src/lib/domains/mobile/mobile.remote.ts @@ -15,6 +15,7 @@ const mc = getMobileController(); const getDevicesInputSchema = v.object({ search: v.optional(v.string()), + refreshAt: v.optional(v.number()), pagination: mobilePaginationSchema, }); diff --git a/apps/main/src/lib/domains/mobile/mobile.vm.svelte.ts b/apps/main/src/lib/domains/mobile/mobile.vm.svelte.ts index 1238680..85c45d5 100644 --- a/apps/main/src/lib/domains/mobile/mobile.vm.svelte.ts +++ b/apps/main/src/lib/domains/mobile/mobile.vm.svelte.ts @@ -37,12 +37,24 @@ class MobileViewModel { private devicesPollTimer: ReturnType | null = null; private smsPollTimer: ReturnType | null = null; + private devicesRequestVersion = 0; + + async fetchDevices({ + showLoading = true, + forceRefresh = false, + }: { + showLoading?: boolean; + forceRefresh?: boolean; + } = {}) { + const requestVersion = ++this.devicesRequestVersion; + if (showLoading) { + this.devicesLoading = true; + } - async fetchDevices() { - this.devicesLoading = true; try { const result = await getDevicesSQ({ search: this.devicesSearch || undefined, + refreshAt: forceRefresh ? Date.now() : undefined, pagination: { page: this.devicesPage, pageSize: this.devicesPageSize, @@ -51,6 +63,10 @@ class MobileViewModel { }, }); + if (requestVersion !== this.devicesRequestVersion) { + return; + } + if (result?.error || !result?.data) { toast.error(result?.error?.message || "Failed to load devices", { description: result?.error?.description || "Please try again later", @@ -58,18 +74,28 @@ class MobileViewModel { return; } - this.devices = result.data.data as MobileDevice[]; + this.devices = [...(result.data.data as MobileDevice[])]; this.devicesTotal = result.data.total; } catch (error) { + if (requestVersion !== this.devicesRequestVersion) { + return; + } + toast.error("Failed to load devices", { description: error instanceof Error ? error.message : "Please try again later", }); } finally { - this.devicesLoading = false; + if (showLoading && requestVersion === this.devicesRequestVersion) { + this.devicesLoading = false; + } } } + async refreshDevices() { + await this.fetchDevices({ showLoading: true, forceRefresh: true }); + } + async fetchDeviceDetail(deviceId: number) { this.deviceDetailLoading = true; try { @@ -154,7 +180,10 @@ class MobileViewModel { startDevicesPolling(intervalMs = 5000) { this.stopDevicesPolling(); this.devicesPollTimer = setInterval(() => { - this.fetchDevices(); + void this.fetchDevices({ + showLoading: false, + forceRefresh: true, + }); }, intervalMs); } diff --git a/apps/main/src/routes/(main)/dashboard/+page.svelte b/apps/main/src/routes/(main)/dashboard/+page.svelte index 0df13f4..2f653a8 100644 --- a/apps/main/src/routes/(main)/dashboard/+page.svelte +++ b/apps/main/src/routes/(main)/dashboard/+page.svelte @@ -17,7 +17,7 @@ breadcrumbs.set([mainNavTree[0]]); onMount(async () => { - await mobileVM.fetchDevices(); + await mobileVM.refreshDevices(); mobileVM.startDevicesPolling(5000); }); @@ -40,7 +40,7 @@