Files
music-v2/app/composables/useFullscreen.ts
T
2026-10-06 03:39:08 +02:00

67 lines
1.4 KiB
TypeScript

type FullscreenState = ReturnType<typeof useState<boolean>>
type FullscreenControls = {
fullscreen: FullscreenState
open: () => Promise<boolean>
close: () => Promise<boolean>
toggle: () => Promise<boolean>
}
const syncFullscreenState = (fullscreen: FullscreenState) => {
fullscreen.value = Boolean(document.fullscreenElement)
}
let fullscreenListenerInstalled = false
export const useFullscreen = () => {
const fullscreen = useState<boolean>("fullscreen", () => false)
const open = async () => {
fullscreen.value = true
if (!import.meta.client) return true
if (!document.documentElement.requestFullscreen) return true
try {
await document.documentElement.requestFullscreen()
return true
} catch {
// Keep the in-app fullscreen player open when native fullscreen is denied.
return false
}
}
const close = async () => {
if (import.meta.client && document.fullscreenElement) {
try {
await document.exitFullscreen()
} catch {
// Fall through to keep the app state consistent.
}
}
fullscreen.value = false
return true
}
const toggle = async () => {
if (fullscreen.value) return close()
return open()
}
if (import.meta.client && !fullscreenListenerInstalled) {
fullscreenListenerInstalled = true
document.addEventListener("fullscreenchange", () => {
syncFullscreenState(fullscreen)
})
syncFullscreenState(fullscreen)
}
return {
fullscreen,
open,
close,
toggle,
} as FullscreenControls
}