bugfixes + added Training Stats
This commit is contained in:
parent
973a07fef8
commit
c905753f7a
@ -2033,6 +2033,24 @@ export default function App() {
|
|||||||
pausedByDisk: false,
|
pausedByDisk: false,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
const applyAutostartState = useCallback((data: unknown) => {
|
||||||
|
const d = (data ?? {}) as any
|
||||||
|
|
||||||
|
setAutostartState({
|
||||||
|
paused: Boolean(d?.paused),
|
||||||
|
pausedByUser: Boolean(d?.pausedByUser),
|
||||||
|
pausedByDisk: Boolean(d?.pausedByDisk),
|
||||||
|
})
|
||||||
|
}, [])
|
||||||
|
|
||||||
|
const loadAutostartState = useCallback(async () => {
|
||||||
|
const s = await apiJSON<AutostartState>('/api/autostart/state', {
|
||||||
|
cache: 'no-store' as any,
|
||||||
|
})
|
||||||
|
|
||||||
|
applyAutostartState(s)
|
||||||
|
}, [applyAutostartState])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
busyRef.current = busy
|
busyRef.current = busy
|
||||||
}, [busy])
|
}, [busy])
|
||||||
@ -2714,6 +2732,7 @@ export default function App() {
|
|||||||
if (!authed) return
|
if (!authed) return
|
||||||
|
|
||||||
let es: EventSource | null = null
|
let es: EventSource | null = null
|
||||||
|
let autostartEs: EventSource | null = null
|
||||||
let fallbackTimer: number | null = null
|
let fallbackTimer: number | null = null
|
||||||
|
|
||||||
const stopFallbackPoll = () => {
|
const stopFallbackPoll = () => {
|
||||||
@ -2758,15 +2777,6 @@ export default function App() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const applyAutostartState = (data: unknown) => {
|
|
||||||
const d = (data ?? {}) as any
|
|
||||||
setAutostartState({
|
|
||||||
paused: Boolean(d?.paused),
|
|
||||||
pausedByUser: Boolean(d?.pausedByUser),
|
|
||||||
pausedByDisk: Boolean(d?.pausedByDisk),
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
const onDoneChanged = () => {
|
const onDoneChanged = () => {
|
||||||
if (selectedTabRef.current !== 'finished') return
|
if (selectedTabRef.current !== 'finished') return
|
||||||
void loadDonePage(donePageRef.current, doneSortRef.current)
|
void loadDonePage(donePageRef.current, doneSortRef.current)
|
||||||
@ -2837,20 +2847,26 @@ export default function App() {
|
|||||||
void loadDoneCount()
|
void loadDoneCount()
|
||||||
void loadTaskStateOnce()
|
void loadTaskStateOnce()
|
||||||
|
|
||||||
void apiJSON<AutostartState>('/api/autostart/state', { cache: 'no-store' as any })
|
void loadAutostartState().catch(() => {})
|
||||||
.then((s) => {
|
|
||||||
setAutostartState({
|
|
||||||
paused: Boolean(s?.paused),
|
|
||||||
pausedByUser: Boolean(s?.pausedByUser),
|
|
||||||
pausedByDisk: Boolean(s?.pausedByDisk),
|
|
||||||
})
|
|
||||||
})
|
|
||||||
.catch(() => {})
|
|
||||||
|
|
||||||
es = new EventSource('/api/events/stream')
|
es = new EventSource('/api/events/stream')
|
||||||
eventSourceRef.current = es
|
eventSourceRef.current = es
|
||||||
modelEventNamesRef.current = new Set()
|
modelEventNamesRef.current = new Set()
|
||||||
|
|
||||||
|
autostartEs = new EventSource('/api/autostart/state/stream')
|
||||||
|
|
||||||
|
autostartEs.addEventListener('autostart', (ev) => {
|
||||||
|
try {
|
||||||
|
applyAutostartState(JSON.parse(String((ev as MessageEvent).data ?? 'null')))
|
||||||
|
} catch {
|
||||||
|
// ignore
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
autostartEs.onerror = () => {
|
||||||
|
// Falls der separate Stream ausfällt, wenigstens beim Fokus/Visibility wieder korrekt ziehen.
|
||||||
|
}
|
||||||
|
|
||||||
es.onopen = () => {
|
es.onopen = () => {
|
||||||
stopFallbackPoll()
|
stopFallbackPoll()
|
||||||
void loadTaskStateOnce()
|
void loadTaskStateOnce()
|
||||||
@ -2867,8 +2883,10 @@ export default function App() {
|
|||||||
|
|
||||||
const onVis = () => {
|
const onVis = () => {
|
||||||
if (document.hidden) return
|
if (document.hidden) return
|
||||||
|
|
||||||
void loadJobs()
|
void loadJobs()
|
||||||
void loadTaskStateOnce()
|
void loadTaskStateOnce()
|
||||||
|
void loadAutostartState().catch(() => {})
|
||||||
|
|
||||||
if (selectedTabRef.current === 'finished') {
|
if (selectedTabRef.current === 'finished') {
|
||||||
void loadDonePage(donePageRef.current, doneSortRef.current)
|
void loadDonePage(donePageRef.current, doneSortRef.current)
|
||||||
@ -2897,10 +2915,21 @@ export default function App() {
|
|||||||
es.close()
|
es.close()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (autostartEs) {
|
||||||
|
autostartEs.close()
|
||||||
|
}
|
||||||
|
|
||||||
eventSourceRef.current = null
|
eventSourceRef.current = null
|
||||||
modelEventNamesRef.current = new Set()
|
modelEventNamesRef.current = new Set()
|
||||||
}
|
}
|
||||||
}, [authed, loadJobs, loadDoneCount, loadPendingAutoStarts])
|
}, [
|
||||||
|
authed,
|
||||||
|
loadJobs,
|
||||||
|
loadDoneCount,
|
||||||
|
loadPendingAutoStarts,
|
||||||
|
applyAutostartState,
|
||||||
|
loadAutostartState,
|
||||||
|
])
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const desired = new Set<string>()
|
const desired = new Set<string>()
|
||||||
@ -3970,14 +3999,14 @@ export default function App() {
|
|||||||
roomStatusByModelKey={roomStatusByModelKey}
|
roomStatusByModelKey={roomStatusByModelKey}
|
||||||
pending={pendingWatchedRooms}
|
pending={pendingWatchedRooms}
|
||||||
autostartState={autostartState}
|
autostartState={autostartState}
|
||||||
onRefreshAutostartState={async () => {
|
onRefreshAutostartState={async (next?: AutostartState) => {
|
||||||
try {
|
try {
|
||||||
const s = await apiJSON<AutostartState>('/api/autostart/state', { cache: 'no-store' as any })
|
if (next) {
|
||||||
setAutostartState({
|
applyAutostartState(next)
|
||||||
paused: Boolean(s?.paused),
|
return
|
||||||
pausedByUser: Boolean(s?.pausedByUser),
|
}
|
||||||
pausedByDisk: Boolean(s?.pausedByDisk),
|
|
||||||
})
|
await loadAutostartState()
|
||||||
} catch {
|
} catch {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
|
|||||||
@ -32,7 +32,7 @@ type Props = {
|
|||||||
jobs: RecordJob[]
|
jobs: RecordJob[]
|
||||||
pending?: PendingWatchedRoom[]
|
pending?: PendingWatchedRoom[]
|
||||||
autostartState?: AutostartState
|
autostartState?: AutostartState
|
||||||
onRefreshAutostartState?: () => Promise<void> | void
|
onRefreshAutostartState?: (next?: AutostartState) => Promise<void> | void
|
||||||
modelsByKey?: Record<
|
modelsByKey?: Record<
|
||||||
string,
|
string,
|
||||||
{
|
{
|
||||||
@ -644,9 +644,9 @@ export default function Downloads({
|
|||||||
|
|
||||||
const [watchedBusy, setWatchedBusy] = useState(false)
|
const [watchedBusy, setWatchedBusy] = useState(false)
|
||||||
|
|
||||||
const refreshWatchedState = useCallback(async () => {
|
const refreshWatchedState = useCallback(async (next?: AutostartState) => {
|
||||||
try {
|
try {
|
||||||
await onRefreshAutostartState?.()
|
await onRefreshAutostartState?.(next)
|
||||||
} catch {
|
} catch {
|
||||||
// ignore
|
// ignore
|
||||||
}
|
}
|
||||||
@ -678,11 +678,22 @@ export default function Downloads({
|
|||||||
|
|
||||||
setWatchedBusy(true)
|
setWatchedBusy(true)
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/autostart/pause', { method: 'POST' })
|
const res = await fetch('/api/autostart/pause', {
|
||||||
if (!res.ok) throw new Error(`HTTP ${res.status}`)
|
method: 'POST',
|
||||||
await refreshWatchedState()
|
headers: { 'Content-Type': 'application/json' },
|
||||||
} catch {
|
cache: 'no-store' as any,
|
||||||
// ignore
|
body: JSON.stringify({ paused: true }),
|
||||||
|
})
|
||||||
|
|
||||||
|
if (!res.ok) {
|
||||||
|
const text = await res.text().catch(() => '')
|
||||||
|
throw new Error(text || `HTTP ${res.status}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await res.json().catch(() => null)
|
||||||
|
await refreshWatchedState(data ?? undefined)
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('Autostart pausieren fehlgeschlagen:', e)
|
||||||
} finally {
|
} finally {
|
||||||
setWatchedBusy(false)
|
setWatchedBusy(false)
|
||||||
}
|
}
|
||||||
@ -693,11 +704,20 @@ export default function Downloads({
|
|||||||
|
|
||||||
setWatchedBusy(true)
|
setWatchedBusy(true)
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/autostart/resume', { method: 'POST' })
|
const res = await fetch('/api/autostart/resume', {
|
||||||
if (!res.ok) throw new Error(`HTTP ${res.status}`)
|
method: 'POST',
|
||||||
await refreshWatchedState()
|
cache: 'no-store' as any,
|
||||||
} catch {
|
})
|
||||||
// ignore
|
|
||||||
|
if (!res.ok) {
|
||||||
|
const text = await res.text().catch(() => '')
|
||||||
|
throw new Error(text || `HTTP ${res.status}`)
|
||||||
|
}
|
||||||
|
|
||||||
|
const data = await res.json().catch(() => null)
|
||||||
|
await refreshWatchedState(data ?? undefined)
|
||||||
|
} catch (e) {
|
||||||
|
console.warn('Autostart fortsetzen fehlgeschlagen:', e)
|
||||||
} finally {
|
} finally {
|
||||||
setWatchedBusy(false)
|
setWatchedBusy(false)
|
||||||
}
|
}
|
||||||
@ -1578,8 +1598,8 @@ export default function Downloads({
|
|||||||
}
|
}
|
||||||
leadingIcon={
|
leadingIcon={
|
||||||
watchedPaused
|
watchedPaused
|
||||||
? <PauseIcon className="size-4 shrink-0" />
|
? <PlayIcon className="size-4 shrink-0" />
|
||||||
: <PlayIcon className="size-4 shrink-0" />
|
: <PauseIcon className="size-4 shrink-0" />
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Autostart
|
Autostart
|
||||||
@ -1652,8 +1672,8 @@ export default function Downloads({
|
|||||||
}
|
}
|
||||||
leadingIcon={
|
leadingIcon={
|
||||||
watchedPaused
|
watchedPaused
|
||||||
? <PauseIcon className="size-4 shrink-0" />
|
? <PlayIcon className="size-4 shrink-0" />
|
||||||
: <PlayIcon className="size-4 shrink-0" />
|
: <PauseIcon className="size-4 shrink-0" />
|
||||||
}
|
}
|
||||||
>
|
>
|
||||||
Autostart
|
Autostart
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user