Improve local filetree view state and sidebar performance

This commit is contained in:
lix-2026
2026-05-27 11:31:12 +08:00
parent 58e2fdb5d8
commit 3ae33cc21d
56 changed files with 8614 additions and 461 deletions
@@ -301,13 +301,11 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
if (currentSourceKind() !== 'local_folder') return false;
var workspaceId = resolveWorkspaceId(trigger || document.body);
var effectiveParentId = String(parentId || '').trim();
var title = window.prompt('新建文件夹', '新建文件夹');
if (!title || !title.trim()) return false;
var result = await dispatchTreeCommand(trigger || document.body, {
action: 'create_folder',
workspaceId: workspaceId,
parentId: effectiveParentId || null,
title: title.trim()
title: '新建文件夹'
});
document.documentElement.setAttribute('data-mnote-filetree-folder-created', 'true');
document.documentElement.setAttribute('data-mnote-filetree-folder-created-id', commandDocumentId(result, result.id || ''));
@@ -357,6 +355,7 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
copyWorkspaceSourceParams,
cssEscape,
currentDocumentId,
currentRootUri,
currentSourceKind,
dispatchTreeCommand,
normalizeSidebarTreeMode,
@@ -387,12 +386,385 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
const startLocalFolderSidebarWatch = (...args) => sidebarTreeLiveApply.startLocalFolderSidebarWatch(...args);
const deltaNeedsProjectionRefresh = (...args) => sidebarTreeLiveApply.deltaNeedsProjectionRefresh(...args);
const toggleChildren = (...args) => sidebarTreeLiveApply.toggleChildren(...args);
const revealFileTreeResource = (...args) => sidebarTreeLiveApply.revealFileTreeResource(...args);
function dispatchSidebarEvent(name, detail) {
document.documentElement.setAttribute('data-mnote-last-tree-action', name);
window.dispatchEvent(new CustomEvent(name, { detail: detail }));
}
function sidebarShortcutWorkspaceId() {
return currentWorkspaceId()
|| (document.getElementById('sidebar-file-tree-root') && document.getElementById('sidebar-file-tree-root').getAttribute('data-workspace-id') || '')
|| (document.getElementById('sidebar-tree-root') && document.getElementById('sidebar-tree-root').getAttribute('data-workspace-id') || '');
}
function sidebarShortcutSourceKind() {
return currentSourceKind() || 'workspace';
}
function currentFileTreeScope() {
var params = new URLSearchParams(window.location.search);
var fromUrl = String(params.get('fileTreeScope') || '').trim();
if (fromUrl) return fromUrl;
var root = document.getElementById('sidebar-file-tree-root');
return root instanceof HTMLElement ? String(root.getAttribute('data-mnote-filetree-scope') || '').trim() : '';
}
function currentTopbarTitle() {
var title = document.querySelector('[data-page-title-current="true"]');
return title && title.textContent ? title.textContent.trim() : '无标题';
}
function fileTreeRowTitleForShortcut(row, fallback) {
var title = row && row.querySelector ? row.querySelector(':scope > .tree-link > .tree-link-title') : null;
return title && title.textContent ? title.textContent.trim() : (fallback || '文件夹');
}
function sidebarShortcutRows() {
return Array.from(document.querySelectorAll('.wolai-starred-section [data-mnote-shortcut-kind]'));
}
function shortcutMatches(row, kind, targetId, relativePath, documentId) {
if (!(row instanceof HTMLElement)) return false;
if ((row.getAttribute('data-mnote-shortcut-kind') || '') !== kind) return false;
if (documentId && (row.getAttribute('data-mnote-shortcut-document-id') || row.getAttribute('data-document-id') || '') === documentId) return true;
if (relativePath && (row.getAttribute('data-mnote-shortcut-relative-path') || '') === relativePath) return true;
return Boolean(targetId && (row.getAttribute('data-mnote-shortcut-target-id') || row.getAttribute('data-node-id') || '') === targetId);
}
async function listSidebarShortcuts(workspaceId) {
var url = new URL('/api/sidebar/shortcuts', window.location.origin);
url.searchParams.set('workspaceId', workspaceId);
var response = await fetch(url.toString(), {
method: 'GET',
credentials: 'include',
headers: { accept: 'application/json' },
cache: 'no-store'
});
var payload = await response.json().catch(function() { return null; });
if (!response.ok) throw new Error(payload && (payload.error || payload.message) || 'sidebar_shortcuts_list_failed_' + response.status);
return payload && Array.isArray(payload.shortcuts) ? payload.shortcuts : [];
}
function shortcutRecordMatches(shortcut, kind, targetId, relativePath, documentId) {
if (!shortcut || shortcut.kind !== kind) return false;
var shortcutMetadata = shortcut && shortcut.metadata && typeof shortcut.metadata === 'object' ? shortcut.metadata : {};
var shortcutRootUri = String(shortcut.rootUri || shortcut.root_uri || shortcutMetadata.rootUri || shortcutMetadata.root_uri || '').trim();
var currentShortcutRootUri = currentRootUri();
if (shortcutRootUri && currentShortcutRootUri && shortcutRootUri !== currentShortcutRootUri) return false;
if (documentId && String(shortcut.documentId || shortcut.document_id || '') === documentId) return true;
if (relativePath && String(shortcut.relativePath || shortcut.relative_path || '') === relativePath) return true;
return Boolean(targetId && String(shortcut.targetId || shortcut.target_id || '') === targetId);
}
async function findSidebarShortcut(payload) {
var workspaceId = payload.workspaceId || sidebarShortcutWorkspaceId();
if (!workspaceId) return null;
var shortcuts = await listSidebarShortcuts(workspaceId);
return shortcuts.find(function(shortcut) {
return shortcutRecordMatches(shortcut, payload.kind, payload.targetId, payload.relativePath, payload.documentId);
}) || null;
}
async function upsertSidebarShortcut(payload) {
var response = await fetch('/api/sidebar/shortcuts', {
method: 'POST',
credentials: 'include',
headers: { accept: 'application/json', 'content-type': 'application/json' },
body: JSON.stringify(payload)
});
var result = await response.json().catch(function() { return null; });
if (!response.ok) throw new Error(result && (result.error || result.message) || 'sidebar_shortcut_upsert_failed_' + response.status);
return result && result.shortcut ? result.shortcut : null;
}
async function deleteSidebarShortcut(shortcutId) {
if (!shortcutId) return false;
var response = await fetch('/api/sidebar/shortcuts/' + encodeURIComponent(shortcutId), {
method: 'DELETE',
credentials: 'include',
headers: { accept: 'application/json' }
});
var result = await response.json().catch(function() { return null; });
if (!response.ok) throw new Error(result && (result.error || result.message) || 'sidebar_shortcut_delete_failed_' + response.status);
return true;
}
function closeSidebarShortcutMenu() {
var existing = document.querySelector('[data-testid="mnote-sidebar-shortcut-menu"]');
if (existing && existing.parentElement) existing.parentElement.removeChild(existing);
document.querySelectorAll('[data-mnote-shortcut-action="menu"][aria-expanded="true"]').forEach(function(button) {
button.setAttribute('aria-expanded', 'false');
});
}
async function removeSidebarShortcutByRow(row) {
if (!(row instanceof HTMLElement)) return false;
var shortcutId = String(row.getAttribute('data-mnote-shortcut-id') || '').trim();
if (!shortcutId) return false;
row.setAttribute('data-mnote-shortcut-pending', 'true');
try {
await deleteSidebarShortcut(shortcutId);
row.remove();
closeSidebarShortcutMenu();
document.documentElement.setAttribute('data-mnote-sidebar-shortcut-last-action', 'remove');
return true;
} finally {
if (row.isConnected) row.removeAttribute('data-mnote-shortcut-pending');
}
}
function openSidebarShortcutMenu(row, trigger) {
if (!(row instanceof HTMLElement)) return;
closeSidebarShortcutMenu();
if (trigger instanceof HTMLElement) trigger.setAttribute('aria-expanded', 'true');
var rect = trigger && trigger.getBoundingClientRect ? trigger.getBoundingClientRect() : row.getBoundingClientRect();
var menu = document.createElement('div');
menu.className = 'mnote-tree-context-menu';
menu.setAttribute('role', 'menu');
menu.setAttribute('data-testid', 'mnote-sidebar-shortcut-menu');
menu.innerHTML = '<button type="button" class="mnote-tree-context-menu__item" role="menuitem" data-mnote-sidebar-shortcut-menu-action="open"><span class="material-symbols-outlined mnote-tree-context-menu__icon" data-icon="login" aria-hidden="true"></span><span class="mnote-tree-context-menu__label">在右侧边栏打开</span></button><div class="mnote-tree-context-menu__separator" role="separator"></div><button type="button" class="mnote-tree-context-menu__item" role="menuitem" data-mnote-sidebar-shortcut-menu-action="copy-link"><span class="material-symbols-outlined mnote-tree-context-menu__icon" data-icon="link" aria-hidden="true"></span><span class="mnote-tree-context-menu__label">复制访问链接</span></button><button type="button" class="mnote-tree-context-menu__item mnote-tree-context-menu__item--danger" role="menuitem" data-mnote-sidebar-shortcut-menu-action="remove"><span class="material-symbols-outlined mnote-tree-context-menu__icon" data-icon="star_off" aria-hidden="true"></span><span class="mnote-tree-context-menu__label">取消星标</span></button>';
menu.__mnoteShortcutRow = row;
document.body.appendChild(menu);
var width = menu.offsetWidth || 220;
var left = Math.min(Math.max(8, rect.right - width), Math.max(8, window.innerWidth - width - 8));
var top = Math.min(Math.max(8, rect.bottom + 4), Math.max(8, window.innerHeight - (menu.offsetHeight || 120) - 8));
menu.style.left = left + 'px';
menu.style.top = top + 'px';
}
function removeSidebarShortcutRow(shortcut) {
sidebarShortcutRows().forEach(function(row) {
if (shortcutMatches(
row,
shortcut.kind,
String(shortcut.targetId || shortcut.target_id || ''),
String(shortcut.relativePath || shortcut.relative_path || ''),
String(shortcut.documentId || shortcut.document_id || '')
)) {
row.remove();
}
});
}
function renderSidebarShortcutRow(shortcut) {
if (!shortcut) return;
var section = document.querySelector('.wolai-starred-section');
if (!(section instanceof HTMLElement)) return;
removeSidebarShortcutRow(shortcut);
var kind = String(shortcut.kind || '').trim();
var shortcutId = String(shortcut.id || shortcut.targetId || shortcut.target_id || '').trim();
var targetId = String(shortcut.targetId || shortcut.target_id || '').trim();
var relativePath = String(shortcut.relativePath || shortcut.relative_path || '').trim();
var documentId = String(shortcut.documentId || shortcut.document_id || '').trim();
var sourceKind = String(shortcut.sourceKind || shortcut.source_kind || '').trim();
var metadata = shortcut.metadata && typeof shortcut.metadata === 'object' ? shortcut.metadata : {};
var rootUri = String(shortcut.rootUri || shortcut.root_uri || metadata.rootUri || metadata.root_uri || '').trim();
var workspaceId = String(shortcut.workspaceId || shortcut.workspace_id || sidebarShortcutWorkspaceId() || '').trim();
var title = String(shortcut.title || (kind === 'folder' ? '文件夹' : '无标题')).trim();
var href = '';
if (documentId) {
var targetUrl = new URL('/documents/' + encodeURIComponent(documentId), window.location.origin);
if (workspaceId) targetUrl.searchParams.set('workspaceId', workspaceId);
if (sourceKind) targetUrl.searchParams.set('sourceKind', sourceKind);
if (rootUri) targetUrl.searchParams.set('rootUri', rootUri);
href = targetUrl.pathname + targetUrl.search;
}
var row = document.createElement(href ? 'a' : 'div');
row.className = 'wolai-page-row';
if (href) row.setAttribute('href', href);
else {
row.setAttribute('role', 'button');
row.setAttribute('tabindex', '0');
}
row.setAttribute('data-testid', 'wolai-sidebar-row');
row.setAttribute('data-node-id', shortcutId || targetId);
row.setAttribute('data-document-id', documentId || shortcutId || targetId);
if (shortcutId) row.setAttribute('data-mnote-shortcut-id', shortcutId);
if (workspaceId) row.setAttribute('data-workspace-id', workspaceId);
row.setAttribute('data-mnote-shortcut-kind', kind);
if (sourceKind) row.setAttribute('data-mnote-shortcut-source-kind', sourceKind);
row.setAttribute('data-mnote-shortcut-target-id', targetId);
if (relativePath) row.setAttribute('data-mnote-shortcut-relative-path', relativePath);
if (rootUri) row.setAttribute('data-mnote-shortcut-root-uri', rootUri);
if (documentId) row.setAttribute('data-mnote-shortcut-document-id', documentId);
row.setAttribute('data-depth', '0');
row.setAttribute('data-active', String(documentId && documentId === currentDocumentId()));
row.innerHTML = '<span class="wolai-row-caret" aria-hidden="true"></span><span class="wolai-row-icon"><span class="material-symbols-outlined wolai-row-symbol" data-icon="' + (kind === 'folder' ? 'folder_open' : 'home') + '" aria-hidden="true"></span></span><span class="wolai-row-title">' + escapeHtml(title) + '</span><button type="button" class="wolai-row-more" data-mnote-shortcut-action="menu" aria-label="更多操作" title="更多操作"><span class="material-symbols-outlined" data-icon="more_horiz" aria-hidden="true"></span></button>';
section.appendChild(row);
}
async function toggleSidebarShortcut(payload) {
var workspaceId = payload.workspaceId || sidebarShortcutWorkspaceId();
if (!workspaceId) return false;
var normalized = Object.assign({}, payload, { workspaceId: workspaceId });
var existing = await findSidebarShortcut(normalized);
if (existing && existing.id) {
await deleteSidebarShortcut(existing.id);
removeSidebarShortcutRow(existing);
document.documentElement.setAttribute('data-mnote-sidebar-shortcut-last-action', 'remove');
return true;
}
var shortcut = await upsertSidebarShortcut(normalized);
renderSidebarShortcutRow(shortcut);
document.documentElement.setAttribute('data-mnote-sidebar-shortcut-last-action', 'upsert');
return true;
}
function currentPageShortcutPayload() {
var documentId = currentDocumentId();
var workspaceId = sidebarShortcutWorkspaceId();
if (!documentId || !workspaceId) return null;
return {
workspaceId: workspaceId,
kind: 'page',
sourceKind: sidebarShortcutSourceKind(),
targetId: documentId,
documentId: documentId,
title: currentTopbarTitle(),
icon: 'star',
rootUri: currentRootUri(),
metadataJson: JSON.stringify({ rootUri: currentRootUri() })
};
}
function folderShortcutPayload(detail, trigger) {
detail = detail || {};
var row = trigger && trigger.closest ? trigger.closest('.tree-row[data-shell-mode="filetree"]') : trigger;
var rowKind = String(detail.rowKind || (row && row.getAttribute('data-row-kind')) || '').trim();
if (rowKind !== 'folder' && rowKind !== 'directory') return null;
var relativePath = String(detail.localRelativePath || (row && row.getAttribute('data-local-relative-path')) || '').trim();
if (!relativePath) return null;
var workspaceId = String(detail.workspaceId || sidebarShortcutWorkspaceId() || '').trim();
if (!workspaceId) return null;
var rowId = String(detail.rowId || (row && row.getAttribute('data-row-id')) || '').trim();
return {
workspaceId: workspaceId,
kind: 'folder',
sourceKind: 'local_folder',
targetId: rowId || ('folder:' + relativePath),
relativePath: relativePath,
title: detail.title || fileTreeRowTitleForShortcut(row, relativePath),
icon: 'folder_open',
rootUri: currentRootUri(),
metadataJson: JSON.stringify({ rootUri: currentRootUri() })
};
}
async function toggleCurrentPageSidebarShortcut(trigger) {
var payload = currentPageShortcutPayload();
if (!payload) return;
if (trigger instanceof HTMLElement) trigger.setAttribute('data-mnote-shortcut-pending', 'true');
try {
await toggleSidebarShortcut(payload);
} finally {
if (trigger instanceof HTMLElement) trigger.removeAttribute('data-mnote-shortcut-pending');
}
}
async function toggleFolderSidebarShortcut(detail, trigger) {
var payload = folderShortcutPayload(detail, trigger);
if (!payload) return false;
await toggleSidebarShortcut(payload);
return true;
}
function ensureStarredFolderFileTreeHost(workspaceId) {
var root = document.getElementById('sidebar-file-tree-root');
if (root instanceof HTMLElement) return root;
var panel = document.getElementById('wolai-sidebar-file-tree-panel');
if (!(panel instanceof HTMLElement)) return null;
var section = document.createElement('div');
section.className = 'sidebar-tree-section sidebar-file-tree-section';
root = document.createElement('div');
root.id = 'sidebar-file-tree-root';
root.className = 'sidebar-tree';
root.setAttribute('data-tree-shell-mode', 'filetree');
if (workspaceId) root.setAttribute('data-workspace-id', workspaceId);
section.appendChild(root);
panel.appendChild(section);
return root;
}
function persistStarredFolderScope(workspaceId, rootUri, relativePath) {
var targetUrl = new URL(window.location.href);
if (workspaceId) targetUrl.searchParams.set('workspaceId', workspaceId);
targetUrl.searchParams.set('sourceKind', 'local_folder');
targetUrl.searchParams.set('rootUri', rootUri);
targetUrl.searchParams.set('treeView', 'filetree');
targetUrl.searchParams.set('fileTreeScope', relativePath);
window.history.replaceState(window.history.state, '', targetUrl.pathname + targetUrl.search + targetUrl.hash);
if (document.body instanceof HTMLElement) {
document.body.setAttribute('data-mnote-source-kind', 'local_folder');
document.body.setAttribute('data-mnote-root-uri', rootUri);
}
}
function readShortcutRootUri(row) {
if (!(row instanceof HTMLElement)) return '';
return String(row.getAttribute('data-mnote-shortcut-root-uri') || '').trim();
}
async function openStarredFolderShortcut(row) {
if (!(row instanceof HTMLElement)) return false;
var relativePath = String(row.getAttribute('data-mnote-shortcut-relative-path') || '').trim();
var workspaceId = String(row.getAttribute('data-workspace-id') || '').trim() || sidebarShortcutWorkspaceId();
var rootUri = readShortcutRootUri(row);
if (!relativePath || !rootUri || !workspaceId) {
document.documentElement.setAttribute('data-mnote-sidebar-shortcut-open-error', !rootUri ? 'missing_root_uri' : 'missing_target');
return false;
}
document.documentElement.removeAttribute('data-mnote-sidebar-shortcut-open-error');
var tab = document.querySelector('[data-mnote-sidebar-tree-tab="filetree"]');
if (tab instanceof HTMLElement) switchSidebarTreeTab(tab);
var root = ensureStarredFolderFileTreeHost(workspaceId);
if (root instanceof HTMLElement) {
root.setAttribute('data-workspace-id', workspaceId);
root.setAttribute('data-mnote-filetree-scope', relativePath);
root.setAttribute('data-mnote-filetree-scope-title', row.textContent ? row.textContent.trim() : relativePath);
}
persistStarredFolderScope(workspaceId, rootUri, relativePath);
document.documentElement.setAttribute('data-mnote-filetree-scope', relativePath);
var sidebarUrl = new URL('/api/tree/projections/sidebar', window.location.origin);
sidebarUrl.searchParams.set('workspaceId', workspaceId);
sidebarUrl.searchParams.set('sourceKind', 'local_folder');
sidebarUrl.searchParams.set('rootUri', rootUri);
var url = new URL('/api/tree/projections/file', window.location.origin);
url.searchParams.set('workspaceId', workspaceId);
url.searchParams.set('sourceKind', 'local_folder');
url.searchParams.set('rootUri', rootUri);
url.searchParams.set('parentRelativePath', relativePath);
var sidebarResponse = await fetch(sidebarUrl.toString(), {
method: 'GET',
credentials: 'include',
headers: { accept: 'application/json' },
cache: 'no-store'
});
var sidebarPayload = await sidebarResponse.json().catch(function() { return null; });
if (!sidebarResponse.ok) throw new Error(sidebarPayload && (sidebarPayload.error || sidebarPayload.message) || 'local_page_tree_failed_' + sidebarResponse.status);
var response = await fetch(url.toString(), {
method: 'GET',
credentials: 'include',
headers: { accept: 'application/json' },
cache: 'no-store'
});
var payload = await response.json().catch(function() { return null; });
if (!response.ok) throw new Error(payload && (payload.error || payload.message) || 'scoped_filetree_failed_' + response.status);
var sidebarProjection = sidebarPayload && (sidebarPayload.result || sidebarPayload) || {};
var fileProjection = payload && (payload.result || payload);
var rendered = renderSidebarSnapshot(Object.assign({}, sidebarProjection, {
dataset: Object.assign({}, sidebarProjection.dataset || {}, { kernel_file_tree_projection: fileProjection })
}));
root = document.getElementById('sidebar-file-tree-root');
if (root instanceof HTMLElement) {
root.setAttribute('data-workspace-id', workspaceId);
root.setAttribute('data-mnote-filetree-scope', relativePath);
root.setAttribute('data-mnote-filetree-scope-title', row.textContent ? row.textContent.trim() : relativePath);
}
return rendered;
}
const sidebarFileTreeOpen = createSidebarFileTreeOpenRuntime({
copyWorkspaceSourceParams,
currentDocumentId,
@@ -736,14 +1108,19 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
async function healLegacyOfficeAttachmentParagraphs() {
var editor = document.querySelector('.editor-surface .ProseMirror');
if (!(editor instanceof HTMLElement)) return;
var index = await fetchLegacyOfficeAttachmentIndex();
var paragraphs = Array.from(editor.querySelectorAll('p'));
paragraphs.forEach(function(paragraph) {
var candidates = paragraphs.filter(function(paragraph) {
if (!(paragraph instanceof HTMLParagraphElement)) return;
if (paragraph.querySelector('a, img, video, audio, table, iframe, canvas')) return;
if (paragraph.childNodes.length !== 1 || paragraph.firstChild?.nodeType !== Node.TEXT_NODE) return;
var fileName = String(paragraph.textContent || '').trim();
if (!fileName) return;
return Boolean(inferOnlyOfficeFileType(fileName, ''));
});
if (!candidates.length) return;
var index = await fetchLegacyOfficeAttachmentIndex();
candidates.forEach(function(paragraph) {
var fileName = String(paragraph.textContent || '').trim();
var detail = index[fileName];
if (!detail) return;
var link = document.createElement('a');
@@ -1545,6 +1922,7 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
createPage,
cssEscape,
currentDocumentId,
currentRootUri,
currentSourceKind,
deleteSingleFileTreeAsset,
dispatchSidebarEvent,
@@ -1563,6 +1941,8 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
openEditorAttachmentEditTab: (...args) => openEditorAttachmentEditTab(...args),
openEditorAttachmentNewWindow: (...args) => openEditorAttachmentNewWindow(...args),
refreshLocalFolderSidebarSnapshot,
removeFileTreeAssetRow,
revealFileTreeResource,
resolveWorkspaceId,
runtimeState: sidebarFileTreeCommandState,
selectedSidebarFileTreeSelection: sidebarFileTreeSelection,
@@ -1620,6 +2000,7 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
const postSidebarFileTreeJson = (...args) => sidebarFileTreeCommand.postSidebarFileTreeJson(...args);
const fileTreeRowsByRowIds = (...args) => sidebarFileTreeCommand.fileTreeRowsByRowIds(...args);
const fileTreeChildCount = (...args) => sidebarFileTreeCommand.fileTreeChildCount(...args);
const moveSidebarFileTreeRows = (...args) => sidebarFileTreeCommand.moveSidebarFileTreeRows(...args);
const pasteSidebarFileTreeClipboard = (...args) => sidebarFileTreeCommand.pasteSidebarFileTreeClipboard(...args);
const deleteSelectedSidebarFileTreeRows = (...args) => sidebarFileTreeCommand.deleteSelectedSidebarFileTreeRows(...args);
@@ -1891,6 +2272,7 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
buildLocalOnlyOfficeOpenUrl,
buildOnlyOfficeOpenPath,
buildOnlyOfficeOpenUrl,
closestAction,
currentDocumentId,
currentRootUri,
currentWorkspaceSourcePayload,
@@ -2274,6 +2656,58 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
return;
}
var pageShortcutTrigger = closestAction(e.target, '[data-mnote-action="toggle-sidebar-shortcut"]');
if (pageShortcutTrigger) {
e.preventDefault();
void toggleCurrentPageSidebarShortcut(pageShortcutTrigger);
return;
}
var shortcutMenu = closestAction(e.target, '[data-testid="mnote-sidebar-shortcut-menu"]');
var shortcutMenuAction = closestAction(e.target, '[data-mnote-sidebar-shortcut-menu-action]');
if (shortcutMenuAction) {
e.preventDefault();
var action = String(shortcutMenuAction.getAttribute('data-mnote-sidebar-shortcut-menu-action') || '').trim();
var shortcutRowFromMenu = shortcutMenu && shortcutMenu.__mnoteShortcutRow instanceof HTMLElement
? shortcutMenu.__mnoteShortcutRow
: null;
if (action === 'remove') {
void removeSidebarShortcutByRow(shortcutRowFromMenu);
return;
}
if (action === 'open') {
closeSidebarShortcutMenu();
if (shortcutRowFromMenu && shortcutRowFromMenu.getAttribute('data-mnote-shortcut-kind') === 'folder') {
void openStarredFolderShortcut(shortcutRowFromMenu);
} else if (shortcutRowFromMenu && shortcutRowFromMenu.getAttribute('href')) {
window.location.assign(shortcutRowFromMenu.getAttribute('href'));
}
return;
}
if (action === 'copy-link') {
var href = shortcutRowFromMenu && shortcutRowFromMenu.getAttribute('href') || window.location.href;
if (navigator.clipboard && href) void navigator.clipboard.writeText(new URL(href, window.location.origin).toString());
closeSidebarShortcutMenu();
return;
}
}
if (!shortcutMenu) closeSidebarShortcutMenu();
var shortcutMenuTrigger = closestAction(e.target, '.wolai-starred-section [data-mnote-shortcut-action="menu"]');
if (shortcutMenuTrigger) {
e.preventDefault();
var shortcutRow = shortcutMenuTrigger.closest('[data-mnote-shortcut-id]');
openSidebarShortcutMenu(shortcutRow, shortcutMenuTrigger);
return;
}
var folderShortcutRow = closestAction(e.target, '.wolai-starred-section [data-mnote-shortcut-kind="folder"]');
if (folderShortcutRow) {
e.preventDefault();
void openStarredFolderShortcut(folderShortcutRow);
return;
}
var localFolderTrigger = closestAction(e.target, '[data-mnote-action="open-local-folder"]');
if (localFolderTrigger) {
e.preventDefault();
@@ -2295,6 +2729,16 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
return;
}
var createFolderTrigger = closestAction(e.target, '[data-mnote-action="create-folder"]');
if (createFolderTrigger) {
e.preventDefault();
if (currentSourceKind() !== 'local_folder') return;
var scope = currentFileTreeScope();
var parentId = scope ? 'local:folder:' + scope : null;
void createFileTreeFolder(createFolderTrigger, parentId);
return;
}
var fileTree = document.getElementById('sidebar-file-tree-root');
if (fileTree && fileTree.contains(e.target)) {
var fileBtn = closestAction(e.target, '[data-rust-action]');
@@ -2345,7 +2789,7 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
return;
}
if ((rowKind === 'document' || rowKind === 'index' || rowKind === 'markdown') && documentId) {
navigateToDocument(documentId, resolveWorkspaceId(fileRow), { treeView: 'filetree' });
navigateToDocument(documentId, resolveWorkspaceId(fileRow), { treeView: 'filetree', fileTreeScope: currentFileTreeScope() });
} else if (assetId) {
dispatchSidebarEvent('tree.asset.open', { rowId: rowId, rowKind: rowKind, documentId: ownerDocumentId || null, assetId: assetId, assetType: assetType || null, objectIdentity: objectIdentity, workspaceId: resolveWorkspaceId(fileRow), openTarget: e.shiftKey || e.ctrlKey || e.metaKey ? 'new-window' : 'active-tab' });
}
@@ -2355,6 +2799,29 @@ import { createSidebarPageSettingsRuntime } from './sidebar-page-settings-runtim
if (sidebarPageTree.handlePageTreeClick(e, { closestAction: closestAction })) return;
});
window.addEventListener('tree.sidebarShortcut.toggleFolder', function(event) {
var detail = event.detail || {};
var row = detail.rowId
? document.querySelector('#sidebar-file-tree-root .tree-row[data-shell-mode="filetree"][data-row-id="' + cssEscape(detail.rowId) + '"]')
: null;
void toggleFolderSidebarShortcut(detail, row);
});
window.addEventListener('tree.filetree.internal-drop', function(event) {
var detail = event.detail || {};
var rowIds = Array.isArray(detail.rowIds) ? detail.rowIds : [];
if (!rowIds.length) return;
var targetRow = detail.targetRowId
? document.querySelector('#sidebar-file-tree-root .tree-row[data-shell-mode="filetree"][data-row-id="' + cssEscape(detail.targetRowId) + '"]')
: null;
recordFileTreeAction('internal-drop', {
rowId: detail.targetRowId || '',
sourceRowIds: rowIds,
copy: Boolean(detail.copy)
});
void moveSidebarFileTreeRows(rowIds, targetRow, { copy: Boolean(detail.copy) });
});
document.addEventListener('contextmenu', function(event) {
var editorAttachmentLink = closestAction(event.target, '.editor-surface .ProseMirror a[data-mnote-attachment-link="true"], .editor-surface .ProseMirror a.mnote-uploaded-attachment-row, .editor-surface .ProseMirror a[href*="/api/local-folder/files/open"]');
if (editorAttachmentLink instanceof HTMLAnchorElement) {