Fix local filetree navigation state and office proxy
This commit is contained in:
@@ -21,6 +21,9 @@ export const createSidebarTreeLiveApplyRuntime = (dependencies = {}) => {
|
||||
var fileTreeLazyChildrenCache = new Map();
|
||||
var fileTreeExpandedRelativePaths = new Set();
|
||||
var fileTreeLazyCacheRootUri = '';
|
||||
var fileTreeExpansionStorageRootUri = '';
|
||||
var fileTreeExpansionRestoreTimer = 0;
|
||||
var FILETREE_EXPANSION_STORAGE_KEY = 'mnote.localFileTree.expandedRelativePaths.v1';
|
||||
|
||||
function updateTitleEverywhere(documentId, title) {
|
||||
if (!documentId) return;
|
||||
@@ -616,19 +619,68 @@ export const createSidebarTreeLiveApplyRuntime = (dependencies = {}) => {
|
||||
fileTreeLazyCacheRootUri = rootUri;
|
||||
fileTreeLazyChildrenCache.clear();
|
||||
fileTreeExpandedRelativePaths.clear();
|
||||
loadStoredFileTreeExpansionState(rootUri);
|
||||
}
|
||||
|
||||
function storedFileTreeExpansionBuckets() {
|
||||
try {
|
||||
if (!window.sessionStorage) return {};
|
||||
var parsed = JSON.parse(window.sessionStorage.getItem(FILETREE_EXPANSION_STORAGE_KEY) || '{}');
|
||||
return parsed && typeof parsed === 'object' && !Array.isArray(parsed) ? parsed : {};
|
||||
} catch (_) {
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
function loadStoredFileTreeExpansionState(rootUri) {
|
||||
var normalizedRootUri = String(rootUri || '').trim();
|
||||
if (!normalizedRootUri || fileTreeExpansionStorageRootUri === normalizedRootUri) return;
|
||||
fileTreeExpansionStorageRootUri = normalizedRootUri;
|
||||
var buckets = storedFileTreeExpansionBuckets();
|
||||
var paths = Array.isArray(buckets[normalizedRootUri]) ? buckets[normalizedRootUri] : [];
|
||||
paths.forEach(function(path) {
|
||||
var normalized = String(path || '').trim();
|
||||
if (normalized) fileTreeExpandedRelativePaths.add(normalized);
|
||||
});
|
||||
}
|
||||
|
||||
function persistFileTreeExpansionState() {
|
||||
var rootUri = String(currentRootUri() || fileTreeLazyCacheRootUri || '').trim();
|
||||
if (!rootUri) return;
|
||||
try {
|
||||
if (!window.sessionStorage) return;
|
||||
var buckets = storedFileTreeExpansionBuckets();
|
||||
buckets[rootUri] = Array.from(fileTreeExpandedRelativePaths)
|
||||
.map(function(path) { return String(path || '').trim(); })
|
||||
.filter(Boolean)
|
||||
.slice(0, 256);
|
||||
window.sessionStorage.setItem(FILETREE_EXPANSION_STORAGE_KEY, JSON.stringify(buckets));
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
function scheduleRestorePersistedFileTreeExpansionState() {
|
||||
if (fileTreeExpansionRestoreTimer) window.clearTimeout(fileTreeExpansionRestoreTimer);
|
||||
fileTreeExpansionRestoreTimer = window.setTimeout(function() {
|
||||
fileTreeExpansionRestoreTimer = 0;
|
||||
restorePersistedFileTreeExpansionState();
|
||||
}, 0);
|
||||
}
|
||||
|
||||
function rememberFileTreeExpansionState() {
|
||||
var changed = false;
|
||||
document.querySelectorAll('#sidebar-file-tree-root .tree-row[data-shell-mode="filetree"]').forEach(function(row) {
|
||||
if (!(row instanceof HTMLElement)) return;
|
||||
var relativePath = localFileTreeRelativePathFromRow(row);
|
||||
if (!relativePath) return;
|
||||
if (row.getAttribute('aria-expanded') === 'true') {
|
||||
if (!fileTreeExpandedRelativePaths.has(relativePath)) changed = true;
|
||||
fileTreeExpandedRelativePaths.add(relativePath);
|
||||
} else {
|
||||
if (fileTreeExpandedRelativePaths.has(relativePath)) changed = true;
|
||||
fileTreeExpandedRelativePaths.delete(relativePath);
|
||||
}
|
||||
});
|
||||
if (changed) persistFileTreeExpansionState();
|
||||
}
|
||||
|
||||
function renderFileProjection(projection) {
|
||||
@@ -727,6 +779,8 @@ export const createSidebarTreeLiveApplyRuntime = (dependencies = {}) => {
|
||||
if (currentSourceKind() !== 'local_folder') return;
|
||||
var rootUri = currentRootUri();
|
||||
if (!rootUri) return;
|
||||
ensureFileTreeLazyCacheScope();
|
||||
scheduleRestorePersistedFileTreeExpansionState();
|
||||
var revision = '';
|
||||
var refreshTimer = 0;
|
||||
var scheduleRefresh = function() {
|
||||
@@ -824,6 +878,7 @@ export const createSidebarTreeLiveApplyRuntime = (dependencies = {}) => {
|
||||
if (!relativePath) return;
|
||||
if (expanded) fileTreeExpandedRelativePaths.add(relativePath);
|
||||
else fileTreeExpandedRelativePaths.delete(relativePath);
|
||||
persistFileTreeExpansionState();
|
||||
}
|
||||
|
||||
function renderCachedFileTreeChildren(row, button, relativePath) {
|
||||
@@ -896,6 +951,29 @@ export const createSidebarTreeLiveApplyRuntime = (dependencies = {}) => {
|
||||
setTreeRowExpanded(row, button, !collapsed);
|
||||
}
|
||||
|
||||
function restorePersistedFileTreeExpansionState() {
|
||||
if (currentSourceKind() !== 'local_folder') return false;
|
||||
ensureFileTreeLazyCacheScope();
|
||||
if (!fileTreeExpandedRelativePaths.size) return false;
|
||||
var restored = false;
|
||||
document.querySelectorAll('#sidebar-file-tree-root .tree-row[data-shell-mode="filetree"]').forEach(function(row) {
|
||||
if (!(row instanceof HTMLElement)) return;
|
||||
if (String(row.getAttribute('data-row-kind') || '').trim() !== 'folder') return;
|
||||
var relativePath = localFileTreeRelativePathFromRow(row);
|
||||
if (!relativePath || !fileTreeExpandedRelativePaths.has(relativePath)) return;
|
||||
var button = row.querySelector('[data-rust-action="toggle"]');
|
||||
if (row.getAttribute('data-filetree-children-loaded') === 'true') {
|
||||
setTreeRowExpanded(row, button, true);
|
||||
restored = true;
|
||||
return;
|
||||
}
|
||||
void loadFileTreeChildren(row, button);
|
||||
restored = true;
|
||||
});
|
||||
if (restored) document.documentElement.setAttribute('data-mnote-filetree-expansion-restored', 'true');
|
||||
return restored;
|
||||
}
|
||||
|
||||
|
||||
function installTreeLiveApplyEventListeners() {
|
||||
window.addEventListener('tree:title-updated', function(event) {
|
||||
@@ -1021,6 +1099,7 @@ export const createSidebarTreeLiveApplyRuntime = (dependencies = {}) => {
|
||||
refreshLocalFolderSidebarSnapshot,
|
||||
removeDocumentRowForMode,
|
||||
renderSidebarSnapshot,
|
||||
restorePersistedFileTreeExpansionState,
|
||||
setTreeLiveApplyError,
|
||||
startLocalFolderSidebarWatch,
|
||||
toggleChildren,
|
||||
|
||||
@@ -474,7 +474,16 @@ pub async fn page(Query(query): Query<OnlyOfficePageQuery>) -> Result<Response,
|
||||
url.host = origin.host;
|
||||
return url.toString();
|
||||
}}
|
||||
const isLocalFolderFileOpen = url.pathname === "/api/local-folder/files/open";
|
||||
const isLocal = ["127.0.0.1", "localhost", "host.docker.internal"].includes(url.hostname);
|
||||
if (proxyOrigin && isLocalFolderFileOpen) {{
|
||||
const origin = new URL(proxyOrigin);
|
||||
url.protocol = origin.protocol;
|
||||
url.host = origin.host;
|
||||
const proxy = new URL("/api/onlyoffice/proxy", proxyOrigin);
|
||||
proxy.searchParams.set("u", base64UrlEncodeUtf8(url.toString()));
|
||||
return proxy.toString();
|
||||
}}
|
||||
if (proxyOrigin && (isLocal || url.searchParams.has("token"))) {{
|
||||
const proxy = new URL("/api/onlyoffice/proxy", proxyOrigin);
|
||||
proxy.searchParams.set("u", base64UrlEncodeUtf8(url.toString()));
|
||||
@@ -1827,6 +1836,11 @@ mod tests {
|
||||
);
|
||||
assert!(html.contains("documentUrlBase,"));
|
||||
assert!(html.contains("resolvedFileUrl: fileState.resolvedFileUrl"));
|
||||
assert!(html.contains(
|
||||
r#"const isLocalFolderFileOpen = url.pathname === "/api/local-folder/files/open";"#
|
||||
));
|
||||
assert!(html.contains("if (proxyOrigin && isLocalFolderFileOpen)"));
|
||||
assert!(html.contains("if (proxyOrigin && (isLocal || url.searchParams.has(\"token\")))"));
|
||||
}
|
||||
|
||||
fn test_state(legacy_next_base_url: Option<String>) -> AppState {
|
||||
|
||||
Reference in New Issue
Block a user