Improve local filetree view state and sidebar performance
This commit is contained in:
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user