dsh-vscode-workbench 0.1.5 → 0.1.7
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/lib/client.js +294 -101
- package/lib/client.js.map +1 -1
- package/lib/index.js +16 -7
- package/lib/index.js.map +1 -1
- package/lib/types/client/Workbench.d.ts +10 -0
- package/lib/types/client/api.d.ts +4 -0
- package/lib/types/types.d.ts +2 -2
- package/package.json +1 -1
- package/src/client/Workbench.tsx +86 -18
- package/src/client/api.ts +6 -2
- package/src/client/styles.ts +13 -3
- package/src/host.ts +6 -3
- package/src/index.ts +5 -2
- package/src/types.ts +1 -1
package/lib/client.js
CHANGED
|
@@ -115,6 +115,13 @@ window.__ModuleLoader__.load({
|
|
|
115
115
|
};
|
|
116
116
|
//#endregion
|
|
117
117
|
//#region src/client/api.ts
|
|
118
|
+
var ApiError = class extends Error {
|
|
119
|
+
code;
|
|
120
|
+
constructor(code, message) {
|
|
121
|
+
super(message);
|
|
122
|
+
this.code = code;
|
|
123
|
+
}
|
|
124
|
+
};
|
|
118
125
|
async function api(method, body, signal) {
|
|
119
126
|
const response = await fetch(`/dsh-vscode/api/${method}`, {
|
|
120
127
|
method: "POST",
|
|
@@ -123,7 +130,7 @@ window.__ModuleLoader__.load({
|
|
|
123
130
|
signal
|
|
124
131
|
});
|
|
125
132
|
const answer = await response.json();
|
|
126
|
-
if (!response.ok || !answer.ok) throw new
|
|
133
|
+
if (!response.ok || !answer.ok) throw new ApiError(answer.error?.code ?? "request-failed", answer.error?.message ?? `request failed (${response.status})`);
|
|
127
134
|
return answer.value;
|
|
128
135
|
}
|
|
129
136
|
//#endregion
|
|
@@ -4468,6 +4475,99 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
4468
4475
|
};
|
|
4469
4476
|
//#endregion
|
|
4470
4477
|
//#region src/client/Workbench.tsx
|
|
4478
|
+
/** Calculate a panel width from a horizontal pointer movement. */
|
|
4479
|
+
function resizedPanelWidth(startWidth, startX, nextX, direction, min, max) {
|
|
4480
|
+
return Math.max(min, Math.min(max, Math.round(startWidth + (nextX - startX) * direction)));
|
|
4481
|
+
}
|
|
4482
|
+
function PanelResizer({ className, label, width, min, max, defaultWidth, direction, onWidth }) {
|
|
4483
|
+
const [dragging, setDragging] = (0, react.useState)(false);
|
|
4484
|
+
const stopDragging = (0, react.useRef)(() => {});
|
|
4485
|
+
(0, react.useEffect)(() => () => stopDragging.current(), []);
|
|
4486
|
+
const stop = () => stopDragging.current();
|
|
4487
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4488
|
+
className,
|
|
4489
|
+
"data-dragging": dragging || void 0,
|
|
4490
|
+
role: "separator",
|
|
4491
|
+
"aria-label": label,
|
|
4492
|
+
"aria-orientation": "vertical",
|
|
4493
|
+
"aria-valuemin": min,
|
|
4494
|
+
"aria-valuemax": max,
|
|
4495
|
+
"aria-valuenow": Math.round(width),
|
|
4496
|
+
tabIndex: 0,
|
|
4497
|
+
title: `${label},双击恢复默认`,
|
|
4498
|
+
onDoubleClick: () => onWidth(defaultWidth),
|
|
4499
|
+
onKeyDown: (event) => {
|
|
4500
|
+
if (event.key === "Home") {
|
|
4501
|
+
event.preventDefault();
|
|
4502
|
+
onWidth(defaultWidth);
|
|
4503
|
+
return;
|
|
4504
|
+
}
|
|
4505
|
+
if (event.key !== "ArrowLeft" && event.key !== "ArrowRight") return;
|
|
4506
|
+
event.preventDefault();
|
|
4507
|
+
const pointerDelta = event.key === "ArrowRight" ? 10 : -10;
|
|
4508
|
+
onWidth(Math.max(min, Math.min(max, Math.round(width + pointerDelta * direction))));
|
|
4509
|
+
},
|
|
4510
|
+
onPointerDown: (event) => {
|
|
4511
|
+
if (event.button !== 0) return;
|
|
4512
|
+
event.preventDefault();
|
|
4513
|
+
stop();
|
|
4514
|
+
const startX = event.clientX;
|
|
4515
|
+
const startWidth = width;
|
|
4516
|
+
event.currentTarget.setPointerCapture?.(event.pointerId);
|
|
4517
|
+
const previousCursor = document.body.style.cursor;
|
|
4518
|
+
const previousUserSelect = document.body.style.userSelect;
|
|
4519
|
+
document.body.style.cursor = "ew-resize";
|
|
4520
|
+
document.body.style.userSelect = "none";
|
|
4521
|
+
setDragging(true);
|
|
4522
|
+
const move = (next) => onWidth(resizedPanelWidth(startWidth, startX, next.clientX, direction, min, max));
|
|
4523
|
+
const cleanup = (commit = false, nextX = startX) => {
|
|
4524
|
+
window.removeEventListener("pointermove", move);
|
|
4525
|
+
window.removeEventListener("pointerup", up);
|
|
4526
|
+
window.removeEventListener("pointercancel", cancel);
|
|
4527
|
+
window.removeEventListener("blur", cancel);
|
|
4528
|
+
document.body.style.cursor = previousCursor;
|
|
4529
|
+
document.body.style.userSelect = previousUserSelect;
|
|
4530
|
+
setDragging(false);
|
|
4531
|
+
stopDragging.current = () => {};
|
|
4532
|
+
if (!commit) return;
|
|
4533
|
+
onWidth(Math.max(min, Math.min(max, Math.round(startWidth + (nextX - startX) * direction))));
|
|
4534
|
+
};
|
|
4535
|
+
const up = (next) => cleanup(true, next.clientX);
|
|
4536
|
+
const cancel = () => cleanup();
|
|
4537
|
+
stopDragging.current = cancel;
|
|
4538
|
+
window.addEventListener("pointermove", move);
|
|
4539
|
+
window.addEventListener("pointerup", up);
|
|
4540
|
+
window.addEventListener("pointercancel", cancel);
|
|
4541
|
+
window.addEventListener("blur", cancel);
|
|
4542
|
+
}
|
|
4543
|
+
});
|
|
4544
|
+
}
|
|
4545
|
+
function unloadedTab(path) {
|
|
4546
|
+
return {
|
|
4547
|
+
path,
|
|
4548
|
+
content: "",
|
|
4549
|
+
draft: "",
|
|
4550
|
+
revision: "",
|
|
4551
|
+
size: 0,
|
|
4552
|
+
binary: false,
|
|
4553
|
+
tooLarge: false,
|
|
4554
|
+
dirty: false,
|
|
4555
|
+
loaded: false,
|
|
4556
|
+
preview: /\.md$/i.test(path)
|
|
4557
|
+
};
|
|
4558
|
+
}
|
|
4559
|
+
/** Restore tab headers without reading their file contents. */
|
|
4560
|
+
function restoreTabPaths(paths) {
|
|
4561
|
+
return [...new Set(paths)].map(unloadedTab);
|
|
4562
|
+
}
|
|
4563
|
+
/** Return whether file changes require reloading one visible directory. */
|
|
4564
|
+
function directoryAffected(directory, changedPaths) {
|
|
4565
|
+
return changedPaths.some((changed) => {
|
|
4566
|
+
const normalized = changed.replace(/\\/g, "/");
|
|
4567
|
+
const parent = normalized.includes("/") ? normalized.slice(0, normalized.lastIndexOf("/")) : "";
|
|
4568
|
+
return normalized === directory || parent === directory;
|
|
4569
|
+
});
|
|
4570
|
+
}
|
|
4471
4571
|
/** Return the basename shown in a tab while preserving its full internal path. */
|
|
4472
4572
|
function tabLabel(tab) {
|
|
4473
4573
|
const path = tab.title ?? tab.diffSourcePath ?? tab.path.replace(/^diff:/, "");
|
|
@@ -4497,7 +4597,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
4497
4597
|
}, []);
|
|
4498
4598
|
return dark;
|
|
4499
4599
|
}
|
|
4500
|
-
function Tree({ sessionId, path, depth, expanded, selected, selectedDirectory, statuses, onToggle, onSelectDirectory, onOpen, onChange, onUpload }) {
|
|
4600
|
+
function Tree({ sessionId, path, depth, expanded, selected, selectedDirectory, statuses, onToggle, onSelectDirectory, onOpen, onChange, onUpload, creating, onCreatingChange, onCreatingCancel, onCreatingSubmit }) {
|
|
4501
4601
|
const [rows, setRows] = (0, react.useState)([]);
|
|
4502
4602
|
const [error, setError] = (0, react.useState)();
|
|
4503
4603
|
const [dropTarget, setDropTarget] = (0, react.useState)(false);
|
|
@@ -4512,7 +4612,10 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
4512
4612
|
}, [sessionId, path]);
|
|
4513
4613
|
(0, react.useEffect)(load, [load]);
|
|
4514
4614
|
(0, react.useEffect)(() => {
|
|
4515
|
-
const handler = () =>
|
|
4615
|
+
const handler = (event) => {
|
|
4616
|
+
const paths = event.detail;
|
|
4617
|
+
if (paths === void 0 || directoryAffected(path, paths)) load();
|
|
4618
|
+
};
|
|
4516
4619
|
window.addEventListener("dvw-files-changed", handler);
|
|
4517
4620
|
return () => window.removeEventListener("dvw-files-changed", handler);
|
|
4518
4621
|
}, [load]);
|
|
@@ -4579,6 +4682,41 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
4579
4682
|
className: "dvw-error",
|
|
4580
4683
|
children: error
|
|
4581
4684
|
}),
|
|
4685
|
+
creating?.directory === path && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(react_jsx_runtime.Fragment, { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4686
|
+
className: "dvw-tree-row dvw-tree-create-row",
|
|
4687
|
+
style: { paddingLeft: 6 + depth * 13 },
|
|
4688
|
+
children: [
|
|
4689
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", { className: "dvw-chevron" }),
|
|
4690
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, {
|
|
4691
|
+
name: creating.kind === "directory" ? "folder" : "new-file",
|
|
4692
|
+
className: `dvw-file-icon ${creating.kind === "directory" ? "folder" : ""}`
|
|
4693
|
+
}),
|
|
4694
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
4695
|
+
className: "dvw-tree-create-input",
|
|
4696
|
+
value: creating.value,
|
|
4697
|
+
autoFocus: true,
|
|
4698
|
+
"aria-label": creating.kind === "directory" ? "新建文件夹名称" : "新建文件名称",
|
|
4699
|
+
"aria-invalid": creating.error !== void 0,
|
|
4700
|
+
placeholder: creating.kind === "directory" ? "文件夹名称" : "文件名称",
|
|
4701
|
+
onChange: (event) => onCreatingChange(event.target.value),
|
|
4702
|
+
onKeyDown: (event) => {
|
|
4703
|
+
if (event.key === "Enter") {
|
|
4704
|
+
event.preventDefault();
|
|
4705
|
+
onCreatingSubmit();
|
|
4706
|
+
}
|
|
4707
|
+
if (event.key === "Escape") {
|
|
4708
|
+
event.preventDefault();
|
|
4709
|
+
onCreatingCancel();
|
|
4710
|
+
}
|
|
4711
|
+
},
|
|
4712
|
+
onBlur: onCreatingCancel
|
|
4713
|
+
})
|
|
4714
|
+
]
|
|
4715
|
+
}), creating.error && /* @__PURE__ */ (0, react_jsx_runtime.jsx)("div", {
|
|
4716
|
+
className: "dvw-tree-create-error",
|
|
4717
|
+
style: { paddingLeft: 42 + depth * 13 },
|
|
4718
|
+
children: creating.error
|
|
4719
|
+
})] }),
|
|
4582
4720
|
rows.map((row) => /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", { children: [/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4583
4721
|
className: "dvw-tree-row",
|
|
4584
4722
|
"data-dvw-upload-directory": row.kind === "directory" ? row.path : void 0,
|
|
@@ -4656,7 +4794,11 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
4656
4794
|
onSelectDirectory,
|
|
4657
4795
|
onOpen,
|
|
4658
4796
|
onChange,
|
|
4659
|
-
onUpload
|
|
4797
|
+
onUpload,
|
|
4798
|
+
creating,
|
|
4799
|
+
onCreatingChange,
|
|
4800
|
+
onCreatingCancel,
|
|
4801
|
+
onCreatingSubmit
|
|
4660
4802
|
})] }, row.path)),
|
|
4661
4803
|
context && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
4662
4804
|
className: "dvw-context-menu",
|
|
@@ -4732,6 +4874,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
4732
4874
|
const [statuses, setStatuses] = (0, react.useState)(/* @__PURE__ */ new Map());
|
|
4733
4875
|
const [dropTarget, setDropTarget] = (0, react.useState)(false);
|
|
4734
4876
|
const [selectedDirectory, setSelectedDirectory] = (0, react.useState)("");
|
|
4877
|
+
const [creating, setCreating] = (0, react.useState)();
|
|
4735
4878
|
const picker = (0, react.useRef)(null);
|
|
4736
4879
|
(0, react.useEffect)(() => {
|
|
4737
4880
|
if (props.cwd) try {
|
|
@@ -4753,19 +4896,42 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
4753
4896
|
window.addEventListener("dvw-files-changed", handler);
|
|
4754
4897
|
return () => window.removeEventListener("dvw-files-changed", handler);
|
|
4755
4898
|
}, [refreshStatus, refreshStatusDebounced]);
|
|
4756
|
-
const
|
|
4757
|
-
const
|
|
4758
|
-
if (
|
|
4899
|
+
const startCreating = (kind) => {
|
|
4900
|
+
const directory = selectedDirectory;
|
|
4901
|
+
if (directory) setExpanded((current) => new Set(current).add(directory));
|
|
4902
|
+
setCreating({
|
|
4903
|
+
kind,
|
|
4904
|
+
directory,
|
|
4905
|
+
value: ""
|
|
4906
|
+
});
|
|
4907
|
+
};
|
|
4908
|
+
const submitCreating = async () => {
|
|
4909
|
+
if (creating === void 0) return;
|
|
4910
|
+
const value = creating.value.trim();
|
|
4911
|
+
if (value === "") {
|
|
4912
|
+
setCreating((current) => current && {
|
|
4913
|
+
...current,
|
|
4914
|
+
error: "请输入名称"
|
|
4915
|
+
});
|
|
4916
|
+
return;
|
|
4917
|
+
}
|
|
4918
|
+
const path = createdEntryPath(creating.directory, value);
|
|
4759
4919
|
try {
|
|
4760
4920
|
await api("fs.create", {
|
|
4761
4921
|
sessionId: props.sessionId,
|
|
4762
4922
|
path,
|
|
4763
|
-
kind
|
|
4923
|
+
kind: creating.kind
|
|
4764
4924
|
});
|
|
4925
|
+
const created = path;
|
|
4926
|
+
setCreating(void 0);
|
|
4927
|
+
setSelectedDirectory(creating.kind === "directory" ? created : creating.directory);
|
|
4765
4928
|
setRevision((x) => x + 1);
|
|
4766
4929
|
window.dispatchEvent(new Event("dvw-files-changed"));
|
|
4767
4930
|
} catch (error) {
|
|
4768
|
-
|
|
4931
|
+
setCreating((current) => current && {
|
|
4932
|
+
...current,
|
|
4933
|
+
error: error instanceof Error ? error.message : String(error)
|
|
4934
|
+
});
|
|
4769
4935
|
}
|
|
4770
4936
|
};
|
|
4771
4937
|
const upload = (0, react.useCallback)(async (directory, files) => {
|
|
@@ -4876,13 +5042,13 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
4876
5042
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4877
5043
|
className: "dvw-icon",
|
|
4878
5044
|
title: "新建文件",
|
|
4879
|
-
onClick: () =>
|
|
5045
|
+
onClick: () => startCreating("file"),
|
|
4880
5046
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { name: "new-file" })
|
|
4881
5047
|
}),
|
|
4882
5048
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
4883
5049
|
className: "dvw-icon",
|
|
4884
|
-
title: "
|
|
4885
|
-
onClick: () =>
|
|
5050
|
+
title: "新建文件夹",
|
|
5051
|
+
onClick: () => startCreating("directory"),
|
|
4886
5052
|
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)(Icon, { name: "new-folder" })
|
|
4887
5053
|
}),
|
|
4888
5054
|
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
@@ -4920,7 +5086,15 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
4920
5086
|
onSelectDirectory: setSelectedDirectory,
|
|
4921
5087
|
onOpen: props.onOpen,
|
|
4922
5088
|
onChange: () => setRevision((x) => x + 1),
|
|
4923
|
-
onUpload: (directory, files) => void upload(directory, files)
|
|
5089
|
+
onUpload: (directory, files) => void upload(directory, files),
|
|
5090
|
+
creating,
|
|
5091
|
+
onCreatingChange: (value) => setCreating((current) => current && {
|
|
5092
|
+
...current,
|
|
5093
|
+
value,
|
|
5094
|
+
error: void 0
|
|
5095
|
+
}),
|
|
5096
|
+
onCreatingCancel: () => setCreating(void 0),
|
|
5097
|
+
onCreatingSubmit: () => void submitCreating()
|
|
4924
5098
|
})
|
|
4925
5099
|
}, revision)] });
|
|
4926
5100
|
}
|
|
@@ -4928,6 +5102,10 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
4928
5102
|
function uploadDestination(selectedDirectory) {
|
|
4929
5103
|
return selectedDirectory ?? "";
|
|
4930
5104
|
}
|
|
5105
|
+
/** Join an inline-created entry name to the currently selected Explorer directory. */
|
|
5106
|
+
function createdEntryPath(directory, name) {
|
|
5107
|
+
return directory ? `${directory}/${name}` : name;
|
|
5108
|
+
}
|
|
4931
5109
|
/** Replace the final path component while preserving its workspace-relative directory. */
|
|
4932
5110
|
function renamedPath(path, name) {
|
|
4933
5111
|
return [...path.split("/").slice(0, -1), name].filter(Boolean).join("/");
|
|
@@ -5329,7 +5507,11 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
5329
5507
|
setStatus(nextStatus);
|
|
5330
5508
|
setCommits(nextCommits);
|
|
5331
5509
|
setError(void 0);
|
|
5332
|
-
}).catch((error) =>
|
|
5510
|
+
}).catch((error) => {
|
|
5511
|
+
setStatus(void 0);
|
|
5512
|
+
setCommits([]);
|
|
5513
|
+
setError(error instanceof ApiError && error.code === "not-repository" ? void 0 : String(error));
|
|
5514
|
+
});
|
|
5333
5515
|
}, [props.sessionId]);
|
|
5334
5516
|
const refreshDebounced = useDebouncedCallback(refresh, 500);
|
|
5335
5517
|
(0, react.useEffect)(refresh, [refresh]);
|
|
@@ -5598,6 +5780,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
5598
5780
|
const tabsRef = (0, react.useRef)(tabs);
|
|
5599
5781
|
tabsRef.current = tabs;
|
|
5600
5782
|
const workspaceRequests = (0, react.useRef)(new WorkspaceRequestScope());
|
|
5783
|
+
const loadingTabs = (0, react.useRef)(/* @__PURE__ */ new Set());
|
|
5601
5784
|
const dshDark = useDshDarkTheme();
|
|
5602
5785
|
const [theme, setTheme] = (0, react.useState)(() => {
|
|
5603
5786
|
const saved = localStorage.getItem("dvw:theme");
|
|
@@ -5620,61 +5803,24 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
5620
5803
|
window.addEventListener("keydown", onKey, true);
|
|
5621
5804
|
return () => window.removeEventListener("keydown", onKey, true);
|
|
5622
5805
|
}, [snapshot.visible]);
|
|
5623
|
-
const openForWorkspace =
|
|
5624
|
-
if (
|
|
5625
|
-
|
|
5626
|
-
|
|
5627
|
-
|
|
5628
|
-
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
}
|
|
5634
|
-
|
|
5635
|
-
const imageUrl = `/dsh-vscode/file?sessionId=${encodeURIComponent(targetSessionId)}&path=${encodeURIComponent(path)}`;
|
|
5636
|
-
if (!workspaceRequests.current.isCurrent(epoch)) return;
|
|
5637
|
-
setTabs((rows) => workspaceRequests.current.isCurrent(epoch) ? [...rows.filter((tab) => tab.path !== path), {
|
|
5638
|
-
path,
|
|
5639
|
-
content: "",
|
|
5640
|
-
draft: "",
|
|
5641
|
-
revision: "",
|
|
5642
|
-
size: 0,
|
|
5643
|
-
binary: false,
|
|
5644
|
-
tooLarge: false,
|
|
5645
|
-
dirty: false,
|
|
5646
|
-
imageUrl
|
|
5647
|
-
}] : rows);
|
|
5648
|
-
setActive(path);
|
|
5649
|
-
return;
|
|
5650
|
-
}
|
|
5651
|
-
try {
|
|
5652
|
-
const doc = await api("fs.read", {
|
|
5653
|
-
sessionId: targetSessionId,
|
|
5654
|
-
path
|
|
5655
|
-
});
|
|
5656
|
-
if (!workspaceRequests.current.isCurrent(epoch)) return;
|
|
5657
|
-
if (doc.binary || doc.tooLarge) {
|
|
5658
|
-
setError(doc.binary ? "二进制文件不能在文本编辑器中打开" : `文件超过 5 MiB:${path}`);
|
|
5659
|
-
return;
|
|
5660
|
-
}
|
|
5661
|
-
setTabs((rows) => workspaceRequests.current.isCurrent(epoch) ? [...rows.filter((tab) => tab.path !== path), {
|
|
5662
|
-
...doc,
|
|
5663
|
-
draft: doc.content,
|
|
5664
|
-
dirty: false,
|
|
5665
|
-
line,
|
|
5666
|
-
column,
|
|
5667
|
-
preview: /\.md$/i.test(path)
|
|
5668
|
-
}] : rows);
|
|
5669
|
-
setActive(path);
|
|
5670
|
-
} catch (error) {
|
|
5671
|
-
if (workspaceRequests.current.isCurrent(epoch)) setError(String(error));
|
|
5672
|
-
}
|
|
5806
|
+
const openForWorkspace = (path, line, column) => {
|
|
5807
|
+
if (tabsRef.current.find((tab) => tab.path === path)) setTabs((rows) => rows.map((tab) => tab.path === path ? {
|
|
5808
|
+
...tab,
|
|
5809
|
+
line,
|
|
5810
|
+
column
|
|
5811
|
+
} : tab));
|
|
5812
|
+
else setTabs((rows) => [...rows, {
|
|
5813
|
+
...unloadedTab(path),
|
|
5814
|
+
line,
|
|
5815
|
+
column
|
|
5816
|
+
}]);
|
|
5817
|
+
setActive(path);
|
|
5673
5818
|
};
|
|
5674
5819
|
(0, react.useEffect)(() => {
|
|
5675
5820
|
if (!snapshot.visible || sessionId === void 0) return;
|
|
5676
5821
|
const epoch = workspaceRequests.current.begin();
|
|
5677
5822
|
const cleared = resetWorkspaceDocuments();
|
|
5823
|
+
loadingTabs.current.clear();
|
|
5678
5824
|
setWorkspace(void 0);
|
|
5679
5825
|
setTabs(cleared.tabs);
|
|
5680
5826
|
tabsRef.current = cleared.tabs;
|
|
@@ -5690,13 +5836,16 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
5690
5836
|
if (parsed.view) service.show(parsed.view);
|
|
5691
5837
|
if (typeof parsed.panelHeight === "number") setPanelHeight(parsed.panelHeight);
|
|
5692
5838
|
if (typeof parsed.sideWidth === "number") setSideWidth(Math.max(210, Math.min(640, Math.round(parsed.sideWidth))));
|
|
5693
|
-
|
|
5839
|
+
const restored = restoreTabPaths(parsed.paths ?? []);
|
|
5840
|
+
setTabs(restored);
|
|
5841
|
+
setActive(restored.some((tab) => tab.path === parsed.active) ? parsed.active : restored.at(-1)?.path);
|
|
5694
5842
|
} catch {}
|
|
5695
5843
|
}).catch((error) => {
|
|
5696
5844
|
if (!controller.signal.aborted && workspaceRequests.current.isCurrent(epoch)) setError(String(error));
|
|
5697
5845
|
});
|
|
5698
5846
|
return () => {
|
|
5699
5847
|
controller.abort();
|
|
5848
|
+
loadingTabs.current.clear();
|
|
5700
5849
|
workspaceRequests.current.invalidate(epoch);
|
|
5701
5850
|
};
|
|
5702
5851
|
}, [snapshot.visible, sessionId]);
|
|
@@ -5704,6 +5853,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
5704
5853
|
if (workspace) localStorage.setItem(`dvw:${workspace.cwd}`, JSON.stringify({
|
|
5705
5854
|
view: snapshot.view,
|
|
5706
5855
|
paths: tabs.filter((t) => !t.path.startsWith("diff:")).map((t) => t.path),
|
|
5856
|
+
active,
|
|
5707
5857
|
panelHeight,
|
|
5708
5858
|
sideWidth
|
|
5709
5859
|
}));
|
|
@@ -5711,6 +5861,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
5711
5861
|
workspace,
|
|
5712
5862
|
snapshot.view,
|
|
5713
5863
|
tabs,
|
|
5864
|
+
active,
|
|
5714
5865
|
panelHeight,
|
|
5715
5866
|
sideWidth
|
|
5716
5867
|
]);
|
|
@@ -5718,8 +5869,12 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
5718
5869
|
if (!snapshot.visible || sessionId === void 0) return;
|
|
5719
5870
|
const protocol = location.protocol === "https:" ? "wss" : "ws";
|
|
5720
5871
|
const ws = new WebSocket(`${protocol}://${location.host}/dsh-vscode/ws/files?sessionId=${encodeURIComponent(sessionId)}`);
|
|
5721
|
-
ws.onmessage = () => {
|
|
5722
|
-
|
|
5872
|
+
ws.onmessage = (event) => {
|
|
5873
|
+
let paths = [];
|
|
5874
|
+
try {
|
|
5875
|
+
paths = JSON.parse(String(event.data)).paths ?? [];
|
|
5876
|
+
} catch {}
|
|
5877
|
+
window.dispatchEvent(new CustomEvent("dvw-files-changed", { detail: paths }));
|
|
5723
5878
|
setTabs((current) => current.map((tab) => tab.dirty ? {
|
|
5724
5879
|
...tab,
|
|
5725
5880
|
external: true
|
|
@@ -5727,9 +5882,49 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
5727
5882
|
};
|
|
5728
5883
|
return () => ws.close();
|
|
5729
5884
|
}, [snapshot.visible, sessionId]);
|
|
5730
|
-
|
|
5731
|
-
if (sessionId === void 0) return;
|
|
5732
|
-
|
|
5885
|
+
(0, react.useEffect)(() => {
|
|
5886
|
+
if (sessionId === void 0 || active === void 0) return;
|
|
5887
|
+
const tab = tabsRef.current.find((row) => row.path === active);
|
|
5888
|
+
if (tab === void 0 || tab.loaded !== false || loadingTabs.current.has(active)) return;
|
|
5889
|
+
const epoch = workspaceRequests.current.current();
|
|
5890
|
+
loadingTabs.current.add(active);
|
|
5891
|
+
if (/\.(?:avif|bmp|gif|ico|jpe?g|png|svg|webp)$/i.test(active)) {
|
|
5892
|
+
const imageUrl = `/dsh-vscode/file?sessionId=${encodeURIComponent(sessionId)}&path=${encodeURIComponent(active)}`;
|
|
5893
|
+
setTabs((rows) => rows.map((row) => row.path === active ? {
|
|
5894
|
+
...row,
|
|
5895
|
+
loaded: true,
|
|
5896
|
+
imageUrl
|
|
5897
|
+
} : row));
|
|
5898
|
+
loadingTabs.current.delete(active);
|
|
5899
|
+
return;
|
|
5900
|
+
}
|
|
5901
|
+
api("fs.read", {
|
|
5902
|
+
sessionId,
|
|
5903
|
+
path: active
|
|
5904
|
+
}).then((doc) => {
|
|
5905
|
+
if (!workspaceRequests.current.isCurrent(epoch)) return;
|
|
5906
|
+
if (doc.binary || doc.tooLarge) {
|
|
5907
|
+
setTabs((rows) => rows.filter((row) => row.path !== active));
|
|
5908
|
+
setActive((current) => current === active ? void 0 : current);
|
|
5909
|
+
setError(doc.binary ? "二进制文件不能在文本编辑器中打开" : `文件超过 5 MiB:${active}`);
|
|
5910
|
+
return;
|
|
5911
|
+
}
|
|
5912
|
+
setTabs((rows) => rows.map((row) => row.path === active ? {
|
|
5913
|
+
...row,
|
|
5914
|
+
...doc,
|
|
5915
|
+
draft: doc.content,
|
|
5916
|
+
loaded: true
|
|
5917
|
+
} : row));
|
|
5918
|
+
}).catch((error) => {
|
|
5919
|
+
if (workspaceRequests.current.isCurrent(epoch)) setError(String(error));
|
|
5920
|
+
}).finally(() => loadingTabs.current.delete(active));
|
|
5921
|
+
}, [
|
|
5922
|
+
active,
|
|
5923
|
+
sessionId,
|
|
5924
|
+
tabs
|
|
5925
|
+
]);
|
|
5926
|
+
const open = (path, line, column) => {
|
|
5927
|
+
if (sessionId !== void 0) openForWorkspace(path, line, column);
|
|
5733
5928
|
};
|
|
5734
5929
|
(0, react.useEffect)(() => {
|
|
5735
5930
|
const listener = (event) => void open(event.detail);
|
|
@@ -5849,21 +6044,15 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
5849
6044
|
chatVisible && /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("aside", {
|
|
5850
6045
|
className: "dvw-chat",
|
|
5851
6046
|
children: [
|
|
5852
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6047
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PanelResizer, {
|
|
5853
6048
|
className: "dvw-chat-resizer",
|
|
5854
|
-
|
|
5855
|
-
|
|
5856
|
-
|
|
5857
|
-
|
|
5858
|
-
|
|
5859
|
-
|
|
5860
|
-
|
|
5861
|
-
window.removeEventListener("pointermove", move);
|
|
5862
|
-
window.removeEventListener("pointerup", up);
|
|
5863
|
-
};
|
|
5864
|
-
window.addEventListener("pointermove", move);
|
|
5865
|
-
window.addEventListener("pointerup", up);
|
|
5866
|
-
}
|
|
6049
|
+
label: "拖动调整 DSH 对话栏宽度",
|
|
6050
|
+
width: chatWidth,
|
|
6051
|
+
min: 400,
|
|
6052
|
+
max: 720,
|
|
6053
|
+
defaultWidth: 420,
|
|
6054
|
+
direction: -1,
|
|
6055
|
+
onWidth: setChatWidth
|
|
5867
6056
|
}),
|
|
5868
6057
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("header", {
|
|
5869
6058
|
className: "dvw-chat-head",
|
|
@@ -6051,21 +6240,15 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
6051
6240
|
})
|
|
6052
6241
|
]
|
|
6053
6242
|
}),
|
|
6054
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
6243
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(PanelResizer, {
|
|
6055
6244
|
className: "dvw-side-resizer",
|
|
6056
|
-
|
|
6057
|
-
|
|
6058
|
-
|
|
6059
|
-
|
|
6060
|
-
|
|
6061
|
-
|
|
6062
|
-
|
|
6063
|
-
window.removeEventListener("pointermove", move);
|
|
6064
|
-
window.removeEventListener("pointerup", up);
|
|
6065
|
-
};
|
|
6066
|
-
window.addEventListener("pointermove", move);
|
|
6067
|
-
window.addEventListener("pointerup", up);
|
|
6068
|
-
}
|
|
6245
|
+
label: "拖动调整源码管理侧边栏宽度",
|
|
6246
|
+
width: sideWidth,
|
|
6247
|
+
min: 210,
|
|
6248
|
+
max: 640,
|
|
6249
|
+
defaultWidth: 210,
|
|
6250
|
+
direction: 1,
|
|
6251
|
+
onWidth: setSideWidth
|
|
6069
6252
|
}),
|
|
6070
6253
|
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("main", {
|
|
6071
6254
|
className: "dvw-main",
|
|
@@ -6313,7 +6496,7 @@ Please report this to https://github.com/markedjs/marked.`, e) {
|
|
|
6313
6496
|
body[data-ds-dark-theme] .dvw-overlay,.dvw-overlay[data-dvw-theme=dark]{color-scheme:dark}
|
|
6314
6497
|
.dvw-overlay[data-dvw-theme=dark]{--dvw-base:#151517;--dvw-surface-1:#232324;--dvw-surface-2:#2c2c2e;--dvw-surface-3:#353638;--dvw-text:#f9fafb;--dvw-text-2:#cfd3d6;--dvw-text-3:#adb2b8;--dvw-border:#ffffff1f;--dvw-border-soft:#ffffff29;--dvw-hover:#ffffff14;--dvw-active:#ffffff24;--dvw-accent:#679efe;--dvw-error:#f25a5a;--dvw-success:#22c55e;--dvw-warn:#f59e0b}
|
|
6315
6498
|
.dvw-overlay[data-dvw-theme=light]{--dvw-base:#fff;--dvw-surface-1:#fff;--dvw-surface-2:#fff;--dvw-surface-3:#fff;--dvw-text:#0f1115;--dvw-text-2:#61666b;--dvw-text-3:#81858c;--dvw-border:#0000001a;--dvw-border-soft:#0000001f;--dvw-hover:#2631480f;--dvw-active:#2631481a;--dvw-accent:#4176e6;--dvw-error:#ec1313;--dvw-success:#22c55e;--dvw-warn:#f59e0b;color-scheme:light}
|
|
6316
|
-
.dvw-overlay *{box-sizing:border-box}.dvw-activity{grid-row:1/3;background:var(--dvw-base);border-right:1px solid var(--dvw-border-soft);display:flex;flex-direction:column;align-items:center}.dvw-act{width:48px;height:48px;border:0;border-left:2px solid transparent;background:transparent;color:var(--dvw-text-3);font-size:22px;cursor:pointer}.dvw-act:hover,.dvw-act[data-active=true]{color:var(--dvw-text)}.dvw-act[data-active=true]{border-left-color:var(--dvw-accent)}.dvw-act.dsh{margin-top:auto}.dvw-side{grid-column:2;grid-row:1/3;min-width:0;width:100%;background:var(--dvw-surface-1);border-right:1px solid var(--dvw-border);display:flex;flex-direction:column}.dvw-side-resizer{grid-column:2;grid-row:1/3;justify-self:end;width:
|
|
6499
|
+
.dvw-overlay *{box-sizing:border-box}.dvw-activity{grid-row:1/3;background:var(--dvw-base);border-right:1px solid var(--dvw-border-soft);display:flex;flex-direction:column;align-items:center}.dvw-act{width:48px;height:48px;border:0;border-left:2px solid transparent;background:transparent;color:var(--dvw-text-3);font-size:22px;cursor:pointer}.dvw-act:hover,.dvw-act[data-active=true]{color:var(--dvw-text)}.dvw-act[data-active=true]{border-left-color:var(--dvw-accent)}.dvw-act.dsh{margin-top:auto}.dvw-side{grid-column:2;grid-row:1/3;min-width:0;width:100%;background:var(--dvw-surface-1);border-right:1px solid var(--dvw-border);display:flex;flex-direction:column}.dvw-side-resizer{grid-column:2;grid-row:1/3;justify-self:end;width:4px;height:100%;z-index:4;cursor:ew-resize;transform:translateX(2px);touch-action:none}.dvw-side-resizer:hover,.dvw-side-resizer:focus-visible,.dvw-side-resizer[data-dragging=true]{background:var(--dvw-accent)}.dvw-side-head{height:36px;display:flex;align-items:center;padding:0 12px;text-transform:uppercase;font-size:11px;letter-spacing:.4px}.dvw-toolbar{margin-left:auto;display:flex;gap:2px}.dvw-icon{border:0;background:transparent;color:var(--dvw-text-2);border-radius:4px;min-width:24px;height:24px;display:inline-grid;place-items:center;cursor:pointer}.dvw-icon:hover{background:var(--dvw-hover);color:var(--dvw-text)}.dvw-icon:disabled{opacity:.45;cursor:default}.dvw-file-picker{display:none}.dvw-tree,.dvw-results,.dvw-git{overflow:auto;flex:1}.dvw-tree[data-drop-target=true]{outline:1px dashed var(--dvw-accent);outline-offset:-3px}.dvw-tree-row{display:flex;align-items:center;height:24px;padding-right:6px;cursor:pointer;white-space:nowrap}.dvw-tree-row:hover{background:var(--dvw-hover)}.dvw-tree-row[data-selected=true],.dvw-tree-row[data-drop-target=true]{background:var(--dvw-active)}.dvw-chevron{width:16px;flex:none;text-align:center;color:var(--dvw-text-3)}.dvw-file-icon{width:18px;flex:none;color:var(--dvw-text-2)}.dvw-file-icon.folder{color:var(--dvw-accent)}.dvw-tree-name{overflow:hidden;text-overflow:ellipsis}.dvw-tree-rename,.dvw-tree-create-input{min-width:0;flex:1;height:20px;border:1px solid var(--dvw-accent);border-radius:0;background:var(--dvw-surface-1);color:var(--dvw-text);padding:0 3px;font:inherit;letter-spacing:0;outline:0}.dvw-tree-create-row{cursor:text}.dvw-tree-create-row:hover{background:transparent}.dvw-tree-create-input::placeholder{color:var(--dvw-text-3)}.dvw-tree-create-input[aria-invalid=true]{border-color:var(--dvw-error)}.dvw-tree-create-error{min-height:20px;padding-top:2px;padding-right:6px;padding-bottom:3px;color:var(--dvw-error);font-size:11px;line-height:15px;white-space:normal;overflow-wrap:anywhere}.dvw-tree-status{margin-left:auto;padding-left:6px;font-size:11px;font-weight:600;color:var(--dvw-warn)}.dvw-tree-status[data-status=M]{color:var(--dvw-warn)}.dvw-tree-status[data-status=A]{color:var(--dvw-success)}.dvw-tree-status[data-status=D]{color:var(--dvw-error)}.dvw-context-menu{position:fixed;z-index:40;min-width:148px;padding:4px;border:1px solid var(--dvw-border);border-radius:5px;background:var(--dvw-surface-3);box-shadow:0 6px 20px rgba(0,0,0,.3)}.dvw-context-menu button{width:100%;height:28px;border:0;border-radius:3px;background:transparent;color:var(--dvw-text);display:flex;align-items:center;gap:8px;padding:0 8px;text-align:left;font:inherit;cursor:pointer}.dvw-context-menu button:hover{background:var(--dvw-hover)}.dvw-context-menu .dvw-context-delete{color:var(--dvw-error)}
|
|
6317
6500
|
.dvw-main{grid-column:3;grid-row:1;display:flex;min-width:0;min-height:0;flex-direction:column;background:var(--dvw-surface-1)}.dvw-tabs{height:36px;background:var(--dvw-base);display:flex;overflow-x:auto}.dvw-tab{height:36px;min-width:110px;max-width:260px;border:0;border-right:1px solid var(--dvw-border-soft);background:var(--dvw-base);color:var(--dvw-text-2);padding:0 8px 0 12px;display:flex;align-items:center;gap:8px;cursor:pointer}.dvw-tab[data-active=true]{background:var(--dvw-surface-1);color:var(--dvw-text);border-top:1px solid var(--dvw-accent)}.dvw-tab-name{overflow:hidden;text-overflow:ellipsis;flex:1;text-align:left}.dvw-editor{position:relative;flex:1;min-height:0}.dvw-editor-toolbar{position:absolute;z-index:3;top:0;right:0;left:0;height:36px;display:flex;align-items:center;justify-content:flex-end;gap:4px;padding:0 10px;border-bottom:1px solid var(--dvw-border-soft);background:var(--dvw-surface-1)}.dvw-editor-body{position:absolute;inset:0;min-height:0}.dvw-editor-body[data-toolbar=true]{top:36px}.dvw-mode-button{height:27px;padding:0 10px;display:flex;align-items:center;gap:6px;border:1px solid transparent;border-radius:5px;background:transparent;color:var(--dvw-text-2);cursor:pointer}.dvw-mode-button:hover{background:var(--dvw-hover)}.dvw-mode-button[data-active=true]{border-color:var(--dvw-border);background:var(--dvw-active);color:var(--dvw-text)}.dvw-empty{height:100%;display:grid;place-items:center;color:var(--dvw-text-3);text-align:center}.dvw-empty strong{font-size:24px;color:var(--dvw-text-2)}.dvw-message{padding:12px;color:var(--dvw-warn)}
|
|
6318
6501
|
.dvw-bottom{grid-column:3;grid-row:2;height:260px;min-height:120px;border-top:1px solid var(--dvw-border);background:var(--dvw-base);display:flex;flex-direction:column}.dvw-bottom-head{height:35px;display:flex;align-items:center;gap:14px;padding:0 12px}.dvw-bottom-title{border:0;border-bottom:1px solid var(--dvw-text);background:transparent;color:var(--dvw-text);height:35px}.dvw-bottom-body{flex:1;min-height:0}.dvw-status{grid-column:1/4;grid-row:3;background:var(--dvw-accent);color:#fff;display:flex;align-items:center;padding:0 8px;gap:18px;font-size:12px}.dvw-theme-control{position:relative;margin-left:auto}.dvw-theme-trigger{height:22px;min-width:112px;display:flex;align-items:center;gap:7px;padding:0 8px;border:0;border-radius:5px;background:color-mix(in srgb,#000 17%,transparent);color:#fff;cursor:pointer}.dvw-theme-trigger:hover{background:color-mix(in srgb,#000 27%,transparent)}.dvw-theme-orb{width:13px;height:13px;border:2px solid #fff;border-radius:50%;background:linear-gradient(90deg,#17181c 50%,#fff 50%)}.dvw-theme-orb.dark{background:#17181c}.dvw-theme-orb.light{background:#fff}.dvw-theme-menu{position:absolute;right:0;bottom:29px;width:224px;padding:6px;border:1px solid var(--dvw-border);border-radius:10px;background:var(--dvw-surface-3);box-shadow:0 10px 35px rgba(0,0,0,.28);color:var(--dvw-text)}.dvw-theme-menu button{width:100%;min-height:48px;border:0;border-radius:7px;background:transparent;color:inherit;display:grid;grid-template-columns:30px 1fr 20px;align-items:center;text-align:left;padding:6px;cursor:pointer}.dvw-theme-menu button:hover,.dvw-theme-menu button[aria-checked=true]{background:var(--dvw-hover)}.dvw-theme-menu strong,.dvw-theme-menu small{display:block}.dvw-theme-menu small{color:var(--dvw-text-3);margin-top:2px}.dvw-theme-swatch{width:22px;height:22px;border-radius:6px;border:1px solid var(--dvw-border);background:linear-gradient(135deg,#17181c 0 50%,#fff 50%)}.dvw-theme-swatch.dark{background:#17181c}.dvw-theme-swatch.light{background:#fff}
|
|
6319
6502
|
.dvw-search-form{padding:8px;display:grid;gap:6px}.dvw-input,.dvw-textarea,.dvw-select{width:100%;border:1px solid var(--dvw-border);background:var(--dvw-surface-2);color:var(--dvw-text);padding:5px 7px;outline:none}.dvw-input:focus,.dvw-textarea:focus,.dvw-select:focus{border-color:var(--dvw-accent)}.dvw-options{display:flex;align-items:center;gap:8px;font-size:11px}.dvw-result-file{padding:5px 8px;font-weight:600}.dvw-result{padding:4px 8px 4px 20px;cursor:pointer;display:flex;gap:8px}.dvw-result:hover{background:var(--dvw-hover)}.dvw-line{color:var(--dvw-text-3);min-width:30px;text-align:right}.dvw-preview{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}
|
|
@@ -6332,8 +6515,18 @@ body[data-ds-dark-theme] .dvw-overlay,.dvw-overlay[data-dvw-theme=dark]{color-sc
|
|
|
6332
6515
|
.dvw-chat-head{height:36px;display:flex;align-items:center;justify-content:space-between;padding:0 6px 0 12px;border-bottom:1px solid var(--dvw-border);background:var(--dvw-base);font-weight:600}
|
|
6333
6516
|
.dvw-chat-head>span{display:flex;align-items:center;gap:7px}.dvw-chat-body{height:calc(100% - 36px);background:var(--dvw-base)}
|
|
6334
6517
|
.dvw-dsh-mark{display:block}
|
|
6335
|
-
.dvw-chat-resizer{position:fixed;top:
|
|
6336
|
-
.dvw-chat-resizer:hover,.dvw-chat-resizer:
|
|
6518
|
+
.dvw-chat-resizer{position:fixed;top:36px;right:calc(var(--dvw-chat-width) - 2px);bottom:0;width:4px;z-index:4;cursor:ew-resize;touch-action:none}
|
|
6519
|
+
.dvw-chat-resizer:hover,.dvw-chat-resizer:focus-visible,.dvw-chat-resizer[data-dragging=true]{background:var(--dvw-accent)}
|
|
6520
|
+
.dvw-side-resizer,.dvw-chat-resizer{width:10px;cursor:ew-resize;touch-action:none;background:transparent}
|
|
6521
|
+
.dvw-side-resizer{position:relative;transform:translateX(5px);z-index:22}
|
|
6522
|
+
.dvw-chat-resizer{position:fixed;top:36px;right:calc(var(--dvw-chat-width) - 5px);z-index:22}
|
|
6523
|
+
.dvw-side-resizer::after,.dvw-chat-resizer::after{content:"";position:absolute;top:0;bottom:0;left:4px;width:2px;background:var(--dvw-border)}
|
|
6524
|
+
.dvw-chat-resizer::after{left:1px;width:6px}
|
|
6525
|
+
.dvw-side-resizer:hover,.dvw-side-resizer:focus-visible,.dvw-side-resizer[data-dragging=true],.dvw-chat-resizer:hover,.dvw-chat-resizer:focus-visible,.dvw-chat-resizer[data-dragging=true]{background:transparent}
|
|
6526
|
+
.dvw-side-resizer:hover::after,.dvw-side-resizer:focus-visible::after,.dvw-side-resizer[data-dragging=true]::after,.dvw-chat-resizer:hover::after,.dvw-chat-resizer:focus-visible::after,.dvw-chat-resizer[data-dragging=true]::after{background:var(--dvw-accent)}
|
|
6527
|
+
.dvw-side{border-right-color:transparent}.dvw-chat,[data-dvw-conversation-panel]{border-left-color:transparent!important}
|
|
6528
|
+
.dvw-side-resizer::after,.dvw-chat-resizer::after{background:transparent}.dvw-side-resizer::after{left:3px;width:3px}
|
|
6529
|
+
.dvw-side-resizer:hover::after,.dvw-side-resizer:focus-visible::after,.dvw-side-resizer[data-dragging=true]::after,.dvw-chat-resizer:hover::after,.dvw-chat-resizer:focus-visible::after,.dvw-chat-resizer[data-dragging=true]::after{background:var(--dvw-accent)}
|
|
6337
6530
|
.dvw-chat-toggle{position:absolute;z-index:5;top:6px;right:6px;border:1px solid var(--dvw-border);background:var(--dvw-base)}
|
|
6338
6531
|
.dvw-overlay:not([data-dvw-chat=true]) .dvw-tabs{padding-right:36px}
|
|
6339
6532
|
[data-dvw-conversation-panel]{position:fixed!important;top:36px!important;right:0!important;bottom:var(--dvw-status-height,24px)!important;left:auto!important;width:var(--dvw-chat-width)!important;height:auto!important;min-width:0!important;z-index:21!important;border-left:1px solid var(--dsw-alias-border-l2)!important;box-shadow:none!important}
|