UNPKG

@owdproject/core

Version:

Nuxt Desktop module for browser desktop experiences (windows, shell, apps)

93 lines (79 loc) 2.76 kB
import { useDebounceFn } from '@vueuse/core' import { nextTick, ref, shallowRef, watch } from 'vue' import { useDesktopWorkspaceStore } from '@owdproject/core/runtime/stores/storeDesktopWorkspace' import { captureElementToCanvas } from '../utils/utilCaptureElementToCanvas' export type WorkspaceRootResolver = ( workspaceId: string, ) => HTMLElement | null | undefined export type UseWorkspaceOverviewCaptureOptions = { /** Delay before capturing after overview opens (ms). Default 150. */ debounceMs?: number /** JPEG quality for thumbnail data URLs (0–1). Default 0.7. */ jpegQuality?: number /** Passed through to html2canvas. */ captureOptions?: Record<string, unknown> } /** * Captures workspace desktop roots as JPEG data URLs while workspace overview is open. * Themes supply a resolver that maps each workspace id to its DOM root (e.g. a layer wrapping * {@link DesktopApplicationRender} with `workspace-filter`). */ export function useWorkspaceOverviewCapture( resolveWorkspaceRoot: WorkspaceRootResolver, options: UseWorkspaceOverviewCaptureOptions = {}, ) { const desktopWorkspaceStore = useDesktopWorkspaceStore() const thumbnails = shallowRef(new Map<string, string>()) const isCapturing = ref(false) const debounceMs = options.debounceMs ?? 150 const jpegQuality = options.jpegQuality ?? 0.7 async function captureWorkspace(workspaceId: string): Promise<string | null> { const element = resolveWorkspaceRoot(workspaceId) const canvas = await captureElementToCanvas(element, options.captureOptions) if (!canvas) return null return canvas.toDataURL('image/jpeg', jpegQuality) } async function refreshThumbnails() { if (!desktopWorkspaceStore.overview) return isCapturing.value = true const next = new Map<string, string>() try { await nextTick() const ids = [...desktopWorkspaceStore.list] await Promise.all( ids.map(async (id) => { const dataUrl = await captureWorkspace(id) if (dataUrl) next.set(id, dataUrl) }), ) thumbnails.value = next } finally { isCapturing.value = false } } const scheduleRefresh = useDebounceFn(() => { void refreshThumbnails() }, debounceMs) watch( () => desktopWorkspaceStore.overview, (open) => { if (open) scheduleRefresh() else thumbnails.value = new Map() }, ) watch( () => desktopWorkspaceStore.list.join('\0'), () => { if (desktopWorkspaceStore.overview) scheduleRefresh() }, ) function thumbnailFor(workspaceId: string): string | undefined { return thumbnails.value.get(workspaceId) } return { thumbnails, isCapturing, refreshThumbnails, thumbnailFor, } }