Files
evening_detective_screen/src/composables/useOnlineConnection.ts
T
2026-10-18 14:15:43 +07:00

76 lines
2.1 KiB
TypeScript

import { useMessage } from 'naive-ui'
import { onMounted, onUnmounted, ref } from 'vue'
import { DEFAULT_SERVER, type OnlineIntent, type OnlineState } from '../types/online'
export function useOnlineConnection() {
const bridge = window.screenBridge
const message = useMessage()
const isReady = ref(false)
const state = ref<OnlineState>({
server: DEFAULT_SERVER,
currentGameId: null,
materials: [],
authenticated: false,
remembered: false,
busy: false,
busyMessage: '',
canCancel: false,
games: [],
playlists: [],
screenId: null,
soundEnabled: null,
connection: 'disabled',
error: '',
notice: '',
progress: null,
preparation: { active: false, completed: 0, total: 0, downloadedBytes: 0, error: '' },
packagesRevision: 0,
})
const isBusy = ref(false)
let timer: ReturnType<typeof setInterval> | undefined
let refreshing = false
function accept(value: OnlineState) {
state.value = value
isReady.value = true
}
async function refresh() {
if (!bridge || refreshing) return
refreshing = true
try {
accept(await bridge.onlineState())
} catch {
/* Закрытие приложения не влияет на подготовленные материалы. */
} finally {
refreshing = false
}
}
async function run(intent: OnlineIntent) {
if (!bridge || isBusy.value) return
isBusy.value = true
try {
accept(await bridge.onlineAction(intent))
} catch (error) {
message.error(error instanceof Error ? error.message : 'Действие не выполнено')
} finally {
isBusy.value = false
await refresh()
}
}
async function cancel() {
try {
await bridge?.onlineAction({ action: 'cancel' })
} catch (error) {
message.error(error instanceof Error ? error.message : 'Не удалось отменить загрузку')
}
}
onMounted(async () => {
await refresh()
timer = setInterval(() => {
void refresh()
}, 500)
})
onUnmounted(() => clearInterval(timer))
return { state, isReady, isBusy, run, cancel }
}