@shellui/core 0.0.12 → 0.0.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{CookiePreferencesView-CIXBJWNt.js → CookiePreferencesView-Bb3hFqw1.js} +3 -3
- package/dist/{CookiePreferencesView-CIXBJWNt.js.map → CookiePreferencesView-Bb3hFqw1.js.map} +1 -1
- package/dist/{DefaultLayout-Bztmv2c_.js → DefaultLayout-D3IpgS4j.js} +4 -4
- package/dist/{DefaultLayout-Bztmv2c_.js.map → DefaultLayout-D3IpgS4j.js.map} +1 -1
- package/dist/{FullscreenLayout-DiX6dbkf.js → FullscreenLayout-Do9vAfl8.js} +3 -3
- package/dist/{FullscreenLayout-DiX6dbkf.js.map → FullscreenLayout-Do9vAfl8.js.map} +1 -1
- package/dist/{HomeView-C610YU6V.js → HomeView-DwckTuxz.js} +2 -2
- package/dist/{HomeView-C610YU6V.js.map → HomeView-DwckTuxz.js.map} +1 -1
- package/dist/{NotFoundView-D00gYlq-.js → NotFoundView-DD7azhz-.js} +2 -2
- package/dist/{NotFoundView-D00gYlq-.js.map → NotFoundView-DD7azhz-.js.map} +1 -1
- package/dist/{OverlayShell-CGjN4rTu.js → OverlayShell-kDY56DaN.js} +2 -2
- package/dist/{OverlayShell-CGjN4rTu.js.map → OverlayShell-kDY56DaN.js.map} +1 -1
- package/dist/{SettingsView-2QMtfS71.js → SettingsView-Bt4I-KDT.js} +4 -4
- package/dist/{SettingsView-2QMtfS71.js.map → SettingsView-Bt4I-KDT.js.map} +1 -1
- package/dist/{WindowsLayout-DkSNQDSb.js → WindowsLayout-CEqkRKyk.js} +3 -3
- package/dist/{WindowsLayout-DkSNQDSb.js.map → WindowsLayout-CEqkRKyk.js.map} +1 -1
- package/dist/features/config/ConfigProvider.d.ts.map +1 -1
- package/dist/features/config/useConfig.d.ts.map +1 -1
- package/dist/{index-PsePV0Ng.js → index-CfvdAI_Y.js} +130 -122
- package/dist/index-CfvdAI_Y.js.map +1 -0
- package/dist/index.js +1 -1
- package/dist/{sidebar-Cvm_uv4l.js → sidebar-Dt-gibIZ.js} +2 -2
- package/dist/{sidebar-Cvm_uv4l.js.map → sidebar-Dt-gibIZ.js.map} +1 -1
- package/dist/{switch-BjkiJBIa.js → switch-CuKXfl3x.js} +2 -2
- package/dist/{switch-BjkiJBIa.js.map → switch-CuKXfl3x.js.map} +1 -1
- package/package.json +2 -2
- package/src/features/config/ConfigProvider.ts +20 -5
- package/src/features/config/useConfig.ts +14 -1
- package/dist/index-PsePV0Ng.js.map +0 -1
|
@@ -2,8 +2,8 @@ import { jsx as n, jsxs as d } from "react/jsx-runtime";
|
|
|
2
2
|
import { useMemo as Z, useState as P, useRef as M, useEffect as T, useCallback as g } from "react";
|
|
3
3
|
import { useTranslation as ne } from "react-i18next";
|
|
4
4
|
import { shellui as q } from "@shellui/sdk";
|
|
5
|
-
import { a as re, s as oe, b as J, Z as $, r as O, c as C } from "./index-
|
|
6
|
-
import { L as se, O as ie } from "./OverlayShell-
|
|
5
|
+
import { a as re, s as oe, b as J, Z as $, r as O, c as C } from "./index-CfvdAI_Y.js";
|
|
6
|
+
import { L as se, O as ie } from "./OverlayShell-kDY56DaN.js";
|
|
7
7
|
import { C as ae } from "./ContentView-CZG-ro_B.js";
|
|
8
8
|
const F = (o) => {
|
|
9
9
|
try {
|
|
@@ -630,4 +630,4 @@ function ze({
|
|
|
630
630
|
export {
|
|
631
631
|
ze as WindowsLayout
|
|
632
632
|
};
|
|
633
|
-
//# sourceMappingURL=WindowsLayout-
|
|
633
|
+
//# sourceMappingURL=WindowsLayout-CEqkRKyk.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"WindowsLayout-DkSNQDSb.js","sources":["../src/features/layouts/WindowsLayout.tsx"],"sourcesContent":["import {\n useMemo,\n useState,\n useCallback,\n useRef,\n useEffect,\n type PointerEvent as ReactPointerEvent,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { shellui } from '@shellui/sdk';\nimport type { NavigationItem, NavigationGroup } from '../config/types';\nimport {\n flattenNavigationItems,\n resolveLocalizedString as resolveNavLabel,\n splitNavigationByPosition,\n} from './utils';\nimport { useSettings } from '../settings/hooks/useSettings';\nimport { LayoutProviders } from './LayoutProviders';\nimport { OverlayShell } from './OverlayShell';\nimport { ContentView } from '@/components/ContentView';\nimport { cn } from '@/lib/utils';\nimport { Z_INDEX } from '@/lib/z-index';\n\ninterface WindowsLayoutProps {\n title?: string;\n appIcon?: string;\n logo?: string;\n navigation: (NavigationItem | NavigationGroup)[];\n}\n\nconst getExternalFaviconUrl = (url: string): string | null => {\n try {\n const parsed = new URL(url);\n const hostname = parsed.hostname;\n if (!hostname) return null;\n return `https://icons.duckduckgo.com/ip3/${hostname}.ico`;\n } catch {\n return null;\n }\n};\n\n/** True when the icon is a local app icon (/icons/); apply theme (dark invert) so it matches foreground. */\nconst isAppIcon = (src: string) => src.startsWith('/icons/');\n\nconst genId = () => `win-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n\nexport interface WindowState {\n id: string;\n path: string;\n pathname: string;\n baseUrl: string;\n label: string;\n icon: string | null;\n bounds: { x: number; y: number; w: number; h: number };\n}\n\nconst MIN_WIDTH = 280;\nconst MIN_HEIGHT = 200;\nconst DEFAULT_WIDTH = 720;\nconst DEFAULT_HEIGHT = 480;\nconst TASKBAR_HEIGHT = 48;\n\nfunction getMaximizedBounds(): WindowState['bounds'] {\n return {\n x: 0,\n y: 0,\n w: typeof window !== 'undefined' ? window.innerWidth : 800,\n h: typeof window !== 'undefined' ? window.innerHeight - TASKBAR_HEIGHT : 600,\n };\n}\n\nfunction buildFinalUrl(baseUrl: string, path: string, pathname: string): string {\n const pathPrefix = `/${path}`;\n const subPath = pathname.length > pathPrefix.length ? pathname.slice(pathPrefix.length + 1) : '';\n if (!subPath) return baseUrl;\n const base = baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`;\n return `${base}${subPath}`;\n}\n\n/** Single draggable/resizable window */\nfunction AppWindow({\n win,\n navItem,\n currentLanguage,\n isFocused,\n onFocus,\n onClose,\n onBoundsChange,\n maxZIndex,\n zIndex,\n}: {\n win: WindowState;\n navItem: NavigationItem;\n currentLanguage: string;\n isFocused: boolean;\n onFocus: () => void;\n onClose: () => void;\n onBoundsChange: (bounds: WindowState['bounds']) => void;\n maxZIndex: number;\n zIndex: number;\n}) {\n const windowLabel = resolveNavLabel(navItem.label, currentLanguage);\n const [bounds, setBounds] = useState(win.bounds);\n const [isMaximized, setIsMaximized] = useState(false);\n const boundsBeforeMaximizeRef = useRef<WindowState['bounds']>(bounds);\n const containerRef = useRef<HTMLDivElement>(null);\n const dragRef = useRef<{\n startX: number;\n startY: number;\n startBounds: WindowState['bounds'];\n lastDx: number;\n lastDy: number;\n } | null>(null);\n const resizeRef = useRef<{\n edge: string;\n startX: number;\n startY: number;\n startBounds: WindowState['bounds'];\n } | null>(null);\n const resizeRafRef = useRef<number | null>(null);\n const pendingResizeBoundsRef = useRef<WindowState['bounds'] | null>(null);\n\n useEffect(() => {\n setBounds(win.bounds);\n }, [win.bounds]);\n\n useEffect(() => {\n onBoundsChange(bounds);\n }, [bounds, onBoundsChange]);\n\n // When maximized, keep filling the viewport on window resize\n useEffect(() => {\n if (!isMaximized) return;\n const onResize = () => setBounds(getMaximizedBounds());\n window.addEventListener('resize', onResize);\n return () => window.removeEventListener('resize', onResize);\n }, [isMaximized]);\n\n const onPointerMove = useCallback((e: PointerEvent) => {\n if (!dragRef.current) return;\n const d = dragRef.current;\n const dx = e.clientX - d.startX;\n const dy = e.clientY - d.startY;\n d.lastDx = dx;\n d.lastDy = dy;\n const el = containerRef.current;\n if (el) {\n el.style.willChange = 'transform';\n el.style.transform = `translate(${dx}px, ${dy}px)`;\n }\n }, []);\n\n const onPointerUp = useCallback(\n (e: PointerEvent) => {\n const el = containerRef.current;\n if (el) {\n el.removeEventListener('pointermove', onPointerMove);\n el.removeEventListener('pointerup', onPointerUp as (e: Event) => void);\n el.releasePointerCapture(e.pointerId);\n }\n if (dragRef.current) {\n const d = dragRef.current;\n if (el) {\n el.style.transform = '';\n el.style.willChange = '';\n }\n const finalBounds: WindowState['bounds'] = {\n ...d.startBounds,\n x: Math.max(0, d.startBounds.x + d.lastDx),\n y: Math.max(0, d.startBounds.y + d.lastDy),\n };\n setBounds(finalBounds);\n dragRef.current = null;\n }\n },\n [onPointerMove],\n );\n\n const handleTitlePointerDown = useCallback(\n (e: ReactPointerEvent) => {\n if (e.button !== 0 || isMaximized) return;\n // Don't start drag when clicking a button (close, maximize) so their click handlers run\n if ((e.target as Element).closest('button')) return;\n e.preventDefault();\n onFocus();\n dragRef.current = {\n startX: e.clientX,\n startY: e.clientY,\n startBounds: { ...bounds },\n lastDx: 0,\n lastDy: 0,\n };\n const el = containerRef.current;\n if (el) {\n el.setPointerCapture(e.pointerId);\n el.addEventListener('pointermove', onPointerMove, { passive: true });\n el.addEventListener('pointerup', onPointerUp as (e: Event) => void);\n }\n },\n [bounds, isMaximized, onFocus, onPointerMove, onPointerUp],\n );\n\n const handleMaximizeToggle = useCallback(() => {\n if (isMaximized) {\n setBounds(boundsBeforeMaximizeRef.current);\n setIsMaximized(false);\n } else {\n boundsBeforeMaximizeRef.current = { ...bounds };\n setBounds(getMaximizedBounds());\n setIsMaximized(true);\n }\n }, [isMaximized, bounds]);\n\n const onResizePointerMove = useCallback((e: PointerEvent) => {\n if (!resizeRef.current) return;\n const { edge, startX, startY, startBounds } = resizeRef.current;\n const dx = e.clientX - startX;\n const dy = e.clientY - startY;\n const next: WindowState['bounds'] = { ...startBounds };\n if (edge.includes('e')) next.w = Math.max(MIN_WIDTH, startBounds.w + dx);\n if (edge.includes('w')) {\n const newW = Math.max(MIN_WIDTH, startBounds.w - dx);\n next.x = startBounds.x + startBounds.w - newW;\n next.w = newW;\n }\n if (edge.includes('s')) next.h = Math.max(MIN_HEIGHT, startBounds.h + dy);\n if (edge.includes('n')) {\n const newH = Math.max(MIN_HEIGHT, startBounds.h - dy);\n next.y = startBounds.y + startBounds.h - newH;\n next.h = newH;\n }\n pendingResizeBoundsRef.current = next;\n if (resizeRafRef.current === null) {\n resizeRafRef.current = requestAnimationFrame(() => {\n const pending = pendingResizeBoundsRef.current;\n resizeRafRef.current = null;\n pendingResizeBoundsRef.current = null;\n if (pending) setBounds(pending);\n });\n }\n }, []);\n\n const onResizePointerUp = useCallback(\n (e: PointerEvent) => {\n const el = containerRef.current;\n if (el) {\n el.removeEventListener('pointermove', onResizePointerMove as (e: Event) => void);\n el.removeEventListener('pointerup', onResizePointerUp as (e: Event) => void);\n el.releasePointerCapture(e.pointerId);\n }\n resizeRef.current = null;\n },\n [onResizePointerMove],\n );\n\n const handleResizePointerDown = useCallback(\n (e: ReactPointerEvent, edge: string) => {\n if (e.button !== 0) return;\n e.preventDefault();\n e.stopPropagation();\n onFocus();\n resizeRef.current = {\n edge,\n startX: e.clientX,\n startY: e.clientY,\n startBounds: { ...bounds },\n };\n const el = containerRef.current;\n if (el) {\n el.setPointerCapture(e.pointerId);\n el.addEventListener('pointermove', onResizePointerMove as (e: Event) => void, {\n passive: true,\n });\n el.addEventListener('pointerup', onResizePointerUp as (e: Event) => void);\n }\n },\n [bounds, onFocus, onResizePointerMove, onResizePointerUp],\n );\n\n const finalUrl = useMemo(\n () => buildFinalUrl(win.baseUrl, win.path, win.pathname),\n [win.baseUrl, win.path, win.pathname],\n );\n\n const z = isFocused ? maxZIndex : zIndex;\n\n return (\n <div\n ref={containerRef}\n className=\"absolute flex flex-col rounded-lg border border-border bg-card shadow-lg overflow-hidden\"\n style={{\n left: bounds.x,\n top: bounds.y,\n width: bounds.w,\n height: bounds.h,\n zIndex: z,\n }}\n onClick={onFocus}\n onMouseDown={onFocus}\n >\n {/* Title bar: pointer capture so drag continues when cursor is over iframe or outside window */}\n <div\n className=\"flex items-center gap-2 pl-2 pr-1 py-1 bg-muted/80 border-b border-border cursor-move select-none shrink-0\"\n onPointerDown={handleTitlePointerDown}\n >\n {win.icon && (\n <img\n src={win.icon}\n alt=\"\"\n className={cn(\n 'h-4 w-4 shrink-0 rounded-sm object-cover',\n isAppIcon(win.icon) && 'opacity-90 dark:opacity-100 dark:invert',\n )}\n />\n )}\n <span className=\"flex-1 text-sm font-medium truncate min-w-0\">{windowLabel}</span>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n handleMaximizeToggle();\n }}\n className=\"p-1 rounded cursor-pointer text-muted-foreground hover:bg-sidebar-accent/50 hover:text-sidebar-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n aria-label={isMaximized ? 'Restore' : 'Maximize'}\n >\n {isMaximized ? <RestoreIcon className=\"h-4 w-4\" /> : <MaximizeIcon className=\"h-4 w-4\" />}\n </button>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onClose();\n }}\n className=\"p-1 rounded cursor-pointer text-muted-foreground hover:bg-destructive/20 hover:text-destructive transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n aria-label=\"Close\"\n >\n <CloseIcon className=\"h-4 w-4\" />\n </button>\n </div>\n {/* Content */}\n <div className=\"flex-1 min-h-0 relative bg-background\">\n {/* When not focused, overlay captures clicks to bring window to front */}\n {!isFocused && (\n <div\n className=\"absolute inset-0 z-10 cursor-pointer\"\n onClick={onFocus}\n onMouseDown={(e) => {\n e.stopPropagation();\n onFocus();\n }}\n aria-hidden\n />\n )}\n <ContentView\n url={finalUrl}\n pathPrefix={win.path}\n ignoreMessages={true}\n navItem={navItem}\n />\n </div>\n {/* Resize handles (hidden when maximized) */}\n {!isMaximized &&\n (['n', 's', 'e', 'w', 'ne', 'nw', 'se', 'sw'] as const).map((edge) => (\n <div\n key={edge}\n className={cn(\n 'absolute bg-transparent',\n edge.includes('n') && 'top-0 h-2 cursor-n-resize',\n edge.includes('s') && 'bottom-0 h-2 cursor-s-resize',\n edge.includes('e') && 'right-0 w-2 cursor-e-resize',\n edge.includes('w') && 'left-0 w-2 cursor-w-resize',\n edge === 'n' && 'left-2 right-2',\n edge === 's' && 'left-2 right-2',\n edge === 'e' && 'top-2 bottom-2',\n edge === 'w' && 'top-2 bottom-2',\n edge === 'ne' && 'top-0 right-0 w-2 h-2 cursor-ne-resize',\n edge === 'nw' && 'top-0 left-0 w-2 h-2 cursor-nw-resize',\n edge === 'se' && 'bottom-0 right-0 w-2 h-2 cursor-se-resize',\n edge === 'sw' && 'bottom-0 left-0 w-2 h-2 cursor-sw-resize',\n )}\n style={\n edge === 'n'\n ? { left: 8, right: 8 }\n : edge === 's'\n ? { left: 8, right: 8 }\n : edge === 'e'\n ? { top: 8, bottom: 8 }\n : edge === 'w'\n ? { top: 8, bottom: 8 }\n : undefined\n }\n onPointerDown={(e) => handleResizePointerDown(e, edge)}\n />\n ))}\n </div>\n );\n}\n\nfunction MaximizeIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n aria-hidden\n >\n <path d=\"M8 3H5a2 2 0 0 0-2 2v3\" />\n <path d=\"M21 8V5a2 2 0 0 0-2-2h-3\" />\n <path d=\"M3 16v3a2 2 0 0 0 2 2h3\" />\n <path d=\"M16 21h3a2 2 0 0 0 2-2v-3\" />\n </svg>\n );\n}\n\nfunction RestoreIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n aria-hidden\n >\n <rect\n x=\"3\"\n y=\"3\"\n width=\"10\"\n height=\"10\"\n rx=\"1\"\n />\n <rect\n x=\"11\"\n y=\"11\"\n width=\"10\"\n height=\"10\"\n rx=\"1\"\n />\n </svg>\n );\n}\n\nfunction CloseIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n aria-hidden\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n );\n}\n\n/** Start menu icon (Windows-style) */\nfunction StartIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n className={className}\n aria-hidden\n >\n <path d=\"M3 3h8v8H3V3zm10 0h8v8h-8V3zM3 13h8v8H3v-8zm10 0h8v8h-8v-8z\" />\n </svg>\n );\n}\n\nfunction getBrowserTimezone(): string {\n if (typeof window !== 'undefined' && Intl.DateTimeFormat) {\n return Intl.DateTimeFormat().resolvedOptions().timeZone;\n }\n return 'UTC';\n}\n\nexport function WindowsLayout({\n title,\n appIcon: _appIcon,\n logo: _logo,\n navigation,\n}: WindowsLayoutProps) {\n const { i18n } = useTranslation();\n const { settings } = useSettings();\n const currentLanguage = i18n.language || 'en';\n const timeZone = settings.region?.timezone ?? getBrowserTimezone();\n const { startNavItems, endNavItems, navigationItems } = useMemo(() => {\n const { start, end } = splitNavigationByPosition(navigation);\n return {\n startNavItems: flattenNavigationItems(start),\n endNavItems: end,\n navigationItems: flattenNavigationItems(navigation),\n };\n }, [navigation]);\n\n const [windows, setWindows] = useState<WindowState[]>([]);\n /** Id of the window that is on top (first plan). Clicking a window or its taskbar button sets this. */\n const [frontWindowId, setFrontWindowId] = useState<string | null>(null);\n const [startMenuOpen, setStartMenuOpen] = useState(false);\n const [now, setNow] = useState(() => new Date());\n const startPanelRef = useRef<HTMLDivElement>(null);\n\n // Update date/time every second for taskbar clock\n useEffect(() => {\n const interval = setInterval(() => setNow(new Date()), 1000);\n return () => clearInterval(interval);\n }, []);\n\n /** Highest z-index: front window always gets this so it stays on top. */\n const maxZIndex = useMemo(\n () => Z_INDEX.WINDOWS_WINDOW_BASE + Math.max(windows.length, 1),\n [windows.length],\n );\n\n const openWindow = useCallback(\n (item: NavigationItem) => {\n const label =\n typeof item.label === 'string' ? item.label : resolveNavLabel(item.label, currentLanguage);\n const faviconUrl =\n item.openIn === 'external' && !item.icon ? getExternalFaviconUrl(item.url) : null;\n const icon = item.icon ?? faviconUrl ?? null;\n const id = genId();\n const bounds = {\n x: 60 + windows.length * 24,\n y: 60 + windows.length * 24,\n w: DEFAULT_WIDTH,\n h: DEFAULT_HEIGHT,\n };\n setWindows((prev) => [\n ...prev,\n {\n id,\n path: item.path,\n pathname: `/${item.path}`,\n baseUrl: item.url,\n label,\n icon,\n bounds,\n },\n ]);\n setFrontWindowId(id);\n setStartMenuOpen(false);\n },\n [currentLanguage, windows.length],\n );\n\n const closeWindow = useCallback((id: string) => {\n setWindows((prev) => prev.filter((w) => w.id !== id));\n setFrontWindowId((current) => (current === id ? null : current));\n }, []);\n\n // When front window is closed or missing, bring first window to front\n useEffect(() => {\n if (windows.length === 0) {\n setFrontWindowId(null);\n return;\n }\n const frontStillExists = frontWindowId !== null && windows.some((w) => w.id === frontWindowId);\n if (!frontStillExists) {\n setFrontWindowId(windows[0].id);\n }\n }, [windows, frontWindowId]);\n\n /** Bring the window to front (first plan). Used when clicking the window or its taskbar button. */\n const focusWindow = useCallback((id: string) => {\n setFrontWindowId(id);\n }, []);\n\n const updateWindowBounds = useCallback((id: string, bounds: WindowState['bounds']) => {\n setWindows((prev) => prev.map((w) => (w.id === id ? { ...w, bounds } : w)));\n }, []);\n\n // Close start menu on click outside\n useEffect(() => {\n if (!startMenuOpen) return;\n const onDocClick = (e: MouseEvent) => {\n if (startPanelRef.current && !startPanelRef.current.contains(e.target as Node)) {\n setStartMenuOpen(false);\n }\n };\n document.addEventListener('mousedown', onDocClick);\n return () => document.removeEventListener('mousedown', onDocClick);\n }, [startMenuOpen]);\n\n const handleNavClick = useCallback(\n (item: NavigationItem) => {\n if (item.openIn === 'modal') {\n shellui.openModal(item.url);\n setStartMenuOpen(false);\n return;\n }\n if (item.openIn === 'drawer') {\n shellui.openDrawer({ url: item.url, position: item.drawerPosition });\n setStartMenuOpen(false);\n return;\n }\n if (item.openIn === 'external') {\n window.open(item.url, '_blank', 'noopener,noreferrer');\n setStartMenuOpen(false);\n return;\n }\n openWindow(item);\n },\n [openWindow],\n );\n\n return (\n <LayoutProviders>\n <OverlayShell navigationItems={navigationItems}>\n <div\n className=\"fixed inset-0 bg-muted/30\"\n style={{ paddingBottom: TASKBAR_HEIGHT }}\n >\n {/* Desktop area: windows */}\n {windows.map((win, index) => {\n const navItem = navigationItems.find((n) => n.path === win.path);\n if (!navItem) return null;\n const isFocused = win.id === frontWindowId;\n const zIndex = Z_INDEX.WINDOWS_WINDOW_BASE + index;\n return (\n <AppWindow\n key={win.id}\n win={win}\n navItem={navItem}\n currentLanguage={currentLanguage}\n isFocused={isFocused}\n onFocus={() => focusWindow(win.id)}\n onClose={() => closeWindow(win.id)}\n onBoundsChange={(bounds) => updateWindowBounds(win.id, bounds)}\n maxZIndex={maxZIndex}\n zIndex={zIndex}\n />\n );\n })}\n </div>\n\n {/* Taskbar */}\n <div\n className=\"fixed left-0 right-0 bottom-0 flex items-center gap-1 px-2 border-t border-border bg-sidebar-background\"\n style={{\n height: TASKBAR_HEIGHT,\n zIndex: Z_INDEX.WINDOWS_TASKBAR,\n paddingBottom: 'env(safe-area-inset-bottom, 0px)',\n }}\n >\n {/* Start button */}\n <div\n className=\"relative shrink-0\"\n ref={startPanelRef}\n >\n <button\n type=\"button\"\n onClick={() => setStartMenuOpen((o) => !o)}\n className={cn(\n 'flex items-center gap-2 h-9 px-3 rounded cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n startMenuOpen\n ? 'bg-sidebar-accent text-sidebar-accent-foreground'\n : 'text-sidebar-foreground hover:bg-sidebar-accent/50 hover:text-sidebar-foreground',\n )}\n aria-expanded={startMenuOpen}\n aria-haspopup=\"true\"\n aria-label=\"Start\"\n >\n <StartIcon className=\"h-5 w-5\" />\n <span className=\"font-semibold text-sm hidden sm:inline\">{title || 'Start'}</span>\n </button>\n {/* Start menu panel */}\n {startMenuOpen && (\n <div\n className=\"absolute bottom-full left-0 mb-1 w-64 max-h-[70vh] overflow-y-auto rounded-lg border border-border bg-popover shadow-lg py-2 z-[10001]\"\n style={{ zIndex: Z_INDEX.MODAL_CONTENT }}\n >\n <div className=\"px-2 pb-2 border-b border-border mb-2\">\n <span className=\"text-sm font-semibold text-popover-foreground\">\n {title || 'Applications'}\n </span>\n </div>\n <div className=\"grid gap-0.5\">\n {startNavItems\n .filter((item) => !item.hidden)\n .map((item) => {\n const label =\n typeof item.label === 'string'\n ? item.label\n : resolveNavLabel(item.label, currentLanguage);\n const icon =\n item.icon ??\n (item.openIn === 'external' ? getExternalFaviconUrl(item.url) : null);\n return (\n <button\n key={item.path}\n type=\"button\"\n onClick={() => handleNavClick(item)}\n className=\"flex items-center gap-3 w-full px-3 py-2 text-left text-sm cursor-pointer text-popover-foreground hover:bg-accent hover:text-accent-foreground rounded-none transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n >\n {icon ? (\n <img\n src={icon}\n alt=\"\"\n className={cn(\n 'h-5 w-5 shrink-0 rounded-sm object-cover',\n isAppIcon(icon) && 'opacity-90 dark:opacity-100 dark:invert',\n )}\n />\n ) : (\n <span className=\"h-5 w-5 shrink-0 rounded-sm bg-muted\" />\n )}\n <span className=\"truncate\">{label}</span>\n </button>\n );\n })}\n </div>\n </div>\n )}\n </div>\n\n {/* Window list */}\n <div className=\"flex-1 flex items-center gap-1 min-w-0 overflow-x-auto\">\n {windows.map((win) => {\n const navItem = navigationItems.find((n) => n.path === win.path);\n const windowLabel = navItem\n ? resolveNavLabel(navItem.label, currentLanguage)\n : win.label;\n const isFocused = win.id === frontWindowId;\n return (\n <button\n key={win.id}\n type=\"button\"\n onClick={() => focusWindow(win.id)}\n onContextMenu={(e) => {\n e.preventDefault();\n closeWindow(win.id);\n }}\n className={cn(\n 'flex items-center gap-2 h-8 px-2 rounded min-w-0 max-w-[140px] shrink-0 cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n isFocused\n ? 'bg-sidebar-accent text-sidebar-accent-foreground'\n : 'text-sidebar-foreground hover:bg-sidebar-accent/50 hover:text-sidebar-foreground',\n )}\n title={windowLabel}\n >\n {win.icon ? (\n <img\n src={win.icon}\n alt=\"\"\n className={cn(\n 'h-4 w-4 shrink-0 rounded-sm object-cover',\n isAppIcon(win.icon) && 'opacity-90 dark:opacity-100 dark:invert',\n )}\n />\n ) : (\n <span className=\"h-4 w-4 shrink-0 rounded-sm bg-muted\" />\n )}\n <span className=\"text-xs truncate\">{windowLabel}</span>\n </button>\n );\n })}\n </div>\n\n {/* End navigation items (right side of taskbar) */}\n {endNavItems.length > 0 && (\n <div className=\"flex items-center gap-0.5 shrink-0 border-l border-sidebar-border pl-2 ml-1\">\n {endNavItems.map((item) => {\n const label =\n typeof item.label === 'string'\n ? item.label\n : resolveNavLabel(item.label, currentLanguage);\n const icon =\n item.icon ??\n (item.openIn === 'external' ? getExternalFaviconUrl(item.url) : null);\n return (\n <button\n key={item.path}\n type=\"button\"\n onClick={() => handleNavClick(item)}\n className=\"flex items-center gap-2 h-8 px-2 rounded cursor-pointer text-sidebar-foreground hover:bg-sidebar-accent/50 hover:text-sidebar-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n title={label}\n >\n {icon ? (\n <img\n src={icon}\n alt=\"\"\n className={cn(\n 'h-4 w-4 shrink-0 rounded-sm object-cover',\n isAppIcon(icon) && 'opacity-90 dark:opacity-100 dark:invert',\n )}\n />\n ) : (\n <span className=\"h-4 w-4 shrink-0 rounded-sm bg-muted\" />\n )}\n <span className=\"text-xs truncate max-w-[100px]\">{label}</span>\n </button>\n );\n })}\n </div>\n )}\n\n {/* Date and time (extreme bottom right, OS-style); uses region timezone from settings */}\n <div\n className=\"flex flex-col items-end justify-center shrink-0 px-3 py-1 text-sidebar-foreground border-l border-sidebar-border ml-1 min-w-0\"\n style={{ paddingRight: 'max(0.75rem, env(safe-area-inset-right))' }}\n role=\"timer\"\n aria-live=\"off\"\n aria-label={new Intl.DateTimeFormat(currentLanguage, {\n timeZone,\n dateStyle: 'full',\n timeStyle: 'medium',\n }).format(now)}\n >\n <time\n dateTime={now.toISOString()}\n className=\"text-xs leading-tight tabular-nums whitespace-nowrap\"\n >\n {new Intl.DateTimeFormat(currentLanguage, {\n timeZone,\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n }).format(now)}\n </time>\n <time\n dateTime={now.toISOString()}\n className=\"text-[10px] leading-tight whitespace-nowrap text-sidebar-foreground/90\"\n >\n {new Intl.DateTimeFormat(currentLanguage, {\n timeZone,\n weekday: 'short',\n day: 'numeric',\n month: 'short',\n }).format(now)}\n </time>\n </div>\n </div>\n </OverlayShell>\n </LayoutProviders>\n );\n}\n"],"names":["getExternalFaviconUrl","url","hostname","isAppIcon","src","genId","MIN_WIDTH","MIN_HEIGHT","DEFAULT_WIDTH","DEFAULT_HEIGHT","TASKBAR_HEIGHT","getMaximizedBounds","buildFinalUrl","baseUrl","path","pathname","pathPrefix","subPath","AppWindow","win","navItem","currentLanguage","isFocused","onFocus","onClose","onBoundsChange","maxZIndex","zIndex","windowLabel","resolveNavLabel","bounds","setBounds","useState","isMaximized","setIsMaximized","boundsBeforeMaximizeRef","useRef","containerRef","dragRef","resizeRef","resizeRafRef","pendingResizeBoundsRef","useEffect","onResize","onPointerMove","useCallback","e","d","dx","dy","el","onPointerUp","finalBounds","handleTitlePointerDown","handleMaximizeToggle","onResizePointerMove","edge","startX","startY","startBounds","next","newW","newH","pending","onResizePointerUp","handleResizePointerDown","finalUrl","useMemo","z","jsxs","jsx","cn","RestoreIcon","MaximizeIcon","CloseIcon","ContentView","className","StartIcon","getBrowserTimezone","WindowsLayout","title","_appIcon","_logo","navigation","i18n","useTranslation","settings","useSettings","timeZone","startNavItems","endNavItems","navigationItems","start","end","splitNavigationByPosition","flattenNavigationItems","windows","setWindows","frontWindowId","setFrontWindowId","startMenuOpen","setStartMenuOpen","now","setNow","startPanelRef","interval","Z_INDEX","openWindow","item","label","faviconUrl","icon","id","prev","closeWindow","w","current","focusWindow","updateWindowBounds","onDocClick","handleNavClick","shellui","LayoutProviders","OverlayShell","index","n","o"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"WindowsLayout-CEqkRKyk.js","sources":["../src/features/layouts/WindowsLayout.tsx"],"sourcesContent":["import {\n useMemo,\n useState,\n useCallback,\n useRef,\n useEffect,\n type PointerEvent as ReactPointerEvent,\n} from 'react';\nimport { useTranslation } from 'react-i18next';\nimport { shellui } from '@shellui/sdk';\nimport type { NavigationItem, NavigationGroup } from '../config/types';\nimport {\n flattenNavigationItems,\n resolveLocalizedString as resolveNavLabel,\n splitNavigationByPosition,\n} from './utils';\nimport { useSettings } from '../settings/hooks/useSettings';\nimport { LayoutProviders } from './LayoutProviders';\nimport { OverlayShell } from './OverlayShell';\nimport { ContentView } from '@/components/ContentView';\nimport { cn } from '@/lib/utils';\nimport { Z_INDEX } from '@/lib/z-index';\n\ninterface WindowsLayoutProps {\n title?: string;\n appIcon?: string;\n logo?: string;\n navigation: (NavigationItem | NavigationGroup)[];\n}\n\nconst getExternalFaviconUrl = (url: string): string | null => {\n try {\n const parsed = new URL(url);\n const hostname = parsed.hostname;\n if (!hostname) return null;\n return `https://icons.duckduckgo.com/ip3/${hostname}.ico`;\n } catch {\n return null;\n }\n};\n\n/** True when the icon is a local app icon (/icons/); apply theme (dark invert) so it matches foreground. */\nconst isAppIcon = (src: string) => src.startsWith('/icons/');\n\nconst genId = () => `win-${Date.now()}-${Math.random().toString(36).slice(2)}`;\n\nexport interface WindowState {\n id: string;\n path: string;\n pathname: string;\n baseUrl: string;\n label: string;\n icon: string | null;\n bounds: { x: number; y: number; w: number; h: number };\n}\n\nconst MIN_WIDTH = 280;\nconst MIN_HEIGHT = 200;\nconst DEFAULT_WIDTH = 720;\nconst DEFAULT_HEIGHT = 480;\nconst TASKBAR_HEIGHT = 48;\n\nfunction getMaximizedBounds(): WindowState['bounds'] {\n return {\n x: 0,\n y: 0,\n w: typeof window !== 'undefined' ? window.innerWidth : 800,\n h: typeof window !== 'undefined' ? window.innerHeight - TASKBAR_HEIGHT : 600,\n };\n}\n\nfunction buildFinalUrl(baseUrl: string, path: string, pathname: string): string {\n const pathPrefix = `/${path}`;\n const subPath = pathname.length > pathPrefix.length ? pathname.slice(pathPrefix.length + 1) : '';\n if (!subPath) return baseUrl;\n const base = baseUrl.endsWith('/') ? baseUrl : `${baseUrl}/`;\n return `${base}${subPath}`;\n}\n\n/** Single draggable/resizable window */\nfunction AppWindow({\n win,\n navItem,\n currentLanguage,\n isFocused,\n onFocus,\n onClose,\n onBoundsChange,\n maxZIndex,\n zIndex,\n}: {\n win: WindowState;\n navItem: NavigationItem;\n currentLanguage: string;\n isFocused: boolean;\n onFocus: () => void;\n onClose: () => void;\n onBoundsChange: (bounds: WindowState['bounds']) => void;\n maxZIndex: number;\n zIndex: number;\n}) {\n const windowLabel = resolveNavLabel(navItem.label, currentLanguage);\n const [bounds, setBounds] = useState(win.bounds);\n const [isMaximized, setIsMaximized] = useState(false);\n const boundsBeforeMaximizeRef = useRef<WindowState['bounds']>(bounds);\n const containerRef = useRef<HTMLDivElement>(null);\n const dragRef = useRef<{\n startX: number;\n startY: number;\n startBounds: WindowState['bounds'];\n lastDx: number;\n lastDy: number;\n } | null>(null);\n const resizeRef = useRef<{\n edge: string;\n startX: number;\n startY: number;\n startBounds: WindowState['bounds'];\n } | null>(null);\n const resizeRafRef = useRef<number | null>(null);\n const pendingResizeBoundsRef = useRef<WindowState['bounds'] | null>(null);\n\n useEffect(() => {\n setBounds(win.bounds);\n }, [win.bounds]);\n\n useEffect(() => {\n onBoundsChange(bounds);\n }, [bounds, onBoundsChange]);\n\n // When maximized, keep filling the viewport on window resize\n useEffect(() => {\n if (!isMaximized) return;\n const onResize = () => setBounds(getMaximizedBounds());\n window.addEventListener('resize', onResize);\n return () => window.removeEventListener('resize', onResize);\n }, [isMaximized]);\n\n const onPointerMove = useCallback((e: PointerEvent) => {\n if (!dragRef.current) return;\n const d = dragRef.current;\n const dx = e.clientX - d.startX;\n const dy = e.clientY - d.startY;\n d.lastDx = dx;\n d.lastDy = dy;\n const el = containerRef.current;\n if (el) {\n el.style.willChange = 'transform';\n el.style.transform = `translate(${dx}px, ${dy}px)`;\n }\n }, []);\n\n const onPointerUp = useCallback(\n (e: PointerEvent) => {\n const el = containerRef.current;\n if (el) {\n el.removeEventListener('pointermove', onPointerMove);\n el.removeEventListener('pointerup', onPointerUp as (e: Event) => void);\n el.releasePointerCapture(e.pointerId);\n }\n if (dragRef.current) {\n const d = dragRef.current;\n if (el) {\n el.style.transform = '';\n el.style.willChange = '';\n }\n const finalBounds: WindowState['bounds'] = {\n ...d.startBounds,\n x: Math.max(0, d.startBounds.x + d.lastDx),\n y: Math.max(0, d.startBounds.y + d.lastDy),\n };\n setBounds(finalBounds);\n dragRef.current = null;\n }\n },\n [onPointerMove],\n );\n\n const handleTitlePointerDown = useCallback(\n (e: ReactPointerEvent) => {\n if (e.button !== 0 || isMaximized) return;\n // Don't start drag when clicking a button (close, maximize) so their click handlers run\n if ((e.target as Element).closest('button')) return;\n e.preventDefault();\n onFocus();\n dragRef.current = {\n startX: e.clientX,\n startY: e.clientY,\n startBounds: { ...bounds },\n lastDx: 0,\n lastDy: 0,\n };\n const el = containerRef.current;\n if (el) {\n el.setPointerCapture(e.pointerId);\n el.addEventListener('pointermove', onPointerMove, { passive: true });\n el.addEventListener('pointerup', onPointerUp as (e: Event) => void);\n }\n },\n [bounds, isMaximized, onFocus, onPointerMove, onPointerUp],\n );\n\n const handleMaximizeToggle = useCallback(() => {\n if (isMaximized) {\n setBounds(boundsBeforeMaximizeRef.current);\n setIsMaximized(false);\n } else {\n boundsBeforeMaximizeRef.current = { ...bounds };\n setBounds(getMaximizedBounds());\n setIsMaximized(true);\n }\n }, [isMaximized, bounds]);\n\n const onResizePointerMove = useCallback((e: PointerEvent) => {\n if (!resizeRef.current) return;\n const { edge, startX, startY, startBounds } = resizeRef.current;\n const dx = e.clientX - startX;\n const dy = e.clientY - startY;\n const next: WindowState['bounds'] = { ...startBounds };\n if (edge.includes('e')) next.w = Math.max(MIN_WIDTH, startBounds.w + dx);\n if (edge.includes('w')) {\n const newW = Math.max(MIN_WIDTH, startBounds.w - dx);\n next.x = startBounds.x + startBounds.w - newW;\n next.w = newW;\n }\n if (edge.includes('s')) next.h = Math.max(MIN_HEIGHT, startBounds.h + dy);\n if (edge.includes('n')) {\n const newH = Math.max(MIN_HEIGHT, startBounds.h - dy);\n next.y = startBounds.y + startBounds.h - newH;\n next.h = newH;\n }\n pendingResizeBoundsRef.current = next;\n if (resizeRafRef.current === null) {\n resizeRafRef.current = requestAnimationFrame(() => {\n const pending = pendingResizeBoundsRef.current;\n resizeRafRef.current = null;\n pendingResizeBoundsRef.current = null;\n if (pending) setBounds(pending);\n });\n }\n }, []);\n\n const onResizePointerUp = useCallback(\n (e: PointerEvent) => {\n const el = containerRef.current;\n if (el) {\n el.removeEventListener('pointermove', onResizePointerMove as (e: Event) => void);\n el.removeEventListener('pointerup', onResizePointerUp as (e: Event) => void);\n el.releasePointerCapture(e.pointerId);\n }\n resizeRef.current = null;\n },\n [onResizePointerMove],\n );\n\n const handleResizePointerDown = useCallback(\n (e: ReactPointerEvent, edge: string) => {\n if (e.button !== 0) return;\n e.preventDefault();\n e.stopPropagation();\n onFocus();\n resizeRef.current = {\n edge,\n startX: e.clientX,\n startY: e.clientY,\n startBounds: { ...bounds },\n };\n const el = containerRef.current;\n if (el) {\n el.setPointerCapture(e.pointerId);\n el.addEventListener('pointermove', onResizePointerMove as (e: Event) => void, {\n passive: true,\n });\n el.addEventListener('pointerup', onResizePointerUp as (e: Event) => void);\n }\n },\n [bounds, onFocus, onResizePointerMove, onResizePointerUp],\n );\n\n const finalUrl = useMemo(\n () => buildFinalUrl(win.baseUrl, win.path, win.pathname),\n [win.baseUrl, win.path, win.pathname],\n );\n\n const z = isFocused ? maxZIndex : zIndex;\n\n return (\n <div\n ref={containerRef}\n className=\"absolute flex flex-col rounded-lg border border-border bg-card shadow-lg overflow-hidden\"\n style={{\n left: bounds.x,\n top: bounds.y,\n width: bounds.w,\n height: bounds.h,\n zIndex: z,\n }}\n onClick={onFocus}\n onMouseDown={onFocus}\n >\n {/* Title bar: pointer capture so drag continues when cursor is over iframe or outside window */}\n <div\n className=\"flex items-center gap-2 pl-2 pr-1 py-1 bg-muted/80 border-b border-border cursor-move select-none shrink-0\"\n onPointerDown={handleTitlePointerDown}\n >\n {win.icon && (\n <img\n src={win.icon}\n alt=\"\"\n className={cn(\n 'h-4 w-4 shrink-0 rounded-sm object-cover',\n isAppIcon(win.icon) && 'opacity-90 dark:opacity-100 dark:invert',\n )}\n />\n )}\n <span className=\"flex-1 text-sm font-medium truncate min-w-0\">{windowLabel}</span>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n handleMaximizeToggle();\n }}\n className=\"p-1 rounded cursor-pointer text-muted-foreground hover:bg-sidebar-accent/50 hover:text-sidebar-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n aria-label={isMaximized ? 'Restore' : 'Maximize'}\n >\n {isMaximized ? <RestoreIcon className=\"h-4 w-4\" /> : <MaximizeIcon className=\"h-4 w-4\" />}\n </button>\n <button\n type=\"button\"\n onClick={(e) => {\n e.stopPropagation();\n onClose();\n }}\n className=\"p-1 rounded cursor-pointer text-muted-foreground hover:bg-destructive/20 hover:text-destructive transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n aria-label=\"Close\"\n >\n <CloseIcon className=\"h-4 w-4\" />\n </button>\n </div>\n {/* Content */}\n <div className=\"flex-1 min-h-0 relative bg-background\">\n {/* When not focused, overlay captures clicks to bring window to front */}\n {!isFocused && (\n <div\n className=\"absolute inset-0 z-10 cursor-pointer\"\n onClick={onFocus}\n onMouseDown={(e) => {\n e.stopPropagation();\n onFocus();\n }}\n aria-hidden\n />\n )}\n <ContentView\n url={finalUrl}\n pathPrefix={win.path}\n ignoreMessages={true}\n navItem={navItem}\n />\n </div>\n {/* Resize handles (hidden when maximized) */}\n {!isMaximized &&\n (['n', 's', 'e', 'w', 'ne', 'nw', 'se', 'sw'] as const).map((edge) => (\n <div\n key={edge}\n className={cn(\n 'absolute bg-transparent',\n edge.includes('n') && 'top-0 h-2 cursor-n-resize',\n edge.includes('s') && 'bottom-0 h-2 cursor-s-resize',\n edge.includes('e') && 'right-0 w-2 cursor-e-resize',\n edge.includes('w') && 'left-0 w-2 cursor-w-resize',\n edge === 'n' && 'left-2 right-2',\n edge === 's' && 'left-2 right-2',\n edge === 'e' && 'top-2 bottom-2',\n edge === 'w' && 'top-2 bottom-2',\n edge === 'ne' && 'top-0 right-0 w-2 h-2 cursor-ne-resize',\n edge === 'nw' && 'top-0 left-0 w-2 h-2 cursor-nw-resize',\n edge === 'se' && 'bottom-0 right-0 w-2 h-2 cursor-se-resize',\n edge === 'sw' && 'bottom-0 left-0 w-2 h-2 cursor-sw-resize',\n )}\n style={\n edge === 'n'\n ? { left: 8, right: 8 }\n : edge === 's'\n ? { left: 8, right: 8 }\n : edge === 'e'\n ? { top: 8, bottom: 8 }\n : edge === 'w'\n ? { top: 8, bottom: 8 }\n : undefined\n }\n onPointerDown={(e) => handleResizePointerDown(e, edge)}\n />\n ))}\n </div>\n );\n}\n\nfunction MaximizeIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n aria-hidden\n >\n <path d=\"M8 3H5a2 2 0 0 0-2 2v3\" />\n <path d=\"M21 8V5a2 2 0 0 0-2-2h-3\" />\n <path d=\"M3 16v3a2 2 0 0 0 2 2h3\" />\n <path d=\"M16 21h3a2 2 0 0 0 2-2v-3\" />\n </svg>\n );\n}\n\nfunction RestoreIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n aria-hidden\n >\n <rect\n x=\"3\"\n y=\"3\"\n width=\"10\"\n height=\"10\"\n rx=\"1\"\n />\n <rect\n x=\"11\"\n y=\"11\"\n width=\"10\"\n height=\"10\"\n rx=\"1\"\n />\n </svg>\n );\n}\n\nfunction CloseIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"none\"\n stroke=\"currentColor\"\n strokeWidth=\"2\"\n strokeLinecap=\"round\"\n strokeLinejoin=\"round\"\n className={className}\n aria-hidden\n >\n <path d=\"M18 6 6 18\" />\n <path d=\"m6 6 12 12\" />\n </svg>\n );\n}\n\n/** Start menu icon (Windows-style) */\nfunction StartIcon({ className }: { className?: string }) {\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n width=\"24\"\n height=\"24\"\n viewBox=\"0 0 24 24\"\n fill=\"currentColor\"\n className={className}\n aria-hidden\n >\n <path d=\"M3 3h8v8H3V3zm10 0h8v8h-8V3zM3 13h8v8H3v-8zm10 0h8v8h-8v-8z\" />\n </svg>\n );\n}\n\nfunction getBrowserTimezone(): string {\n if (typeof window !== 'undefined' && Intl.DateTimeFormat) {\n return Intl.DateTimeFormat().resolvedOptions().timeZone;\n }\n return 'UTC';\n}\n\nexport function WindowsLayout({\n title,\n appIcon: _appIcon,\n logo: _logo,\n navigation,\n}: WindowsLayoutProps) {\n const { i18n } = useTranslation();\n const { settings } = useSettings();\n const currentLanguage = i18n.language || 'en';\n const timeZone = settings.region?.timezone ?? getBrowserTimezone();\n const { startNavItems, endNavItems, navigationItems } = useMemo(() => {\n const { start, end } = splitNavigationByPosition(navigation);\n return {\n startNavItems: flattenNavigationItems(start),\n endNavItems: end,\n navigationItems: flattenNavigationItems(navigation),\n };\n }, [navigation]);\n\n const [windows, setWindows] = useState<WindowState[]>([]);\n /** Id of the window that is on top (first plan). Clicking a window or its taskbar button sets this. */\n const [frontWindowId, setFrontWindowId] = useState<string | null>(null);\n const [startMenuOpen, setStartMenuOpen] = useState(false);\n const [now, setNow] = useState(() => new Date());\n const startPanelRef = useRef<HTMLDivElement>(null);\n\n // Update date/time every second for taskbar clock\n useEffect(() => {\n const interval = setInterval(() => setNow(new Date()), 1000);\n return () => clearInterval(interval);\n }, []);\n\n /** Highest z-index: front window always gets this so it stays on top. */\n const maxZIndex = useMemo(\n () => Z_INDEX.WINDOWS_WINDOW_BASE + Math.max(windows.length, 1),\n [windows.length],\n );\n\n const openWindow = useCallback(\n (item: NavigationItem) => {\n const label =\n typeof item.label === 'string' ? item.label : resolveNavLabel(item.label, currentLanguage);\n const faviconUrl =\n item.openIn === 'external' && !item.icon ? getExternalFaviconUrl(item.url) : null;\n const icon = item.icon ?? faviconUrl ?? null;\n const id = genId();\n const bounds = {\n x: 60 + windows.length * 24,\n y: 60 + windows.length * 24,\n w: DEFAULT_WIDTH,\n h: DEFAULT_HEIGHT,\n };\n setWindows((prev) => [\n ...prev,\n {\n id,\n path: item.path,\n pathname: `/${item.path}`,\n baseUrl: item.url,\n label,\n icon,\n bounds,\n },\n ]);\n setFrontWindowId(id);\n setStartMenuOpen(false);\n },\n [currentLanguage, windows.length],\n );\n\n const closeWindow = useCallback((id: string) => {\n setWindows((prev) => prev.filter((w) => w.id !== id));\n setFrontWindowId((current) => (current === id ? null : current));\n }, []);\n\n // When front window is closed or missing, bring first window to front\n useEffect(() => {\n if (windows.length === 0) {\n setFrontWindowId(null);\n return;\n }\n const frontStillExists = frontWindowId !== null && windows.some((w) => w.id === frontWindowId);\n if (!frontStillExists) {\n setFrontWindowId(windows[0].id);\n }\n }, [windows, frontWindowId]);\n\n /** Bring the window to front (first plan). Used when clicking the window or its taskbar button. */\n const focusWindow = useCallback((id: string) => {\n setFrontWindowId(id);\n }, []);\n\n const updateWindowBounds = useCallback((id: string, bounds: WindowState['bounds']) => {\n setWindows((prev) => prev.map((w) => (w.id === id ? { ...w, bounds } : w)));\n }, []);\n\n // Close start menu on click outside\n useEffect(() => {\n if (!startMenuOpen) return;\n const onDocClick = (e: MouseEvent) => {\n if (startPanelRef.current && !startPanelRef.current.contains(e.target as Node)) {\n setStartMenuOpen(false);\n }\n };\n document.addEventListener('mousedown', onDocClick);\n return () => document.removeEventListener('mousedown', onDocClick);\n }, [startMenuOpen]);\n\n const handleNavClick = useCallback(\n (item: NavigationItem) => {\n if (item.openIn === 'modal') {\n shellui.openModal(item.url);\n setStartMenuOpen(false);\n return;\n }\n if (item.openIn === 'drawer') {\n shellui.openDrawer({ url: item.url, position: item.drawerPosition });\n setStartMenuOpen(false);\n return;\n }\n if (item.openIn === 'external') {\n window.open(item.url, '_blank', 'noopener,noreferrer');\n setStartMenuOpen(false);\n return;\n }\n openWindow(item);\n },\n [openWindow],\n );\n\n return (\n <LayoutProviders>\n <OverlayShell navigationItems={navigationItems}>\n <div\n className=\"fixed inset-0 bg-muted/30\"\n style={{ paddingBottom: TASKBAR_HEIGHT }}\n >\n {/* Desktop area: windows */}\n {windows.map((win, index) => {\n const navItem = navigationItems.find((n) => n.path === win.path);\n if (!navItem) return null;\n const isFocused = win.id === frontWindowId;\n const zIndex = Z_INDEX.WINDOWS_WINDOW_BASE + index;\n return (\n <AppWindow\n key={win.id}\n win={win}\n navItem={navItem}\n currentLanguage={currentLanguage}\n isFocused={isFocused}\n onFocus={() => focusWindow(win.id)}\n onClose={() => closeWindow(win.id)}\n onBoundsChange={(bounds) => updateWindowBounds(win.id, bounds)}\n maxZIndex={maxZIndex}\n zIndex={zIndex}\n />\n );\n })}\n </div>\n\n {/* Taskbar */}\n <div\n className=\"fixed left-0 right-0 bottom-0 flex items-center gap-1 px-2 border-t border-border bg-sidebar-background\"\n style={{\n height: TASKBAR_HEIGHT,\n zIndex: Z_INDEX.WINDOWS_TASKBAR,\n paddingBottom: 'env(safe-area-inset-bottom, 0px)',\n }}\n >\n {/* Start button */}\n <div\n className=\"relative shrink-0\"\n ref={startPanelRef}\n >\n <button\n type=\"button\"\n onClick={() => setStartMenuOpen((o) => !o)}\n className={cn(\n 'flex items-center gap-2 h-9 px-3 rounded cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n startMenuOpen\n ? 'bg-sidebar-accent text-sidebar-accent-foreground'\n : 'text-sidebar-foreground hover:bg-sidebar-accent/50 hover:text-sidebar-foreground',\n )}\n aria-expanded={startMenuOpen}\n aria-haspopup=\"true\"\n aria-label=\"Start\"\n >\n <StartIcon className=\"h-5 w-5\" />\n <span className=\"font-semibold text-sm hidden sm:inline\">{title || 'Start'}</span>\n </button>\n {/* Start menu panel */}\n {startMenuOpen && (\n <div\n className=\"absolute bottom-full left-0 mb-1 w-64 max-h-[70vh] overflow-y-auto rounded-lg border border-border bg-popover shadow-lg py-2 z-[10001]\"\n style={{ zIndex: Z_INDEX.MODAL_CONTENT }}\n >\n <div className=\"px-2 pb-2 border-b border-border mb-2\">\n <span className=\"text-sm font-semibold text-popover-foreground\">\n {title || 'Applications'}\n </span>\n </div>\n <div className=\"grid gap-0.5\">\n {startNavItems\n .filter((item) => !item.hidden)\n .map((item) => {\n const label =\n typeof item.label === 'string'\n ? item.label\n : resolveNavLabel(item.label, currentLanguage);\n const icon =\n item.icon ??\n (item.openIn === 'external' ? getExternalFaviconUrl(item.url) : null);\n return (\n <button\n key={item.path}\n type=\"button\"\n onClick={() => handleNavClick(item)}\n className=\"flex items-center gap-3 w-full px-3 py-2 text-left text-sm cursor-pointer text-popover-foreground hover:bg-accent hover:text-accent-foreground rounded-none transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n >\n {icon ? (\n <img\n src={icon}\n alt=\"\"\n className={cn(\n 'h-5 w-5 shrink-0 rounded-sm object-cover',\n isAppIcon(icon) && 'opacity-90 dark:opacity-100 dark:invert',\n )}\n />\n ) : (\n <span className=\"h-5 w-5 shrink-0 rounded-sm bg-muted\" />\n )}\n <span className=\"truncate\">{label}</span>\n </button>\n );\n })}\n </div>\n </div>\n )}\n </div>\n\n {/* Window list */}\n <div className=\"flex-1 flex items-center gap-1 min-w-0 overflow-x-auto\">\n {windows.map((win) => {\n const navItem = navigationItems.find((n) => n.path === win.path);\n const windowLabel = navItem\n ? resolveNavLabel(navItem.label, currentLanguage)\n : win.label;\n const isFocused = win.id === frontWindowId;\n return (\n <button\n key={win.id}\n type=\"button\"\n onClick={() => focusWindow(win.id)}\n onContextMenu={(e) => {\n e.preventDefault();\n closeWindow(win.id);\n }}\n className={cn(\n 'flex items-center gap-2 h-8 px-2 rounded min-w-0 max-w-[140px] shrink-0 cursor-pointer transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',\n isFocused\n ? 'bg-sidebar-accent text-sidebar-accent-foreground'\n : 'text-sidebar-foreground hover:bg-sidebar-accent/50 hover:text-sidebar-foreground',\n )}\n title={windowLabel}\n >\n {win.icon ? (\n <img\n src={win.icon}\n alt=\"\"\n className={cn(\n 'h-4 w-4 shrink-0 rounded-sm object-cover',\n isAppIcon(win.icon) && 'opacity-90 dark:opacity-100 dark:invert',\n )}\n />\n ) : (\n <span className=\"h-4 w-4 shrink-0 rounded-sm bg-muted\" />\n )}\n <span className=\"text-xs truncate\">{windowLabel}</span>\n </button>\n );\n })}\n </div>\n\n {/* End navigation items (right side of taskbar) */}\n {endNavItems.length > 0 && (\n <div className=\"flex items-center gap-0.5 shrink-0 border-l border-sidebar-border pl-2 ml-1\">\n {endNavItems.map((item) => {\n const label =\n typeof item.label === 'string'\n ? item.label\n : resolveNavLabel(item.label, currentLanguage);\n const icon =\n item.icon ??\n (item.openIn === 'external' ? getExternalFaviconUrl(item.url) : null);\n return (\n <button\n key={item.path}\n type=\"button\"\n onClick={() => handleNavClick(item)}\n className=\"flex items-center gap-2 h-8 px-2 rounded cursor-pointer text-sidebar-foreground hover:bg-sidebar-accent/50 hover:text-sidebar-foreground transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2\"\n title={label}\n >\n {icon ? (\n <img\n src={icon}\n alt=\"\"\n className={cn(\n 'h-4 w-4 shrink-0 rounded-sm object-cover',\n isAppIcon(icon) && 'opacity-90 dark:opacity-100 dark:invert',\n )}\n />\n ) : (\n <span className=\"h-4 w-4 shrink-0 rounded-sm bg-muted\" />\n )}\n <span className=\"text-xs truncate max-w-[100px]\">{label}</span>\n </button>\n );\n })}\n </div>\n )}\n\n {/* Date and time (extreme bottom right, OS-style); uses region timezone from settings */}\n <div\n className=\"flex flex-col items-end justify-center shrink-0 px-3 py-1 text-sidebar-foreground border-l border-sidebar-border ml-1 min-w-0\"\n style={{ paddingRight: 'max(0.75rem, env(safe-area-inset-right))' }}\n role=\"timer\"\n aria-live=\"off\"\n aria-label={new Intl.DateTimeFormat(currentLanguage, {\n timeZone,\n dateStyle: 'full',\n timeStyle: 'medium',\n }).format(now)}\n >\n <time\n dateTime={now.toISOString()}\n className=\"text-xs leading-tight tabular-nums whitespace-nowrap\"\n >\n {new Intl.DateTimeFormat(currentLanguage, {\n timeZone,\n hour: '2-digit',\n minute: '2-digit',\n second: '2-digit',\n }).format(now)}\n </time>\n <time\n dateTime={now.toISOString()}\n className=\"text-[10px] leading-tight whitespace-nowrap text-sidebar-foreground/90\"\n >\n {new Intl.DateTimeFormat(currentLanguage, {\n timeZone,\n weekday: 'short',\n day: 'numeric',\n month: 'short',\n }).format(now)}\n </time>\n </div>\n </div>\n </OverlayShell>\n </LayoutProviders>\n );\n}\n"],"names":["getExternalFaviconUrl","url","hostname","isAppIcon","src","genId","MIN_WIDTH","MIN_HEIGHT","DEFAULT_WIDTH","DEFAULT_HEIGHT","TASKBAR_HEIGHT","getMaximizedBounds","buildFinalUrl","baseUrl","path","pathname","pathPrefix","subPath","AppWindow","win","navItem","currentLanguage","isFocused","onFocus","onClose","onBoundsChange","maxZIndex","zIndex","windowLabel","resolveNavLabel","bounds","setBounds","useState","isMaximized","setIsMaximized","boundsBeforeMaximizeRef","useRef","containerRef","dragRef","resizeRef","resizeRafRef","pendingResizeBoundsRef","useEffect","onResize","onPointerMove","useCallback","e","d","dx","dy","el","onPointerUp","finalBounds","handleTitlePointerDown","handleMaximizeToggle","onResizePointerMove","edge","startX","startY","startBounds","next","newW","newH","pending","onResizePointerUp","handleResizePointerDown","finalUrl","useMemo","z","jsxs","jsx","cn","RestoreIcon","MaximizeIcon","CloseIcon","ContentView","className","StartIcon","getBrowserTimezone","WindowsLayout","title","_appIcon","_logo","navigation","i18n","useTranslation","settings","useSettings","timeZone","startNavItems","endNavItems","navigationItems","start","end","splitNavigationByPosition","flattenNavigationItems","windows","setWindows","frontWindowId","setFrontWindowId","startMenuOpen","setStartMenuOpen","now","setNow","startPanelRef","interval","Z_INDEX","openWindow","item","label","faviconUrl","icon","id","prev","closeWindow","w","current","focusWindow","updateWindowBounds","onDocClick","handleNavClick","shellui","LayoutProviders","OverlayShell","index","n","o"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ConfigProvider.d.ts","sourceRoot":"","sources":["../../../src/features/config/ConfigProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAI7C,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,eAAO,MAAM,aAAa,oDAAiD,CAAC;AAE5E,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,SAAS,CAAC;CACrB;AAMD;;;GAGG;AAEH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,
|
|
1
|
+
{"version":3,"file":"ConfigProvider.d.ts","sourceRoot":"","sources":["../../../src/features/config/ConfigProvider.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,aAAa,EAAE,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAE/E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAI7C,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,aAAa,CAAC;CACvB;AAED,eAAO,MAAM,aAAa,oDAAiD,CAAC;AAE5E,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,SAAS,CAAC;CACrB;AAMD;;;GAGG;AAEH,wBAAgB,cAAc,CAAC,KAAK,EAAE,mBAAmB,GAAG,UAAU,CAAC,OAAO,aAAa,CAAC,CAqF3F"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"useConfig.d.ts","sourceRoot":"","sources":["../../../src/features/config/useConfig.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE1E;;;;GAIG;AACH,wBAAgB,SAAS,IAAI,kBAAkB,
|
|
1
|
+
{"version":3,"file":"useConfig.d.ts","sourceRoot":"","sources":["../../../src/features/config/useConfig.ts"],"names":[],"mappings":"AACA,OAAO,EAAiB,KAAK,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE1E;;;;GAIG;AACH,wBAAgB,SAAS,IAAI,kBAAkB,CAmB9C"}
|