react-os-shell 4.9.0 → 4.11.0
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/README.md +16 -1
- package/dist/{Browser-7AQ7Y4Z7.js → Browser-V3F6MZ6J.js} +5 -5
- package/dist/{Browser-7AQ7Y4Z7.js.map → Browser-V3F6MZ6J.js.map} +1 -1
- package/dist/{Calculator-B7KJQ2NF.js → Calculator-U7JLNROS.js} +4 -4
- package/dist/{Calculator-B7KJQ2NF.js.map → Calculator-U7JLNROS.js.map} +1 -1
- package/dist/ConfirmDialog-Y4BYT77R.js +4 -0
- package/dist/{ConfirmDialog-U5H3MP3M.js.map → ConfirmDialog-Y4BYT77R.js.map} +1 -1
- package/dist/{CurrencyConverter-AILEZUIU.js → CurrencyConverter-2UFQ75WE.js} +4 -4
- package/dist/{CurrencyConverter-AILEZUIU.js.map → CurrencyConverter-2UFQ75WE.js.map} +1 -1
- package/dist/{Documents-IX6JISOV.js → Documents-3V7XPDOS.js} +5 -5
- package/dist/{Documents-IX6JISOV.js.map → Documents-3V7XPDOS.js.map} +1 -1
- package/dist/{Files-O7WK4TQG.js → Files-TH37G6YY.js} +5 -5
- package/dist/{Files-O7WK4TQG.js.map → Files-TH37G6YY.js.map} +1 -1
- package/dist/{Notepad-LO7FRU34.js → Notepad-OXSKELWV.js} +5 -5
- package/dist/{Notepad-LO7FRU34.js.map → Notepad-OXSKELWV.js.map} +1 -1
- package/dist/{PomodoroTimer-DSVXJ7D4.js → PomodoroTimer-Q53KOASQ.js} +5 -5
- package/dist/{PomodoroTimer-DSVXJ7D4.js.map → PomodoroTimer-Q53KOASQ.js.map} +1 -1
- package/dist/{Preview-QCAN5EU3.js → Preview-J6YDYCX4.js} +5 -5
- package/dist/{Preview-QCAN5EU3.js.map → Preview-J6YDYCX4.js.map} +1 -1
- package/dist/{Spreadsheet-SUP2H2B4.js → Spreadsheet-BSBZ46CE.js} +5 -5
- package/dist/{Spreadsheet-SUP2H2B4.js.map → Spreadsheet-BSBZ46CE.js.map} +1 -1
- package/dist/{Stock-UT2JMEVS.js → Stock-SRUFZGQC.js} +4 -4
- package/dist/{Stock-UT2JMEVS.js.map → Stock-SRUFZGQC.js.map} +1 -1
- package/dist/{Weather-37TNIYWI.js → Weather-47E3IRKF.js} +4 -4
- package/dist/{Weather-37TNIYWI.js.map → Weather-47E3IRKF.js.map} +1 -1
- package/dist/{WorldClock-EESGFXPN.js → WorldClock-7L2YHNC3.js} +4 -4
- package/dist/{WorldClock-EESGFXPN.js.map → WorldClock-7L2YHNC3.js.map} +1 -1
- package/dist/apps/index.js +15 -15
- package/dist/{chunk-G6AUDFI4.js → chunk-E2EGGV2Z.js} +121 -41
- package/dist/chunk-E2EGGV2Z.js.map +1 -0
- package/dist/{chunk-TIKW3XWE.js → chunk-J4XK47N3.js} +4 -4
- package/dist/{chunk-TIKW3XWE.js.map → chunk-J4XK47N3.js.map} +1 -1
- package/dist/{chunk-UH3H3KAN.js → chunk-JROEOUJD.js} +3 -3
- package/dist/{chunk-UH3H3KAN.js.map → chunk-JROEOUJD.js.map} +1 -1
- package/dist/chunk-VG2WSTEJ.js +7 -0
- package/dist/{chunk-NQTQPOT4.js.map → chunk-VG2WSTEJ.js.map} +1 -1
- package/dist/{chunk-BOTXJSDK.js → chunk-XVHRGMS3.js} +3 -3
- package/dist/{chunk-BOTXJSDK.js.map → chunk-XVHRGMS3.js.map} +1 -1
- package/dist/index.d.ts +25 -6
- package/dist/index.js +24 -6
- package/dist/index.js.map +1 -1
- package/dist/styles.css +4 -3
- package/package.json +2 -1
- package/dist/ConfirmDialog-U5H3MP3M.js +0 -4
- package/dist/chunk-G6AUDFI4.js.map +0 -1
- package/dist/chunk-NQTQPOT4.js +0 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/apps/WorldClock.tsx"],"names":[],"mappings":"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","file":"WorldClock-EESGFXPN.js","sourcesContent":["import { useState, useEffect, useCallback } from 'react';\nimport { useWidgetSettings } from '../shell/Modal';\nimport WidgetSettingsModal, { loadAppearance, type WidgetAppearance } from '../shell/WidgetSettingsModal';\nimport { useShellPrefs } from '../shell/ShellPrefs';\nimport { AVAILABLE_CITIES, fetchCityWeather, getCondition, toFahrenheit, type CityWeather } from './_weatherData';\n\nconst SETTINGS_KEY = 'world_clock_appearance';\nconst DEFAULT_CITIES = ['London', 'Shanghai', 'New York'];\n\ninterface WeatherPrefs { useFahrenheit: boolean }\n\n/**\n * Resolve the local time for the supplied IANA timezone into a digital\n * `12:34` + `AM` / `PM` pair. Used by the World Clock rows.\n */\nfunction digitalTime(tz: string, now: Date): { time: string; ampm: string } {\n try {\n const parts = new Intl.DateTimeFormat('en-US', {\n timeZone: tz, hour: 'numeric', minute: '2-digit', hour12: true,\n }).formatToParts(now);\n const h = parts.find(p => p.type === 'hour')?.value || '12';\n const m = parts.find(p => p.type === 'minute')?.value || '00';\n const ampm = (parts.find(p => p.type === 'dayPeriod')?.value || '').toUpperCase();\n return { time: `${h}:${m}`, ampm };\n } catch { return { time: '', ampm: '' }; }\n}\n\n/**\n * World Clock widget — multi-city list. Each row pairs a tiny analogue\n * clock (minimal-style: ring, four cardinal dots, two hands) with the\n * city's current weather. The weather emoji doubles as a day/night cue\n * (☀ vs 🌙 for clear, the same icons for everything else). Reads the\n * shared Open-Meteo cache so it doesn't re-hit the API when the Weather\n * widget already has the data.\n */\nexport default function WorldClock() {\n const { prefs, save } = useShellPrefs();\n const [appearance, setAppearance] = useState(() => loadAppearance(SETTINGS_KEY));\n const [settingsOpen, setSettingsOpen] = useState(false);\n const [configCities, setConfigCities] = useState<string[]>([]);\n const [configAppearance, setConfigAppearance] = useState<WidgetAppearance>(appearance);\n\n const wxPrefs: WeatherPrefs = {\n useFahrenheit: !!(prefs.weather_prefs as WeatherPrefs | undefined)?.useFahrenheit,\n };\n const [configWxPrefs, setConfigWxPrefs] = useState(wxPrefs);\n\n // Tick once every 30 s so the analogue minute-hands drift smoothly. We\n // don't show seconds so faster polling is wasted re-renders.\n const [now, setNow] = useState(() => new Date());\n useEffect(() => {\n const t = setInterval(() => setNow(new Date()), 30 * 1000);\n return () => clearInterval(t);\n }, []);\n\n // Resolve the saved city list and migrate the legacy IANA-timezone\n // format (`Europe/London`) over to the new city-name format\n // (`London`).\n const tzToCity: Record<string, string> = Object.fromEntries(\n Object.entries(AVAILABLE_CITIES).map(([city, info]) => [info.tz, city])\n );\n const rawClocks = prefs.world_clocks as string[] | undefined;\n const cities: string[] = (() => {\n if (!Array.isArray(rawClocks) || rawClocks.length === 0) return DEFAULT_CITIES;\n const out: string[] = [];\n for (const v of rawClocks) {\n const asCity = AVAILABLE_CITIES[v] ? v : tzToCity[v];\n if (asCity && !out.includes(asCity)) out.push(asCity);\n }\n return out.length ? out : DEFAULT_CITIES;\n })();\n\n const [data, setData] = useState<Record<string, CityWeather>>({});\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n (async () => {\n const next: Record<string, CityWeather> = {};\n await Promise.all(cities.map(async c => {\n const w = await fetchCityWeather(c);\n if (w) next[c] = w;\n }));\n if (!cancelled) { setData(next); setLoading(false); }\n })();\n return () => { cancelled = true; };\n }, [cities.join(',')]);\n\n useWidgetSettings(useCallback(() => {\n setConfigCities([...cities]);\n setConfigAppearance({ ...appearance });\n setConfigWxPrefs({ ...wxPrefs });\n setSettingsOpen(true);\n }, [cities.join(','), appearance, wxPrefs.useFahrenheit]));\n\n const saveSettings = () => {\n if (configCities.length === 0) return;\n save({\n world_clocks: configCities,\n weather_prefs: { ...(prefs.weather_prefs as object | undefined ?? {}), useFahrenheit: configWxPrefs.useFahrenheit },\n });\n setAppearance(configAppearance);\n localStorage.setItem(SETTINGS_KEY, JSON.stringify(configAppearance));\n setSettingsOpen(false);\n };\n\n const formatTemp = (c: number) => wxPrefs.useFahrenheit ? `${toFahrenheit(c)}°` : `${c}°`;\n\n return (\n <>\n {/* Theme-aware panel — same colour as the taskbar so all dashboard\n * widgets read as a coordinated set across light and dark themes.\n * Rows use `divide-y` rather than per-row border classes so the\n * last row never paints a stray separator line at the panel's\n * bottom edge. */}\n <div\n style={{\n backgroundColor: `rgb(var(--taskbar-bg-rgb, 243 244 246) / ${appearance.activeOpacity / 100})`,\n backdropFilter: appearance.activeBlur > 0 ? `blur(${appearance.activeBlur}px)` : undefined,\n }}>\n <div className=\"divide-y divide-gray-200\">\n {loading && cities.every(c => !data[c]) && (\n <div className=\"px-3 py-6 text-center text-xs text-gray-500\">Loading…</div>\n )}\n {cities.map((cityName) => {\n const w = data[cityName];\n const tz = AVAILABLE_CITIES[cityName]?.tz ?? 'UTC';\n const { time, ampm } = digitalTime(tz, now);\n if (!w) {\n return (\n <div key={cityName} className=\"px-4 py-3\">\n <div className=\"flex items-baseline justify-between gap-2\">\n <span className=\"text-[15px] font-semibold tracking-tight text-gray-900 truncate\">{cityName}</span>\n <span className=\"tabular-nums text-[13px] font-medium text-gray-500\">{time}<span className=\"text-[9px] ml-0.5 opacity-70\">{ampm}</span></span>\n </div>\n <div className=\"text-[11px] text-gray-400 mt-1\">Loading weather…</div>\n </div>\n );\n }\n const [condition, emoji] = getCondition(w.code, w.isDay);\n return (\n <div key={cityName} className=\"px-4 py-3\">\n {/* Top — city name on the left, big temperature on the right. */}\n <div className=\"flex items-baseline justify-between gap-2\">\n <span className=\"text-[15px] font-semibold tracking-tight text-gray-900 truncate\">{cityName}</span>\n <span className=\"text-[26px] font-extralight leading-none tabular-nums tracking-tight text-gray-900 shrink-0\">{formatTemp(w.temp)}</span>\n </div>\n\n {/* Bottom — emoji · digital time · condition on the left;\n H/L on the right. */}\n <div className=\"flex items-center justify-between gap-2 mt-1.5 text-[11px]\">\n <div className=\"flex items-center gap-1.5 min-w-0 text-gray-500\">\n <span className=\"text-base leading-none shrink-0\">{emoji}</span>\n <span className=\"tabular-nums font-semibold text-gray-700 shrink-0\">\n {time}<span className=\"text-[9px] font-medium ml-0.5 opacity-70\">{ampm}</span>\n </span>\n <span className=\"text-gray-300 shrink-0\">·</span>\n <span className=\"truncate\">{condition}</span>\n </div>\n <span className=\"tabular-nums text-gray-500 shrink-0\">H:{formatTemp(w.high)} L:{formatTemp(w.low)}</span>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n\n <WidgetSettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} title=\"World Clock Settings\"\n appearance={configAppearance} onAppearanceChange={setConfigAppearance} onSave={saveSettings}>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Display</h3>\n <div className=\"flex items-center gap-3 mb-2\">\n <span className=\"text-sm text-gray-600 w-24\">Temperature</span>\n <div className=\"flex gap-1\">\n {([{ key: false, label: '°C' }, { key: true, label: '°F' }] as const).map(o => (\n <button key={String(o.key)} onClick={() => setConfigWxPrefs(p => ({ ...p, useFahrenheit: o.key }))}\n className={`px-3 py-1 text-xs font-medium rounded-lg border transition-colors ${configWxPrefs.useFahrenheit === o.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'}`}>\n {o.label}\n </button>\n ))}\n </div>\n </div>\n <p className=\"text-[10px] text-gray-400 mt-1\">Shared with the Weather widget.</p>\n </div>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Cities</h3>\n <div className=\"grid grid-cols-2 gap-1 max-h-56 overflow-y-auto\">\n {Object.keys(AVAILABLE_CITIES).map(name => (\n <label key={name} className=\"flex items-center gap-2 text-sm py-1 cursor-pointer hover:bg-gray-50 rounded px-2\">\n <input type=\"checkbox\" checked={configCities.includes(name)}\n onChange={() => setConfigCities(prev => prev.includes(name) ? prev.filter(c => c !== name) : [...prev, name])}\n className=\"rounded border-gray-300 text-blue-600 focus:ring-blue-500 h-3.5 w-3.5\" />\n {name}\n </label>\n ))}\n </div>\n </div>\n </WidgetSettingsModal>\n </>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/apps/WorldClock.tsx"],"names":[],"mappings":"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","file":"WorldClock-7L2YHNC3.js","sourcesContent":["import { useState, useEffect, useCallback } from 'react';\nimport { useWidgetSettings } from '../shell/Modal';\nimport WidgetSettingsModal, { loadAppearance, type WidgetAppearance } from '../shell/WidgetSettingsModal';\nimport { useShellPrefs } from '../shell/ShellPrefs';\nimport { AVAILABLE_CITIES, fetchCityWeather, getCondition, toFahrenheit, type CityWeather } from './_weatherData';\n\nconst SETTINGS_KEY = 'world_clock_appearance';\nconst DEFAULT_CITIES = ['London', 'Shanghai', 'New York'];\n\ninterface WeatherPrefs { useFahrenheit: boolean }\n\n/**\n * Resolve the local time for the supplied IANA timezone into a digital\n * `12:34` + `AM` / `PM` pair. Used by the World Clock rows.\n */\nfunction digitalTime(tz: string, now: Date): { time: string; ampm: string } {\n try {\n const parts = new Intl.DateTimeFormat('en-US', {\n timeZone: tz, hour: 'numeric', minute: '2-digit', hour12: true,\n }).formatToParts(now);\n const h = parts.find(p => p.type === 'hour')?.value || '12';\n const m = parts.find(p => p.type === 'minute')?.value || '00';\n const ampm = (parts.find(p => p.type === 'dayPeriod')?.value || '').toUpperCase();\n return { time: `${h}:${m}`, ampm };\n } catch { return { time: '', ampm: '' }; }\n}\n\n/**\n * World Clock widget — multi-city list. Each row pairs a tiny analogue\n * clock (minimal-style: ring, four cardinal dots, two hands) with the\n * city's current weather. The weather emoji doubles as a day/night cue\n * (☀ vs 🌙 for clear, the same icons for everything else). Reads the\n * shared Open-Meteo cache so it doesn't re-hit the API when the Weather\n * widget already has the data.\n */\nexport default function WorldClock() {\n const { prefs, save } = useShellPrefs();\n const [appearance, setAppearance] = useState(() => loadAppearance(SETTINGS_KEY));\n const [settingsOpen, setSettingsOpen] = useState(false);\n const [configCities, setConfigCities] = useState<string[]>([]);\n const [configAppearance, setConfigAppearance] = useState<WidgetAppearance>(appearance);\n\n const wxPrefs: WeatherPrefs = {\n useFahrenheit: !!(prefs.weather_prefs as WeatherPrefs | undefined)?.useFahrenheit,\n };\n const [configWxPrefs, setConfigWxPrefs] = useState(wxPrefs);\n\n // Tick once every 30 s so the analogue minute-hands drift smoothly. We\n // don't show seconds so faster polling is wasted re-renders.\n const [now, setNow] = useState(() => new Date());\n useEffect(() => {\n const t = setInterval(() => setNow(new Date()), 30 * 1000);\n return () => clearInterval(t);\n }, []);\n\n // Resolve the saved city list and migrate the legacy IANA-timezone\n // format (`Europe/London`) over to the new city-name format\n // (`London`).\n const tzToCity: Record<string, string> = Object.fromEntries(\n Object.entries(AVAILABLE_CITIES).map(([city, info]) => [info.tz, city])\n );\n const rawClocks = prefs.world_clocks as string[] | undefined;\n const cities: string[] = (() => {\n if (!Array.isArray(rawClocks) || rawClocks.length === 0) return DEFAULT_CITIES;\n const out: string[] = [];\n for (const v of rawClocks) {\n const asCity = AVAILABLE_CITIES[v] ? v : tzToCity[v];\n if (asCity && !out.includes(asCity)) out.push(asCity);\n }\n return out.length ? out : DEFAULT_CITIES;\n })();\n\n const [data, setData] = useState<Record<string, CityWeather>>({});\n const [loading, setLoading] = useState(true);\n\n useEffect(() => {\n let cancelled = false;\n setLoading(true);\n (async () => {\n const next: Record<string, CityWeather> = {};\n await Promise.all(cities.map(async c => {\n const w = await fetchCityWeather(c);\n if (w) next[c] = w;\n }));\n if (!cancelled) { setData(next); setLoading(false); }\n })();\n return () => { cancelled = true; };\n }, [cities.join(',')]);\n\n useWidgetSettings(useCallback(() => {\n setConfigCities([...cities]);\n setConfigAppearance({ ...appearance });\n setConfigWxPrefs({ ...wxPrefs });\n setSettingsOpen(true);\n }, [cities.join(','), appearance, wxPrefs.useFahrenheit]));\n\n const saveSettings = () => {\n if (configCities.length === 0) return;\n save({\n world_clocks: configCities,\n weather_prefs: { ...(prefs.weather_prefs as object | undefined ?? {}), useFahrenheit: configWxPrefs.useFahrenheit },\n });\n setAppearance(configAppearance);\n localStorage.setItem(SETTINGS_KEY, JSON.stringify(configAppearance));\n setSettingsOpen(false);\n };\n\n const formatTemp = (c: number) => wxPrefs.useFahrenheit ? `${toFahrenheit(c)}°` : `${c}°`;\n\n return (\n <>\n {/* Theme-aware panel — same colour as the taskbar so all dashboard\n * widgets read as a coordinated set across light and dark themes.\n * Rows use `divide-y` rather than per-row border classes so the\n * last row never paints a stray separator line at the panel's\n * bottom edge. */}\n <div\n style={{\n backgroundColor: `rgb(var(--taskbar-bg-rgb, 243 244 246) / ${appearance.activeOpacity / 100})`,\n backdropFilter: appearance.activeBlur > 0 ? `blur(${appearance.activeBlur}px)` : undefined,\n }}>\n <div className=\"divide-y divide-gray-200\">\n {loading && cities.every(c => !data[c]) && (\n <div className=\"px-3 py-6 text-center text-xs text-gray-500\">Loading…</div>\n )}\n {cities.map((cityName) => {\n const w = data[cityName];\n const tz = AVAILABLE_CITIES[cityName]?.tz ?? 'UTC';\n const { time, ampm } = digitalTime(tz, now);\n if (!w) {\n return (\n <div key={cityName} className=\"px-4 py-3\">\n <div className=\"flex items-baseline justify-between gap-2\">\n <span className=\"text-[15px] font-semibold tracking-tight text-gray-900 truncate\">{cityName}</span>\n <span className=\"tabular-nums text-[13px] font-medium text-gray-500\">{time}<span className=\"text-[9px] ml-0.5 opacity-70\">{ampm}</span></span>\n </div>\n <div className=\"text-[11px] text-gray-400 mt-1\">Loading weather…</div>\n </div>\n );\n }\n const [condition, emoji] = getCondition(w.code, w.isDay);\n return (\n <div key={cityName} className=\"px-4 py-3\">\n {/* Top — city name on the left, big temperature on the right. */}\n <div className=\"flex items-baseline justify-between gap-2\">\n <span className=\"text-[15px] font-semibold tracking-tight text-gray-900 truncate\">{cityName}</span>\n <span className=\"text-[26px] font-extralight leading-none tabular-nums tracking-tight text-gray-900 shrink-0\">{formatTemp(w.temp)}</span>\n </div>\n\n {/* Bottom — emoji · digital time · condition on the left;\n H/L on the right. */}\n <div className=\"flex items-center justify-between gap-2 mt-1.5 text-[11px]\">\n <div className=\"flex items-center gap-1.5 min-w-0 text-gray-500\">\n <span className=\"text-base leading-none shrink-0\">{emoji}</span>\n <span className=\"tabular-nums font-semibold text-gray-700 shrink-0\">\n {time}<span className=\"text-[9px] font-medium ml-0.5 opacity-70\">{ampm}</span>\n </span>\n <span className=\"text-gray-300 shrink-0\">·</span>\n <span className=\"truncate\">{condition}</span>\n </div>\n <span className=\"tabular-nums text-gray-500 shrink-0\">H:{formatTemp(w.high)} L:{formatTemp(w.low)}</span>\n </div>\n </div>\n );\n })}\n </div>\n </div>\n\n <WidgetSettingsModal open={settingsOpen} onClose={() => setSettingsOpen(false)} title=\"World Clock Settings\"\n appearance={configAppearance} onAppearanceChange={setConfigAppearance} onSave={saveSettings}>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Display</h3>\n <div className=\"flex items-center gap-3 mb-2\">\n <span className=\"text-sm text-gray-600 w-24\">Temperature</span>\n <div className=\"flex gap-1\">\n {([{ key: false, label: '°C' }, { key: true, label: '°F' }] as const).map(o => (\n <button key={String(o.key)} onClick={() => setConfigWxPrefs(p => ({ ...p, useFahrenheit: o.key }))}\n className={`px-3 py-1 text-xs font-medium rounded-lg border transition-colors ${configWxPrefs.useFahrenheit === o.key ? 'bg-blue-600 text-white border-blue-600' : 'bg-white text-gray-700 border-gray-300 hover:bg-gray-50'}`}>\n {o.label}\n </button>\n ))}\n </div>\n </div>\n <p className=\"text-[10px] text-gray-400 mt-1\">Shared with the Weather widget.</p>\n </div>\n <div>\n <h3 className=\"text-sm font-semibold text-gray-700 mb-2\">Cities</h3>\n <div className=\"grid grid-cols-2 gap-1 max-h-56 overflow-y-auto\">\n {Object.keys(AVAILABLE_CITIES).map(name => (\n <label key={name} className=\"flex items-center gap-2 text-sm py-1 cursor-pointer hover:bg-gray-50 rounded px-2\">\n <input type=\"checkbox\" checked={configCities.includes(name)}\n onChange={() => setConfigCities(prev => prev.includes(name) ? prev.filter(c => c !== name) : [...prev, name])}\n className=\"rounded border-gray-300 text-blue-600 focus:ring-blue-500 h-3.5 w-3.5\" />\n {name}\n </label>\n ))}\n </div>\n </div>\n </WidgetSettingsModal>\n </>\n );\n}\n"]}
|
package/dist/apps/index.js
CHANGED
|
@@ -2,25 +2,25 @@ export { openFilesInTrashMode, setFilesDemoTree } from '../chunk-HC6N2OXO.js';
|
|
|
2
2
|
export { setBrowserStartUrl } from '../chunk-BFBWLCO6.js';
|
|
3
3
|
import '../chunk-H5NDQZ4A.js';
|
|
4
4
|
export { setPdfPreview } from '../chunk-BV6SQ46N.js';
|
|
5
|
-
export { BUILTIN_APP_INFO } from '../chunk-
|
|
5
|
+
export { BUILTIN_APP_INFO } from '../chunk-J4XK47N3.js';
|
|
6
6
|
export { setSpreadsheetPreview } from '../chunk-4SQU5YV6.js';
|
|
7
|
-
import '../chunk-
|
|
8
|
-
import '../chunk-
|
|
7
|
+
import '../chunk-VG2WSTEJ.js';
|
|
8
|
+
import '../chunk-E2EGGV2Z.js';
|
|
9
9
|
import '../chunk-RVT2A2MO.js';
|
|
10
10
|
import { lazy } from 'react';
|
|
11
11
|
|
|
12
|
-
var Calculator = lazy(() => import('../Calculator-
|
|
13
|
-
var Spreadsheet = lazy(() => import('../Spreadsheet-
|
|
14
|
-
var Weather = lazy(() => import('../Weather-
|
|
15
|
-
var CurrencyConverter = lazy(() => import('../CurrencyConverter-
|
|
16
|
-
var PomodoroTimer = lazy(() => import('../PomodoroTimer-
|
|
17
|
-
var Notepad = lazy(() => import('../Notepad-
|
|
18
|
-
var WorldClock = lazy(() => import('../WorldClock-
|
|
19
|
-
var Stock = lazy(() => import('../Stock-
|
|
20
|
-
var Preview = lazy(() => import('../Preview-
|
|
21
|
-
var Documents = lazy(() => import('../Documents-
|
|
22
|
-
var Files = lazy(() => import('../Files-
|
|
23
|
-
var Browser = lazy(() => import('../Browser-
|
|
12
|
+
var Calculator = lazy(() => import('../Calculator-U7JLNROS.js'));
|
|
13
|
+
var Spreadsheet = lazy(() => import('../Spreadsheet-BSBZ46CE.js'));
|
|
14
|
+
var Weather = lazy(() => import('../Weather-47E3IRKF.js'));
|
|
15
|
+
var CurrencyConverter = lazy(() => import('../CurrencyConverter-2UFQ75WE.js'));
|
|
16
|
+
var PomodoroTimer = lazy(() => import('../PomodoroTimer-Q53KOASQ.js'));
|
|
17
|
+
var Notepad = lazy(() => import('../Notepad-OXSKELWV.js'));
|
|
18
|
+
var WorldClock = lazy(() => import('../WorldClock-7L2YHNC3.js'));
|
|
19
|
+
var Stock = lazy(() => import('../Stock-SRUFZGQC.js'));
|
|
20
|
+
var Preview = lazy(() => import('../Preview-J6YDYCX4.js'));
|
|
21
|
+
var Documents = lazy(() => import('../Documents-3V7XPDOS.js'));
|
|
22
|
+
var Files = lazy(() => import('../Files-TH37G6YY.js'));
|
|
23
|
+
var Browser = lazy(() => import('../Browser-V3F6MZ6J.js'));
|
|
24
24
|
var utilityApps = {
|
|
25
25
|
"/calculator": { component: Calculator, label: "Calculator", size: "sm", allowPinOnTop: true, utility: true, widget: true, dimensions: [280, 420] },
|
|
26
26
|
"/spreadsheet": { component: Spreadsheet, label: "Spreadsheets", size: "2xl", appStyle: true, multiInstance: true },
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { useShellAuth, glassStyle, GLASS_DIVIDER, navIcons } from './chunk-RVT2A2MO.js';
|
|
2
|
-
import { createContext, Component, useReducer, useRef, useCallback, useState, useEffect, useMemo, useContext, useId,
|
|
2
|
+
import { createContext, Component, useReducer, useRef, useCallback, useState, useEffect, useMemo, useContext, useId, useLayoutEffect, useSyncExternalStore, isValidElement, cloneElement, Suspense } from 'react';
|
|
3
3
|
import { Dialog, DialogBackdrop, DialogPanel, DialogTitle } from '@headlessui/react';
|
|
4
4
|
import { XMarkIcon, ExclamationTriangleIcon } from '@heroicons/react/24/outline';
|
|
5
5
|
import { createPortal } from 'react-dom';
|
|
@@ -355,6 +355,33 @@ var MinimizedContext = createContext({
|
|
|
355
355
|
restoreIfMinimized: () => false,
|
|
356
356
|
openItems: []
|
|
357
357
|
});
|
|
358
|
+
var WindowDirtyContext = createContext(null);
|
|
359
|
+
function useWindowDirty(dirty) {
|
|
360
|
+
const register = useContext(WindowDirtyContext);
|
|
361
|
+
const idRef = useRef(null);
|
|
362
|
+
if (idRef.current === null) idRef.current = /* @__PURE__ */ Symbol("window-dirty");
|
|
363
|
+
useLayoutEffect(() => {
|
|
364
|
+
if (!register) return;
|
|
365
|
+
return register(idRef.current, dirty);
|
|
366
|
+
}, [register, dirty]);
|
|
367
|
+
}
|
|
368
|
+
function useWindowDirtyRegistry() {
|
|
369
|
+
const registrations = useRef(/* @__PURE__ */ new Map());
|
|
370
|
+
const [dirty, setDirty] = useState(false);
|
|
371
|
+
const registerDirty = useCallback((id, value) => {
|
|
372
|
+
const updateAggregate = () => {
|
|
373
|
+
const next = Array.from(registrations.current.values()).some(Boolean);
|
|
374
|
+
setDirty((current) => current === next ? current : next);
|
|
375
|
+
};
|
|
376
|
+
registrations.current.set(id, value);
|
|
377
|
+
updateAggregate();
|
|
378
|
+
return () => {
|
|
379
|
+
registrations.current.delete(id);
|
|
380
|
+
updateAggregate();
|
|
381
|
+
};
|
|
382
|
+
}, []);
|
|
383
|
+
return { dirty, registerDirty };
|
|
384
|
+
}
|
|
358
385
|
function useWindowManager() {
|
|
359
386
|
return useContext(MinimizedContext);
|
|
360
387
|
}
|
|
@@ -365,11 +392,12 @@ function shortcutSpecFor(item) {
|
|
|
365
392
|
return { entityType, entityId, label: item.label };
|
|
366
393
|
}
|
|
367
394
|
function PageWindow({ item, onClose, accentRgb }) {
|
|
395
|
+
const { dirty, registerDirty } = useWindowDirtyRegistry();
|
|
368
396
|
const raw = WINDOW_REGISTRY[item.route];
|
|
369
397
|
if (!raw || !isPageEntry(raw)) return null;
|
|
370
398
|
const entry = raw;
|
|
371
399
|
const Component2 = entry.component;
|
|
372
|
-
return /* @__PURE__ */ jsx(Modal, { open: true, onClose, icon: navIcons[item.route], title: entry.label, size: entry.size || "2xl", allowPinOnTop: entry.allowPinOnTop, initialPosition: entry.initialPosition, widget: entry.widget, compact: entry.compact, appStyle: entry.appStyle, flushBody: entry.flushBody, autoHeight: entry.autoHeight, autoMinHeight: entry.autoMinHeight, dimensions: entry.dimensions, windowKey: item.id, openedFromKey: item.openedFrom, accentRgb, children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsx(LoadingSpinner, {}) }), children: /* @__PURE__ */ jsx(Component2, {}) }) });
|
|
400
|
+
return /* @__PURE__ */ jsx(Modal, { open: true, onClose, icon: navIcons[item.route], title: entry.label, size: entry.size || "2xl", dirty, allowPinOnTop: entry.allowPinOnTop, initialPosition: entry.initialPosition, widget: entry.widget, compact: entry.compact, appStyle: entry.appStyle, flushBody: entry.flushBody, autoHeight: entry.autoHeight, autoMinHeight: entry.autoMinHeight, dimensions: entry.dimensions, windowKey: item.id, openedFromKey: item.openedFrom, accentRgb, children: /* @__PURE__ */ jsx(WindowDirtyContext.Provider, { value: registerDirty, children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsx(LoadingSpinner, {}) }), children: /* @__PURE__ */ jsx(Component2, {}) }) }) });
|
|
373
401
|
}
|
|
374
402
|
function DocFavStar({ entityType, entityId, label }) {
|
|
375
403
|
const queryClient = useQueryClient();
|
|
@@ -397,6 +425,7 @@ function RestoredRegistryModal({ item, onClose, onMinimize, accentRgb }) {
|
|
|
397
425
|
if (!raw || !isEntityEntry(raw)) return null;
|
|
398
426
|
const entry = raw;
|
|
399
427
|
const [editing, setEditing] = useState(false);
|
|
428
|
+
const { dirty, registerDirty } = useWindowDirtyRegistry();
|
|
400
429
|
const qkPrefix = entry.queryKey || entry.endpoint.replace(/^\/|\/$/g, "").split("/").pop() || item.entityType;
|
|
401
430
|
const isDuplicate = item.entitySnapshot?._duplicate;
|
|
402
431
|
const isDraft = typeof item.entityId === "string" && item.entityId.startsWith("new-");
|
|
@@ -426,12 +455,12 @@ function RestoredRegistryModal({ item, onClose, onMinimize, accentRgb }) {
|
|
|
426
455
|
return () => window.removeEventListener("modal-reorder", handler);
|
|
427
456
|
}, [refetch, entry.selfFetching, isDuplicate, isDraft]);
|
|
428
457
|
const handleClose = useCallback(() => {
|
|
429
|
-
if (editing) {
|
|
458
|
+
if (editing && !dirty) {
|
|
430
459
|
setEditing(false);
|
|
431
460
|
} else {
|
|
432
461
|
onClose();
|
|
433
462
|
}
|
|
434
|
-
}, [editing, onClose]);
|
|
463
|
+
}, [editing, dirty, onClose]);
|
|
435
464
|
const titleBase = entry.selfFetching ? item.label : entity ? entry.title(entity, editing, setEditing) : item.label;
|
|
436
465
|
const entityIconKey = entry.icon;
|
|
437
466
|
const entityIcon = entityIconKey ? navIcons[entityIconKey] : null;
|
|
@@ -457,12 +486,13 @@ function RestoredRegistryModal({ item, onClose, onMinimize, accentRgb }) {
|
|
|
457
486
|
windowKey: item.id,
|
|
458
487
|
openedFromKey: item.openedFrom,
|
|
459
488
|
size: entry.size || "2xl",
|
|
489
|
+
dirty,
|
|
460
490
|
dimensions: entry.dimensions,
|
|
461
491
|
autoHeight: entry.autoHeight,
|
|
462
492
|
autoMinHeight: entry.autoMinHeight,
|
|
463
493
|
appStyle: entry.appStyle,
|
|
464
494
|
accentRgb,
|
|
465
|
-
children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(LoadingSpinner, {}), children: entry.selfFetching ? entry.render(null, handleClose, item.entityId, editing, setEditing) : isLoading && !entity ? /* @__PURE__ */ jsx(LoadingSpinner, {}) : entity ? entry.render(entity, handleClose, item.entityId, editing, setEditing) : /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 py-8 text-center", children: "Not found." }) })
|
|
495
|
+
children: /* @__PURE__ */ jsx(WindowDirtyContext.Provider, { value: registerDirty, children: /* @__PURE__ */ jsx(Suspense, { fallback: /* @__PURE__ */ jsx(LoadingSpinner, {}), children: entry.selfFetching ? entry.render(null, handleClose, item.entityId, editing, setEditing) : isLoading && !entity ? /* @__PURE__ */ jsx(LoadingSpinner, {}) : entity ? entry.render(entity, handleClose, item.entityId, editing, setEditing) : /* @__PURE__ */ jsx("p", { className: "text-sm text-gray-500 py-8 text-center", children: "Not found." }) }) })
|
|
466
496
|
}
|
|
467
497
|
);
|
|
468
498
|
}
|
|
@@ -691,7 +721,7 @@ function TaskbarTabPreview({ items, anchorEl, onActivate, onClose, onMouseEnter,
|
|
|
691
721
|
document.body
|
|
692
722
|
);
|
|
693
723
|
}
|
|
694
|
-
function TaskbarWindows({ openWindows, onRemove,
|
|
724
|
+
function TaskbarWindows({ openWindows, onRemove, onSplitView, onActivate, onActivateById }) {
|
|
695
725
|
const [target, setTarget] = useState(null);
|
|
696
726
|
useEffect(() => {
|
|
697
727
|
const el = document.getElementById("taskbar-windows");
|
|
@@ -940,6 +970,10 @@ function WindowManagerProvider({ children, windowAccentForRoute }) {
|
|
|
940
970
|
const location = useLocation();
|
|
941
971
|
const isAuthPage = AUTH_PAGES.some((p) => location.pathname.startsWith(p));
|
|
942
972
|
const [openWindows, setOpenWindows] = useState(() => restoreWindowState());
|
|
973
|
+
const openWindowsRef = useRef(openWindows);
|
|
974
|
+
useLayoutEffect(() => {
|
|
975
|
+
openWindowsRef.current = openWindows;
|
|
976
|
+
}, [openWindows]);
|
|
943
977
|
const hasUserActed = useRef(false);
|
|
944
978
|
useEffect(() => {
|
|
945
979
|
if (openWindows.length > 0) hasUserActed.current = true;
|
|
@@ -949,9 +983,16 @@ function WindowManagerProvider({ children, windowAccentForRoute }) {
|
|
|
949
983
|
if (w.route) routeByWindowKey.set(w.id, w.route);
|
|
950
984
|
}
|
|
951
985
|
}, [openWindows]);
|
|
952
|
-
const
|
|
986
|
+
const forceRemoveWindow = useCallback((id) => {
|
|
953
987
|
setOpenWindows((prev) => prev.filter((m) => m.id !== id));
|
|
954
988
|
}, []);
|
|
989
|
+
const requestClose = useCallback((id) => {
|
|
990
|
+
if (!findPanelByWindowKey(id)) {
|
|
991
|
+
forceRemoveWindow(id);
|
|
992
|
+
return;
|
|
993
|
+
}
|
|
994
|
+
requestModalClose(id);
|
|
995
|
+
}, [forceRemoveWindow]);
|
|
955
996
|
const activateAfterMount = (windowKey) => {
|
|
956
997
|
setTimeout(() => {
|
|
957
998
|
const panel = document.querySelector(`[data-modal-panel][data-window-key="${windowKey}"]`);
|
|
@@ -985,6 +1026,13 @@ function WindowManagerProvider({ children, windowAccentForRoute }) {
|
|
|
985
1026
|
const openPage = useCallback((path) => {
|
|
986
1027
|
if (!WINDOW_REGISTRY[path] || !isPageEntry(WINDOW_REGISTRY[path])) return;
|
|
987
1028
|
const entry = WINDOW_REGISTRY[path];
|
|
1029
|
+
if (entry.widget) {
|
|
1030
|
+
const existing = openWindowsRef.current.find((m) => m.type === "page" && m.route === path);
|
|
1031
|
+
if (existing) {
|
|
1032
|
+
requestClose(existing.id);
|
|
1033
|
+
return;
|
|
1034
|
+
}
|
|
1035
|
+
}
|
|
988
1036
|
const openedFrom = currentlyActiveWindowKey();
|
|
989
1037
|
setOpenWindows((prev) => {
|
|
990
1038
|
if (entry.multiInstance) {
|
|
@@ -1000,9 +1048,7 @@ function WindowManagerProvider({ children, windowAccentForRoute }) {
|
|
|
1000
1048
|
}
|
|
1001
1049
|
const existing = prev.find((m) => m.type === "page" && m.route === path);
|
|
1002
1050
|
if (existing) {
|
|
1003
|
-
if (entry.widget)
|
|
1004
|
-
return prev.filter((m) => m !== existing);
|
|
1005
|
-
}
|
|
1051
|
+
if (entry.widget) return prev;
|
|
1006
1052
|
activateAfterMount(existing.id);
|
|
1007
1053
|
return prev;
|
|
1008
1054
|
}
|
|
@@ -1016,12 +1062,13 @@ function WindowManagerProvider({ children, windowAccentForRoute }) {
|
|
|
1016
1062
|
openedFrom
|
|
1017
1063
|
}];
|
|
1018
1064
|
});
|
|
1019
|
-
}, []);
|
|
1065
|
+
}, [requestClose]);
|
|
1020
1066
|
const minimize = useCallback(() => {
|
|
1021
1067
|
}, []);
|
|
1022
1068
|
const restore = useCallback(() => {
|
|
1023
1069
|
}, []);
|
|
1024
|
-
const
|
|
1070
|
+
const closeEntity = requestClose;
|
|
1071
|
+
const remove = requestClose;
|
|
1025
1072
|
const restoreIfMinimized = () => false;
|
|
1026
1073
|
return /* @__PURE__ */ jsxs(MinimizedContext.Provider, { value: { openWindows, openEntity, openPage, closeEntity, minimize, items: [], openItems: openWindows, restore, remove, restoreIfMinimized }, children: [
|
|
1027
1074
|
children,
|
|
@@ -1029,8 +1076,7 @@ function WindowManagerProvider({ children, windowAccentForRoute }) {
|
|
|
1029
1076
|
TaskbarWindows,
|
|
1030
1077
|
{
|
|
1031
1078
|
openWindows,
|
|
1032
|
-
onRemove:
|
|
1033
|
-
onCloseAll: () => setOpenWindows([]),
|
|
1079
|
+
onRemove: requestClose,
|
|
1034
1080
|
onSplitView: triggerSplitView,
|
|
1035
1081
|
onActivate: (label) => {
|
|
1036
1082
|
const panels = document.querySelectorAll("[data-modal-panel]");
|
|
@@ -1060,12 +1106,12 @@ function WindowManagerProvider({ children, windowAccentForRoute }) {
|
|
|
1060
1106
|
return /* @__PURE__ */ jsx(
|
|
1061
1107
|
WindowErrorBoundary,
|
|
1062
1108
|
{
|
|
1063
|
-
fallback: (error, reset) => /* @__PURE__ */ jsx(Modal, { open: true, onClose: () =>
|
|
1064
|
-
children: /* @__PURE__ */ jsx(WindowShortcutProvider, { spec: shortcutSpecFor(item), children: /* @__PURE__ */ jsx(UndoProvider, { windowId: item.id, children: item.type === "page" ? /* @__PURE__ */ jsx(PageWindow, { item, onClose: () =>
|
|
1109
|
+
fallback: (error, reset) => /* @__PURE__ */ jsx(Modal, { open: true, onClose: () => forceRemoveWindow(item.id), title: item.label, size: "md", autoHeight: true, windowKey: item.id, children: /* @__PURE__ */ jsx(WindowCrashedFallback, { error, onReload: reset }) }),
|
|
1110
|
+
children: /* @__PURE__ */ jsx(WindowShortcutProvider, { spec: shortcutSpecFor(item), children: /* @__PURE__ */ jsx(UndoProvider, { windowId: item.id, children: item.type === "page" ? /* @__PURE__ */ jsx(PageWindow, { item, onClose: () => forceRemoveWindow(item.id), accentRgb }) : /* @__PURE__ */ jsx(
|
|
1065
1111
|
RestoredRegistryModal,
|
|
1066
1112
|
{
|
|
1067
1113
|
item,
|
|
1068
|
-
onClose: () =>
|
|
1114
|
+
onClose: () => forceRemoveWindow(item.id),
|
|
1069
1115
|
onMinimize: () => {
|
|
1070
1116
|
},
|
|
1071
1117
|
accentRgb
|
|
@@ -1451,7 +1497,7 @@ function CancelButton({ onClick, children, className }) {
|
|
|
1451
1497
|
const ctx = useContext(ModalActionsContext);
|
|
1452
1498
|
const handleClick = async () => {
|
|
1453
1499
|
if (ctx?.isDirty) {
|
|
1454
|
-
const { confirm: confirm2 } = await import('./ConfirmDialog-
|
|
1500
|
+
const { confirm: confirm2 } = await import('./ConfirmDialog-Y4BYT77R.js');
|
|
1455
1501
|
const ok = await confirm2({
|
|
1456
1502
|
title: "Discard changes?",
|
|
1457
1503
|
message: "You have unsaved changes. Are you sure you want to cancel? All changes will be lost.",
|
|
@@ -1858,6 +1904,12 @@ function registerModalEscapeInterceptor(fn) {
|
|
|
1858
1904
|
escapeInterceptors.delete(fn);
|
|
1859
1905
|
};
|
|
1860
1906
|
}
|
|
1907
|
+
var MODAL_CLOSE_REQUEST_EVENT = "modal-close-request";
|
|
1908
|
+
function requestModalClose(windowKey) {
|
|
1909
|
+
window.dispatchEvent(new CustomEvent(MODAL_CLOSE_REQUEST_EVENT, {
|
|
1910
|
+
detail: { windowKey }
|
|
1911
|
+
}));
|
|
1912
|
+
}
|
|
1861
1913
|
function runEscapeInterceptors(e) {
|
|
1862
1914
|
for (const fn of escapeInterceptors) {
|
|
1863
1915
|
try {
|
|
@@ -2103,6 +2155,7 @@ function Modal({ open, onClose, title, icon, copyText, size = "lg", dirty = fals
|
|
|
2103
2155
|
const [windowMenu, setWindowMenu] = useState(null);
|
|
2104
2156
|
const shortcutSpec = useContext(WindowShortcutContext);
|
|
2105
2157
|
const { prefs: shellPrefs, save: saveShellPrefs } = useShellPrefs();
|
|
2158
|
+
const accentStripeOn = !!shellPrefs.window_accent_stripe;
|
|
2106
2159
|
const favDocs = shellPrefs.favorite_documents || [];
|
|
2107
2160
|
const isOnDesktop = !!shortcutSpec && favDocs.some((d) => d.entityType === shortcutSpec.entityType && d.entityId === shortcutSpec.entityId);
|
|
2108
2161
|
const toggleDesktopShortcut = useCallback(() => {
|
|
@@ -2529,6 +2582,14 @@ function Modal({ open, onClose, title, icon, copyText, size = "lg", dirty = fals
|
|
|
2529
2582
|
}
|
|
2530
2583
|
onClose();
|
|
2531
2584
|
}, [isDirty, onClose]);
|
|
2585
|
+
useLayoutEffect(() => {
|
|
2586
|
+
if (!open || !windowKey) return;
|
|
2587
|
+
const handler = (event) => {
|
|
2588
|
+
if (event.detail?.windowKey === windowKey) guardedClose();
|
|
2589
|
+
};
|
|
2590
|
+
window.addEventListener(MODAL_CLOSE_REQUEST_EVENT, handler);
|
|
2591
|
+
return () => window.removeEventListener(MODAL_CLOSE_REQUEST_EVENT, handler);
|
|
2592
|
+
}, [open, windowKey, guardedClose]);
|
|
2532
2593
|
const preSnapBoxRef = useRef(null);
|
|
2533
2594
|
const startDrag = useCallback((e) => {
|
|
2534
2595
|
if (e.button !== 0) return;
|
|
@@ -2935,14 +2996,6 @@ function Modal({ open, onClose, title, icon, copyText, size = "lg", dirty = fals
|
|
|
2935
2996
|
"aria-hidden": "true"
|
|
2936
2997
|
}
|
|
2937
2998
|
),
|
|
2938
|
-
accentRgb && !widget && !isMobile && /* @__PURE__ */ jsx(
|
|
2939
|
-
"div",
|
|
2940
|
-
{
|
|
2941
|
-
"aria-hidden": "true",
|
|
2942
|
-
className: "absolute top-0 left-0 right-0 h-[3px] z-[6] pointer-events-none",
|
|
2943
|
-
style: { backgroundColor: `rgb(var(--window-accent-rgb) / ${isActive ? 0.9 : 0.55})` }
|
|
2944
|
-
}
|
|
2945
|
-
),
|
|
2946
2999
|
widget ? (
|
|
2947
3000
|
/* Widget: no title bar — drag via body, close via right-click context menu */
|
|
2948
3001
|
null
|
|
@@ -3056,6 +3109,14 @@ function Modal({ open, onClose, title, icon, copyText, size = "lg", dirty = fals
|
|
|
3056
3109
|
]
|
|
3057
3110
|
}
|
|
3058
3111
|
),
|
|
3112
|
+
accentRgb && accentStripeOn && !widget && !isMobile && /* @__PURE__ */ jsx(
|
|
3113
|
+
"div",
|
|
3114
|
+
{
|
|
3115
|
+
"aria-hidden": "true",
|
|
3116
|
+
className: "h-[3px] shrink-0 pointer-events-none",
|
|
3117
|
+
style: { backgroundColor: `rgb(var(--window-accent-rgb) / ${isActive ? 0.9 : 0.55})` }
|
|
3118
|
+
}
|
|
3119
|
+
),
|
|
3059
3120
|
/* @__PURE__ */ jsx(ModalIdContext.Provider, { value: modalId, children: /* @__PURE__ */ jsx(ModalActionsContext.Provider, { value: { rightRef: actionsRef, leftRef: actionsLeftRef, notify: () => setHasActions(true), active: isActive, isDirty }, children: /* @__PURE__ */ jsx(
|
|
3060
3121
|
"div",
|
|
3061
3122
|
{
|
|
@@ -3264,15 +3325,26 @@ var prompt = (opts) => globalPromptFn(opts);
|
|
|
3264
3325
|
function ConfirmProvider({ children }) {
|
|
3265
3326
|
const [open, setOpen] = useState(false);
|
|
3266
3327
|
const [options, setOptions] = useState({ message: "" });
|
|
3328
|
+
const [confirmId, setConfirmId] = useState(0);
|
|
3267
3329
|
const resolveRef = useRef();
|
|
3330
|
+
const activeConfirmIdRef = useRef(null);
|
|
3331
|
+
const nextConfirmIdRef = useRef(0);
|
|
3332
|
+
const confirmQueueRef = useRef([]);
|
|
3333
|
+
const showConfirm = useCallback((request) => {
|
|
3334
|
+
activeConfirmIdRef.current = request.id;
|
|
3335
|
+
resolveRef.current = request.resolve;
|
|
3336
|
+
setConfirmId(request.id);
|
|
3337
|
+
setOptions(request.options);
|
|
3338
|
+
setOpen(true);
|
|
3339
|
+
}, []);
|
|
3268
3340
|
const confirmFn = useCallback((opts) => {
|
|
3269
3341
|
const normalized = typeof opts === "string" ? { message: opts } : opts;
|
|
3270
|
-
setOptions(normalized);
|
|
3271
|
-
setOpen(true);
|
|
3272
3342
|
return new Promise((resolve) => {
|
|
3273
|
-
|
|
3343
|
+
const request = { id: ++nextConfirmIdRef.current, options: normalized, resolve };
|
|
3344
|
+
if (activeConfirmIdRef.current === null) showConfirm(request);
|
|
3345
|
+
else confirmQueueRef.current.push(request);
|
|
3274
3346
|
});
|
|
3275
|
-
}, []);
|
|
3347
|
+
}, [showConfirm]);
|
|
3276
3348
|
const [dOpen, setDOpen] = useState(false);
|
|
3277
3349
|
const [dOptions, setDOptions] = useState({ message: "", confirmWord: "Delete" });
|
|
3278
3350
|
const [dInput, setDInput] = useState("");
|
|
@@ -3303,9 +3375,17 @@ function ConfirmProvider({ children }) {
|
|
|
3303
3375
|
globalDestructiveConfirmFn = destructiveConfirmFn;
|
|
3304
3376
|
globalPromptFn = promptFn;
|
|
3305
3377
|
}, [confirmFn, destructiveConfirmFn, promptFn]);
|
|
3306
|
-
const handleClose = (result) => {
|
|
3307
|
-
|
|
3308
|
-
resolveRef.current
|
|
3378
|
+
const handleClose = (id, result) => {
|
|
3379
|
+
if (activeConfirmIdRef.current !== id) return;
|
|
3380
|
+
const resolve = resolveRef.current;
|
|
3381
|
+
const next = confirmQueueRef.current.shift();
|
|
3382
|
+
if (next) showConfirm(next);
|
|
3383
|
+
else {
|
|
3384
|
+
activeConfirmIdRef.current = null;
|
|
3385
|
+
resolveRef.current = void 0;
|
|
3386
|
+
setOpen(false);
|
|
3387
|
+
}
|
|
3388
|
+
resolve?.(result);
|
|
3309
3389
|
};
|
|
3310
3390
|
const handleDClose = (result) => {
|
|
3311
3391
|
setDOpen(false);
|
|
@@ -3339,18 +3419,18 @@ function ConfirmProvider({ children }) {
|
|
|
3339
3419
|
return true;
|
|
3340
3420
|
}
|
|
3341
3421
|
if (open) {
|
|
3342
|
-
handleClose(false);
|
|
3422
|
+
handleClose(confirmId, false);
|
|
3343
3423
|
return true;
|
|
3344
3424
|
}
|
|
3345
3425
|
return false;
|
|
3346
3426
|
});
|
|
3347
|
-
}, [open, dOpen, pOpen]);
|
|
3427
|
+
}, [open, dOpen, pOpen, confirmId]);
|
|
3348
3428
|
const variant = options.variant || (options.confirmLabel?.toLowerCase().includes("delete") || options.message.toLowerCase().includes("delete") ? "danger" : "info");
|
|
3349
3429
|
const confirmBtnClass = variant === "danger" ? "bg-red-600 hover:bg-red-700 text-white" : variant === "warning" ? "bg-yellow-600 hover:bg-yellow-700 text-white" : "bg-blue-600 hover:bg-blue-700 text-white";
|
|
3350
3430
|
const iconClass = variant === "danger" ? "text-red-600 bg-red-100" : variant === "warning" ? "text-yellow-600 bg-yellow-100" : "text-blue-600 bg-blue-100";
|
|
3351
3431
|
return /* @__PURE__ */ jsxs(ConfirmContext.Provider, { value: confirmFn, children: [
|
|
3352
3432
|
children,
|
|
3353
|
-
/* @__PURE__ */ jsxs(Dialog, { open, onClose: () => handleClose(false), className: "relative z-[9999]", children: [
|
|
3433
|
+
/* @__PURE__ */ jsxs(Dialog, { open, onClose: () => handleClose(confirmId, false), className: "relative z-[9999]", children: [
|
|
3354
3434
|
/* @__PURE__ */ jsx(DialogBackdrop, { className: "fixed inset-0 bg-black/30 transition-opacity" }),
|
|
3355
3435
|
/* @__PURE__ */ jsx("div", { className: "fixed inset-0 flex items-center justify-center p-4", children: /* @__PURE__ */ jsxs(DialogPanel, { className: "w-full max-w-md rounded-lg bg-white p-6 shadow-xl", children: [
|
|
3356
3436
|
/* @__PURE__ */ jsxs("div", { className: "flex gap-4", children: [
|
|
@@ -3365,7 +3445,7 @@ function ConfirmProvider({ children }) {
|
|
|
3365
3445
|
"button",
|
|
3366
3446
|
{
|
|
3367
3447
|
type: "button",
|
|
3368
|
-
onClick: () => handleClose(false),
|
|
3448
|
+
onClick: () => handleClose(confirmId, false),
|
|
3369
3449
|
className: "bg-white text-gray-700 border border-gray-300 px-4 py-2 text-sm font-medium rounded-lg hover:bg-gray-50",
|
|
3370
3450
|
children: options.cancelLabel || "Cancel"
|
|
3371
3451
|
}
|
|
@@ -3374,7 +3454,7 @@ function ConfirmProvider({ children }) {
|
|
|
3374
3454
|
"button",
|
|
3375
3455
|
{
|
|
3376
3456
|
type: "button",
|
|
3377
|
-
onClick: () => handleClose(true),
|
|
3457
|
+
onClick: () => handleClose(confirmId, true),
|
|
3378
3458
|
className: `px-4 py-2 text-sm font-medium rounded-lg ${confirmBtnClass}`,
|
|
3379
3459
|
children: options.confirmLabel || "OK"
|
|
3380
3460
|
}
|
|
@@ -3491,6 +3571,6 @@ function ConfirmProvider({ children }) {
|
|
|
3491
3571
|
] });
|
|
3492
3572
|
}
|
|
3493
3573
|
|
|
3494
|
-
export { CancelButton, ConfirmProvider, CopyButton, DocFavStar, LoadingSpinner, Modal, ModalActions, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, SIDEBAR_STRIP_W, ShellPrefsProvider, UndoProvider, WINDOW_REGISTRY, WindowCrashedFallback, WindowErrorBoundary, WindowManagerProvider, WindowTitle, beginWindowGesture, cancelWindowFront, client_default, commitExposeHighlight, confirm, confirmDestructive, drainPerfEvents, exitExposeMode, forgetMaximizedWindowBoxes, getActiveModalId, getActiveWindowRoute, getExposeHighlight, getWindowPosition, isEntityEntry, isPageEntry, isShellApiClientConfigured, markMenuOpen, prompt, registerModalEscapeInterceptor, requestWindowFront, setExposeHighlight, setPerfCollecting, setShellApiClient, setShellWindowRegistry, setWindowDefaultPosition, setWindowPosition, subscribeExposeHighlight, toggleExposeMode, useConfirm, useIsActiveWindow, useIsMobile, useLocalStoragePrefs, useModalActive, useShellPrefs, useUndo, useUndoable, useUndoableState, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle };
|
|
3495
|
-
//# sourceMappingURL=chunk-
|
|
3496
|
-
//# sourceMappingURL=chunk-
|
|
3574
|
+
export { CancelButton, ConfirmProvider, CopyButton, DocFavStar, LoadingSpinner, Modal, ModalActions, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, SIDEBAR_STRIP_W, ShellPrefsProvider, UndoProvider, WINDOW_REGISTRY, WindowCrashedFallback, WindowErrorBoundary, WindowManagerProvider, WindowTitle, beginWindowGesture, cancelWindowFront, client_default, commitExposeHighlight, confirm, confirmDestructive, drainPerfEvents, exitExposeMode, forgetMaximizedWindowBoxes, getActiveModalId, getActiveWindowRoute, getExposeHighlight, getWindowPosition, isEntityEntry, isPageEntry, isShellApiClientConfigured, markMenuOpen, prompt, registerModalEscapeInterceptor, requestWindowFront, setExposeHighlight, setPerfCollecting, setShellApiClient, setShellWindowRegistry, setWindowDefaultPosition, setWindowPosition, subscribeExposeHighlight, toggleExposeMode, useConfirm, useIsActiveWindow, useIsMobile, useLocalStoragePrefs, useModalActive, useShellPrefs, useUndo, useUndoable, useUndoableState, useWidgetSettings, useWindowDirty, useWindowManager, useWindowMenuItem, useWindowTitle };
|
|
3575
|
+
//# sourceMappingURL=chunk-E2EGGV2Z.js.map
|
|
3576
|
+
//# sourceMappingURL=chunk-E2EGGV2Z.js.map
|