use server sent events instead of polling
All checks were successful
Build Container / Build Container (push) Successful in 1m27s
All checks were successful
Build Container / Build Container (push) Successful in 1m27s
This commit is contained in:
parent
8bc4e7f28e
commit
8281848215
2 changed files with 90 additions and 46 deletions
|
|
@ -1,5 +1,5 @@
|
|||
import {Fetcher} from "openapi-typescript-fetch"
|
||||
import type {paths} from "../api/schema"
|
||||
import type {components, paths} from "../api/schema"
|
||||
import type {ui} from "../i18n/ui.ts"
|
||||
|
||||
const fetcher = Fetcher.for<paths>()
|
||||
|
|
@ -29,7 +29,7 @@ declare global {
|
|||
lang: keyof typeof ui;
|
||||
doors: Array<DoorType>;
|
||||
auth: AuthType;
|
||||
doorAction: (action: 'unlock' | 'lock', doorId: string) => void;
|
||||
doorAction: (action: "unlock" | "lock", doorId: string) => void;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -105,18 +105,18 @@ async function checkUser() {
|
|||
if (e instanceof getUserInfo.Error) {
|
||||
const error = e.getActualType()
|
||||
|
||||
if (error.status === 401) {
|
||||
if (!auth.recentLogout)
|
||||
auth.recentLogout = auth.authenticated // set recentLogout true, if user was logged in before
|
||||
auth.authenticated = false
|
||||
auth.authorized = false
|
||||
auth.until = null
|
||||
auth.username = ""
|
||||
} else if (error.status >= 500 && error.status < 600) {
|
||||
|
||||
if (error.status >= 500 && error.status < 600) {
|
||||
apiError.current = "serverError"
|
||||
} else {
|
||||
console.error("unknown error:", error)
|
||||
}
|
||||
|
||||
if (!auth.recentLogout)
|
||||
auth.recentLogout = auth.authenticated // set recentLogout true, if user was logged in before
|
||||
auth.authenticated = false
|
||||
auth.authorized = false
|
||||
auth.until = null
|
||||
auth.username = ""
|
||||
|
||||
}
|
||||
} finally {
|
||||
localStorage.setItem("auth", JSON.stringify(auth))
|
||||
|
|
@ -125,15 +125,24 @@ async function checkUser() {
|
|||
}
|
||||
}
|
||||
|
||||
async function fetchDoors() {
|
||||
async function subscribeDoorEvents() {
|
||||
if (doors.length === 0) {
|
||||
loading.doors = true
|
||||
}
|
||||
refresh()
|
||||
const getDoors = fetcher.path("/api/locks/").method("get").create()
|
||||
|
||||
try {
|
||||
const {data: doorInfo} = await getDoors({})
|
||||
const evtSource = new EventSource("/api/locks/stream")
|
||||
|
||||
evtSource.onerror = () => {
|
||||
if (!window.navigator.onLine) {
|
||||
apiError.current = "networkError"
|
||||
} else {
|
||||
apiError.current = "serverError"
|
||||
}
|
||||
}
|
||||
|
||||
evtSource.onmessage = (event) => {
|
||||
const doorInfo: Array<components["schemas"]["Lock"]> = JSON.parse(event.data)
|
||||
|
||||
apiError.current = null
|
||||
while (doors.length) {
|
||||
|
|
@ -164,29 +173,6 @@ async function fetchDoors() {
|
|||
|
||||
loading.doors = false
|
||||
refresh()
|
||||
} catch (e) {
|
||||
// check which operation threw the exception
|
||||
if (e instanceof getDoors.Error) {
|
||||
const error = e.getActualType()
|
||||
|
||||
if (error.status === 401) {
|
||||
console.log("unauthorized")
|
||||
loading.doors = false
|
||||
refresh()
|
||||
} else if (error.status >= 500 && error.status < 600) {
|
||||
apiError.current = "serverError"
|
||||
clearInterval(doorsInterval)
|
||||
} else {
|
||||
console.error("unknown error:", error)
|
||||
}
|
||||
}
|
||||
|
||||
if (e instanceof Error) {
|
||||
switch (e.name) {
|
||||
case "TypeError":
|
||||
apiError.current = "networkError"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -295,7 +281,7 @@ function refresh() {
|
|||
|
||||
|
||||
loadAuthFromLocalStorage()
|
||||
const doorsInterval = setInterval(fetchDoors, 250) // TODO: replace with SSE
|
||||
subscribeDoorEvents()
|
||||
checkUser()
|
||||
|
||||
document.addEventListener("loadeddata", () => {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue