@michengai/dsh-codex-ui 0.2.70 → 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 +51 -215
- package/package.json +1 -1
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";
|
|
@@ -2705,6 +2511,19 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
2705
2511
|
}
|
|
2706
2512
|
//#endregion
|
|
2707
2513
|
//#region src/client/ChannelBrowser.tsx
|
|
2514
|
+
const CHANNEL_LOCALE_KEYS = {
|
|
2515
|
+
dingtalk: "channel.dingtalk",
|
|
2516
|
+
feishu: "channel.feishu",
|
|
2517
|
+
lark: "channel.lark",
|
|
2518
|
+
weixin: "channel.weixin",
|
|
2519
|
+
wecom: "channel.wecom",
|
|
2520
|
+
qq: "channel.qq",
|
|
2521
|
+
telegram: "channel.telegram"
|
|
2522
|
+
};
|
|
2523
|
+
function channelLabel(id, fallback, t) {
|
|
2524
|
+
const key = CHANNEL_LOCALE_KEYS[id];
|
|
2525
|
+
return key === void 0 ? fallback : t(key);
|
|
2526
|
+
}
|
|
2708
2527
|
/** 频道树:数据来自 IM,行/菜单/悬停与任务树共用。 */
|
|
2709
2528
|
function ChannelBrowser(props) {
|
|
2710
2529
|
const [menu, setMenu] = (0, react.useState)();
|
|
@@ -2747,8 +2566,8 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
2747
2566
|
setGroups(next);
|
|
2748
2567
|
setPollError(void 0);
|
|
2749
2568
|
}
|
|
2750
|
-
}).catch((
|
|
2751
|
-
if (!disposed) setPollError(
|
|
2569
|
+
}).catch(() => {
|
|
2570
|
+
if (!disposed) setPollError(t("channels.loadError"));
|
|
2752
2571
|
}).finally(() => {
|
|
2753
2572
|
loading = false;
|
|
2754
2573
|
});
|
|
@@ -2781,11 +2600,12 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
2781
2600
|
}),
|
|
2782
2601
|
groups.map((group) => {
|
|
2783
2602
|
const isExpanded = expanded[group.id] ?? true;
|
|
2603
|
+
const label = channelLabel(group.id, group.label, t);
|
|
2784
2604
|
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
2785
2605
|
className: "dcu-wb-project",
|
|
2786
2606
|
children: [/* @__PURE__ */ (0, react_jsx_runtime.jsx)(GroupHead, {
|
|
2787
2607
|
expanded: isExpanded,
|
|
2788
|
-
title:
|
|
2608
|
+
title: label,
|
|
2789
2609
|
icon: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(ChannelBrandIcon, { id: group.id }),
|
|
2790
2610
|
onToggle: () => {
|
|
2791
2611
|
setExpanded((current) => ({
|
|
@@ -2835,7 +2655,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
2835
2655
|
const box = hoverCardAnchor(event.currentTarget.getBoundingClientRect());
|
|
2836
2656
|
showTip({
|
|
2837
2657
|
title,
|
|
2838
|
-
project:
|
|
2658
|
+
project: label,
|
|
2839
2659
|
time: updatedAt === void 0 ? void 0 : formatHoverTime(updatedAt),
|
|
2840
2660
|
left: box.left,
|
|
2841
2661
|
top: box.top
|
|
@@ -4036,6 +3856,14 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
4036
3856
|
"sidebar.channelsTab": "频道",
|
|
4037
3857
|
"sidebar.scheduleTab": "定时",
|
|
4038
3858
|
"channels.empty": "还没有频道会话。先在设置 → IM助理 里连接渠道。",
|
|
3859
|
+
"channels.loadError": "无法读取频道会话。",
|
|
3860
|
+
"channel.dingtalk": "钉钉",
|
|
3861
|
+
"channel.feishu": "飞书",
|
|
3862
|
+
"channel.lark": "Lark",
|
|
3863
|
+
"channel.weixin": "微信",
|
|
3864
|
+
"channel.wecom": "企业微信",
|
|
3865
|
+
"channel.qq": "QQ",
|
|
3866
|
+
"channel.telegram": "Telegram",
|
|
4039
3867
|
"schedule.empty": "还没有定时任务运行记录。",
|
|
4040
3868
|
"search.placeholder": "搜索会话、设置和操作",
|
|
4041
3869
|
"search.empty": "没有匹配的结果。",
|
|
@@ -4044,7 +3872,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
4044
3872
|
"search.actions": "快捷操作",
|
|
4045
3873
|
"workspace.label": "工作区会话",
|
|
4046
3874
|
"workspace.pinned": "置顶",
|
|
4047
|
-
"workspace.pinnedEmpty": "
|
|
3875
|
+
"workspace.pinnedEmpty": "拖动项目到此处置顶",
|
|
4048
3876
|
"workspace.projects": "项目",
|
|
4049
3877
|
"workspace.recent": "最近",
|
|
4050
3878
|
"workspace.recentEmpty": "无聊天",
|
|
@@ -4147,6 +3975,14 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
4147
3975
|
"sidebar.channelsTab": "Channels",
|
|
4148
3976
|
"sidebar.scheduleTab": "Schedule",
|
|
4149
3977
|
"channels.empty": "No channel conversations yet. Connect a channel in Settings → IM Assistant.",
|
|
3978
|
+
"channels.loadError": "Could not load channel conversations.",
|
|
3979
|
+
"channel.dingtalk": "DingTalk",
|
|
3980
|
+
"channel.feishu": "Feishu",
|
|
3981
|
+
"channel.lark": "Lark",
|
|
3982
|
+
"channel.weixin": "WeChat",
|
|
3983
|
+
"channel.wecom": "WeCom",
|
|
3984
|
+
"channel.qq": "QQ",
|
|
3985
|
+
"channel.telegram": "Telegram",
|
|
4150
3986
|
"schedule.empty": "No scheduled-task runs yet.",
|
|
4151
3987
|
"search.placeholder": "Search conversations, settings, and actions",
|
|
4152
3988
|
"search.empty": "No matching results.",
|
|
@@ -4164,7 +4000,7 @@ header [data-dcu-title-folder] svg,header [data-dcu-title-more] svg{display:bloc
|
|
|
4164
4000
|
"workspace.pin": "Pin project",
|
|
4165
4001
|
"workspace.unpin": "Unpin",
|
|
4166
4002
|
"workspace.pinned": "Pinned",
|
|
4167
|
-
"workspace.pinnedEmpty": "Drag a project
|
|
4003
|
+
"workspace.pinnedEmpty": "Drag a project here to pin it",
|
|
4168
4004
|
"workspace.openPath": "Open in file explorer",
|
|
4169
4005
|
"workspace.delete": "Delete project",
|
|
4170
4006
|
"workspace.deleteDescription": "This removes “{name}” from the project list. The folder and conversation records remain.",
|