Skip to content

Commit a2f3f3e

Browse files
committed
feat: add pan and zoom diagram viewer
1 parent cc80f42 commit a2f3f3e

13 files changed

Lines changed: 865 additions & 122 deletions

‎packages/app-core/src/components/EditorPane.tsx‎

Lines changed: 49 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ import { livePreviewPlugin } from '../lib/cm-live-preview'
6767
import { slashCommandSource, slashCommandRender } from '../lib/cm-slash-commands'
6868
import { dateShortcutSource } from '../lib/cm-date-shortcuts'
6969
import { wikilinkSource } from '../lib/cm-wikilinks'
70-
import { LazyPreview as Preview } from './LazyPreview'
70+
import { LazyDiagramTabView, LazyPreview as Preview } from './LazyPreview'
7171
import { ConnectionsPanel } from './ConnectionsPanel'
7272
import { OutlinePanel } from './OutlinePanel'
7373
import { CommentsPanel, type CommentDraft } from './CommentsPanel'
@@ -144,6 +144,11 @@ import {
144144
assetTitleFromPath,
145145
isAssetTabPath
146146
} from '../lib/asset-tabs'
147+
import {
148+
diagramFromTabPath,
149+
diagramTitleFromTabPath,
150+
isDiagramTabPath
151+
} from '../lib/diagram-tabs'
147152
import { classifyLocalAssetHref } from '../lib/local-assets'
148153
import { getKeymapDisplay, type KeymapId } from '../lib/keymaps'
149154
import { isTabStripOverflowing } from '../lib/tab-strip-overflow'
@@ -1909,118 +1914,80 @@ export function EditorPane({ pane }: { pane: PaneLeaf }): JSX.Element {
19091914
() => {
19101915
const pinnedSet = new Set(pinnedTabs)
19111916
return tabs.map((path) => {
1917+
const base = {
1918+
path,
1919+
pinned: pinnedSet.has(path),
1920+
isQuick: false,
1921+
isTasks: false,
1922+
isTag: false,
1923+
isHelp: false,
1924+
isArchive: false,
1925+
isTrash: false,
1926+
isAsset: false,
1927+
isDiagram: false
1928+
}
19121929
if (isTasksTabPath(path)) {
19131930
return {
1914-
path,
1931+
...base,
19151932
title: 'Tasks',
1916-
pinned: pinnedSet.has(path),
1917-
isQuick: false,
1918-
isTasks: true,
1919-
isTag: false,
1920-
isHelp: false,
1921-
isArchive: false,
1922-
isTrash: false,
1923-
isAsset: false
1933+
isTasks: true
19241934
}
19251935
}
19261936
if (isQuickNotesTabPath(path)) {
19271937
return {
1928-
path,
1938+
...base,
19291939
title: folderLabels.quick,
1930-
pinned: pinnedSet.has(path),
1931-
isQuick: true,
1932-
isTasks: false,
1933-
isTag: false,
1934-
isHelp: false,
1935-
isArchive: false,
1936-
isTrash: false,
1937-
isAsset: false
1940+
isQuick: true
19381941
}
19391942
}
19401943
if (isTagsTabPath(path)) {
19411944
return {
1942-
path,
1945+
...base,
19431946
title: 'Tags',
1944-
pinned: pinnedSet.has(path),
1945-
isQuick: false,
1946-
isTasks: false,
1947-
isTag: true,
1948-
isHelp: false,
1949-
isArchive: false,
1950-
isTrash: false,
1951-
isAsset: false
1947+
isTag: true
19521948
}
19531949
}
19541950
if (isHelpTabPath(path)) {
19551951
return {
1956-
path,
1952+
...base,
19571953
title: 'Help',
1958-
pinned: pinnedSet.has(path),
1959-
isQuick: false,
1960-
isTasks: false,
1961-
isTag: false,
1962-
isHelp: true,
1963-
isArchive: false,
1964-
isTrash: false,
1965-
isAsset: false
1954+
isHelp: true
19661955
}
19671956
}
19681957
if (isArchiveTabPath(path)) {
19691958
return {
1970-
path,
1959+
...base,
19711960
title: folderLabels.archive,
1972-
pinned: pinnedSet.has(path),
1973-
isQuick: false,
1974-
isTasks: false,
1975-
isTag: false,
1976-
isHelp: false,
1977-
isArchive: true,
1978-
isTrash: false,
1979-
isAsset: false
1961+
isArchive: true
19801962
}
19811963
}
19821964
if (isTrashTabPath(path)) {
19831965
return {
1984-
path,
1966+
...base,
19851967
title: folderLabels.trash,
1986-
pinned: pinnedSet.has(path),
1987-
isQuick: false,
1988-
isTasks: false,
1989-
isTag: false,
1990-
isHelp: false,
1991-
isArchive: false,
1992-
isTrash: true,
1993-
isAsset: false
1968+
isTrash: true
19941969
}
19951970
}
19961971
if (isAssetTabPath(path)) {
19971972
const assetPath = assetPathFromTab(path)
19981973
return {
1999-
path,
1974+
...base,
20001975
title: assetTitleFromPath(assetPath),
2001-
pinned: pinnedSet.has(path),
2002-
isQuick: false,
2003-
isTasks: false,
2004-
isTag: false,
2005-
isHelp: false,
2006-
isArchive: false,
2007-
isTrash: false,
20081976
isAsset: true
20091977
}
20101978
}
1979+
if (isDiagramTabPath(path)) {
1980+
return {
1981+
...base,
1982+
title: diagramTitleFromTabPath(path),
1983+
isDiagram: true
1984+
}
1985+
}
20111986
const meta = path === content?.path ? content : notes.find((n) => n.path === path)
20121987
const title = meta?.title ?? path.split('/').pop()?.replace(/\.md$/i, '') ?? path
20131988
return {
2014-
path,
1989+
...base,
20151990
title,
2016-
pinned: pinnedSet.has(path),
2017-
isQuick: false,
2018-
isTasks: false,
2019-
isTag: false,
2020-
isHelp: false,
2021-
isArchive: false,
2022-
isTrash: false,
2023-
isAsset: false
20241991
}
20251992
})
20261993
},
@@ -2090,7 +2057,8 @@ export function EditorPane({ pane }: { pane: PaneLeaf }): JSX.Element {
20902057
isHelpTabPath(path) ||
20912058
isArchiveTabPath(path) ||
20922059
isTrashTabPath(path) ||
2093-
isAssetTabPath(path)
2060+
isAssetTabPath(path) ||
2061+
isDiagramTabPath(path)
20942062
) {
20952063
return [
20962064
{ label: 'Close', onSelect: async () => closeTabInPane(paneId, path) },
@@ -2194,6 +2162,7 @@ export function EditorPane({ pane }: { pane: PaneLeaf }): JSX.Element {
21942162
isArchive: boolean
21952163
isTrash: boolean
21962164
isAsset: boolean
2165+
isDiagram: boolean
21972166
}) => {
21982167
const active = tab.path === activeTab
21992168
const isVirtual =
@@ -2203,7 +2172,8 @@ export function EditorPane({ pane }: { pane: PaneLeaf }): JSX.Element {
22032172
tab.isHelp ||
22042173
tab.isArchive ||
22052174
tab.isTrash ||
2206-
tab.isAsset
2175+
tab.isAsset ||
2176+
tab.isDiagram
22072177
return (
22082178
<div
22092179
key={tab.path}
@@ -2326,6 +2296,9 @@ export function EditorPane({ pane }: { pane: PaneLeaf }): JSX.Element {
23262296
{tab.isAsset && (
23272297
<DocumentIcon width={13} height={13} className="shrink-0 text-accent" />
23282298
)}
2299+
{tab.isDiagram && (
2300+
<DocumentIcon width={13} height={13} className="shrink-0 text-accent" />
2301+
)}
23292302
<span className="min-w-0 flex-1 truncate">{tab.title}</span>
23302303
</button>
23312304
<button
@@ -2691,6 +2664,8 @@ export function EditorPane({ pane }: { pane: PaneLeaf }): JSX.Element {
26912664
<TrashView />
26922665
) : activeTab && isAssetTabPath(activeTab) ? (
26932666
<AssetTabView tabPath={activeTab} vaultRoot={vault?.root ?? null} />
2667+
) : activeTab && isDiagramTabPath(activeTab) ? (
2668+
<LazyDiagramTabView diagram={diagramFromTabPath(activeTab)} />
26942669
) : content ? (
26952670
<div
26962671
className={[

‎packages/app-core/src/components/LazyPreview.tsx‎

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
import { lazy, Suspense } from 'react'
2+
import type { DiagramTabPayload } from '../lib/diagram-tabs'
23

34
const PreviewImpl = lazy(() =>
45
import('./Preview').then((mod) => ({ default: mod.Preview }))
56
)
67

8+
const DiagramTabViewImpl = lazy(() =>
9+
import('./Preview').then((mod) => ({ default: mod.DiagramTabView }))
10+
)
11+
712
export function LazyPreview({
813
markdown,
914
notePath,
@@ -26,3 +31,15 @@ export function LazyPreview({
2631
</Suspense>
2732
)
2833
}
34+
35+
export function LazyDiagramTabView({
36+
diagram
37+
}: {
38+
diagram: DiagramTabPayload | null
39+
}): JSX.Element {
40+
return (
41+
<Suspense fallback={null}>
42+
<DiagramTabViewImpl diagram={diagram} />
43+
</Suspense>
44+
)
45+
}

0 commit comments

Comments
 (0)