diff --git a/rust/crates/mnote-web/browser/document-editor-adapter-runtime.js b/rust/crates/mnote-web/browser/document-editor-adapter-runtime.js
index 142e5f9a..822aa9ee 100644
--- a/rust/crates/mnote-web/browser/document-editor-adapter-runtime.js
+++ b/rust/crates/mnote-web/browser/document-editor-adapter-runtime.js
@@ -257,6 +257,12 @@ import {
shell.setAttribute('data-layout-density', String(options.layoutDensity || 'normal'));
shell.setAttribute('data-page-font', String(options.pageFont || 'default'));
shell.setAttribute('data-page-show-heading-numbers', String(Boolean(options.showHeadingNumbers)));
+ const hideTitleHeader = Boolean(options.hideTitleHeader || options.hide_title_header);
+ const header = shell.querySelector('.document-shell-header');
+ if (header instanceof HTMLElement) {
+ header.hidden = hideTitleHeader;
+ header.setAttribute('data-page-title-hidden', String(hideTitleHeader));
+ }
}
pane.querySelectorAll('[data-page-title-input="true"]').forEach((node) => {
if (!(node instanceof HTMLTextAreaElement)) return;
@@ -756,6 +762,22 @@ import {
bindMainEditorPageTab('primary');
bindMainEditorPageTab('secondary');
+ const shouldPrewarmPrimaryRuntime = paneRuntimes.length === 0
+ && document.querySelector('.mnote-workspace-empty-editor-host')
+ && document.querySelector(`${ROOT_SELECTOR}[data-pane-role="primary"]`);
+ if (shouldPrewarmPrimaryRuntime) {
+ const prewarmRuntime = () => {
+ loadRuntime().catch((error) => {
+ console.warn('mnote editor runtime prewarm failed', error);
+ });
+ };
+ if (typeof window.requestIdleCallback === 'function') {
+ window.requestIdleCallback(prewarmRuntime, { timeout: 2000 });
+ } else {
+ window.setTimeout(prewarmRuntime, 800);
+ }
+ }
+
window.addEventListener('pagehide', () => {
Array.from(documentSessionRegistry.values()).forEach((session) => {
sessionViews(session).forEach((view) => {
diff --git a/rust/crates/mnote-web/src/routes/gateway.rs b/rust/crates/mnote-web/src/routes/gateway.rs
index b515058e..ee076464 100644
--- a/rust/crates/mnote-web/src/routes/gateway.rs
+++ b/rust/crates/mnote-web/src/routes/gateway.rs
@@ -2826,6 +2826,8 @@ mod tests {
assert!(!html.contains(r#"data-row-id="local:asset:attachments/report-a.pdf""#));
assert!(html.contains(r#"data-testid="mnote-document-workspace""#));
assert!(html.contains(r#"data-mnote-resource-tab-host="true""#));
+ assert!(html.contains(r#"data-testid="mnote-leptos-tiptap-island-editor-root""#));
+ assert!(html.contains(r#"data-pane-role="primary""#));
assert!(html.contains("__MNOTE_DOCUMENT_PANES_BOOTSTRAP__"));
assert!(html.contains(
r#""#
diff --git a/rust/crates/mnote-web/src/ssr/pages/document.rs b/rust/crates/mnote-web/src/ssr/pages/document.rs
index 72c72727..9a06c776 100644
--- a/rust/crates/mnote-web/src/ssr/pages/document.rs
+++ b/rust/crates/mnote-web/src/ssr/pages/document.rs
@@ -25,7 +25,7 @@ pub struct DocumentPaneViewModel {
}
#[component]
-fn DocumentPane(model: DocumentPaneViewModel) -> impl IntoView {
+pub(super) fn DocumentPane(model: DocumentPaneViewModel) -> impl IntoView {
let pane_hidden = !model.visible;
let pane_role = model.pane_role.to_string();
let pane_role_attr = pane_role.clone();
diff --git a/rust/crates/mnote-web/src/ssr/pages/home.rs b/rust/crates/mnote-web/src/ssr/pages/home.rs
index b6c4b1ce..1cdfb2e6 100644
--- a/rust/crates/mnote-web/src/ssr/pages/home.rs
+++ b/rust/crates/mnote-web/src/ssr/pages/home.rs
@@ -1,6 +1,9 @@
//! MNOTE 首页组件(Wolai 风格)
-use super::layout::PageLayout;
+use super::{
+ document::{DocumentPane, DocumentPaneViewModel},
+ layout::PageLayout,
+};
use leptos::prelude::*;
/// MNOTE 首页。
@@ -61,6 +64,21 @@ pub fn HomePage(
}.into_any()
} else {
+ let empty_primary_model = DocumentPaneViewModel {
+ pane_role: "primary",
+ title: "文件夹".to_string(),
+ document_id: String::new(),
+ workspace_id: workspace_id.clone().unwrap_or_default(),
+ page_wide_layout: false,
+ page_small_text: false,
+ page_layout_density: "normal".to_string(),
+ page_font: "default".to_string(),
+ page_show_heading_numbers: false,
+ has_page_subtree: false,
+ primary_legacy_ids: true,
+ visible: true,
+ hide_title_header: true,
+ };
view! {