Host: workspaces (always) and encrypted folder sync (AppConfig::with_sync) commands; SiteHooks::backup_sections and backup_section_names say what a backup and sync carry; commands::WORKSPACES, commands::SYNC, testkit::assert_sync_guards

This commit is contained in:
CRTkafa 2026-10-01 04:26:03 +07:00
parent fa81dddec2
commit a36a7080a3
5 changed files with 435 additions and 5 deletions

View file

@ -89,6 +89,9 @@ pub struct AppConfig {
/// Google Fonts (install, remove, preview; the cache in app data): serves [`commands::GFONTS`]
/// and calls [`SiteHooks::fonts_changed`]. Needs the `net` feature.
pub fonts: bool,
/// Encrypted folder sync of the settings backup: serves [`commands::SYNC`] and needs
/// [`SiteHooks::backup_sections`]. ([`commands::WORKSPACES`] is served for every app.)
pub sync: bool,
/// Native updates and the hotfix channel: serves [`commands::UPDATE`] and runs the update loop.
/// Needs `updater` (the plugin) and the `net` feature.
#[cfg(feature = "net")]
@ -117,6 +120,7 @@ impl AppConfig {
store: None,
media: false,
fonts: false,
sync: false,
#[cfg(feature = "net")]
updates: None,
}
@ -129,6 +133,12 @@ impl AppConfig {
self
}
/// Serves the sync commands ([`commands::SYNC`]).
pub const fn with_sync(mut self) -> Self {
self.sync = true;
self
}
/// Serves the Google Fonts commands ([`commands::GFONTS`]).
pub const fn with_fonts(mut self) -> Self {
self.fonts = true;
@ -229,6 +239,18 @@ pub trait SiteHooks: Send + Sync + 'static {
/// theme, and the font bytes, again.
fn fonts_changed(&self, _app: &AppHandle) {}
/// The app's native settings as backup sections (themes, plugins, tweaks, ... keyed by section
/// name, from app data): what a backup and [`commands::SYNC`] carry besides the shell's own
/// storage. By default none.
fn backup_sections(&self, _app: &AppHandle) -> Result<serde_json::Map<String, serde_json::Value>, String> {
Ok(serde_json::Map::new())
}
/// The names of the sections an import may carry (others are dropped). By default none.
fn backup_section_names(&self) -> &'static [&'static str] {
&[]
}
/// `tab` was laid out for `item` (existing or new), before it is placed.
fn tab_placed(&self, _app: &AppHandle, _tab: &Webview, _item: &TabLayout) {}
@ -1147,6 +1169,11 @@ fn store_handler() -> impl Fn(tauri::ipc::Invoke<Wry>) -> bool + Send + Sync + '
|_| false
}
/// The workspaces and sync commands ([`commands::WORKSPACES`], [`commands::SYNC`]).
fn sync_handler() -> impl Fn(tauri::ipc::Invoke<Wry>) -> bool + Send + Sync + 'static {
crate::sync_commands::handler()
}
/// The update commands ([`commands::UPDATE`]): with the `net` feature only.
#[cfg(feature = "net")]
fn update_handler() -> impl Fn(tauri::ipc::Invoke<Wry>) -> bool + Send + Sync + 'static {
@ -1208,6 +1235,7 @@ impl App {
let media_handler = media_handler();
let fonts_handler = fonts_handler();
let update_handler = update_handler();
let sync_handler = sync_handler();
let builder = tauri::Builder::<Wry>::default()
// Must be first: a second launch focuses the running window instead of fighting over
// the app's data and WebView profile (and hands over its link).
@ -1288,6 +1316,7 @@ impl App {
#[cfg(feature = "net")]
crate::store_commands::init(&handle, &config);
crate::media_commands::init(&handle);
crate::sync_commands::init(&handle);
#[cfg(feature = "net")]
crate::fonts_commands::init(&handle);
#[cfg(feature = "net")]
@ -1314,6 +1343,8 @@ impl App {
fonts_handler(invoke)
} else if commands::UPDATE.contains(&invoke.message.command()) {
update_handler(invoke)
} else if commands::WORKSPACES.contains(&invoke.message.command()) || commands::SYNC.contains(&invoke.message.command()) {
sync_handler(invoke)
} else if commands::is_host(invoke.message.command()) {
host_handler(invoke)
} else {