@michengai/dsh-codex-ui 0.2.71 → 0.2.72
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/client.js +17 -211
- package/package.json +6 -6
package/dist/client.js
CHANGED
|
@@ -262,7 +262,6 @@ window.__ModuleLoader__.load({
|
|
|
262
262
|
//#endregion
|
|
263
263
|
//#region src/client/session-manager.ts
|
|
264
264
|
const SESSION_PINS_STORAGE_KEY = "dsh.session-pins.v1";
|
|
265
|
-
const SESSION_SECTION_PINS_STORAGE_KEY = "dsh-codex-ui.pinned-section-sessions.v1";
|
|
266
265
|
const SESSION_UNREAD_STORAGE_KEY = "dsh.session-unread.v1";
|
|
267
266
|
function normalizeSessionIds(ids) {
|
|
268
267
|
return [...new Set(ids.filter((id) => id.trim() !== ""))];
|
|
@@ -295,15 +294,6 @@ window.__ModuleLoader__.load({
|
|
|
295
294
|
url.searchParams.set("session", sessionId);
|
|
296
295
|
return url.toString();
|
|
297
296
|
}
|
|
298
|
-
/** 把会话插入置顶列表的指定位置;省略锚点时追加到末尾。 */
|
|
299
|
-
function insertSessionId(ids, id, beforeId) {
|
|
300
|
-
const next = ids.filter((item) => item !== id);
|
|
301
|
-
if (beforeId === void 0) return [...next, id];
|
|
302
|
-
if (beforeId === id) return ids.includes(id) ? [...ids] : [...next, id];
|
|
303
|
-
const index = next.indexOf(beforeId);
|
|
304
|
-
next.splice(index < 0 ? next.length : index, 0, id);
|
|
305
|
-
return next;
|
|
306
|
-
}
|
|
307
297
|
//#endregion
|
|
308
298
|
//#region src/client/session-tree.tsx
|
|
309
299
|
function PinIcon() {
|
|
@@ -1121,22 +1111,10 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
1121
1111
|
return item === void 0 ? [] : [item];
|
|
1122
1112
|
});
|
|
1123
1113
|
}
|
|
1124
|
-
/** 置顶区的会话按拖入顺序展示;不因父项目已置顶而隐藏。 */
|
|
1125
|
-
function standalonePinnedSessionIds(pinnedSessionIds) {
|
|
1126
|
-
return [...pinnedSessionIds];
|
|
1127
|
-
}
|
|
1128
|
-
/** 置顶区已有会话时,不再同时展示任何项目文件夹,避免旧置顶项目叠成两条。 */
|
|
1129
|
-
function workspaceIdsHiddenByPinnedSessions(workspaces, pinnedSessionIds) {
|
|
1130
|
-
if (pinnedSessionIds.length === 0) return [];
|
|
1131
|
-
return workspaces.map((workspace) => String(workspace.workspaceId));
|
|
1132
|
-
}
|
|
1133
1114
|
const SESSION_DRAG_TYPE = "application/x-dcu-session";
|
|
1134
1115
|
const WORKSPACE_DRAG_TYPE = "application/x-dcu-workspace";
|
|
1135
1116
|
const SESSION_DRAG_PREFIX = "dcu-session:";
|
|
1136
1117
|
const WORKSPACE_DRAG_PREFIX = "dcu-workspace:";
|
|
1137
|
-
function dragTypes(data) {
|
|
1138
|
-
return data === void 0 ? [] : Array.from(data.types);
|
|
1139
|
-
}
|
|
1140
1118
|
function textPayload(data) {
|
|
1141
1119
|
try {
|
|
1142
1120
|
return data?.getData("text/plain") ?? "";
|
|
@@ -1144,11 +1122,6 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
1144
1122
|
return "";
|
|
1145
1123
|
}
|
|
1146
1124
|
}
|
|
1147
|
-
/** 拖过置顶区时用来决定是否 preventDefault;只看 types,不读数据。 */
|
|
1148
|
-
function isSidebarItemDrag(data) {
|
|
1149
|
-
const types = dragTypes(data);
|
|
1150
|
-
return types.includes("application/x-dcu-session") || types.includes("application/x-dcu-workspace") || types.includes("text/plain");
|
|
1151
|
-
}
|
|
1152
1125
|
/** 写入会话拖拽载荷;drop 时以这个为准,不依赖尚未刷新的 React 状态。 */
|
|
1153
1126
|
function writeSessionDrag(data, sessionId, title) {
|
|
1154
1127
|
data.effectAllowed = "move";
|
|
@@ -1190,11 +1163,11 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
1190
1163
|
.dcu-wb-section-head{position:relative;display:flex;align-items:center;min-height:24px;padding:0 4px;border-radius:6px}.dcu-wb-section-head:hover .dcu-wb-actions{display:flex}.dcu-wb-section-label{display:flex;align-items:center;gap:4px;flex:1;min-width:0;min-height:24px;border:0;padding:2px 4px;background:transparent;color:var(--dcu-sidebar-tertiary);font:13px/20px var(--dcu-font,inherit);font-weight:400;letter-spacing:.02em;text-align:left;cursor:pointer}.dcu-wb-section-caret{display:grid;place-items:center;flex:none;width:12px;height:12px;color:currentColor;opacity:0;transform:rotate(0deg);transform-origin:50% 50%;transition:opacity 140ms ease,transform 180ms ease}.dcu-wb-section-caret svg{display:block}.dcu-wb-section-head:hover .dcu-wb-section-caret,.dcu-wb-section-label:focus-visible .dcu-wb-section-caret{opacity:.78}.dcu-wb-section-label[aria-expanded=true] .dcu-wb-section-caret{transform:rotate(90deg)}.dcu-wb-section-body{display:grid;grid-template-rows:0fr;transition:grid-template-rows 220ms ease}.dcu-wb-section-body[data-open=true]{grid-template-rows:1fr}.dcu-wb-section-body>div{overflow:hidden;min-height:0}@media (prefers-reduced-motion:reduce){.dcu-wb-section-caret,.dcu-wb-section-body{transition:none}}
|
|
1191
1164
|
.dcu-wb-project{position:relative}
|
|
1192
1165
|
.dcu-wb-project-head,.dcu-wb-session{position:relative;display:flex;align-items:center;gap:6px;width:100%;border-radius:8px;padding:0 8px;color:var(--dcu-sidebar-primary);cursor:pointer}
|
|
1193
|
-
.dcu-wb-project-head{height:
|
|
1194
|
-
.dcu-wb-project-head:hover,.dcu-wb-project-head.dcu-wb-menu-open,.dcu-wb-session:hover,.dcu-wb-session.dcu-wb-selected,.dcu-wb-session.dcu-wb-menu-open{background:var(--dcu-sidebar-hover)}.dcu-wb-project-head+.dcu-wb-session,.dcu-wb-project-head+.dcu-wb-nochat{margin-top:
|
|
1166
|
+
.dcu-wb-project-head{height:28px;background:transparent;font:inherit;text-align:left}
|
|
1167
|
+
.dcu-wb-project-head:hover,.dcu-wb-project-head.dcu-wb-menu-open,.dcu-wb-session:hover,.dcu-wb-session.dcu-wb-selected,.dcu-wb-session.dcu-wb-menu-open{background:var(--dcu-sidebar-hover)}.dcu-wb-project-head+.dcu-wb-session,.dcu-wb-project-head+.dcu-wb-nochat{margin-top:0}.dcu-wb-session+.dcu-wb-session{margin-top:2px}
|
|
1195
1168
|
.dcu-wb-project-head[draggable=true],.dcu-wb-session[draggable=true]{cursor:grab}
|
|
1196
1169
|
.dcu-wb-project-head[draggable=true]:active,.dcu-wb-session[draggable=true]:active{cursor:grabbing}
|
|
1197
|
-
.dcu-wb-section,.dcu-wb-section:focus,.dcu-wb-section:focus-visible,.dcu-wb-project-head:focus,.dcu-wb-session:focus{outline:0}.dcu-wb-pin-end,.dcu-wb-pin-start{position:relative;height:8px}.dcu-wb-project-head.dcu-wb-drop::before,.dcu-wb-session.dcu-wb-drop::before,.dcu-wb-pin-end.dcu-wb-drop::before,.dcu-wb-pin-start.dcu-wb-drop::before{content:"";position:absolute;left:8px;right:8px;top:-4px;height:8px;pointer-events:none;background:radial-gradient(circle at 4px 50%,var(--dsw-alias-state-business-primary) 3.25px,transparent 3.45px),linear-gradient(var(--dsw-alias-state-business-primary),var(--dsw-alias-state-business-primary)) 10px 50%/calc(100% - 10px) 2px no-repeat}.dcu-wb-pin-start.dcu-wb-drop::before{top:0}.dcu-wb-project-head.dcu-wb-drop-after::before,.dcu-wb-session.dcu-wb-drop-after::before{top:auto;bottom
|
|
1170
|
+
.dcu-wb-section,.dcu-wb-section:focus,.dcu-wb-section:focus-visible,.dcu-wb-project-head:focus,.dcu-wb-session:focus{outline:0}.dcu-wb-pin-end,.dcu-wb-pin-start{position:relative;height:8px}.dcu-wb-project-head.dcu-wb-drop::before,.dcu-wb-session.dcu-wb-drop::before,.dcu-wb-pin-end.dcu-wb-drop::before,.dcu-wb-pin-start.dcu-wb-drop::before{content:"";position:absolute;left:8px;right:8px;top:-4px;height:8px;pointer-events:none;background:radial-gradient(circle at 4px 50%,var(--dsw-alias-state-business-primary) 3.25px,transparent 3.45px),linear-gradient(var(--dsw-alias-state-business-primary),var(--dsw-alias-state-business-primary)) 10px 50%/calc(100% - 10px) 2px no-repeat}.dcu-wb-pin-start.dcu-wb-drop::before,.dcu-wb-project-head.dcu-wb-drop::before,.dcu-wb-session.dcu-wb-drop::before{top:0}.dcu-wb-project-head.dcu-wb-drop-after::before,.dcu-wb-session.dcu-wb-drop-after::before{top:auto;bottom:0}.dcu-wb-dragging{opacity:.28}.dcu-wb-drag-ghost{position:fixed;top:-120px;left:-240px;z-index:10040;max-width:220px;height:32px;padding:0 10px;border:1px solid var(--dcu-sidebar-border);border-radius:8px;background:var(--dcu-sidebar-hover);color:var(--dcu-sidebar-primary);font:13px/32px var(--dcu-font,inherit);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;pointer-events:none;opacity:0}
|
|
1198
1171
|
.dcu-wb-folder{display:grid;place-items:center;flex:none;width:16px;height:20px;color:var(--dcu-sidebar-icon)}.dcu-wb-brand{display:block;width:16px;height:16px}
|
|
1199
1172
|
.dcu-wb-project-current .dcu-wb-folder{color:var(--dsw-alias-state-business-primary)}
|
|
1200
1173
|
.dcu-wb-project-title,.dcu-wb-session-title{min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:14px;line-height:20px}
|
|
@@ -1222,7 +1195,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
1222
1195
|
.dcu-wb-rename-input:focus{border-color:var(--dsw-alias-button-info-fill)}
|
|
1223
1196
|
`;
|
|
1224
1197
|
const runningStyles = `.dcu-wb-running{flex:none;width:12px;height:12px;border:2px solid color-mix(in srgb,var(--dcu-sidebar-secondary) 25%,transparent);border-top-color:var(--dcu-sidebar-secondary);border-radius:50%;animation:dcu-wb-spin .8s linear infinite}@keyframes dcu-wb-spin{to{transform:rotate(360deg)}}@media (prefers-reduced-motion:reduce){.dcu-wb-running{animation:none}}`;
|
|
1225
|
-
const typographyStyles = `.dcu-wb{font:14px/20px var(--dcu-font,var(--dsw-font-family))}.dcu-wb-section-label{color:var(--dcu-sidebar-tertiary);font-size:13px;font-weight:400;letter-spacing:.02em}.dcu-wb-project-title{font-size:14px;line-height:20px;font-weight:400;color:var(--dcu-sidebar-primary)}.dcu-wb-session-title{font-size:14px;line-height:20px;font-weight:400;color:var(--dcu-sidebar-secondary)}.dcu-wb-session.dcu-wb-selected .dcu-wb-session-title,.dcu-wb-session:hover .dcu-wb-session-title{color:var(--dcu-sidebar-primary)}.dcu-wb-empty{color:var(--dcu-sidebar-tertiary);font-size:13px;line-height:18px}.dcu-wb-nochat{padding:
|
|
1198
|
+
const typographyStyles = `.dcu-wb{font:14px/20px var(--dcu-font,var(--dsw-font-family))}.dcu-wb-section-label{color:var(--dcu-sidebar-tertiary);font-size:13px;font-weight:400;letter-spacing:.02em}.dcu-wb-project-title{font-size:14px;line-height:20px;font-weight:400;color:var(--dcu-sidebar-primary)}.dcu-wb-session-title{font-size:14px;line-height:20px;font-weight:400;color:var(--dcu-sidebar-secondary)}.dcu-wb-session.dcu-wb-selected .dcu-wb-session-title,.dcu-wb-session:hover .dcu-wb-session-title{color:var(--dcu-sidebar-primary)}.dcu-wb-empty{color:var(--dcu-sidebar-tertiary);font-size:13px;line-height:18px}.dcu-wb-nochat{padding:0 8px 4px 28px;color:var(--dcu-sidebar-tertiary);font-size:14px;line-height:20px}`;
|
|
1226
1199
|
const WORKSPACE_TREE_STYLE = stylesheet$4 + runningStyles + typographyStyles;
|
|
1227
1200
|
function storage$1() {
|
|
1228
1201
|
return typeof window === "undefined" ? void 0 : window.localStorage;
|
|
@@ -1245,7 +1218,6 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
1245
1218
|
const [expanded, setExpanded] = (0, react.useState)({});
|
|
1246
1219
|
const [pinnedWorkspaceIds, setPinnedWorkspaceIds] = (0, react.useState)(() => readPinnedWorkspaceIds(storage$1()));
|
|
1247
1220
|
const [pinnedSessionIds, setPinnedSessionIds] = (0, react.useState)(() => readSessionIds(storage$1(), SESSION_PINS_STORAGE_KEY));
|
|
1248
|
-
const [sectionSessionIds, setSectionSessionIds] = (0, react.useState)(() => readSessionIds(storage$1(), SESSION_SECTION_PINS_STORAGE_KEY));
|
|
1249
1221
|
const [unreadSessionIds, setUnreadSessionIds] = (0, react.useState)(() => readSessionIds(storage$1(), SESSION_UNREAD_STORAGE_KEY));
|
|
1250
1222
|
const [menu, setMenu] = (0, react.useState)();
|
|
1251
1223
|
const [renameTarget, setRenameTarget] = (0, react.useState)();
|
|
@@ -1274,13 +1246,6 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
1274
1246
|
(0, react.useEffect)(() => {
|
|
1275
1247
|
writeSessionIds(storage$1(), SESSION_PINS_STORAGE_KEY, pinnedSessionIds);
|
|
1276
1248
|
}, [pinnedSessionIds]);
|
|
1277
|
-
(0, react.useEffect)(() => {
|
|
1278
|
-
writeSessionIds(storage$1(), SESSION_SECTION_PINS_STORAGE_KEY, sectionSessionIds);
|
|
1279
|
-
}, [sectionSessionIds]);
|
|
1280
|
-
(0, react.useEffect)(() => {
|
|
1281
|
-
if (sectionSessionIds.length === 0) return;
|
|
1282
|
-
setPinnedWorkspaceIds((ids) => ids.length === 0 ? ids : []);
|
|
1283
|
-
}, [sectionSessionIds]);
|
|
1284
1249
|
(0, react.useEffect)(() => {
|
|
1285
1250
|
writeSessionIds(storage$1(), SESSION_UNREAD_STORAGE_KEY, unreadSessionIds);
|
|
1286
1251
|
}, [unreadSessionIds]);
|
|
@@ -1367,14 +1332,12 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
1367
1332
|
sessions.current,
|
|
1368
1333
|
menu
|
|
1369
1334
|
]);
|
|
1370
|
-
const
|
|
1371
|
-
const
|
|
1372
|
-
const projectPinned = (id) => pinnedWorkspaceIds.includes(String(id)) && !hiddenPinnedWorkspaceIds.has(String(id));
|
|
1373
|
-
const pinnedGroups = orderByIds(groups.items, pinnedWorkspaceIds, (workspace) => String(workspace.workspaceId)).filter((workspace) => !hiddenPinnedWorkspaceIds.has(String(workspace.workspaceId)));
|
|
1335
|
+
const projectPinned = (id) => pinnedWorkspaceIds.includes(String(id));
|
|
1336
|
+
const pinnedGroups = orderByIds(groups.items, pinnedWorkspaceIds, (workspace) => String(workspace.workspaceId));
|
|
1374
1337
|
const regularGroups = groups.items.filter((workspace) => !projectPinned(workspace.workspaceId));
|
|
1375
|
-
const pinDragActive = workspaceDragId !== void 0
|
|
1338
|
+
const pinDragActive = workspaceDragId !== void 0;
|
|
1376
1339
|
const assignedIds = workspaces.items.flatMap((workspace) => workspace.sessionIds.map((id) => String(id)));
|
|
1377
|
-
const recentIds = ungroupedSessionIds(sessions.ids ?? Object.keys(sessions.byId), sessions.byId, assignedIds, workspaces.archivedSessionIds).
|
|
1340
|
+
const recentIds = ungroupedSessionIds(sessions.ids ?? Object.keys(sessions.byId), sessions.byId, assignedIds, workspaces.archivedSessionIds).sort((left, right) => (sessions.byId[right]?.updatedAt ?? 0) - (sessions.byId[left]?.updatedAt ?? 0));
|
|
1378
1341
|
const run = async (key, action) => {
|
|
1379
1342
|
setBusy(key);
|
|
1380
1343
|
setError(void 0);
|
|
@@ -1412,7 +1375,6 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
1412
1375
|
if (target.kind === "session") {
|
|
1413
1376
|
await deleteSession(target.id);
|
|
1414
1377
|
setPinnedSessionIds((ids) => ids.filter((id) => id !== target.id));
|
|
1415
|
-
setSectionSessionIds((ids) => ids.filter((id) => id !== target.id));
|
|
1416
1378
|
setUnreadSessionIds((ids) => ids.filter((id) => id !== target.id));
|
|
1417
1379
|
} else {
|
|
1418
1380
|
await deleteWorkspace(target.id);
|
|
@@ -1481,14 +1443,10 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
1481
1443
|
const pinWorkspaceAt = (id, beforeId) => {
|
|
1482
1444
|
setPinnedWorkspaceIds((ids) => insertPinnedWorkspace(ids, id, beforeId));
|
|
1483
1445
|
};
|
|
1484
|
-
const pinSessionAt = (id, beforeId) => {
|
|
1485
|
-
setSectionSessionIds((ids) => insertSessionId(ids, id, beforeId));
|
|
1486
|
-
setPinnedWorkspaceIds((ids) => ids.length === 0 ? ids : []);
|
|
1487
|
-
};
|
|
1488
1446
|
const renderGroup = (workspace, zone) => {
|
|
1489
1447
|
const expandKey = zone === "pinned" ? `pin:${workspace.workspaceId}` : String(workspace.workspaceId);
|
|
1490
1448
|
const isExpanded = expanded[expandKey] ?? true;
|
|
1491
|
-
const shownIds = workspace.visibleIds
|
|
1449
|
+
const shownIds = workspace.visibleIds;
|
|
1492
1450
|
const menuOpen = menu?.type === "workspace" && menu.id === workspace.workspaceId;
|
|
1493
1451
|
const menuAt = menuOpen && menu.x !== void 0 && menu.y !== void 0 ? {
|
|
1494
1452
|
x: menu.x,
|
|
@@ -1498,7 +1456,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
1498
1456
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
1499
1457
|
className: `dcu-wb-project${isCurrentWorkspace ? " dcu-wb-project-current" : ""}`,
|
|
1500
1458
|
onDragOver: (event) => {
|
|
1501
|
-
if (workspaceDragId === void 0
|
|
1459
|
+
if (workspaceDragId === void 0) return;
|
|
1502
1460
|
event.preventDefault();
|
|
1503
1461
|
event.stopPropagation();
|
|
1504
1462
|
event.dataTransfer.dropEffect = "move";
|
|
@@ -1519,17 +1477,6 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
1519
1477
|
onDrop: (event) => {
|
|
1520
1478
|
event.preventDefault();
|
|
1521
1479
|
event.stopPropagation();
|
|
1522
|
-
const droppedSession = readSessionDrag(event.dataTransfer, sessionDrag?.sessionId);
|
|
1523
|
-
if (zone === "pinned" && droppedSession !== void 0) {
|
|
1524
|
-
setSessionDrag(void 0);
|
|
1525
|
-
setSessionDropId(void 0);
|
|
1526
|
-
setWorkspaceDragId(void 0);
|
|
1527
|
-
setWorkspaceDropId(void 0);
|
|
1528
|
-
setWorkspaceDropAfter(false);
|
|
1529
|
-
setPinSlot(void 0);
|
|
1530
|
-
pinSessionAt(droppedSession);
|
|
1531
|
-
return;
|
|
1532
|
-
}
|
|
1533
1480
|
const dragged = readWorkspaceDrag(event.dataTransfer, workspaceDragId);
|
|
1534
1481
|
const after = event.clientY > event.currentTarget.getBoundingClientRect().top + event.currentTarget.getBoundingClientRect().height / 2;
|
|
1535
1482
|
setWorkspaceDragId(void 0);
|
|
@@ -1918,27 +1865,20 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
1918
1865
|
className: "dcu-wb-section",
|
|
1919
1866
|
"aria-label": t("workspace.pinned"),
|
|
1920
1867
|
onDragOver: (event) => {
|
|
1921
|
-
if (!pinDragActive
|
|
1868
|
+
if (!pinDragActive) return;
|
|
1922
1869
|
event.preventDefault();
|
|
1923
1870
|
event.dataTransfer.dropEffect = "move";
|
|
1924
1871
|
if (event.target === event.currentTarget || event.target instanceof Element && event.target.closest(".dcu-wb-section-head") !== null) setPinSlot("header");
|
|
1925
1872
|
},
|
|
1926
1873
|
onDrop: (event) => {
|
|
1927
1874
|
event.preventDefault();
|
|
1928
|
-
const draggedSession = readSessionDrag(event.dataTransfer, sessionDrag?.sessionId);
|
|
1929
1875
|
const draggedWorkspace = readWorkspaceDrag(event.dataTransfer, workspaceDragId);
|
|
1930
1876
|
const slot = pinSlot;
|
|
1931
1877
|
setWorkspaceDragId(void 0);
|
|
1932
1878
|
setWorkspaceDropId(void 0);
|
|
1933
1879
|
setWorkspaceDropAfter(false);
|
|
1934
|
-
setSessionDrag(void 0);
|
|
1935
|
-
setSessionDropId(void 0);
|
|
1936
1880
|
setPinSlot(void 0);
|
|
1937
|
-
if (
|
|
1938
|
-
pinSessionAt(draggedSession, slot === "header" ? pinSectionSessions[0] : slot === "end" || slot === void 0 || !pinSectionSessions.includes(slot) ? void 0 : slot);
|
|
1939
|
-
return;
|
|
1940
|
-
}
|
|
1941
|
-
if (draggedWorkspace !== void 0) pinWorkspaceAt(draggedWorkspace, slot === "header" ? pinnedGroups[0] === void 0 ? void 0 : String(pinnedGroups[0].workspaceId) : slot === "end" || slot === void 0 || pinSectionSessions.includes(slot) ? void 0 : slot);
|
|
1881
|
+
if (draggedWorkspace !== void 0) pinWorkspaceAt(draggedWorkspace, slot === "header" ? pinnedGroups[0] === void 0 ? void 0 : String(pinnedGroups[0].workspaceId) : slot === "end" || slot === void 0 ? void 0 : slot);
|
|
1942
1882
|
},
|
|
1943
1883
|
onDragLeave: (event) => {
|
|
1944
1884
|
if (event.currentTarget.contains(event.relatedTarget)) return;
|
|
@@ -1978,7 +1918,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
1978
1918
|
(pinDragActive || pinSlot === "header") && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1979
1919
|
className: `dcu-wb-pin-start${pinSlot === "header" ? " dcu-wb-drop" : ""}`,
|
|
1980
1920
|
onDragOver: (event) => {
|
|
1981
|
-
if (!pinDragActive
|
|
1921
|
+
if (!pinDragActive) return;
|
|
1982
1922
|
event.preventDefault();
|
|
1983
1923
|
event.stopPropagation();
|
|
1984
1924
|
event.dataTransfer.dropEffect = "move";
|
|
@@ -1987,149 +1927,15 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
1987
1927
|
setWorkspaceDropAfter(false);
|
|
1988
1928
|
}
|
|
1989
1929
|
}),
|
|
1990
|
-
|
|
1930
|
+
pinnedGroups.length === 0 && pinSlot !== "header" && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
1991
1931
|
className: "dcu-wb-empty",
|
|
1992
1932
|
children: t("workspace.pinnedEmpty")
|
|
1993
1933
|
}),
|
|
1994
|
-
pinSectionSessions.map((id) => {
|
|
1995
|
-
const session = sessions.byId[id];
|
|
1996
|
-
if (session === void 0) return null;
|
|
1997
|
-
const title = session.displayTitle;
|
|
1998
|
-
const workspace = groups.items.find((item) => item.visibleIds.includes(id));
|
|
1999
|
-
const path = session.cwd ?? workspace?.path;
|
|
2000
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)(SessionRow, {
|
|
2001
|
-
id,
|
|
2002
|
-
title,
|
|
2003
|
-
flat: true,
|
|
2004
|
-
selected: sessions.current === id,
|
|
2005
|
-
menuOpen: menu?.type === "session" && menu.id === id,
|
|
2006
|
-
pinned: true,
|
|
2007
|
-
unread: unreadSessionIds.includes(id),
|
|
2008
|
-
running: session.running === true,
|
|
2009
|
-
t,
|
|
2010
|
-
menuItems: sessionMenu(id, title, path),
|
|
2011
|
-
menuPoint: menu?.type === "session" && menu.id === id && menu.x !== void 0 && menu.y !== void 0 ? {
|
|
2012
|
-
x: menu.x,
|
|
2013
|
-
y: menu.y
|
|
2014
|
-
} : void 0,
|
|
2015
|
-
draggable: true,
|
|
2016
|
-
dropActive: sessionDropId === id,
|
|
2017
|
-
onDragStart: (event) => {
|
|
2018
|
-
event.stopPropagation();
|
|
2019
|
-
setWorkspaceDragId(void 0);
|
|
2020
|
-
writeSessionDrag(event.dataTransfer, id, title);
|
|
2021
|
-
const preview = document.createElement("div");
|
|
2022
|
-
preview.className = "dcu-wb-drag-ghost";
|
|
2023
|
-
preview.textContent = title;
|
|
2024
|
-
document.body.appendChild(preview);
|
|
2025
|
-
event.dataTransfer.setDragImage(preview, 16, 18);
|
|
2026
|
-
window.requestAnimationFrame(() => {
|
|
2027
|
-
preview.remove();
|
|
2028
|
-
});
|
|
2029
|
-
setSessionDrag({
|
|
2030
|
-
sessionId: id,
|
|
2031
|
-
workspaceId: workspace?.workspaceId ?? ""
|
|
2032
|
-
});
|
|
2033
|
-
},
|
|
2034
|
-
onDragEnd: () => {
|
|
2035
|
-
setSessionDrag(void 0);
|
|
2036
|
-
setSessionDropId(void 0);
|
|
2037
|
-
setPinSlot(void 0);
|
|
2038
|
-
},
|
|
2039
|
-
onDragOver: (event) => {
|
|
2040
|
-
if (sessionDrag === void 0) return;
|
|
2041
|
-
event.preventDefault();
|
|
2042
|
-
event.stopPropagation();
|
|
2043
|
-
setSessionDropId(id);
|
|
2044
|
-
setPinSlot(id);
|
|
2045
|
-
},
|
|
2046
|
-
onDrop: (event) => {
|
|
2047
|
-
event.preventDefault();
|
|
2048
|
-
event.stopPropagation();
|
|
2049
|
-
const draggedSession = readSessionDrag(event.dataTransfer, sessionDrag?.sessionId);
|
|
2050
|
-
const after = event.clientY > event.currentTarget.getBoundingClientRect().top + event.currentTarget.getBoundingClientRect().height / 2;
|
|
2051
|
-
setSessionDrag(void 0);
|
|
2052
|
-
setSessionDropId(void 0);
|
|
2053
|
-
setPinSlot(void 0);
|
|
2054
|
-
if (draggedSession === void 0) return;
|
|
2055
|
-
pinSessionAt(draggedSession, dropBeforeId(pinSectionSessions, id, after));
|
|
2056
|
-
},
|
|
2057
|
-
onOpen: () => {
|
|
2058
|
-
setUnreadSessionIds((ids) => ids.filter((item) => item !== id));
|
|
2059
|
-
openSession(id);
|
|
2060
|
-
},
|
|
2061
|
-
onMenuChange: (open) => {
|
|
2062
|
-
setMenu(open ? {
|
|
2063
|
-
id,
|
|
2064
|
-
type: "session"
|
|
2065
|
-
} : void 0);
|
|
2066
|
-
},
|
|
2067
|
-
onPin: () => {
|
|
2068
|
-
setSectionSessionIds((ids) => ids.filter((item) => item !== id));
|
|
2069
|
-
},
|
|
2070
|
-
onArchive: () => {
|
|
2071
|
-
run("archive", () => archiveSession(id));
|
|
2072
|
-
},
|
|
2073
|
-
onHover: (event) => {
|
|
2074
|
-
const box = hoverCardAnchor(event.currentTarget.getBoundingClientRect());
|
|
2075
|
-
showTip({
|
|
2076
|
-
kind: "session",
|
|
2077
|
-
id,
|
|
2078
|
-
title,
|
|
2079
|
-
project: workspace?.title,
|
|
2080
|
-
path,
|
|
2081
|
-
time: formatHoverTime(session.updatedAt),
|
|
2082
|
-
left: box.left,
|
|
2083
|
-
top: box.top
|
|
2084
|
-
});
|
|
2085
|
-
},
|
|
2086
|
-
onLeave: hideTip,
|
|
2087
|
-
onContextMenu: (event) => {
|
|
2088
|
-
event.preventDefault();
|
|
2089
|
-
event.stopPropagation();
|
|
2090
|
-
dismissTip();
|
|
2091
|
-
setMenu({
|
|
2092
|
-
id,
|
|
2093
|
-
type: "session",
|
|
2094
|
-
x: event.clientX,
|
|
2095
|
-
y: event.clientY
|
|
2096
|
-
});
|
|
2097
|
-
},
|
|
2098
|
-
onSelectAction: (action) => {
|
|
2099
|
-
if (busy !== void 0) return;
|
|
2100
|
-
if (action === "rename") beginRename("session", id, title);
|
|
2101
|
-
if (action === "pin") {
|
|
2102
|
-
setSectionSessionIds((ids) => ids.filter((item) => item !== id));
|
|
2103
|
-
setMenu(void 0);
|
|
2104
|
-
}
|
|
2105
|
-
if (action === "unread") {
|
|
2106
|
-
setUnreadSessionIds((ids) => toggleSessionId(ids, id));
|
|
2107
|
-
setMenu(void 0);
|
|
2108
|
-
}
|
|
2109
|
-
if (action === "archive") run("archive", () => archiveSession(id));
|
|
2110
|
-
if (action === "delete") {
|
|
2111
|
-
setDeleteTarget({
|
|
2112
|
-
id,
|
|
2113
|
-
kind: "session",
|
|
2114
|
-
title
|
|
2115
|
-
});
|
|
2116
|
-
setError(void 0);
|
|
2117
|
-
setMenu(void 0);
|
|
2118
|
-
}
|
|
2119
|
-
if (action === "fork") run("fork", () => forkSession(id));
|
|
2120
|
-
if (action === "openPath" && path !== void 0) run("open-path", () => openPath(path));
|
|
2121
|
-
if (action === "copyPath") copy(path);
|
|
2122
|
-
if (action === "copyTitle") copy(title);
|
|
2123
|
-
if (action === "copyId") copy(id);
|
|
2124
|
-
if (action === "copyLink") copy(sessionDeepLink(browserBase(), id));
|
|
2125
|
-
}
|
|
2126
|
-
}, id);
|
|
2127
|
-
}),
|
|
2128
1934
|
pinnedGroups.map((workspace) => renderGroup(workspace, "pinned")),
|
|
2129
1935
|
pinDragActive && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
2130
1936
|
className: `dcu-wb-pin-end${pinSlot === "end" ? " dcu-wb-drop" : ""}`,
|
|
2131
1937
|
onDragOver: (event) => {
|
|
2132
|
-
if (!pinDragActive
|
|
1938
|
+
if (!pinDragActive) return;
|
|
2133
1939
|
event.preventDefault();
|
|
2134
1940
|
event.stopPropagation();
|
|
2135
1941
|
event.dataTransfer.dropEffect = "move";
|
|
@@ -4066,7 +3872,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
4066
3872
|
"search.actions": "快捷操作",
|
|
4067
3873
|
"workspace.label": "工作区会话",
|
|
4068
3874
|
"workspace.pinned": "置顶",
|
|
4069
|
-
"workspace.pinnedEmpty": "
|
|
3875
|
+
"workspace.pinnedEmpty": "拖动项目到此处置顶",
|
|
4070
3876
|
"workspace.projects": "项目",
|
|
4071
3877
|
"workspace.recent": "最近",
|
|
4072
3878
|
"workspace.recentEmpty": "无聊天",
|
|
@@ -4194,7 +4000,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
4194
4000
|
"workspace.pin": "Pin project",
|
|
4195
4001
|
"workspace.unpin": "Unpin",
|
|
4196
4002
|
"workspace.pinned": "Pinned",
|
|
4197
|
-
"workspace.pinnedEmpty": "Drag a project
|
|
4003
|
+
"workspace.pinnedEmpty": "Drag a project here to pin it",
|
|
4198
4004
|
"workspace.openPath": "Open in file explorer",
|
|
4199
4005
|
"workspace.delete": "Delete project",
|
|
4200
4006
|
"workspace.deleteDescription": "This removes “{name}” from the project list. The folder and conversation records remain.",
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@michengai/dsh-codex-ui",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.72",
|
|
4
4
|
"description": "以 Codex 风格重构 DSH Web 侧栏的独立客户端插件",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"publishConfig": {
|
|
@@ -51,6 +51,10 @@
|
|
|
51
51
|
"platform": "web"
|
|
52
52
|
}
|
|
53
53
|
},
|
|
54
|
+
"scripts": {
|
|
55
|
+
"build": "tsc --noEmit && tsdown",
|
|
56
|
+
"test": "tsx tests/hover-tip.assert.ts && tsx tests/companion-slots.assert.ts && tsx tests/channel-api.assert.ts && tsx tests/schedule-sessions.assert.ts && tsx tests/session-tree.assert.ts && tsx tests/pinned-sessions.assert.ts && tsx tests/session-manager.assert.ts && tsx tests/workspace-browser.assert.ts && tsx tests/sidebar-search.assert.ts && tsx tests/settings-navigation.assert.ts && tsx tests/settings-nav-icons.assert.ts && tsx tests/locales.assert.ts && vitest run tests/client-runtime.integration.spec.ts && tsx tests/settings-integration.assert.ts && tsx tests/about-dependencies.assert.ts && tsx tests/dependency-manager.assert.ts && tsx tests/conversation-bubbles.assert.ts && tsx tests/conversation-header.assert.ts && tsx tests/conversation-visuals.assert.ts && tsdown && tsx tests/client-bundle.assert.ts && tsx tests/codex-suite.assert.ts"
|
|
57
|
+
},
|
|
54
58
|
"peerDependencies": {
|
|
55
59
|
"@deepseek-ai/cordis": ">=4.0.1 <5.0.0",
|
|
56
60
|
"@deepseek-ai/dsh-client-locale": ">=0.1.0-rc.0 <0.2.0",
|
|
@@ -96,9 +100,5 @@
|
|
|
96
100
|
"tsx": "^4.22.4",
|
|
97
101
|
"typescript": "^6.0.3",
|
|
98
102
|
"vitest": "^4.1.8"
|
|
99
|
-
},
|
|
100
|
-
"scripts": {
|
|
101
|
-
"build": "tsc --noEmit && tsdown",
|
|
102
|
-
"test": "tsx tests/hover-tip.assert.ts && tsx tests/companion-slots.assert.ts && tsx tests/channel-api.assert.ts && tsx tests/schedule-sessions.assert.ts && tsx tests/session-tree.assert.ts && tsx tests/pinned-sessions.assert.ts && tsx tests/session-manager.assert.ts && tsx tests/workspace-browser.assert.ts && tsx tests/sidebar-search.assert.ts && tsx tests/settings-navigation.assert.ts && tsx tests/settings-nav-icons.assert.ts && tsx tests/locales.assert.ts && vitest run tests/client-runtime.integration.spec.ts && tsx tests/settings-integration.assert.ts && tsx tests/about-dependencies.assert.ts && tsx tests/dependency-manager.assert.ts && tsx tests/conversation-bubbles.assert.ts && tsx tests/conversation-header.assert.ts && tsx tests/conversation-visuals.assert.ts && tsdown && tsx tests/client-bundle.assert.ts && tsx tests/codex-suite.assert.ts"
|
|
103
103
|
}
|
|
104
|
-
}
|
|
104
|
+
}
|