Improve local filetree view state and sidebar performance
This commit is contained in:
@@ -8,11 +8,12 @@ use crate::routes::local_folder_source::{
|
||||
};
|
||||
use crate::routes::snapshot_support::load_sidebar_dataset;
|
||||
use crate::routes::web_shell::{
|
||||
build_document_panes_bootstrap_json, build_editor_bootstrap_json,
|
||||
build_page_aggregate_snapshot, escape_html, escape_script_json, load_file_tree_html,
|
||||
load_sidebar_tree_html, load_workspace_shell_projection,
|
||||
attach_sidebar_shortcuts_to_dataset, build_document_panes_bootstrap_json,
|
||||
build_editor_bootstrap_json, build_page_aggregate_snapshot, escape_html, escape_script_json,
|
||||
load_file_tree_html, load_sidebar_tree_html, load_workspace_shell_projection,
|
||||
render_document_title_controller_script, render_editor_island_adapter_script,
|
||||
render_local_file_tree_html, render_local_sidebar_tree_html,
|
||||
render_editor_runtime_preload_links, render_local_file_tree_html,
|
||||
render_local_file_tree_html_scoped, render_local_sidebar_tree_html,
|
||||
};
|
||||
use crate::transport::convex::execute_convex_mutation_by_name;
|
||||
use crate::workspace_shell::{
|
||||
@@ -67,6 +68,7 @@ pub(crate) struct RootEntryQuery {
|
||||
workspace_id: Option<String>,
|
||||
source_kind: Option<String>,
|
||||
root_uri: Option<String>,
|
||||
file_tree_scope: Option<String>,
|
||||
tree_view: Option<String>,
|
||||
restore_focus_row_id: Option<String>,
|
||||
}
|
||||
@@ -300,6 +302,11 @@ pub async fn root_entry(
|
||||
.as_deref()
|
||||
.map(str::trim)
|
||||
.is_some_and(|value| value == "filetree");
|
||||
let file_tree_scope = query
|
||||
.file_tree_scope
|
||||
.as_deref()
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty());
|
||||
let (
|
||||
workspace_id,
|
||||
workspace_projection,
|
||||
@@ -318,15 +325,8 @@ pub async fn root_entry(
|
||||
WebError::bad_request_code("local_folder_root_required", "缺少本地文件夹 rootUri")
|
||||
})?;
|
||||
ensure_local_workspace_read_access_with_state(&state, &context, root_uri)?;
|
||||
let snapshot = if requests_filetree_first {
|
||||
crate::routes::local_folder_source::load_local_folder_file_tree_snapshot_with_reveal(
|
||||
root_uri,
|
||||
requested_page_id.as_deref(),
|
||||
)?
|
||||
} else {
|
||||
load_local_folder_page_tree_snapshot(root_uri)?
|
||||
};
|
||||
let workspace_id = snapshot
|
||||
let page_tree_snapshot = load_local_folder_page_tree_snapshot(root_uri)?;
|
||||
let workspace_id = page_tree_snapshot
|
||||
.dataset
|
||||
.get("workspace")
|
||||
.and_then(|workspace| workspace.get("id"))
|
||||
@@ -337,8 +337,15 @@ pub async fn root_entry(
|
||||
.to_string();
|
||||
let requested_or_recent_page_id =
|
||||
choose_root_entry_active_page_id(requested_page_id.clone(), None, None, None);
|
||||
let mut workspace_dataset = page_tree_snapshot.dataset.clone();
|
||||
attach_sidebar_shortcuts_to_dataset(
|
||||
&state,
|
||||
&context,
|
||||
&workspace_id,
|
||||
&mut workspace_dataset,
|
||||
);
|
||||
let workspace_projection = build_workspace_shell_projection(
|
||||
&snapshot.dataset,
|
||||
&workspace_dataset,
|
||||
&workspace_id,
|
||||
requested_or_recent_page_id.as_deref(),
|
||||
"本地文件夹",
|
||||
@@ -352,20 +359,18 @@ pub async fn root_entry(
|
||||
.first()
|
||||
.map(|item| item.id.as_str()),
|
||||
);
|
||||
let sidebar_tree_html = if requests_filetree_first {
|
||||
String::new()
|
||||
} else {
|
||||
render_local_sidebar_tree_html(root_uri, selected_active_page_id.as_deref())?
|
||||
};
|
||||
let sidebar_tree_html =
|
||||
render_local_sidebar_tree_html(root_uri, selected_active_page_id.as_deref())?;
|
||||
let restore_focus_row_id = query
|
||||
.restore_focus_row_id
|
||||
.as_deref()
|
||||
.map(str::trim)
|
||||
.filter(|value| !value.is_empty());
|
||||
let file_tree_html = render_local_file_tree_html(
|
||||
let file_tree_html = render_local_file_tree_html_scoped(
|
||||
root_uri,
|
||||
selected_active_page_id.as_deref(),
|
||||
restore_focus_row_id,
|
||||
file_tree_scope,
|
||||
)?;
|
||||
(
|
||||
workspace_id,
|
||||
@@ -399,8 +404,15 @@ pub async fn root_entry(
|
||||
.filter(|value| !value.is_empty())
|
||||
.unwrap_or("local-folder")
|
||||
.to_string();
|
||||
let mut workspace_dataset = snapshot.dataset.clone();
|
||||
attach_sidebar_shortcuts_to_dataset(
|
||||
&state,
|
||||
&context,
|
||||
&workspace_id,
|
||||
&mut workspace_dataset,
|
||||
);
|
||||
let workspace_projection = build_workspace_shell_projection(
|
||||
&snapshot.dataset,
|
||||
&workspace_dataset,
|
||||
&workspace_id,
|
||||
requested_page_id.as_deref(),
|
||||
&default_workspace_name,
|
||||
@@ -437,6 +449,7 @@ pub async fn root_entry(
|
||||
None,
|
||||
);
|
||||
let workspace_projection = load_workspace_shell_projection(
|
||||
Some(&state),
|
||||
state.config(),
|
||||
&context,
|
||||
&workspace_id,
|
||||
@@ -489,6 +502,7 @@ pub async fn root_entry(
|
||||
} else {
|
||||
None
|
||||
},
|
||||
file_tree_scope,
|
||||
);
|
||||
let workspace_name = workspace_projection.workspace_name.clone();
|
||||
let active_page_id = selected_active_page_id.unwrap_or_default();
|
||||
@@ -593,12 +607,19 @@ pub async fn root_entry(
|
||||
Err(_) => ("MNOTE".to_string(), render_workspace_entry(), String::new()),
|
||||
}
|
||||
};
|
||||
let editor_runtime_preload_links =
|
||||
if body_extra.contains("document-editor-adapter-runtime.js") {
|
||||
render_editor_runtime_preload_links()
|
||||
} else {
|
||||
""
|
||||
};
|
||||
let mut response = Html(format!(
|
||||
r#"<!doctype html>
|
||||
<html lang="zh-CN">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<title>{}</title>
|
||||
{}
|
||||
<style>{}</style>
|
||||
</head>
|
||||
<body data-mnote-web-owner="mnote-web" data-mnote-shell="workspace" data-mnote-actor-id="{}" data-mnote-source-kind="{}" data-mnote-root-uri="{}">
|
||||
@@ -607,6 +628,7 @@ pub async fn root_entry(
|
||||
</body>
|
||||
</html>"#,
|
||||
escape_html(&html_title),
|
||||
editor_runtime_preload_links,
|
||||
crate::ssr::MNOTE_CSS,
|
||||
escape_html(context.auth.actor_id.as_str()),
|
||||
escape_html(active_source_kind.as_deref().unwrap_or("convex_workspace")),
|
||||
@@ -654,21 +676,25 @@ pub async fn trash_entry(
|
||||
crate::routes::local_folder_source::local_workspace_id_from_root_uri(root_uri)?;
|
||||
let sidebar_tree_html = render_local_sidebar_tree_html(root_uri, None).unwrap_or_default();
|
||||
let file_tree_html = render_local_file_tree_html(root_uri, None, None).unwrap_or_default();
|
||||
let workspace_projection = build_workspace_shell_projection(
|
||||
&json!({
|
||||
"active_workspace_id": workspace_id,
|
||||
"workspaces": [{ "id": workspace_id, "name": "我的空间" }],
|
||||
"documents": [],
|
||||
}),
|
||||
let mut workspace_dataset = json!({
|
||||
"active_workspace_id": workspace_id,
|
||||
"workspaces": [{ "id": workspace_id, "name": "我的空间" }],
|
||||
"documents": [],
|
||||
});
|
||||
attach_sidebar_shortcuts_to_dataset(
|
||||
&state,
|
||||
&context,
|
||||
&workspace_id,
|
||||
None,
|
||||
"我的空间",
|
||||
&mut workspace_dataset,
|
||||
);
|
||||
let workspace_projection =
|
||||
build_workspace_shell_projection(&workspace_dataset, &workspace_id, None, "我的空间");
|
||||
let workspace_sidebar_html = render_workspace_shell_sidebar_html(
|
||||
&workspace_projection,
|
||||
Some(sidebar_tree_html.as_str()),
|
||||
Some(file_tree_html.as_str()),
|
||||
None,
|
||||
None,
|
||||
);
|
||||
let trash_workbench_html = render_local_trash_workbench_html(
|
||||
&workspace_id,
|
||||
@@ -714,6 +740,7 @@ pub async fn trash_entry(
|
||||
let workspace_id =
|
||||
resolve_root_workspace_id(&state, &context, query.workspace_id.as_deref()).await?;
|
||||
let workspace_projection = load_workspace_shell_projection(
|
||||
Some(&state),
|
||||
state.config(),
|
||||
&context,
|
||||
&workspace_id,
|
||||
@@ -732,6 +759,7 @@ pub async fn trash_entry(
|
||||
Some(sidebar_tree_html.as_str()),
|
||||
Some(file_tree_html.as_str()),
|
||||
None,
|
||||
None,
|
||||
);
|
||||
let dataset = load_sidebar_dataset(state.config(), &context, &workspace_id)
|
||||
.await
|
||||
@@ -2779,6 +2807,9 @@ mod tests {
|
||||
assert!(html.contains(r#"data-mnote-shell="workspace""#));
|
||||
assert!(html.contains("local_folder"));
|
||||
assert!(html.contains("README.md"));
|
||||
assert!(html.contains(r#"id="sidebar-tree-root""#));
|
||||
assert!(html.contains(r#"data-shell-mode="page""#));
|
||||
assert!(html.contains(r#"data-node-id="local-md:README.md""#));
|
||||
assert!(html.contains(r#"data-row-id="local:folder:docs""#));
|
||||
assert!(!html.contains(r#"data-row-id="local:markdown:docs/child.md""#));
|
||||
assert!(html.contains(r#"data-row-id="local:asset:plain.txt""#));
|
||||
@@ -2832,6 +2863,12 @@ mod tests {
|
||||
assert!(html.contains(
|
||||
r#"<script type="module" src="/api/mnote-browser-runtime/document-editor-adapter-runtime.js"></script>"#
|
||||
));
|
||||
assert!(html.contains(
|
||||
r#"<link rel="modulepreload" href="/api/leptos-tiptap-runtime/mnote-leptos-tiptap-spike-island.js">"#
|
||||
));
|
||||
assert!(html.contains(
|
||||
r#"<link rel="preload" href="/api/leptos-tiptap-runtime/mnote-leptos-tiptap-spike-island_bg.wasm" as="fetch" type="application/wasm" crossorigin>"#
|
||||
));
|
||||
assert!(
|
||||
include_str!("../../browser/document-resource-tab-runtime.js")
|
||||
.contains("openResourceInActiveTab")
|
||||
|
||||
Reference in New Issue
Block a user