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 msRequestFullscreen?: () => Promise | void webkitRequestFullscreen?: () => Promise | void } type FullscreenCapableDocument = Document & { mozCancelFullScreen?: () => Promise | void mozFullScreenElement?: Element | null msExitFullscreen?: () => Promise | void msFullscreenElement?: Element | null webkitExitFullscreen?: () => Promise | 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) }