104 lines
2.7 KiB
TypeScript
104 lines
2.7 KiB
TypeScript
import { type ClassValue, clsx } from 'clsx'
|
|
import { twMerge } from 'tailwind-merge'
|
|
import { FULLSCREEN_CHANGE_EVENTS } from '@/constants'
|
|
|
|
export function cn(...inputs: ClassValue[]) {
|
|
return twMerge(clsx(inputs))
|
|
}
|
|
|
|
type FullscreenCapableElement = HTMLElement & {
|
|
mozRequestFullScreen?: () => Promise<void> | void
|
|
msRequestFullscreen?: () => Promise<void> | void
|
|
webkitRequestFullscreen?: () => Promise<void> | void
|
|
}
|
|
|
|
type FullscreenCapableDocument = Document & {
|
|
mozCancelFullScreen?: () => Promise<void> | void
|
|
mozFullScreenElement?: Element | null
|
|
msExitFullscreen?: () => Promise<void> | void
|
|
msFullscreenElement?: Element | null
|
|
webkitExitFullscreen?: () => Promise<void> | void
|
|
webkitFullscreenElement?: Element | null
|
|
}
|
|
|
|
export function isDesktopFullscreen() {
|
|
if (typeof document === 'undefined') {
|
|
return false
|
|
}
|
|
|
|
const fullscreenDocument = document as FullscreenCapableDocument
|
|
|
|
return Boolean(
|
|
document.fullscreenElement ||
|
|
fullscreenDocument.webkitFullscreenElement ||
|
|
fullscreenDocument.mozFullScreenElement ||
|
|
fullscreenDocument.msFullscreenElement,
|
|
)
|
|
}
|
|
|
|
export async function exitDesktopFullscreen() {
|
|
if (typeof document === 'undefined') {
|
|
return false
|
|
}
|
|
|
|
const fullscreenDocument = document as FullscreenCapableDocument
|
|
|
|
await Promise.resolve(
|
|
document.exitFullscreen?.() ??
|
|
fullscreenDocument.webkitExitFullscreen?.() ??
|
|
fullscreenDocument.mozCancelFullScreen?.() ??
|
|
fullscreenDocument.msExitFullscreen?.(),
|
|
)
|
|
|
|
return !isDesktopFullscreen()
|
|
}
|
|
|
|
export function subscribeDesktopFullscreenChange(listener: () => void) {
|
|
if (typeof document === 'undefined') {
|
|
return () => {}
|
|
}
|
|
|
|
for (const eventName of FULLSCREEN_CHANGE_EVENTS) {
|
|
document.addEventListener(eventName, listener)
|
|
}
|
|
|
|
return () => {
|
|
for (const eventName of FULLSCREEN_CHANGE_EVENTS) {
|
|
document.removeEventListener(eventName, listener)
|
|
}
|
|
}
|
|
}
|
|
|
|
export async function requestDesktopFullscreen(
|
|
target: HTMLElement = document.documentElement,
|
|
) {
|
|
if (typeof window === 'undefined' || typeof document === 'undefined') {
|
|
return false
|
|
}
|
|
|
|
if (isDesktopFullscreen()) {
|
|
return true
|
|
}
|
|
|
|
const fullscreenTarget = target as FullscreenCapableElement
|
|
|
|
await Promise.resolve(
|
|
fullscreenTarget.requestFullscreen?.() ??
|
|
fullscreenTarget.webkitRequestFullscreen?.() ??
|
|
fullscreenTarget.mozRequestFullScreen?.() ??
|
|
fullscreenTarget.msRequestFullscreen?.(),
|
|
)
|
|
|
|
return isDesktopFullscreen()
|
|
}
|
|
|
|
export async function toggleDesktopFullscreen(
|
|
target: HTMLElement = document.documentElement,
|
|
) {
|
|
if (isDesktopFullscreen()) {
|
|
return exitDesktopFullscreen()
|
|
}
|
|
|
|
return requestDesktopFullscreen(target)
|
|
}
|