mirror of
https://github.com/moku-project/Moku.git
synced 2026-06-13 09:19:56 -05:00
fix: read idleTimeoutMin from settings; clean up idle + splash canvas fixes
This commit is contained in:
@@ -290,6 +290,7 @@
|
|||||||
if (logW <= 0 || logH <= 0) return
|
if (logW <= 0 || logH <= 0) return
|
||||||
if (logW === lastLogW && logH === lastLogH && scale === lastScale) return
|
if (logW === lastLogW && logH === lastLogH && scale === lastScale) return
|
||||||
lastLogW = logW; lastLogH = logH; lastScale = scale
|
lastLogW = logW; lastLogH = logH; lastScale = scale
|
||||||
|
if (live) cleanup() // release old offscreen canvases before rebuilding at new size
|
||||||
const built = buildCards(logW, logH)
|
const built = buildCards(logW, logH)
|
||||||
const stamps = built.cards.map(c => buildStamp(c, scale))
|
const stamps = built.cards.map(c => buildStamp(c, scale))
|
||||||
const vig = buildVignette(logW, logH, scale)
|
const vig = buildVignette(logW, logH, scale)
|
||||||
@@ -339,10 +340,25 @@
|
|||||||
function resume() { if (!paused) return; paused = false; raf = requestAnimationFrame(frame) }
|
function resume() { if (!paused) return; paused = false; raf = requestAnimationFrame(frame) }
|
||||||
function onVis() { document.hidden ? pause() : resume() }
|
function onVis() { document.hidden ? pause() : resume() }
|
||||||
|
|
||||||
|
// clears all canvas contexts and nulls live state so the GC can collect the offscreen bitmaps
|
||||||
|
function cleanup() {
|
||||||
|
if (live) {
|
||||||
|
live.stamps.forEach(canvas => {
|
||||||
|
const c = canvas.getContext('2d')
|
||||||
|
if (c) c.clearRect(0, 0, canvas.width, canvas.height)
|
||||||
|
})
|
||||||
|
const vigCtx = live.vignette.getContext('2d')
|
||||||
|
if (vigCtx) vigCtx.clearRect(0, 0, live.vignette.width, live.vignette.height)
|
||||||
|
}
|
||||||
|
ctx.clearRect(0, 0, el.width, el.height)
|
||||||
|
live = null
|
||||||
|
}
|
||||||
|
|
||||||
document.addEventListener('visibilitychange', onVis)
|
document.addEventListener('visibilitychange', onVis)
|
||||||
raf = requestAnimationFrame(frame)
|
raf = requestAnimationFrame(frame)
|
||||||
return () => {
|
return () => {
|
||||||
cancelAnimationFrame(raf)
|
cancelAnimationFrame(raf)
|
||||||
|
cleanup()
|
||||||
extraCleanup?.()
|
extraCleanup?.()
|
||||||
document.removeEventListener('visibilitychange', onVis)
|
document.removeEventListener('visibilitychange', onVis)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,7 @@
|
|||||||
|
|
||||||
const POLL_MS = 1500
|
const POLL_MS = 1500
|
||||||
let pollTimer: ReturnType<typeof setTimeout> | null = null
|
let pollTimer: ReturnType<typeof setTimeout> | null = null
|
||||||
|
let idleTimer: ReturnType<typeof setTimeout> | null = null
|
||||||
let polling = false
|
let polling = false
|
||||||
|
|
||||||
async function pollLoop() {
|
async function pollLoop() {
|
||||||
@@ -117,11 +118,14 @@
|
|||||||
polling = true
|
polling = true
|
||||||
pollLoop()
|
pollLoop()
|
||||||
|
|
||||||
|
resetIdleTimer()
|
||||||
|
|
||||||
return () => {
|
return () => {
|
||||||
polling = false
|
polling = false
|
||||||
if (pollTimer !== null) { clearTimeout(pollTimer); pollTimer = null }
|
if (pollTimer !== null) { clearTimeout(pollTimer); pollTimer = null }
|
||||||
if (discordInitialized) destroyRpc()
|
if (idleTimer !== null) { clearTimeout(idleTimer); idleTimer = null }
|
||||||
platformService.destroy()
|
if (discordInitialized) destroyRpc().catch(() => {})
|
||||||
|
platformService.destroy().catch(() => {})
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -146,7 +150,37 @@
|
|||||||
if (appState.status === 'booting') _splashDismissed = false
|
if (appState.status === 'booting') _splashDismissed = false
|
||||||
})
|
})
|
||||||
|
|
||||||
function onIdleDismiss() { appState.idleSplash = false }
|
$effect(() => {
|
||||||
|
if (appState.status === 'ready') resetIdleTimer()
|
||||||
|
})
|
||||||
|
|
||||||
|
$effect(() => {
|
||||||
|
if (appState.status !== 'ready') return
|
||||||
|
// capture phase so events from any component — including modals — reset the timer
|
||||||
|
const onActivity = () => resetIdleTimer()
|
||||||
|
document.addEventListener('mousemove', onActivity, true)
|
||||||
|
document.addEventListener('keydown', onActivity, true)
|
||||||
|
document.addEventListener('touchstart', onActivity, true)
|
||||||
|
document.addEventListener('click', onActivity, true)
|
||||||
|
return () => {
|
||||||
|
document.removeEventListener('mousemove', onActivity, true)
|
||||||
|
document.removeEventListener('keydown', onActivity, true)
|
||||||
|
document.removeEventListener('touchstart', onActivity, true)
|
||||||
|
document.removeEventListener('click', onActivity, true)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
function resetIdleTimer() {
|
||||||
|
if (idleTimer) clearTimeout(idleTimer)
|
||||||
|
appState.idleSplash = false
|
||||||
|
// read the setting live so changes take effect without a restart
|
||||||
|
const timeoutMs = (settingsState.settings.idleTimeoutMin ?? 5) * 60_000
|
||||||
|
idleTimer = setTimeout(() => {
|
||||||
|
if (appState.status === 'ready') appState.idleSplash = true
|
||||||
|
}, timeoutMs)
|
||||||
|
}
|
||||||
|
|
||||||
|
function onIdleDismiss() { appState.idleSplash = false; resetIdleTimer() }
|
||||||
|
|
||||||
function onSplashRetry() {
|
function onSplashRetry() {
|
||||||
import('$lib/state/boot.svelte').then(({ retryBoot }) => {
|
import('$lib/state/boot.svelte').then(({ retryBoot }) => {
|
||||||
|
|||||||
Reference in New Issue
Block a user