Files
pictureFrame-webApp/frontend/src/stores/devices.ts
T
football2801 d11ddff912
CI / test (push) Has been cancelled
feat(device): replace daily wakeHour with multi-time wakeTimes (minutes)
Frame settings now offer two update-frequency modes: "at specific times" or
"every X minutes". Times are stored as an int[] of minutes-since-midnight,
allowing multiple slots per day at minute granularity. Backend computes the
earliest upcoming slot for X-Interval-Ms and uses the most-recent-past slot
as the rotation-due boundary. PWA settings sheet has hour/minute/AM-PM
dropdowns with + Add / trash, a live "next update" preview, and a note
that changes only take effect at the device's next sync.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-07 14:32:58 -04:00

66 lines
2.4 KiB
TypeScript

import { defineStore } from 'pinia'
import { ref } from 'vue'
import type { Device } from '@/types'
export const useDevicesStore = defineStore('devices', () => {
const devices = ref<Device[]>([])
const loading = ref(false)
const error = ref<string | null>(null)
/**
* Fetch the device list. Pass `silent: true` from background refreshes
* (pull-to-refresh, visibility-change polling) so the loading spinner
* doesn't blink and replace the existing cards mid-fetch.
*/
async function fetchDevices(opts: { silent?: boolean } = {}) {
if (!opts.silent) loading.value = true
error.value = null
try {
const res = await fetch('/api/devices')
if (!res.ok) throw new Error('Failed to load devices')
devices.value = await res.json()
} catch (e) {
error.value = e instanceof Error ? e.message : 'Unknown error'
} finally {
loading.value = false
}
}
async function updateDevice(id: number, patch: Partial<Pick<Device, 'name' | 'orientation' | 'rotationIntervalMinutes' | 'wakeTimes' | 'timezone' | 'uniquenessWindow'>>) {
const res = await fetch(`/api/devices/${id}`, {
method: 'PATCH',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(patch),
})
if (!res.ok) throw new Error('Failed to update device')
const updated: Device = await res.json()
const idx = devices.value.findIndex(d => d.id === id)
if (idx !== -1) devices.value[idx] = updated
return updated
}
async function lockImage(deviceId: number, imageId: number): Promise<Device> {
const res = await fetch(`/api/devices/${deviceId}/lock`, {
method: 'PUT',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ imageId }),
})
if (!res.ok) throw new Error('Failed to lock image')
const updated: Device = await res.json()
const idx = devices.value.findIndex(d => d.id === deviceId)
if (idx !== -1) devices.value[idx] = updated
return updated
}
async function unlockImage(deviceId: number): Promise<Device> {
const res = await fetch(`/api/devices/${deviceId}/lock`, { method: 'DELETE' })
if (!res.ok) throw new Error('Failed to unlock')
const updated: Device = await res.json()
const idx = devices.value.findIndex(d => d.id === deviceId)
if (idx !== -1) devices.value[idx] = updated
return updated
}
return { devices, loading, error, fetchDevices, updateDevice, lockImage, unlockImage }
})