@bendyline/docblocks-react 2.1.0 → 2.1.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -3
- package/dist/ExportDialog-VYATD5UC.js +9 -0
- package/dist/{ExportToolbarControls-GHAOJMH6.js → ExportToolbarControls-5HUE3LSX.js} +69 -40
- package/dist/{GitToolbarControl-GNMRVKWQ.js → GitToolbarControl-FW3BZFXV.js} +2 -3
- package/dist/{GitUI-VHOBQY43.js → GitUI-GMH3PAYL.js} +3 -4
- package/dist/{LazyEditorShell-EF2BWRXU.js → LazyEditorShell-RF54B5UD.js} +0 -1
- package/dist/{ShareDialog-63ENBEDZ.js → ShareDialog-PAMOQQFB.js} +0 -1
- package/dist/{chunk-UNYZQXWR.js → chunk-3CZ27FOA.js} +45 -10
- package/dist/{chunk-FEWQUQML.js → chunk-3QSZY74C.js} +1 -2
- package/dist/chunk-BI7NVU6T.js +31 -0
- package/dist/{chunk-VHDP4IPL.js → chunk-BPGEBGAN.js} +0 -1
- package/dist/{chunk-DD4VFJQI.js → chunk-EBWYGTN7.js} +2 -1
- package/dist/{chunk-ZI56BNB7.js → chunk-GHQ4X7KM.js} +27 -7
- package/dist/{chunk-5A4KEWKT.js → chunk-HFYPTTCH.js} +0 -1
- package/dist/{chunk-FMGTHSTX.js → chunk-LG6HAWCK.js} +0 -1
- package/dist/{chunk-57ZJJOC5.js → chunk-TFMO7EVO.js} +0 -1
- package/dist/{chunk-4XXSWN3T.js → chunk-YBEYTVU2.js} +0 -1
- package/dist/editor.js +1 -2
- package/dist/export/index.d.ts +18 -8
- package/dist/export/index.js +10 -7
- package/dist/index.d.ts +16 -7
- package/dist/index.js +346 -97
- package/dist/run-export-Z5BVFLIR.js +9 -0
- package/dist/settings/index.js +2 -3
- package/package.json +8 -8
- package/src/styles/docblocks.css +448 -9
- package/dist/ExportDialog-7LDIXJZ3.js +0 -10
- package/dist/ExportDialog-7LDIXJZ3.js.map +0 -1
- package/dist/ExportToolbarControls-GHAOJMH6.js.map +0 -1
- package/dist/GitToolbarControl-GNMRVKWQ.js.map +0 -1
- package/dist/GitUI-VHOBQY43.js.map +0 -1
- package/dist/LazyEditorShell-EF2BWRXU.js.map +0 -1
- package/dist/ShareDialog-63ENBEDZ.js.map +0 -1
- package/dist/chunk-4XXSWN3T.js.map +0 -1
- package/dist/chunk-57ZJJOC5.js.map +0 -1
- package/dist/chunk-5A4KEWKT.js.map +0 -1
- package/dist/chunk-DD4VFJQI.js.map +0 -1
- package/dist/chunk-FEWQUQML.js.map +0 -1
- package/dist/chunk-FMGTHSTX.js.map +0 -1
- package/dist/chunk-UNYZQXWR.js.map +0 -1
- package/dist/chunk-VHDP4IPL.js.map +0 -1
- package/dist/chunk-ZI56BNB7.js.map +0 -1
- package/dist/editor.js.map +0 -1
- package/dist/export/index.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/run-export-ICTZITXC.js +0 -10
- package/dist/run-export-ICTZITXC.js.map +0 -1
- package/dist/settings/index.js.map +0 -1
package/dist/index.js
CHANGED
|
@@ -6,7 +6,10 @@ import {
|
|
|
6
6
|
conflictedPaths,
|
|
7
7
|
isFileDirty,
|
|
8
8
|
useGitContext
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-HFYPTTCH.js";
|
|
10
|
+
import {
|
|
11
|
+
updateExportTargetExtension
|
|
12
|
+
} from "./chunk-BI7NVU6T.js";
|
|
10
13
|
import {
|
|
11
14
|
AccentColorSettings,
|
|
12
15
|
DB_CHROME_COLORS,
|
|
@@ -20,25 +23,25 @@ import {
|
|
|
20
23
|
saveAccentColor,
|
|
21
24
|
saveThemePreference,
|
|
22
25
|
saveWriteCanvasPreferences
|
|
23
|
-
} from "./chunk-
|
|
26
|
+
} from "./chunk-3QSZY74C.js";
|
|
24
27
|
import {
|
|
25
28
|
pickEmptyDocumentPrompt
|
|
26
|
-
} from "./chunk-
|
|
29
|
+
} from "./chunk-BPGEBGAN.js";
|
|
27
30
|
import {
|
|
28
31
|
ExportDialog
|
|
29
|
-
} from "./chunk-
|
|
32
|
+
} from "./chunk-3CZ27FOA.js";
|
|
30
33
|
import {
|
|
31
34
|
buildExportFilename,
|
|
32
35
|
runExport
|
|
33
|
-
} from "./chunk-
|
|
34
|
-
import "./chunk-
|
|
36
|
+
} from "./chunk-GHQ4X7KM.js";
|
|
37
|
+
import "./chunk-YBEYTVU2.js";
|
|
35
38
|
import {
|
|
36
39
|
Dialog
|
|
37
|
-
} from "./chunk-
|
|
40
|
+
} from "./chunk-LG6HAWCK.js";
|
|
38
41
|
import {
|
|
39
42
|
DEFAULT_OPTIONS,
|
|
40
43
|
loadLastExportOptions
|
|
41
|
-
} from "./chunk-
|
|
44
|
+
} from "./chunk-EBWYGTN7.js";
|
|
42
45
|
|
|
43
46
|
// src/FileExplorer/FileExplorer.tsx
|
|
44
47
|
import { useCallback as useCallback3, useEffect as useEffect3, useMemo, useRef as useRef3, useState as useState3 } from "react";
|
|
@@ -1291,11 +1294,11 @@ function FileExplorer({
|
|
|
1291
1294
|
disabled: newItemCreationPending,
|
|
1292
1295
|
onClick: () => {
|
|
1293
1296
|
setNewItemError(null);
|
|
1294
|
-
setNewItemType("
|
|
1297
|
+
setNewItemType("directory");
|
|
1295
1298
|
},
|
|
1296
|
-
title: "New
|
|
1297
|
-
"aria-label": "New
|
|
1298
|
-
children: /* @__PURE__ */ jsx3(
|
|
1299
|
+
title: "New Folder",
|
|
1300
|
+
"aria-label": "New Folder",
|
|
1301
|
+
children: /* @__PURE__ */ jsx3(NewFolderIcon, {})
|
|
1299
1302
|
}
|
|
1300
1303
|
),
|
|
1301
1304
|
/* @__PURE__ */ jsx3(
|
|
@@ -1305,11 +1308,11 @@ function FileExplorer({
|
|
|
1305
1308
|
disabled: newItemCreationPending,
|
|
1306
1309
|
onClick: () => {
|
|
1307
1310
|
setNewItemError(null);
|
|
1308
|
-
setNewItemType("
|
|
1311
|
+
setNewItemType("file");
|
|
1309
1312
|
},
|
|
1310
|
-
title: "New
|
|
1311
|
-
"aria-label": "New
|
|
1312
|
-
children: /* @__PURE__ */ jsx3(
|
|
1313
|
+
title: "New File",
|
|
1314
|
+
"aria-label": "New File",
|
|
1315
|
+
children: /* @__PURE__ */ jsx3(NewFileIcon, {})
|
|
1313
1316
|
}
|
|
1314
1317
|
)
|
|
1315
1318
|
] })
|
|
@@ -1469,12 +1472,18 @@ function WorkspacePicker({
|
|
|
1469
1472
|
}) {
|
|
1470
1473
|
const [workspaces, setWorkspaces] = useState4([]);
|
|
1471
1474
|
const [isOpen, setIsOpen] = useState4(false);
|
|
1475
|
+
const [creatingNew, setCreatingNew] = useState4(false);
|
|
1476
|
+
const [newWorkspaceName, setNewWorkspaceName] = useState4("");
|
|
1477
|
+
const [newWorkspaceError, setNewWorkspaceError] = useState4(null);
|
|
1478
|
+
const [newWorkspacePending, setNewWorkspacePending] = useState4(false);
|
|
1472
1479
|
const pickerRef = useRef4(null);
|
|
1473
1480
|
useEffect4(() => {
|
|
1474
1481
|
if (!isOpen) return;
|
|
1475
1482
|
function handleOutsideClick(e) {
|
|
1476
1483
|
if (pickerRef.current && !pickerRef.current.contains(e.target)) {
|
|
1477
1484
|
setIsOpen(false);
|
|
1485
|
+
setCreatingNew(false);
|
|
1486
|
+
setNewWorkspaceError(null);
|
|
1478
1487
|
}
|
|
1479
1488
|
}
|
|
1480
1489
|
document.addEventListener("mousedown", handleOutsideClick);
|
|
@@ -1497,8 +1506,34 @@ function WorkspacePicker({
|
|
|
1497
1506
|
},
|
|
1498
1507
|
[onSelect]
|
|
1499
1508
|
);
|
|
1509
|
+
const handleStartCreateNew = useCallback4(() => {
|
|
1510
|
+
const existingNames = new Set(workspaces.map((workspace) => workspace.name.toLowerCase()));
|
|
1511
|
+
let suffix = workspaces.length + 1;
|
|
1512
|
+
while (existingNames.has(`workspace ${suffix}`.toLowerCase())) suffix += 1;
|
|
1513
|
+
setNewWorkspaceName(`Workspace ${suffix}`);
|
|
1514
|
+
setNewWorkspaceError(null);
|
|
1515
|
+
setCreatingNew(true);
|
|
1516
|
+
}, [workspaces]);
|
|
1517
|
+
const handleCancelCreateNew = useCallback4(() => {
|
|
1518
|
+
setCreatingNew(false);
|
|
1519
|
+
setNewWorkspaceName("");
|
|
1520
|
+
setNewWorkspaceError(null);
|
|
1521
|
+
}, []);
|
|
1500
1522
|
const handleCreateNew = useCallback4(async () => {
|
|
1501
|
-
|
|
1523
|
+
if (newWorkspacePending) return;
|
|
1524
|
+
const name = newWorkspaceName.trim();
|
|
1525
|
+
if (!name) {
|
|
1526
|
+
setNewWorkspaceError("Enter a workspace name.");
|
|
1527
|
+
return;
|
|
1528
|
+
}
|
|
1529
|
+
if (name.length > 80) {
|
|
1530
|
+
setNewWorkspaceError("Workspace names must be 80 characters or fewer.");
|
|
1531
|
+
return;
|
|
1532
|
+
}
|
|
1533
|
+
if (workspaces.some((workspace) => workspace.name.toLowerCase() === name.toLowerCase())) {
|
|
1534
|
+
setNewWorkspaceError("A workspace with that name already exists.");
|
|
1535
|
+
return;
|
|
1536
|
+
}
|
|
1502
1537
|
const id = `ws-${Date.now()}`;
|
|
1503
1538
|
const descriptor = {
|
|
1504
1539
|
id,
|
|
@@ -1506,11 +1541,21 @@ function WorkspacePicker({
|
|
|
1506
1541
|
type: "indexeddb",
|
|
1507
1542
|
lastOpened: (/* @__PURE__ */ new Date()).toISOString()
|
|
1508
1543
|
};
|
|
1509
|
-
|
|
1510
|
-
|
|
1511
|
-
|
|
1512
|
-
|
|
1513
|
-
|
|
1544
|
+
setNewWorkspacePending(true);
|
|
1545
|
+
setNewWorkspaceError(null);
|
|
1546
|
+
try {
|
|
1547
|
+
await saveWorkspace(descriptor);
|
|
1548
|
+
await refresh();
|
|
1549
|
+
onSelect(descriptor);
|
|
1550
|
+
setCreatingNew(false);
|
|
1551
|
+
setNewWorkspaceName("");
|
|
1552
|
+
setIsOpen(false);
|
|
1553
|
+
} catch {
|
|
1554
|
+
setNewWorkspaceError("The workspace could not be created. Try again.");
|
|
1555
|
+
} finally {
|
|
1556
|
+
setNewWorkspacePending(false);
|
|
1557
|
+
}
|
|
1558
|
+
}, [newWorkspaceName, newWorkspacePending, onSelect, refresh, workspaces]);
|
|
1514
1559
|
const activeWs = workspaces.find((w) => w.id === activeWorkspaceId);
|
|
1515
1560
|
const activeWorkspaceName = activeWs?.name ?? "No workspace";
|
|
1516
1561
|
return /* @__PURE__ */ jsxs4("div", { ref: pickerRef, className: `db-workspace-picker ${className ?? ""}`, children: [
|
|
@@ -1518,7 +1563,11 @@ function WorkspacePicker({
|
|
|
1518
1563
|
"button",
|
|
1519
1564
|
{
|
|
1520
1565
|
className: "db-workspace-picker-btn",
|
|
1521
|
-
onClick: () =>
|
|
1566
|
+
onClick: () => {
|
|
1567
|
+
const nextOpen = !isOpen;
|
|
1568
|
+
setIsOpen(nextOpen);
|
|
1569
|
+
if (!nextOpen) handleCancelCreateNew();
|
|
1570
|
+
},
|
|
1522
1571
|
title: "Switch workspace",
|
|
1523
1572
|
"aria-label": `Switch workspace, current: ${activeWorkspaceName}`,
|
|
1524
1573
|
children: [
|
|
@@ -1551,10 +1600,57 @@ function WorkspacePicker({
|
|
|
1551
1600
|
ws.id
|
|
1552
1601
|
)),
|
|
1553
1602
|
/* @__PURE__ */ jsx4("div", { className: "db-workspace-dropdown-divider" }),
|
|
1554
|
-
!electron &&
|
|
1603
|
+
!electron && (creatingNew ? /* @__PURE__ */ jsxs4(
|
|
1604
|
+
"form",
|
|
1605
|
+
{
|
|
1606
|
+
className: "db-workspace-create",
|
|
1607
|
+
"aria-busy": newWorkspacePending,
|
|
1608
|
+
onSubmit: (event) => {
|
|
1609
|
+
event.preventDefault();
|
|
1610
|
+
void handleCreateNew();
|
|
1611
|
+
},
|
|
1612
|
+
children: [
|
|
1613
|
+
/* @__PURE__ */ jsx4("label", { className: "db-workspace-create-label", htmlFor: "db-new-workspace-name", children: "Workspace name" }),
|
|
1614
|
+
/* @__PURE__ */ jsx4(
|
|
1615
|
+
"input",
|
|
1616
|
+
{
|
|
1617
|
+
id: "db-new-workspace-name",
|
|
1618
|
+
className: "db-workspace-create-input",
|
|
1619
|
+
value: newWorkspaceName,
|
|
1620
|
+
maxLength: 80,
|
|
1621
|
+
disabled: newWorkspacePending,
|
|
1622
|
+
"aria-invalid": newWorkspaceError !== null,
|
|
1623
|
+
"aria-describedby": newWorkspaceError ? "db-new-workspace-error" : void 0,
|
|
1624
|
+
autoFocus: true,
|
|
1625
|
+
onChange: (event) => {
|
|
1626
|
+
setNewWorkspaceName(event.target.value);
|
|
1627
|
+
setNewWorkspaceError(null);
|
|
1628
|
+
},
|
|
1629
|
+
onKeyDown: (event) => {
|
|
1630
|
+
if (event.key === "Escape") handleCancelCreateNew();
|
|
1631
|
+
}
|
|
1632
|
+
}
|
|
1633
|
+
),
|
|
1634
|
+
newWorkspaceError && /* @__PURE__ */ jsx4("p", { id: "db-new-workspace-error", className: "db-workspace-create-error", role: "alert", children: newWorkspaceError }),
|
|
1635
|
+
/* @__PURE__ */ jsxs4("div", { className: "db-workspace-create-actions", children: [
|
|
1636
|
+
/* @__PURE__ */ jsx4(
|
|
1637
|
+
"button",
|
|
1638
|
+
{
|
|
1639
|
+
type: "button",
|
|
1640
|
+
className: "db-workspace-create-cancel",
|
|
1641
|
+
disabled: newWorkspacePending,
|
|
1642
|
+
onClick: handleCancelCreateNew,
|
|
1643
|
+
children: "Cancel"
|
|
1644
|
+
}
|
|
1645
|
+
),
|
|
1646
|
+
/* @__PURE__ */ jsx4("button", { type: "submit", disabled: newWorkspacePending, children: newWorkspacePending ? "Creating\xE2\u20AC\xA6" : "Create" })
|
|
1647
|
+
] })
|
|
1648
|
+
]
|
|
1649
|
+
}
|
|
1650
|
+
) : /* @__PURE__ */ jsx4("button", { className: "db-workspace-dropdown-item", onClick: handleStartCreateNew, children: /* @__PURE__ */ jsxs4("span", { className: "db-workspace-dropdown-action-label", children: [
|
|
1555
1651
|
/* @__PURE__ */ jsx4(NewFolderIcon, {}),
|
|
1556
1652
|
/* @__PURE__ */ jsx4("span", { children: "New Workspace" })
|
|
1557
|
-
] }) }),
|
|
1653
|
+
] }) })),
|
|
1558
1654
|
(electron || isNativeFileSystemSupported()) && /* @__PURE__ */ jsx4(
|
|
1559
1655
|
"button",
|
|
1560
1656
|
{
|
|
@@ -1583,7 +1679,6 @@ function WorkspacePicker({
|
|
|
1583
1679
|
|
|
1584
1680
|
// src/DocBlocksShell/DocBlocksShell.tsx
|
|
1585
1681
|
import { useState as useState14, useCallback as useCallback14, useEffect as useEffect14, useRef as useRef14, useMemo as useMemo3, lazy as lazy2, Suspense as Suspense2 } from "react";
|
|
1586
|
-
import "@bendyline/squisq-editor-react/styles";
|
|
1587
1682
|
import { MediaContext } from "@bendyline/squisq-react";
|
|
1588
1683
|
import {
|
|
1589
1684
|
DocumentVersionManager
|
|
@@ -1648,7 +1743,9 @@ function AppMenu({
|
|
|
1648
1743
|
onKeepBrowserData,
|
|
1649
1744
|
onInstallApp,
|
|
1650
1745
|
getStorageEstimate,
|
|
1651
|
-
storagePersistent
|
|
1746
|
+
storagePersistent,
|
|
1747
|
+
appVersion,
|
|
1748
|
+
appBuildDate
|
|
1652
1749
|
}) {
|
|
1653
1750
|
const [isOpen, setIsOpen] = useState5(false);
|
|
1654
1751
|
const [showAbout, setShowAbout] = useState5(false);
|
|
@@ -1745,8 +1842,8 @@ function AppMenu({
|
|
|
1745
1842
|
{
|
|
1746
1843
|
className: "db-app-menu-item",
|
|
1747
1844
|
role: "menuitem",
|
|
1748
|
-
onClick: () => handleAction(() =>
|
|
1749
|
-
children: "
|
|
1845
|
+
onClick: () => handleAction(() => setShowSettings(true)),
|
|
1846
|
+
children: "Storage protection\u2026"
|
|
1750
1847
|
}
|
|
1751
1848
|
),
|
|
1752
1849
|
onDownloadAllWorkspaces && /* @__PURE__ */ jsx5(
|
|
@@ -1799,7 +1896,7 @@ function AppMenu({
|
|
|
1799
1896
|
)} of the ${formatBytes(
|
|
1800
1897
|
storageEstimate.quota
|
|
1801
1898
|
)} this browser allows for the site.` : "Storage usage is not available in this browser." }),
|
|
1802
|
-
storagePersistent !== void 0 && /* @__PURE__ */ jsx5("p", { className: "db-settings-hint", children: storagePersistent ? "
|
|
1899
|
+
storagePersistent !== void 0 && /* @__PURE__ */ jsx5("p", { className: "db-settings-hint", children: storagePersistent ? "Protected from routine browser cleanup on this device." : "Browsers may clear site data under storage pressure unless protection is granted." }),
|
|
1803
1900
|
onKeepBrowserData && /* @__PURE__ */ jsx5(
|
|
1804
1901
|
"button",
|
|
1805
1902
|
{
|
|
@@ -1807,7 +1904,7 @@ function AppMenu({
|
|
|
1807
1904
|
className: "db-settings-action",
|
|
1808
1905
|
disabled: requestingPersistentStorage,
|
|
1809
1906
|
onClick: () => void handleKeepBrowserDataFromSettings(),
|
|
1810
|
-
children: requestingPersistentStorage ? "Requesting
|
|
1907
|
+
children: requestingPersistentStorage ? "Requesting storage protection\u2026" : "Protect data from browser cleanup"
|
|
1811
1908
|
}
|
|
1812
1909
|
)
|
|
1813
1910
|
] }),
|
|
@@ -1863,7 +1960,15 @@ function AppMenu({
|
|
|
1863
1960
|
showAbout && /* @__PURE__ */ jsxs5(Dialog, { title: "About DocBlocks", onClose: () => setShowAbout(false), children: [
|
|
1864
1961
|
/* @__PURE__ */ jsxs5("p", { children: [
|
|
1865
1962
|
/* @__PURE__ */ jsx5("strong", { children: "DocBlocks" }),
|
|
1866
|
-
" is a
|
|
1963
|
+
" is a local-first Markdown document editor. Your files stay under your control."
|
|
1964
|
+
] }),
|
|
1965
|
+
appVersion && /* @__PURE__ */ jsxs5("p", { className: "db-about-version", children: [
|
|
1966
|
+
/* @__PURE__ */ jsx5("span", { children: "Version" }),
|
|
1967
|
+
/* @__PURE__ */ jsx5("code", { "aria-label": `DocBlocks version ${appVersion}`, children: appVersion })
|
|
1968
|
+
] }),
|
|
1969
|
+
appBuildDate && /* @__PURE__ */ jsxs5("p", { className: "db-about-version", children: [
|
|
1970
|
+
/* @__PURE__ */ jsx5("span", { children: "Build" }),
|
|
1971
|
+
/* @__PURE__ */ jsx5("time", { dateTime: appBuildDate, children: appBuildDate })
|
|
1867
1972
|
] }),
|
|
1868
1973
|
/* @__PURE__ */ jsxs5("p", { children: [
|
|
1869
1974
|
"Built with",
|
|
@@ -1886,6 +1991,26 @@ function AppMenu({
|
|
|
1886
1991
|
}
|
|
1887
1992
|
),
|
|
1888
1993
|
/* @__PURE__ */ jsx5("span", { className: "db-dialog-sep", children: "\xB7" }),
|
|
1994
|
+
/* @__PURE__ */ jsx5(
|
|
1995
|
+
"a",
|
|
1996
|
+
{
|
|
1997
|
+
href: "https://github.com/bendyline/docblocks/releases",
|
|
1998
|
+
target: "_blank",
|
|
1999
|
+
rel: "noopener noreferrer",
|
|
2000
|
+
children: "Release notes"
|
|
2001
|
+
}
|
|
2002
|
+
),
|
|
2003
|
+
/* @__PURE__ */ jsx5("span", { className: "db-dialog-sep", children: "\xB7" }),
|
|
2004
|
+
/* @__PURE__ */ jsx5(
|
|
2005
|
+
"a",
|
|
2006
|
+
{
|
|
2007
|
+
href: "https://github.com/bendyline/docblocks/issues",
|
|
2008
|
+
target: "_blank",
|
|
2009
|
+
rel: "noopener noreferrer",
|
|
2010
|
+
children: "Support"
|
|
2011
|
+
}
|
|
2012
|
+
),
|
|
2013
|
+
/* @__PURE__ */ jsx5("span", { className: "db-dialog-sep", children: "\xB7" }),
|
|
1889
2014
|
/* @__PURE__ */ jsx5(
|
|
1890
2015
|
"a",
|
|
1891
2016
|
{
|
|
@@ -2129,7 +2254,7 @@ function useDocumentSession(autoSaveDelayMs = 500) {
|
|
|
2129
2254
|
import { lazy, Suspense } from "react";
|
|
2130
2255
|
import { jsx as jsx8 } from "react/jsx-runtime";
|
|
2131
2256
|
var ExportToolbarControlsImplementation = lazy(
|
|
2132
|
-
() => import("./ExportToolbarControls-
|
|
2257
|
+
() => import("./ExportToolbarControls-5HUE3LSX.js").then((module) => ({
|
|
2133
2258
|
default: module.ExportToolbarControls
|
|
2134
2259
|
}))
|
|
2135
2260
|
);
|
|
@@ -2514,17 +2639,45 @@ function retainFileSystemProvider(provider) {
|
|
|
2514
2639
|
// src/DocBlocksShell/document-title.ts
|
|
2515
2640
|
import { useEffect as useEffect9 } from "react";
|
|
2516
2641
|
var APP_TITLE = "DocBlocks";
|
|
2517
|
-
|
|
2518
|
-
|
|
2642
|
+
var INSTALLED_DISPLAY_QUERIES = [
|
|
2643
|
+
"(display-mode: window-controls-overlay)",
|
|
2644
|
+
"(display-mode: standalone)"
|
|
2645
|
+
];
|
|
2646
|
+
function unbrandedHomeTitle(homeDocumentTitle) {
|
|
2647
|
+
if (homeDocumentTitle === APP_TITLE) return "";
|
|
2648
|
+
for (const separator of [" \u2014 ", " - ", ": ", " | "]) {
|
|
2649
|
+
const prefix = `${APP_TITLE}${separator}`;
|
|
2650
|
+
if (homeDocumentTitle.startsWith(prefix)) return homeDocumentTitle.slice(prefix.length);
|
|
2651
|
+
}
|
|
2652
|
+
return homeDocumentTitle;
|
|
2653
|
+
}
|
|
2654
|
+
function titleForSelectedFile(selectedFile, homeDocumentTitle = APP_TITLE, homeDocumentPath, includeAppName = true) {
|
|
2655
|
+
if (!selectedFile || selectedFile === homeDocumentPath) {
|
|
2656
|
+
return includeAppName ? homeDocumentTitle : unbrandedHomeTitle(homeDocumentTitle);
|
|
2657
|
+
}
|
|
2519
2658
|
const filename = selectedFile.replace(/^\/+/, "").split("/").pop();
|
|
2520
2659
|
const name = filename?.replace(/\.[^.]+$/, "");
|
|
2521
|
-
|
|
2660
|
+
if (!name) return includeAppName ? APP_TITLE : "";
|
|
2661
|
+
return includeAppName ? `${name} - ${APP_TITLE}` : name;
|
|
2522
2662
|
}
|
|
2523
2663
|
function useDocumentTitle(selectedFile, homeDocumentTitle, homeDocumentPath) {
|
|
2524
2664
|
useEffect9(() => {
|
|
2525
|
-
if (typeof document
|
|
2526
|
-
|
|
2527
|
-
|
|
2665
|
+
if (typeof document === "undefined") return;
|
|
2666
|
+
const displayQueries = typeof globalThis.matchMedia === "function" ? INSTALLED_DISPLAY_QUERIES.map((query) => globalThis.matchMedia(query)) : [];
|
|
2667
|
+
const updateTitle = () => {
|
|
2668
|
+
const includeAppName = !displayQueries.some((query) => query.matches);
|
|
2669
|
+
document.title = titleForSelectedFile(
|
|
2670
|
+
selectedFile,
|
|
2671
|
+
homeDocumentTitle,
|
|
2672
|
+
homeDocumentPath,
|
|
2673
|
+
includeAppName
|
|
2674
|
+
);
|
|
2675
|
+
};
|
|
2676
|
+
updateTitle();
|
|
2677
|
+
for (const query of displayQueries) query.addEventListener("change", updateTitle);
|
|
2678
|
+
return () => {
|
|
2679
|
+
for (const query of displayQueries) query.removeEventListener("change", updateTitle);
|
|
2680
|
+
};
|
|
2528
2681
|
}, [homeDocumentPath, homeDocumentTitle, selectedFile]);
|
|
2529
2682
|
}
|
|
2530
2683
|
|
|
@@ -3055,7 +3208,7 @@ function UpdateAvailableNotice({
|
|
|
3055
3208
|
blocked = false,
|
|
3056
3209
|
statusBarVisible
|
|
3057
3210
|
}) {
|
|
3058
|
-
const [promptOpen, setPromptOpen] = useState13(
|
|
3211
|
+
const [promptOpen, setPromptOpen] = useState13(true);
|
|
3059
3212
|
if (!available || !onApplyUpdate) return null;
|
|
3060
3213
|
const promptVisible = promptOpen && !blocked;
|
|
3061
3214
|
return /* @__PURE__ */ jsxs10(Fragment6, { children: [
|
|
@@ -3074,9 +3227,9 @@ function UpdateAvailableNotice({
|
|
|
3074
3227
|
}
|
|
3075
3228
|
),
|
|
3076
3229
|
promptVisible && /* @__PURE__ */ jsxs10("div", { id: UPDATE_PROMPT_ID, className: "db-update-banner", role: "alert", children: [
|
|
3077
|
-
/* @__PURE__ */ jsx11("span", { children: "A new version of DocBlocks is available." }),
|
|
3230
|
+
/* @__PURE__ */ jsx11("span", { children: "A new version of DocBlocks is available. Reload to update the editor and site pages." }),
|
|
3078
3231
|
/* @__PURE__ */ jsxs10("div", { className: "db-update-banner-actions", children: [
|
|
3079
|
-
/* @__PURE__ */ jsx11("button", { type: "button", onClick: onApplyUpdate, children: "Reload" }),
|
|
3232
|
+
/* @__PURE__ */ jsx11("button", { type: "button", onClick: onApplyUpdate, disabled: blocked, children: "Reload" }),
|
|
3080
3233
|
/* @__PURE__ */ jsx11("button", { type: "button", onClick: () => setPromptOpen(false), children: "Later" })
|
|
3081
3234
|
] })
|
|
3082
3235
|
] })
|
|
@@ -3392,14 +3545,19 @@ async function copyTransientWorkspaceContents(source, destination) {
|
|
|
3392
3545
|
|
|
3393
3546
|
// src/DocBlocksShell/DocBlocksShell.tsx
|
|
3394
3547
|
import { Fragment as Fragment7, jsx as jsx12, jsxs as jsxs11 } from "react/jsx-runtime";
|
|
3395
|
-
var
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3548
|
+
var editorShellModulePromise = null;
|
|
3549
|
+
function loadEditorShell() {
|
|
3550
|
+
editorShellModulePromise ?? (editorShellModulePromise = (async () => {
|
|
3551
|
+
const workersReady = globalThis.docBlocksMonacoWorkersReady;
|
|
3552
|
+
await workersReady?.catch(() => void 0);
|
|
3553
|
+
return import("./LazyEditorShell-RF54B5UD.js");
|
|
3554
|
+
})());
|
|
3555
|
+
return editorShellModulePromise;
|
|
3556
|
+
}
|
|
3557
|
+
var EditorShell = lazy2(loadEditorShell);
|
|
3558
|
+
var GitUI = lazy2(() => import("./GitUI-GMH3PAYL.js").then((m) => ({ default: m.GitUI })));
|
|
3401
3559
|
var GitToolbarControl = lazy2(
|
|
3402
|
-
() => import("./GitToolbarControl-
|
|
3560
|
+
() => import("./GitToolbarControl-FW3BZFXV.js").then((m) => ({ default: m.GitToolbarControl }))
|
|
3403
3561
|
);
|
|
3404
3562
|
var DOCBLOCKS_VIDEO_EXPORT_PALETTE = Object.freeze({
|
|
3405
3563
|
overlay: "rgba(0, 0, 0, 0.72)",
|
|
@@ -3679,6 +3837,8 @@ function DocBlocksShell({
|
|
|
3679
3837
|
theme: hostTheme = "auto",
|
|
3680
3838
|
logoUrl,
|
|
3681
3839
|
issueReportVersion,
|
|
3840
|
+
appBuildDate,
|
|
3841
|
+
ffmpegWasm,
|
|
3682
3842
|
homeDocumentTitle,
|
|
3683
3843
|
homeDocumentPath,
|
|
3684
3844
|
allowVersioning = true,
|
|
@@ -3723,14 +3883,20 @@ function DocBlocksShell({
|
|
|
3723
3883
|
saveViewPreferences(prefs);
|
|
3724
3884
|
}, []);
|
|
3725
3885
|
const isMobile = useIsMobile();
|
|
3726
|
-
const [mobileShowEditor, setMobileShowEditor] = useState14(
|
|
3886
|
+
const [mobileShowEditor, setMobileShowEditor] = useState14(
|
|
3887
|
+
() => isMobile && isWelcomeGatewayDismissed()
|
|
3888
|
+
);
|
|
3889
|
+
useEffect14(() => {
|
|
3890
|
+
if (isMobile) void loadEditorShell();
|
|
3891
|
+
}, [isMobile]);
|
|
3727
3892
|
const [sidebarWidth, setSidebarWidth] = useState14(loadSidebarWidth);
|
|
3728
3893
|
const [compactLayout, setCompactLayout] = useState14(false);
|
|
3729
3894
|
const effectiveCompact = isMobile || compactLayout;
|
|
3730
3895
|
const showBrowserStorageWarning = !isElectronHost2();
|
|
3896
|
+
const appVersion = isElectronHost2() ? `${getDocBlocksHost().env.appVersion} desktop` : issueReportVersion ?? "web";
|
|
3731
3897
|
const issueReportUrl = buildIssueReportUrl({
|
|
3732
3898
|
reportedAt: /* @__PURE__ */ new Date(),
|
|
3733
|
-
version:
|
|
3899
|
+
version: appVersion,
|
|
3734
3900
|
userAgent: typeof navigator === "undefined" ? "" : navigator.userAgent
|
|
3735
3901
|
});
|
|
3736
3902
|
const [browserStoragePersistent, setBrowserStoragePersistent] = useState14(false);
|
|
@@ -4259,25 +4425,25 @@ function DocBlocksShell({
|
|
|
4259
4425
|
"",
|
|
4260
4426
|
"Your markdown can do anything.",
|
|
4261
4427
|
"",
|
|
4262
|
-
"DocBlocks is a free
|
|
4428
|
+
"DocBlocks is a free, local-first Markdown editor for creating, organizing, and publishing documents without sending your writing to a server. What you write here can become a Word or PDF document, a slide deck, a web page, or a video.",
|
|
4263
4429
|
"",
|
|
4264
4430
|
"Simple to write. Beautiful wherever it goes.",
|
|
4265
4431
|
"",
|
|
4266
4432
|
"## Features",
|
|
4267
4433
|
"",
|
|
4268
|
-
"- **Rich Markdown
|
|
4269
|
-
"- **Workspaces**
|
|
4270
|
-
"- **Useful
|
|
4271
|
-
"- **Playback
|
|
4272
|
-
"- **
|
|
4434
|
+
"- **Rich Markdown editing** \u2014 Write visually or switch to raw Markdown source at any time. Section annotations can change how individual blocks are presented.",
|
|
4435
|
+
"- **Workspaces** \u2014 Organize documents into separate browser workspaces or folders on your device.",
|
|
4436
|
+
"- **Useful everywhere** \u2014 Export Word, PowerPoint, PDF, HTML, and Markdown in the app, with EPUB and additional formats available through the CLI.",
|
|
4437
|
+
"- **Playback and video** \u2014 Preview a document as a rich presentation and export it as an MP4 video.",
|
|
4438
|
+
"- **Private by default** \u2014 No ads, accounts, or tracking. Your browser workspace stays on this device.",
|
|
4273
4439
|
"",
|
|
4274
4440
|
"## Getting Started",
|
|
4275
4441
|
"",
|
|
4276
|
-
"1. Create a
|
|
4277
|
-
"2. Start writing in
|
|
4278
|
-
"3. Your work is saved automatically",
|
|
4442
|
+
"1. Create a document with the **New file** button in the file pane.",
|
|
4443
|
+
"2. Start writing in Markdown \u2014 the editor supports headings, lists, links, images, and more.",
|
|
4444
|
+
"3. Your work is saved automatically.",
|
|
4279
4445
|
"",
|
|
4280
|
-
"Built
|
|
4446
|
+
"Built with [squisq](https://github.com/bendyline/squisq) by [Bendyline](https://bendyline.com).",
|
|
4281
4447
|
"",
|
|
4282
4448
|
"## Explore DocBlocks",
|
|
4283
4449
|
"",
|
|
@@ -5179,6 +5345,52 @@ function DocBlocksShell({
|
|
|
5179
5345
|
promptForText,
|
|
5180
5346
|
showToast
|
|
5181
5347
|
]);
|
|
5348
|
+
const handleNewFolder = useCallback14(async () => {
|
|
5349
|
+
if (!provider) return;
|
|
5350
|
+
const name = await promptForText({
|
|
5351
|
+
title: "New folder",
|
|
5352
|
+
label: "Folder name",
|
|
5353
|
+
initialValue: "Untitled folder",
|
|
5354
|
+
confirmLabel: "Create"
|
|
5355
|
+
});
|
|
5356
|
+
if (!name) return;
|
|
5357
|
+
const folderName = name.trim();
|
|
5358
|
+
if (!folderName || /[\\/]/.test(folderName)) {
|
|
5359
|
+
showToast("error", "Use a folder name without slashes.");
|
|
5360
|
+
return;
|
|
5361
|
+
}
|
|
5362
|
+
const path = `/${folderName}`;
|
|
5363
|
+
try {
|
|
5364
|
+
const providerV2 = getFileSystemProviderV25(provider);
|
|
5365
|
+
if (providerV2) {
|
|
5366
|
+
await providerV2.createDirectory(parseWorkspacePath5(path), { mode: "create" });
|
|
5367
|
+
} else {
|
|
5368
|
+
if (await providerEntryExists(provider, path)) {
|
|
5369
|
+
throw new Error("A file or folder with that name already exists.");
|
|
5370
|
+
}
|
|
5371
|
+
await provider.createDirectory(path);
|
|
5372
|
+
}
|
|
5373
|
+
} catch (error) {
|
|
5374
|
+
const message = error instanceof FsError5 && error.code === "already-exists" ? "A file or folder with that name already exists." : error instanceof Error ? error.message : "Could not create the folder.";
|
|
5375
|
+
showToast("error", message);
|
|
5376
|
+
return;
|
|
5377
|
+
}
|
|
5378
|
+
setSelectedFile(null);
|
|
5379
|
+
setSelectedFolder(path);
|
|
5380
|
+
setFolderEntries([]);
|
|
5381
|
+
setExplorerKey((key) => key + 1);
|
|
5382
|
+
closeWelcomeGateway();
|
|
5383
|
+
if (activeWorkspaceId) pushHash(activeWorkspaceId, null);
|
|
5384
|
+
if (effectiveCompact) setMobileShowEditor(true);
|
|
5385
|
+
}, [
|
|
5386
|
+
provider,
|
|
5387
|
+
promptForText,
|
|
5388
|
+
showToast,
|
|
5389
|
+
closeWelcomeGateway,
|
|
5390
|
+
activeWorkspaceId,
|
|
5391
|
+
pushHash,
|
|
5392
|
+
effectiveCompact
|
|
5393
|
+
]);
|
|
5182
5394
|
const actionNewHandledRef = useRef14(false);
|
|
5183
5395
|
useEffect14(() => {
|
|
5184
5396
|
if (!provider || actionNewHandledRef.current) return;
|
|
@@ -5867,10 +6079,11 @@ function DocBlocksShell({
|
|
|
5867
6079
|
),
|
|
5868
6080
|
/* @__PURE__ */ jsxs11("div", { style: { display: "flex", flex: 1, overflow: "hidden" }, children: [
|
|
5869
6081
|
(!effectiveCompact || !mobileShowEditor) && /* @__PURE__ */ jsxs11(
|
|
5870
|
-
"
|
|
6082
|
+
"aside",
|
|
5871
6083
|
{
|
|
5872
6084
|
ref: sidebarRef,
|
|
5873
6085
|
className: "db-shell-sidebar",
|
|
6086
|
+
"aria-label": "Workspace and files",
|
|
5874
6087
|
style: effectiveCompact ? void 0 : { width: `${sidebarWidth}px` },
|
|
5875
6088
|
children: [
|
|
5876
6089
|
/* @__PURE__ */ jsxs11("div", { className: "db-shell-sidebar-header", children: [
|
|
@@ -5890,7 +6103,9 @@ function DocBlocksShell({
|
|
|
5890
6103
|
onKeepBrowserData: showBrowserStorageWarning && !browserStoragePersistent ? handleKeepBrowserData : void 0,
|
|
5891
6104
|
onInstallApp: installPromptEvent ? handleInstallApp : void 0,
|
|
5892
6105
|
getStorageEstimate: showBrowserStorageWarning ? getBrowserStorageEstimate : void 0,
|
|
5893
|
-
storagePersistent: showBrowserStorageWarning ? browserStoragePersistent : void 0
|
|
6106
|
+
storagePersistent: showBrowserStorageWarning ? browserStoragePersistent : void 0,
|
|
6107
|
+
appVersion,
|
|
6108
|
+
appBuildDate
|
|
5894
6109
|
}
|
|
5895
6110
|
),
|
|
5896
6111
|
/* @__PURE__ */ jsx12(
|
|
@@ -5945,6 +6160,40 @@ function DocBlocksShell({
|
|
|
5945
6160
|
},
|
|
5946
6161
|
explorerKey
|
|
5947
6162
|
),
|
|
6163
|
+
isMobile && showWelcomeGateway && /* @__PURE__ */ jsxs11(
|
|
6164
|
+
"section",
|
|
6165
|
+
{
|
|
6166
|
+
className: "db-mobile-first-run",
|
|
6167
|
+
"aria-labelledby": "db-mobile-first-run-title",
|
|
6168
|
+
children: [
|
|
6169
|
+
/* @__PURE__ */ jsx12("p", { className: "db-mobile-first-run-eyebrow", children: "Local-first Markdown editor" }),
|
|
6170
|
+
/* @__PURE__ */ jsx12("h1", { id: "db-mobile-first-run-title", children: "Welcome to DocBlocks" }),
|
|
6171
|
+
/* @__PURE__ */ jsx12("p", { children: "Write visually, keep plain Markdown underneath, and export the same document in useful formats. Your browser workspace stays on this device." }),
|
|
6172
|
+
/* @__PURE__ */ jsxs11("div", { className: "db-mobile-first-run-actions", children: [
|
|
6173
|
+
/* @__PURE__ */ jsx12(
|
|
6174
|
+
"button",
|
|
6175
|
+
{
|
|
6176
|
+
type: "button",
|
|
6177
|
+
onClick: () => {
|
|
6178
|
+
closeWelcomeGateway();
|
|
6179
|
+
setMobileShowEditor(true);
|
|
6180
|
+
},
|
|
6181
|
+
children: "Tour the welcome document"
|
|
6182
|
+
}
|
|
6183
|
+
),
|
|
6184
|
+
/* @__PURE__ */ jsx12(
|
|
6185
|
+
"button",
|
|
6186
|
+
{
|
|
6187
|
+
type: "button",
|
|
6188
|
+
className: "db-mobile-first-run-secondary",
|
|
6189
|
+
onClick: () => void handleNewFile(),
|
|
6190
|
+
children: "Create a document"
|
|
6191
|
+
}
|
|
6192
|
+
)
|
|
6193
|
+
] })
|
|
6194
|
+
]
|
|
6195
|
+
}
|
|
6196
|
+
),
|
|
5948
6197
|
/* @__PURE__ */ jsxs11("div", { className: "db-shell-sidebar-footer", children: [
|
|
5949
6198
|
/* @__PURE__ */ jsx12("a", { href: "https://docblocks.com/docs/", target: "_blank", rel: "noopener noreferrer", children: "Docs" }),
|
|
5950
6199
|
/* @__PURE__ */ jsx12("span", { className: "db-shell-sidebar-footer-separator", "aria-hidden": "true", children: "\u2022" }),
|
|
@@ -5981,6 +6230,7 @@ function DocBlocksShell({
|
|
|
5981
6230
|
(!effectiveCompact || mobileShowEditor) && /* @__PURE__ */ jsxs11(
|
|
5982
6231
|
"main",
|
|
5983
6232
|
{
|
|
6233
|
+
"aria-label": "Document editor",
|
|
5984
6234
|
className: updateAvailable && onApplyUpdate && updateStatusBarVisible ? "db-shell-editor-area db-shell-editor-area--has-update" : "db-shell-editor-area",
|
|
5985
6235
|
style: {
|
|
5986
6236
|
flex: 1,
|
|
@@ -5994,7 +6244,7 @@ function DocBlocksShell({
|
|
|
5994
6244
|
/* @__PURE__ */ jsx12(
|
|
5995
6245
|
Suspense2,
|
|
5996
6246
|
{
|
|
5997
|
-
fallback: /* @__PURE__ */ jsx12("div", { className: "db-shell-empty", role: "status", children: "Loading
|
|
6247
|
+
fallback: /* @__PURE__ */ jsx12("div", { className: "db-shell-empty", role: "status", children: "Loading your document\u2026" }),
|
|
5998
6248
|
children: /* @__PURE__ */ jsx12(
|
|
5999
6249
|
EditorShell,
|
|
6000
6250
|
{
|
|
@@ -6047,6 +6297,7 @@ function DocBlocksShell({
|
|
|
6047
6297
|
destinationAdapter: exportDestinationAdapter,
|
|
6048
6298
|
colorScheme: resolvedTheme,
|
|
6049
6299
|
videoExportPalette: DOCBLOCKS_VIDEO_EXPORT_PALETTE,
|
|
6300
|
+
ffmpegWasm,
|
|
6050
6301
|
initialSharedMode
|
|
6051
6302
|
}
|
|
6052
6303
|
)
|
|
@@ -6056,11 +6307,12 @@ function DocBlocksShell({
|
|
|
6056
6307
|
)
|
|
6057
6308
|
}
|
|
6058
6309
|
),
|
|
6059
|
-
showWelcomeGateway && /* @__PURE__ */ jsxs11("div", { className: "db-welcome-gateway", role: "note", "aria-label": "Welcome tip", children: [
|
|
6310
|
+
showWelcomeGateway && !isMobile && /* @__PURE__ */ jsxs11("div", { className: "db-welcome-gateway", role: "note", "aria-label": "Welcome tip", children: [
|
|
6060
6311
|
/* @__PURE__ */ jsxs11("span", { className: "db-welcome-gateway-text", children: [
|
|
6061
6312
|
"You\u2019re watching this welcome doc in ",
|
|
6062
6313
|
/* @__PURE__ */ jsx12("strong", { children: "Slideshow" }),
|
|
6063
|
-
"
|
|
6314
|
+
" ",
|
|
6315
|
+
"view\u2014 it\u2019s a regular markdown file, and so is everything you\u2019ll write."
|
|
6064
6316
|
] }),
|
|
6065
6317
|
/* @__PURE__ */ jsx12("button", { className: "db-welcome-gateway-cta", onClick: handleStartWriting, children: "Start writing" }),
|
|
6066
6318
|
/* @__PURE__ */ jsx12(
|
|
@@ -6095,12 +6347,38 @@ function DocBlocksShell({
|
|
|
6095
6347
|
},
|
|
6096
6348
|
entry.path
|
|
6097
6349
|
)) })
|
|
6098
|
-
] }) : /* @__PURE__ */ jsxs11("div", { className: "db-shell-empty", children: [
|
|
6350
|
+
] }) : /* @__PURE__ */ jsxs11("div", { className: "db-shell-empty db-shell-empty--workspace", children: [
|
|
6099
6351
|
effectiveCompact && /* @__PURE__ */ jsxs11("button", { className: "db-mobile-back", onClick: () => setMobileShowEditor(false), children: [
|
|
6100
6352
|
/* @__PURE__ */ jsx12("span", { className: "db-mobile-files-icon", children: /* @__PURE__ */ jsx12(FolderGlyph, {}) }),
|
|
6101
6353
|
"Back to files"
|
|
6102
6354
|
] }),
|
|
6103
|
-
/* @__PURE__ */
|
|
6355
|
+
/* @__PURE__ */ jsxs11("div", { className: "db-workspace-empty-content", children: [
|
|
6356
|
+
/* @__PURE__ */ jsx12("span", { className: "db-workspace-empty-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsx12(FileGlyph, {}) }),
|
|
6357
|
+
/* @__PURE__ */ jsx12("h1", { children: activeWorkspaceDescriptor?.name ? `${activeWorkspaceDescriptor.name} is ready` : "Your workspace is ready" }),
|
|
6358
|
+
/* @__PURE__ */ jsx12("p", { children: "Create your first Markdown document, or open a folder you already use." }),
|
|
6359
|
+
/* @__PURE__ */ jsxs11("div", { className: "db-workspace-empty-actions", children: [
|
|
6360
|
+
/* @__PURE__ */ jsx12("button", { type: "button", onClick: () => void handleNewFile(), children: "Create your first document" }),
|
|
6361
|
+
/* @__PURE__ */ jsx12(
|
|
6362
|
+
"button",
|
|
6363
|
+
{
|
|
6364
|
+
type: "button",
|
|
6365
|
+
className: "db-workspace-empty-secondary",
|
|
6366
|
+
onClick: () => void handleNewFolder(),
|
|
6367
|
+
children: "New folder"
|
|
6368
|
+
}
|
|
6369
|
+
),
|
|
6370
|
+
(isElectronHost2() || typeof globalThis.showDirectoryPicker === "function") && /* @__PURE__ */ jsx12(
|
|
6371
|
+
"button",
|
|
6372
|
+
{
|
|
6373
|
+
type: "button",
|
|
6374
|
+
className: "db-workspace-empty-secondary",
|
|
6375
|
+
onClick: () => void handleOpenFolder(),
|
|
6376
|
+
children: "Open a folder"
|
|
6377
|
+
}
|
|
6378
|
+
)
|
|
6379
|
+
] }),
|
|
6380
|
+
/* @__PURE__ */ jsx12("p", { className: "db-workspace-empty-hint", children: "Browser workspaces stay on this device. Use the sidebar backup action to keep a portable copy." })
|
|
6381
|
+
] })
|
|
6104
6382
|
] }),
|
|
6105
6383
|
/* @__PURE__ */ jsx12(
|
|
6106
6384
|
UpdateAvailableNotice,
|
|
@@ -6119,34 +6397,6 @@ function DocBlocksShell({
|
|
|
6119
6397
|
}
|
|
6120
6398
|
);
|
|
6121
6399
|
}
|
|
6122
|
-
|
|
6123
|
-
// src/Export/export-destination.ts
|
|
6124
|
-
function updateExportTargetExtension(targetPath, suggestedFilename) {
|
|
6125
|
-
const nextExtension = extensionOf(suggestedFilename);
|
|
6126
|
-
if (!nextExtension) return targetPath;
|
|
6127
|
-
if (!targetPath.trim()) return suggestedFilename;
|
|
6128
|
-
const suffixIndex = firstSuffixIndex(targetPath);
|
|
6129
|
-
const pathPart = suffixIndex === -1 ? targetPath : targetPath.slice(0, suffixIndex);
|
|
6130
|
-
const suffix = suffixIndex === -1 ? "" : targetPath.slice(suffixIndex);
|
|
6131
|
-
const separatorIndex = Math.max(pathPart.lastIndexOf("/"), pathPart.lastIndexOf("\\"));
|
|
6132
|
-
const dotIndex = pathPart.lastIndexOf(".");
|
|
6133
|
-
const stem = dotIndex > separatorIndex ? pathPart.slice(0, dotIndex) : pathPart;
|
|
6134
|
-
return `${stem}${nextExtension}${suffix}`;
|
|
6135
|
-
}
|
|
6136
|
-
function extensionOf(value) {
|
|
6137
|
-
const suffixIndex = firstSuffixIndex(value);
|
|
6138
|
-
const pathPart = suffixIndex === -1 ? value : value.slice(0, suffixIndex);
|
|
6139
|
-
const separatorIndex = Math.max(pathPart.lastIndexOf("/"), pathPart.lastIndexOf("\\"));
|
|
6140
|
-
const dotIndex = pathPart.lastIndexOf(".");
|
|
6141
|
-
return dotIndex > separatorIndex ? pathPart.slice(dotIndex) : "";
|
|
6142
|
-
}
|
|
6143
|
-
function firstSuffixIndex(value) {
|
|
6144
|
-
const query = value.indexOf("?");
|
|
6145
|
-
const fragment = value.indexOf("#");
|
|
6146
|
-
if (query === -1) return fragment;
|
|
6147
|
-
if (fragment === -1) return query;
|
|
6148
|
-
return Math.min(query, fragment);
|
|
6149
|
-
}
|
|
6150
6400
|
export {
|
|
6151
6401
|
AccentColorSettings,
|
|
6152
6402
|
AppMenu,
|
|
@@ -6167,4 +6417,3 @@ export {
|
|
|
6167
6417
|
useDocumentSession,
|
|
6168
6418
|
useFileTree
|
|
6169
6419
|
};
|
|
6170
|
-
//# sourceMappingURL=index.js.map
|