react-os-shell 4.3.1 → 4.4.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/dist/{Browser-674YMWMK.js → Browser-YVV3HOKJ.js} +5 -5
- package/dist/{Browser-674YMWMK.js.map → Browser-YVV3HOKJ.js.map} +1 -1
- package/dist/{Calculator-3ULKK5ZA.js → Calculator-GBC3FLAJ.js} +4 -4
- package/dist/{Calculator-3ULKK5ZA.js.map → Calculator-GBC3FLAJ.js.map} +1 -1
- package/dist/ConfirmDialog-R7NZVI2V.js +4 -0
- package/dist/{ConfirmDialog-XJP67AHR.js.map → ConfirmDialog-R7NZVI2V.js.map} +1 -1
- package/dist/{CurrencyConverter-JC2N7AY3.js → CurrencyConverter-URPZQBNV.js} +4 -4
- package/dist/{CurrencyConverter-JC2N7AY3.js.map → CurrencyConverter-URPZQBNV.js.map} +1 -1
- package/dist/{Documents-MJKEUOOL.js → Documents-5SFFQZBP.js} +5 -5
- package/dist/{Documents-MJKEUOOL.js.map → Documents-5SFFQZBP.js.map} +1 -1
- package/dist/{Files-BTZMPTL6.js → Files-YQJRHUGF.js} +5 -5
- package/dist/{Files-BTZMPTL6.js.map → Files-YQJRHUGF.js.map} +1 -1
- package/dist/{Notepad-NGLFEJLA.js → Notepad-FUQ74K4N.js} +5 -5
- package/dist/{Notepad-NGLFEJLA.js.map → Notepad-FUQ74K4N.js.map} +1 -1
- package/dist/{PomodoroTimer-RPCRTUKC.js → PomodoroTimer-QQOMBVP3.js} +5 -5
- package/dist/{PomodoroTimer-RPCRTUKC.js.map → PomodoroTimer-QQOMBVP3.js.map} +1 -1
- package/dist/{Preview-H4S427VB.js → Preview-OP4IUJFT.js} +5 -5
- package/dist/{Preview-H4S427VB.js.map → Preview-OP4IUJFT.js.map} +1 -1
- package/dist/{Spreadsheet-2YYUKKSY.js → Spreadsheet-GADWOYDX.js} +5 -5
- package/dist/{Spreadsheet-2YYUKKSY.js.map → Spreadsheet-GADWOYDX.js.map} +1 -1
- package/dist/{Stock-YTQ2OYQ7.js → Stock-33C4U7CR.js} +4 -4
- package/dist/{Stock-YTQ2OYQ7.js.map → Stock-33C4U7CR.js.map} +1 -1
- package/dist/{Weather-4I4EFUJO.js → Weather-G3XHTB75.js} +4 -4
- package/dist/{Weather-4I4EFUJO.js.map → Weather-G3XHTB75.js.map} +1 -1
- package/dist/{WorldClock-7PZI7VRE.js → WorldClock-ZUVI3LBN.js} +4 -4
- package/dist/{WorldClock-7PZI7VRE.js.map → WorldClock-ZUVI3LBN.js.map} +1 -1
- package/dist/apps/index.js +15 -15
- package/dist/{chunk-PMPJLVZV.js → chunk-5HCDJPX7.js} +3 -3
- package/dist/{chunk-PMPJLVZV.js.map → chunk-5HCDJPX7.js.map} +1 -1
- package/dist/{chunk-VA6M46NL.js → chunk-EF5W3EXL.js} +47 -10
- package/dist/chunk-EF5W3EXL.js.map +1 -0
- package/dist/chunk-GDOCYHAG.js +7 -0
- package/dist/{chunk-K6MB36UJ.js.map → chunk-GDOCYHAG.js.map} +1 -1
- package/dist/{chunk-YF2XNVGN.js → chunk-LSFZJZTQ.js} +3 -3
- package/dist/{chunk-YF2XNVGN.js.map → chunk-LSFZJZTQ.js.map} +1 -1
- package/dist/{chunk-ASRXGCSQ.js → chunk-PZTYN2RX.js} +4 -4
- package/dist/{chunk-ASRXGCSQ.js.map → chunk-PZTYN2RX.js.map} +1 -1
- package/dist/index.d.ts +270 -155
- package/dist/index.js +209 -76
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/dist/ConfirmDialog-XJP67AHR.js +0 -4
- package/dist/chunk-K6MB36UJ.js +0 -7
- package/dist/chunk-VA6M46NL.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { subscribePomo, getPomoSnapshot } from './chunk-
|
|
2
|
-
export { setShellTodoProvider } from './chunk-
|
|
1
|
+
import { subscribePomo, getPomoSnapshot } from './chunk-LSFZJZTQ.js';
|
|
2
|
+
export { setShellTodoProvider } from './chunk-LSFZJZTQ.js';
|
|
3
3
|
export { ImageAnnotator_default as ImageAnnotator } from './chunk-QU5L5ZYM.js';
|
|
4
4
|
import { PREVIEW_OPENED_EVENT, openPreviewFile } from './chunk-DINNWYVB.js';
|
|
5
5
|
export { Breadcrumbs } from './chunk-DINNWYVB.js';
|
|
@@ -15,10 +15,10 @@ export { setShellAuthBridge } from './chunk-3NZSR3ZG.js';
|
|
|
15
15
|
import { EditableGrid } from './chunk-GP4Y3VCB.js';
|
|
16
16
|
export { EditableGrid } from './chunk-GP4Y3VCB.js';
|
|
17
17
|
import './chunk-4SQU5YV6.js';
|
|
18
|
-
import { APP_VERSION, VERSION } from './chunk-
|
|
19
|
-
export { VERSION } from './chunk-
|
|
20
|
-
import { registerModalEscapeInterceptor, useIsMobile, useWindowManager, PopupMenu, PopupMenuLabel, PopupMenuDivider, PopupMenuItem, WINDOW_REGISTRY, isPageEntry, Modal, useShellPrefs, SIDEBAR_STRIP_W, forgetMaximizedWindowBoxes, ModalActions, useModalActive, client_default, LoadingSpinner, isShellApiClientConfigured, useUndo, CancelButton, setWindowPosition } from './chunk-
|
|
21
|
-
export { CancelButton, ConfirmProvider, CopyButton, DocFavStar, Modal, ModalActions, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, ShellPrefsProvider, UndoProvider, WindowCrashedFallback, WindowErrorBoundary, WindowManagerProvider, WindowTitle, commitExposeHighlight, confirm, confirmDestructive, exitExposeMode, getActiveWindowRoute, getExposeHighlight, getWindowPosition, isEntityEntry, isPageEntry, prompt, registerModalEscapeInterceptor, setExposeHighlight, setShellApiClient, setShellWindowRegistry, setWindowDefaultPosition, setWindowPosition, subscribeExposeHighlight, toggleExposeMode, useIsActiveWindow, useLocalStoragePrefs, useModalActive, useShellPrefs, useUndo, useUndoable, useUndoableState, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle } from './chunk-
|
|
18
|
+
import { APP_VERSION, VERSION } from './chunk-GDOCYHAG.js';
|
|
19
|
+
export { VERSION } from './chunk-GDOCYHAG.js';
|
|
20
|
+
import { registerModalEscapeInterceptor, useIsMobile, useWindowManager, PopupMenu, PopupMenuLabel, PopupMenuDivider, PopupMenuItem, WINDOW_REGISTRY, isPageEntry, Modal, setPerfCollecting, drainPerfEvents, useShellPrefs, markMenuOpen, SIDEBAR_STRIP_W, forgetMaximizedWindowBoxes, ModalActions, useModalActive, client_default, LoadingSpinner, isShellApiClientConfigured, useUndo, CancelButton, setWindowPosition } from './chunk-EF5W3EXL.js';
|
|
21
|
+
export { CancelButton, ConfirmProvider, CopyButton, DocFavStar, Modal, ModalActions, PopupMenu, PopupMenuDivider, PopupMenuItem, PopupMenuLabel, ShellPrefsProvider, UndoProvider, WindowCrashedFallback, WindowErrorBoundary, WindowManagerProvider, WindowTitle, beginWindowGesture, commitExposeHighlight, confirm, confirmDestructive, exitExposeMode, getActiveWindowRoute, getExposeHighlight, getWindowPosition, isEntityEntry, isPageEntry, markMenuOpen, prompt, registerModalEscapeInterceptor, setExposeHighlight, setShellApiClient, setShellWindowRegistry, setWindowDefaultPosition, setWindowPosition, subscribeExposeHighlight, toggleExposeMode, useIsActiveWindow, useLocalStoragePrefs, useModalActive, useShellPrefs, useUndo, useUndoable, useUndoableState, useWidgetSettings, useWindowManager, useWindowMenuItem, useWindowTitle } from './chunk-EF5W3EXL.js';
|
|
22
22
|
import { glassStyle, startMenuCategories, navSections, isSection, GLASS_INPUT_BG, navIcons, isReachable, sectionIcons, useShellAuth, visibleChildren } from './chunk-DKDD5KXG.js';
|
|
23
23
|
export { GLASS_DIVIDER, GLASS_INPUT_BG, ShellAuthProvider, glassStyle, setShellNavIcons, useShellAuth } from './chunk-DKDD5KXG.js';
|
|
24
24
|
import { createContext, lazy, forwardRef, useCallback, useState, useRef, useId, useEffect, useLayoutEffect, useMemo, useContext, isValidElement, cloneElement, Suspense, Fragment as Fragment$1, Children, useSyncExternalStore } from 'react';
|
|
@@ -1428,15 +1428,28 @@ function classify(reading) {
|
|
|
1428
1428
|
}
|
|
1429
1429
|
|
|
1430
1430
|
// src/shell/perfLog.ts
|
|
1431
|
+
var ACTIVITY_ORDER = [
|
|
1432
|
+
{ kind: "submenu", test: (r) => r.submenus > 0 },
|
|
1433
|
+
{ kind: "menu", test: (r) => r.menus > 0 },
|
|
1434
|
+
{ kind: "resize", test: (r) => r.resizeMs > 0 },
|
|
1435
|
+
{ kind: "move", test: (r) => r.moveMs > 0 },
|
|
1436
|
+
{ kind: "scroll", test: (r) => r.scrolls > 0 },
|
|
1437
|
+
{ kind: "type", test: (r) => r.keys > 0 },
|
|
1438
|
+
{ kind: "click", test: (r) => r.clicks > 0 || r.dragMs > 0 }
|
|
1439
|
+
];
|
|
1440
|
+
function classifyActivity(r) {
|
|
1441
|
+
return ACTIVITY_ORDER.find((entry) => entry.test(r))?.kind ?? "idle";
|
|
1442
|
+
}
|
|
1431
1443
|
var LOG_CAP = 2400;
|
|
1432
1444
|
var MIN_GROUP_SAMPLES = 4;
|
|
1445
|
+
var MIN_EVENT_SAMPLES = 2;
|
|
1433
1446
|
function appendRecord(log, record, cap = LOG_CAP) {
|
|
1434
1447
|
const next = log.length >= cap ? log.slice(log.length - cap + 1) : log.slice();
|
|
1435
1448
|
next.push(record);
|
|
1436
1449
|
return next;
|
|
1437
1450
|
}
|
|
1438
1451
|
function isInteracting(r) {
|
|
1439
|
-
return r
|
|
1452
|
+
return classifyActivity(r) !== "idle";
|
|
1440
1453
|
}
|
|
1441
1454
|
function median(values) {
|
|
1442
1455
|
if (!values.length) return 0;
|
|
@@ -1445,7 +1458,27 @@ function median(values) {
|
|
|
1445
1458
|
return sorted.length % 2 ? sorted[mid] : (sorted[mid - 1] + sorted[mid]) / 2;
|
|
1446
1459
|
}
|
|
1447
1460
|
function group(records) {
|
|
1448
|
-
|
|
1461
|
+
const measured = records.filter((r) => r.fps > 0);
|
|
1462
|
+
return {
|
|
1463
|
+
samples: records.length,
|
|
1464
|
+
medianFps: median(measured.map((r) => r.fps)),
|
|
1465
|
+
worstMs: records.reduce((worst, r) => r.worstMs > worst ? r.worstMs : worst, 0),
|
|
1466
|
+
stalls: records.length - measured.length
|
|
1467
|
+
};
|
|
1468
|
+
}
|
|
1469
|
+
function bucket(records, keyOf) {
|
|
1470
|
+
const map = /* @__PURE__ */ new Map();
|
|
1471
|
+
for (const r of records) {
|
|
1472
|
+
const key = keyOf(r);
|
|
1473
|
+
if (key === null) continue;
|
|
1474
|
+
const existing = map.get(key);
|
|
1475
|
+
if (existing) existing.push(r);
|
|
1476
|
+
else map.set(key, [r]);
|
|
1477
|
+
}
|
|
1478
|
+
return map;
|
|
1479
|
+
}
|
|
1480
|
+
function rankWorstFirst(groups) {
|
|
1481
|
+
return groups.sort((a, b) => a.medianFps - b.medianFps);
|
|
1449
1482
|
}
|
|
1450
1483
|
function summariseLog(log) {
|
|
1451
1484
|
const empty = {
|
|
@@ -1456,37 +1489,34 @@ function summariseLog(log) {
|
|
|
1456
1489
|
verdictShare: { smooth: 0, gpu: 0, cpu: 0, unknown: 0 },
|
|
1457
1490
|
interacting: null,
|
|
1458
1491
|
idle: null,
|
|
1492
|
+
byActivity: [],
|
|
1459
1493
|
byWindowCount: [],
|
|
1460
|
-
worstWindows: []
|
|
1494
|
+
worstWindows: [],
|
|
1495
|
+
worstMenus: []
|
|
1461
1496
|
};
|
|
1462
1497
|
if (!log.length) return empty;
|
|
1463
|
-
const measured = log.filter((r) => r.fps > 0);
|
|
1464
1498
|
const verdictShare = { ...empty.verdictShare };
|
|
1465
1499
|
for (const r of log) verdictShare[r.verdict] += 1 / log.length;
|
|
1466
|
-
const interacting =
|
|
1467
|
-
const idle =
|
|
1468
|
-
const byWindows = /* @__PURE__ */ new Map();
|
|
1469
|
-
const byKey = /* @__PURE__ */ new Map();
|
|
1470
|
-
for (const r of measured) {
|
|
1471
|
-
const bucket = byWindows.get(r.windows);
|
|
1472
|
-
if (bucket) bucket.push(r);
|
|
1473
|
-
else byWindows.set(r.windows, [r]);
|
|
1474
|
-
if (r.active) {
|
|
1475
|
-
const keyed = byKey.get(r.active);
|
|
1476
|
-
if (keyed) keyed.push(r);
|
|
1477
|
-
else byKey.set(r.active, [r]);
|
|
1478
|
-
}
|
|
1479
|
-
}
|
|
1500
|
+
const interacting = log.filter(isInteracting);
|
|
1501
|
+
const idle = log.filter((r) => !isInteracting(r));
|
|
1480
1502
|
return {
|
|
1481
1503
|
samples: log.length,
|
|
1482
1504
|
durationMs: log[log.length - 1].t - log[0].t,
|
|
1483
|
-
medianFps: median(
|
|
1505
|
+
medianFps: median(log.filter((r) => r.fps > 0).map((r) => r.fps)),
|
|
1484
1506
|
worstFrameMs: log.reduce((worst, r) => r.worstMs > worst ? r.worstMs : worst, 0),
|
|
1485
1507
|
verdictShare,
|
|
1486
1508
|
interacting: interacting.length >= MIN_GROUP_SAMPLES ? group(interacting) : null,
|
|
1487
1509
|
idle: idle.length >= MIN_GROUP_SAMPLES ? group(idle) : null,
|
|
1488
|
-
|
|
1489
|
-
|
|
1510
|
+
byActivity: rankWorstFirst(
|
|
1511
|
+
[...bucket(log, classifyActivity).entries()].filter(([, rs]) => rs.length >= MIN_EVENT_SAMPLES).map(([kind, rs]) => ({ kind, ...group(rs) }))
|
|
1512
|
+
),
|
|
1513
|
+
byWindowCount: [...bucket(log, (r) => r.windows).entries()].filter(([, rs]) => rs.length >= MIN_GROUP_SAMPLES).map(([windows, rs]) => ({ windows, ...group(rs) })).sort((a, b) => a.windows - b.windows),
|
|
1514
|
+
worstWindows: rankWorstFirst(
|
|
1515
|
+
[...bucket(log, (r) => r.active).entries()].filter(([, rs]) => rs.length >= MIN_GROUP_SAMPLES).map(([key, rs]) => ({ key, ...group(rs) }))
|
|
1516
|
+
),
|
|
1517
|
+
worstMenus: rankWorstFirst(
|
|
1518
|
+
[...bucket(log, (r) => r.menuKey).entries()].filter(([, rs]) => rs.length >= MIN_EVENT_SAMPLES).map(([key, rs]) => ({ key, ...group(rs) }))
|
|
1519
|
+
)
|
|
1490
1520
|
};
|
|
1491
1521
|
}
|
|
1492
1522
|
var CSV_COLUMNS = [
|
|
@@ -1502,7 +1532,12 @@ var CSV_COLUMNS = [
|
|
|
1502
1532
|
"clicks",
|
|
1503
1533
|
"keys",
|
|
1504
1534
|
"scrolls",
|
|
1505
|
-
"dragMs"
|
|
1535
|
+
"dragMs",
|
|
1536
|
+
"menus",
|
|
1537
|
+
"submenus",
|
|
1538
|
+
"menuKey",
|
|
1539
|
+
"moveMs",
|
|
1540
|
+
"resizeMs"
|
|
1506
1541
|
];
|
|
1507
1542
|
function toCsv(log) {
|
|
1508
1543
|
const cell = (value) => {
|
|
@@ -1520,6 +1555,7 @@ var WINDOW_MS = 1e3;
|
|
|
1520
1555
|
var HISTORY = 40;
|
|
1521
1556
|
var PERSIST_EVERY_MS = 1e4;
|
|
1522
1557
|
var LOG_STORAGE_KEY = "react-os-shell:perf-log";
|
|
1558
|
+
var MAX_DRAG_GAP_MS = 100;
|
|
1523
1559
|
var VERDICT_STYLES = {
|
|
1524
1560
|
smooth: { dot: "bg-emerald-400", text: "text-emerald-300" },
|
|
1525
1561
|
gpu: { dot: "bg-amber-400", text: "text-amber-300" },
|
|
@@ -1541,7 +1577,7 @@ function readWindows() {
|
|
|
1541
1577
|
});
|
|
1542
1578
|
return { windows: panels.length, active };
|
|
1543
1579
|
}
|
|
1544
|
-
function PerfStats({ onClose, className = "" }) {
|
|
1580
|
+
function PerfStats({ onClose, onSubmit, className = "" }) {
|
|
1545
1581
|
const framesRef = useRef([]);
|
|
1546
1582
|
const blockedMsRef = useRef(0);
|
|
1547
1583
|
const activityRef = useRef({ clicks: 0, keys: 0, scrolls: 0, dragMs: 0 });
|
|
@@ -1549,11 +1585,20 @@ function PerfStats({ onClose, className = "" }) {
|
|
|
1549
1585
|
const logRef = useRef([]);
|
|
1550
1586
|
const startedAtRef = useRef(0);
|
|
1551
1587
|
const persistedAtRef = useRef(0);
|
|
1588
|
+
const snapshotRef = useRef(null);
|
|
1552
1589
|
const [longTaskSupported, setLongTaskSupported] = useState(false);
|
|
1553
1590
|
const [reading, setReading] = useState({ fps: 0, frameMs: 0, worstMs: 0, blockedPct: null });
|
|
1554
1591
|
const [history, setHistory] = useState([]);
|
|
1555
1592
|
const [heap, setHeap] = useState(null);
|
|
1556
1593
|
const [logSize, setLogSize] = useState(0);
|
|
1594
|
+
const [composing, setComposing] = useState(false);
|
|
1595
|
+
const [message, setMessage] = useState("");
|
|
1596
|
+
const [sending, setSending] = useState(false);
|
|
1597
|
+
const [sendError, setSendError] = useState(null);
|
|
1598
|
+
useEffect(() => {
|
|
1599
|
+
setPerfCollecting(true);
|
|
1600
|
+
return () => setPerfCollecting(false);
|
|
1601
|
+
}, []);
|
|
1557
1602
|
useEffect(() => {
|
|
1558
1603
|
let raf = 0;
|
|
1559
1604
|
const tick = (now) => {
|
|
@@ -1588,8 +1633,9 @@ function PerfStats({ onClose, className = "" }) {
|
|
|
1588
1633
|
const onPointerMove = () => {
|
|
1589
1634
|
if (!dragRef.current.down) return;
|
|
1590
1635
|
const now = performance.now();
|
|
1591
|
-
|
|
1636
|
+
const gap = now - dragRef.current.since;
|
|
1592
1637
|
dragRef.current.since = now;
|
|
1638
|
+
if (gap <= MAX_DRAG_GAP_MS) activityRef.current.dragMs += gap;
|
|
1593
1639
|
};
|
|
1594
1640
|
const onPointerUp = () => {
|
|
1595
1641
|
dragRef.current.down = false;
|
|
@@ -1643,6 +1689,7 @@ function PerfStats({ onClose, className = "" }) {
|
|
|
1643
1689
|
const heapMB = memory ? memory.usedJSHeapSize / 1048576 : null;
|
|
1644
1690
|
const nextReading = { ...frames, blockedPct };
|
|
1645
1691
|
const activity = activityRef.current;
|
|
1692
|
+
const events = drainPerfEvents();
|
|
1646
1693
|
const { windows, active } = readWindows();
|
|
1647
1694
|
logRef.current = appendRecord(logRef.current, {
|
|
1648
1695
|
t: Math.round(now - startedAtRef.current),
|
|
@@ -1655,7 +1702,12 @@ function PerfStats({ onClose, className = "" }) {
|
|
|
1655
1702
|
clicks: activity.clicks,
|
|
1656
1703
|
keys: activity.keys,
|
|
1657
1704
|
scrolls: activity.scrolls,
|
|
1658
|
-
dragMs: Math.round(activity.dragMs)
|
|
1705
|
+
dragMs: Math.round(activity.dragMs),
|
|
1706
|
+
menus: events.menus,
|
|
1707
|
+
submenus: events.submenus,
|
|
1708
|
+
menuKey: events.menuKey,
|
|
1709
|
+
moveMs: Math.round(events.moveMs),
|
|
1710
|
+
resizeMs: Math.round(events.resizeMs)
|
|
1659
1711
|
});
|
|
1660
1712
|
activity.clicks = 0;
|
|
1661
1713
|
activity.keys = 0;
|
|
@@ -1672,38 +1724,65 @@ function PerfStats({ onClose, className = "" }) {
|
|
|
1672
1724
|
}, FLUSH_MS);
|
|
1673
1725
|
return () => clearInterval(id);
|
|
1674
1726
|
}, [longTaskSupported, persist]);
|
|
1675
|
-
const
|
|
1676
|
-
|
|
1677
|
-
|
|
1678
|
-
|
|
1679
|
-
link.href = url;
|
|
1680
|
-
link.download = `perf-log-${stamp}.${extension}`;
|
|
1681
|
-
link.click();
|
|
1682
|
-
URL.revokeObjectURL(url);
|
|
1727
|
+
const beginReport = useCallback(() => {
|
|
1728
|
+
snapshotRef.current = logRef.current.slice();
|
|
1729
|
+
setSendError(null);
|
|
1730
|
+
setComposing(true);
|
|
1683
1731
|
}, []);
|
|
1684
|
-
const
|
|
1685
|
-
|
|
1686
|
-
|
|
1732
|
+
const verdict = classify(reading);
|
|
1733
|
+
const buildReport = useCallback(() => {
|
|
1734
|
+
const records = snapshotRef.current ?? logRef.current;
|
|
1735
|
+
const stamp = (/* @__PURE__ */ new Date()).toISOString().replace(/[:.]/g, "-").slice(0, 19);
|
|
1736
|
+
return {
|
|
1737
|
+
message,
|
|
1738
|
+
filename: `perf-log-${stamp}.json`,
|
|
1739
|
+
summary: summariseLog(records),
|
|
1740
|
+
verdict: verdict.label,
|
|
1741
|
+
json: JSON.stringify(
|
|
1687
1742
|
{
|
|
1688
1743
|
generatedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
1744
|
+
message,
|
|
1745
|
+
verdict: verdict.label,
|
|
1689
1746
|
userAgent: navigator.userAgent,
|
|
1690
1747
|
screen: { width: window.screen.width, height: window.screen.height, dpr: window.devicePixelRatio },
|
|
1691
1748
|
reducedTransparency: document.documentElement.classList.contains("rosh-reduce-transparency"),
|
|
1692
|
-
summary: summariseLog(
|
|
1693
|
-
records
|
|
1749
|
+
summary: summariseLog(records),
|
|
1750
|
+
records
|
|
1694
1751
|
},
|
|
1695
1752
|
null,
|
|
1696
1753
|
2
|
|
1697
|
-
)
|
|
1698
|
-
|
|
1699
|
-
|
|
1700
|
-
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1754
|
+
)
|
|
1755
|
+
};
|
|
1756
|
+
}, [message, verdict.label]);
|
|
1757
|
+
const downloadReport = useCallback((report) => {
|
|
1758
|
+
const url = URL.createObjectURL(new Blob([report.json], { type: "application/json" }));
|
|
1759
|
+
const link = document.createElement("a");
|
|
1760
|
+
link.href = url;
|
|
1761
|
+
link.download = report.filename;
|
|
1762
|
+
link.click();
|
|
1763
|
+
URL.revokeObjectURL(url);
|
|
1764
|
+
}, []);
|
|
1765
|
+
const send = useCallback(async () => {
|
|
1766
|
+
const report = buildReport();
|
|
1767
|
+
setSending(true);
|
|
1768
|
+
setSendError(null);
|
|
1769
|
+
try {
|
|
1770
|
+
if (onSubmit) await onSubmit(report);
|
|
1771
|
+
else downloadReport(report);
|
|
1772
|
+
snapshotRef.current = null;
|
|
1773
|
+
setMessage("");
|
|
1774
|
+
setComposing(false);
|
|
1775
|
+
} catch (err) {
|
|
1776
|
+
setSendError(err instanceof Error && err.message ? err.message : "Could not send. Try again.");
|
|
1777
|
+
} finally {
|
|
1778
|
+
setSending(false);
|
|
1779
|
+
}
|
|
1780
|
+
}, [buildReport, downloadReport, onSubmit]);
|
|
1704
1781
|
const styles = VERDICT_STYLES[verdict.kind];
|
|
1705
1782
|
const peak = Math.max(60, ...history);
|
|
1706
1783
|
const loggedSeconds = Math.round(logSize * FLUSH_MS / 1e3);
|
|
1784
|
+
const sendLabel = onSubmit ? "Send" : "Download";
|
|
1785
|
+
const reportSamples = snapshotRef.current?.length ?? logSize;
|
|
1707
1786
|
return /* @__PURE__ */ jsxs(
|
|
1708
1787
|
"div",
|
|
1709
1788
|
{
|
|
@@ -1766,34 +1845,73 @@ function PerfStats({ onClose, className = "" }) {
|
|
|
1766
1845
|
] }),
|
|
1767
1846
|
/* @__PURE__ */ jsx("p", { className: "mt-0.5 leading-snug text-white/45", children: verdict.detail })
|
|
1768
1847
|
] }),
|
|
1769
|
-
/* @__PURE__ */
|
|
1848
|
+
/* @__PURE__ */ jsx("div", { className: "mt-2 border-t border-white/10 pt-1.5", children: composing ? (
|
|
1849
|
+
/* Composer. `select-text` because the panel as a whole is
|
|
1850
|
+
`select-none` — without it the user cannot correct their own
|
|
1851
|
+
sentence. */
|
|
1852
|
+
/* @__PURE__ */ jsxs("div", { className: "select-text space-y-1.5", children: [
|
|
1853
|
+
/* @__PURE__ */ jsx("label", { className: "block text-white/40", htmlFor: "perf-report-message", children: "What were you doing?" }),
|
|
1854
|
+
/* @__PURE__ */ jsx(
|
|
1855
|
+
"textarea",
|
|
1856
|
+
{
|
|
1857
|
+
id: "perf-report-message",
|
|
1858
|
+
value: message,
|
|
1859
|
+
onChange: (e) => setMessage(e.target.value),
|
|
1860
|
+
rows: 3,
|
|
1861
|
+
autoFocus: true,
|
|
1862
|
+
placeholder: "e.g. opening the second-level menu stutters",
|
|
1863
|
+
className: "w-full resize-none rounded border border-white/15 bg-black/40 px-1.5 py-1 font-mono text-[10px] text-white/90 placeholder:text-white/25 focus:border-white/40 focus:outline-none"
|
|
1864
|
+
}
|
|
1865
|
+
),
|
|
1866
|
+
sendError && /* @__PURE__ */ jsx("p", { className: "leading-snug text-rose-300", children: sendError }),
|
|
1867
|
+
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
1868
|
+
/* @__PURE__ */ jsxs("span", { className: "text-white/35", children: [
|
|
1869
|
+
reportSamples,
|
|
1870
|
+
" samples"
|
|
1871
|
+
] }),
|
|
1872
|
+
/* @__PURE__ */ jsxs("span", { className: "flex gap-1", children: [
|
|
1873
|
+
/* @__PURE__ */ jsx(
|
|
1874
|
+
"button",
|
|
1875
|
+
{
|
|
1876
|
+
onClick: () => {
|
|
1877
|
+
setComposing(false);
|
|
1878
|
+
snapshotRef.current = null;
|
|
1879
|
+
setSendError(null);
|
|
1880
|
+
},
|
|
1881
|
+
disabled: sending,
|
|
1882
|
+
className: "rounded border border-white/15 px-1.5 py-0.5 text-white/50 transition-colors hover:border-white/30 hover:text-white disabled:opacity-40",
|
|
1883
|
+
children: "Cancel"
|
|
1884
|
+
}
|
|
1885
|
+
),
|
|
1886
|
+
/* @__PURE__ */ jsx(
|
|
1887
|
+
"button",
|
|
1888
|
+
{
|
|
1889
|
+
onClick: send,
|
|
1890
|
+
disabled: sending,
|
|
1891
|
+
className: "rounded border border-white/30 bg-white/10 px-1.5 py-0.5 text-white/90 transition-colors hover:bg-white/20 disabled:cursor-not-allowed disabled:opacity-40",
|
|
1892
|
+
children: sending ? "Sending\u2026" : sendLabel
|
|
1893
|
+
}
|
|
1894
|
+
)
|
|
1895
|
+
] })
|
|
1896
|
+
] })
|
|
1897
|
+
] })
|
|
1898
|
+
) : /* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between", children: [
|
|
1770
1899
|
/* @__PURE__ */ jsxs("span", { className: "text-white/35", children: [
|
|
1771
1900
|
"log ",
|
|
1772
1901
|
logSize,
|
|
1773
1902
|
" \xB7 ",
|
|
1774
1903
|
loggedSeconds < 60 ? `${loggedSeconds}s` : `${Math.round(loggedSeconds / 60)}m`
|
|
1775
1904
|
] }),
|
|
1776
|
-
/* @__PURE__ */
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
|
|
1781
|
-
|
|
1782
|
-
|
|
1783
|
-
|
|
1784
|
-
|
|
1785
|
-
|
|
1786
|
-
/* @__PURE__ */ jsx(
|
|
1787
|
-
"button",
|
|
1788
|
-
{
|
|
1789
|
-
onClick: exportCsv,
|
|
1790
|
-
disabled: !logSize,
|
|
1791
|
-
className: "rounded border border-white/15 px-1.5 py-0.5 text-white/60 transition-colors hover:border-white/30 hover:text-white disabled:cursor-not-allowed disabled:opacity-40",
|
|
1792
|
-
children: "CSV"
|
|
1793
|
-
}
|
|
1794
|
-
)
|
|
1795
|
-
] })
|
|
1796
|
-
] })
|
|
1905
|
+
/* @__PURE__ */ jsx(
|
|
1906
|
+
"button",
|
|
1907
|
+
{
|
|
1908
|
+
onClick: beginReport,
|
|
1909
|
+
disabled: !logSize,
|
|
1910
|
+
className: "rounded border border-white/15 px-1.5 py-0.5 text-white/60 transition-colors hover:border-white/30 hover:text-white disabled:cursor-not-allowed disabled:opacity-40",
|
|
1911
|
+
children: onSubmit ? "Report this" : "Save report"
|
|
1912
|
+
}
|
|
1913
|
+
)
|
|
1914
|
+
] }) })
|
|
1797
1915
|
]
|
|
1798
1916
|
}
|
|
1799
1917
|
);
|
|
@@ -2986,7 +3104,13 @@ function Desktop({ profile }) {
|
|
|
2986
3104
|
const taskbarAtBottom = prefs.taskbar_position !== "top" && prefs.taskbar_position !== "left" && prefs.taskbar_position !== "right";
|
|
2987
3105
|
const side = prefs.taskbar_position === "right" ? "left-3" : "right-3";
|
|
2988
3106
|
const bottom = taskbarAtBottom ? versionShowing ? "bottom-24" : "bottom-16" : versionShowing ? "bottom-8" : "bottom-3";
|
|
2989
|
-
return /* @__PURE__ */ jsx("div", { className: `absolute z-[240] ${side} ${bottom}`, children: /* @__PURE__ */ jsx(
|
|
3107
|
+
return /* @__PURE__ */ jsx("div", { className: `absolute z-[240] ${side} ${bottom}`, children: /* @__PURE__ */ jsx(
|
|
3108
|
+
PerfStats,
|
|
3109
|
+
{
|
|
3110
|
+
onClose: () => saveShellPrefs({ show_desktop_stats: false }),
|
|
3111
|
+
onSubmit: host.onSubmitPerfReport
|
|
3112
|
+
}
|
|
3113
|
+
) });
|
|
2990
3114
|
})(),
|
|
2991
3115
|
prefs.show_desktop_version === true && (host.productVersion ?? APP_VERSION) && /* @__PURE__ */ jsx(
|
|
2992
3116
|
"button",
|
|
@@ -3325,6 +3449,15 @@ function StartMenu({
|
|
|
3325
3449
|
useEffect(() => {
|
|
3326
3450
|
setHoveredChild(null);
|
|
3327
3451
|
}, [hoveredSection]);
|
|
3452
|
+
useEffect(() => {
|
|
3453
|
+
if (open) markMenuOpen("menu", "start");
|
|
3454
|
+
}, [open]);
|
|
3455
|
+
useEffect(() => {
|
|
3456
|
+
if (hoveredSection) markMenuOpen("submenu", hoveredSection);
|
|
3457
|
+
}, [hoveredSection]);
|
|
3458
|
+
useEffect(() => {
|
|
3459
|
+
if (hoveredChild) markMenuOpen("submenu", hoveredChild);
|
|
3460
|
+
}, [hoveredChild]);
|
|
3328
3461
|
useLayoutEffect(() => {
|
|
3329
3462
|
if (!flyoutRef.current || !hoveredSection || search.length >= 2) return;
|
|
3330
3463
|
const h = flyoutRef.current.offsetHeight;
|
|
@@ -4840,7 +4973,7 @@ function Customization({ omit, section } = {}) {
|
|
|
4840
4973
|
/* @__PURE__ */ jsxs("span", { className: "text-sm text-gray-700", children: [
|
|
4841
4974
|
"Show performance stats",
|
|
4842
4975
|
/* @__PURE__ */ jsx("span", { className: "block text-xs text-gray-400", children: "Overlays frame rate, worst frame time and a bottleneck reading on the desktop, beside the version number. Turn it on to check whether Reduce transparency actually helps on this machine \u2014 or whether the slowness is coming from somewhere else." }),
|
|
4843
|
-
/* @__PURE__ */ jsx("span", { className: "block text-xs text-gray-400 mt-1", children: "While it is on, each reading is recorded with what was happening at the time \u2014 how many windows were open, which one was on top, and counts of clicks, keystrokes
|
|
4976
|
+
/* @__PURE__ */ jsx("span", { className: "block text-xs text-gray-400 mt-1", children: "While it is on, each reading is recorded with what was happening at the time \u2014 how many windows were open, which one was on top, which menu or submenu you opened, how long you spent moving or resizing a window, and counts of clicks, keystrokes and scrolls. No page content or keystroke text is recorded. The log stays on this device unless you use the overlay's Report button, which sends it \u2014 with whatever you type in the box \u2014 to the team as a bug report." })
|
|
4844
4977
|
] })
|
|
4845
4978
|
] })
|
|
4846
4979
|
] })
|
|
@@ -10504,6 +10637,6 @@ function useEditHotkey(callback) {
|
|
|
10504
10637
|
}, [callback, isActive]);
|
|
10505
10638
|
}
|
|
10506
10639
|
|
|
10507
|
-
export { ALT, ALT_SHIFT_D, ALT_SHIFT_E, ALT_SHIFT_N, Accordion, AuthScreen, Avatar, AvatarGroup, BLOCKED_PCT_CPU, Banner, BarChart, BehaviorPanel, BulkImportGrid, Button_default as Button, CMD_A, CMD_DOT, CMD_ENTER, CMD_K, CMD_S, Card, ChangePasswordForm, ChatTemplate, Checkbox_default as Checkbox, CheckoutTemplate, ColoredBadge, ContainerFillChart, Customization, DEV_BANNER_TEXT, DashboardTemplate, DataTablePage, DateRangePicker, Desktop, DesktopHostProvider, DevIndicator, DonutChart, ENTER, EmailTemplate, EmptyState, EntityList, ErrorPage, FilterBar, FormField, FormLayoutPage, GalleryTemplate, GlobalSearch, HelpCenter, INPUT_BASE, Input_default as Input, Kanban, LOG_CAP, Label, Layout, ListFooter, ListLoadError, LoadingSpinner2 as LoadingSpinner, MIN_GROUP_SAMPLES, MOD, Markdown, MediaUploadField, MediaUploadGrid, MetricBar, MilestoneTimeline, NativeSelect, NotificationBell, PageHeader, Pagination, PdfActionButton, PerfStats, Radio_default as Radio, ResizableTable, SHIFT, SMOOTH_FPS, SearchableSelect, Select_default as Select, ServerStatusIndicator, ShellEntityFetcherProvider, ShortcutHelp, SidebarActionButton, SidebarGroupLabel, SidebarNavItem, SoundsPanel, Sparkline, StartMenu, StatCard, StatusBadge, StatusBadgeProvider, SystemPreferences, Tabs, Textarea_default as Textarea, Tooltip, TopNav, UndoControls, WidgetManager, appendRecord as appendPerfRecord, applyDevTitle, classify as classifyPerf, createWindowRegistry, findDuplicateKeys, formatDate, inputClasses, isDevEnv, isInteracting, isMac, isSeverityTone, mediaFileName, mergeBulkItems, toCsv as perfLogToCsv, severityOf, summariseFrames, summariseLog as summarisePerfLog, toISODate2 as toISODate, useClickOutside, useColumnConfig, useDesktopHost, useEditHotkey, useFilters, useInfiniteScroll, useNewHotkey, useShellEntityFetcher, useSort, useTableNav };
|
|
10640
|
+
export { ALT, ALT_SHIFT_D, ALT_SHIFT_E, ALT_SHIFT_N, Accordion, AuthScreen, Avatar, AvatarGroup, BLOCKED_PCT_CPU, Banner, BarChart, BehaviorPanel, BulkImportGrid, Button_default as Button, CMD_A, CMD_DOT, CMD_ENTER, CMD_K, CMD_S, Card, ChangePasswordForm, ChatTemplate, Checkbox_default as Checkbox, CheckoutTemplate, ColoredBadge, ContainerFillChart, Customization, DEV_BANNER_TEXT, DashboardTemplate, DataTablePage, DateRangePicker, Desktop, DesktopHostProvider, DevIndicator, DonutChart, ENTER, EmailTemplate, EmptyState, EntityList, ErrorPage, FilterBar, FormField, FormLayoutPage, GalleryTemplate, GlobalSearch, HelpCenter, INPUT_BASE, Input_default as Input, Kanban, LOG_CAP, Label, Layout, ListFooter, ListLoadError, LoadingSpinner2 as LoadingSpinner, MIN_EVENT_SAMPLES, MIN_GROUP_SAMPLES, MOD, Markdown, MediaUploadField, MediaUploadGrid, MetricBar, MilestoneTimeline, NativeSelect, NotificationBell, PageHeader, Pagination, PdfActionButton, PerfStats, Radio_default as Radio, ResizableTable, SHIFT, SMOOTH_FPS, SearchableSelect, Select_default as Select, ServerStatusIndicator, ShellEntityFetcherProvider, ShortcutHelp, SidebarActionButton, SidebarGroupLabel, SidebarNavItem, SoundsPanel, Sparkline, StartMenu, StatCard, StatusBadge, StatusBadgeProvider, SystemPreferences, Tabs, Textarea_default as Textarea, Tooltip, TopNav, UndoControls, WidgetManager, appendRecord as appendPerfRecord, applyDevTitle, classifyActivity, classify as classifyPerf, createWindowRegistry, findDuplicateKeys, formatDate, inputClasses, isDevEnv, isInteracting, isMac, isSeverityTone, mediaFileName, mergeBulkItems, toCsv as perfLogToCsv, severityOf, summariseFrames, summariseLog as summarisePerfLog, toISODate2 as toISODate, useClickOutside, useColumnConfig, useDesktopHost, useEditHotkey, useFilters, useInfiniteScroll, useNewHotkey, useShellEntityFetcher, useSort, useTableNav };
|
|
10508
10641
|
//# sourceMappingURL=index.js.map
|
|
10509
10642
|
//# sourceMappingURL=index.js.map
|