Repair: the Google Fonts host commands as 7f9e172 meant them (a staging race split them from 43fc8a1)
Two agents staged the same host files at once:7f9e172went in with the diagnostics' hunks of app.rs, commands.rs and lib.rs instead of its own, and43fc8a1then dropped fonts_commands.rs. This puts back exactly the Google Fonts wiring from the working tree (AppConfig::with_fonts, SiteHooks::fonts_changed, commands::GFONTS, the fonts handler, fonts_commands.rs); the diagnostics stay as committed. theme.rs, still in progress, is not included. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
parent
43fc8a15f5
commit
825742b964
4 changed files with 112 additions and 5 deletions
|
|
@ -86,6 +86,9 @@ pub struct AppConfig {
|
|||
pub store: Option<&'static crate::store::StoreConfig>,
|
||||
/// The shell's media panel (gallery folders, the clipboard history): serves [`commands::MEDIA`].
|
||||
pub media: bool,
|
||||
/// 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,
|
||||
}
|
||||
|
||||
impl AppConfig {
|
||||
|
|
@ -109,9 +112,16 @@ impl AppConfig {
|
|||
home_url: None,
|
||||
store: None,
|
||||
media: false,
|
||||
fonts: false,
|
||||
}
|
||||
}
|
||||
|
||||
/// Serves the Google Fonts commands ([`commands::GFONTS`]).
|
||||
pub const fn with_fonts(mut self) -> Self {
|
||||
self.fonts = true;
|
||||
self
|
||||
}
|
||||
|
||||
/// Serves the media panel's commands ([`commands::MEDIA`]).
|
||||
pub const fn with_media(mut self) -> Self {
|
||||
self.media = true;
|
||||
|
|
@ -202,6 +212,10 @@ pub trait SiteHooks: Send + Sync + 'static {
|
|||
/// A tab webview was created.
|
||||
fn tab_created(&self, _app: &AppHandle) {}
|
||||
|
||||
/// A Google font was installed or removed ([`commands::GFONTS`]): give the site tabs their
|
||||
/// theme, and the font bytes, again.
|
||||
fn fonts_changed(&self, _app: &AppHandle) {}
|
||||
|
||||
/// `tab` was laid out for `item` (existing or new), before it is placed.
|
||||
fn tab_placed(&self, _app: &AppHandle, _tab: &Webview, _item: &TabLayout) {}
|
||||
|
||||
|
|
@ -248,6 +262,11 @@ fn host_state(app: &AppHandle) -> tauri::State<'_, Host> {
|
|||
app.state::<Host>()
|
||||
}
|
||||
|
||||
/// The app's site hooks ([`run_app`] must be running).
|
||||
pub(crate) fn hooks(app: &AppHandle) -> Arc<dyn SiteHooks> {
|
||||
host_state(app).hooks.clone()
|
||||
}
|
||||
|
||||
/// The app's config ([`run_app`] must be running).
|
||||
pub fn config(app: &AppHandle) -> AppConfig {
|
||||
host_state(app).config
|
||||
|
|
@ -1115,6 +1134,17 @@ fn store_handler() -> impl Fn(tauri::ipc::Invoke<Wry>) -> bool + Send + Sync + '
|
|||
|_| false
|
||||
}
|
||||
|
||||
/// The Google Fonts commands ([`commands::GFONTS`]): with the `net` feature (downloads) only.
|
||||
#[cfg(feature = "net")]
|
||||
fn fonts_handler() -> impl Fn(tauri::ipc::Invoke<Wry>) -> bool + Send + Sync + 'static {
|
||||
crate::fonts_commands::handler()
|
||||
}
|
||||
|
||||
#[cfg(not(feature = "net"))]
|
||||
fn fonts_handler() -> impl Fn(tauri::ipc::Invoke<Wry>) -> bool + Send + Sync + 'static {
|
||||
|_| false
|
||||
}
|
||||
|
||||
/// The media panel's commands ([`commands::MEDIA`]).
|
||||
fn media_handler() -> impl Fn(tauri::ipc::Invoke<Wry>) -> bool + Send + Sync + 'static {
|
||||
crate::media_commands::handler()
|
||||
|
|
@ -1152,6 +1182,7 @@ impl App {
|
|||
let host_handler = host_handler();
|
||||
let store_handler = store_handler();
|
||||
let media_handler = media_handler();
|
||||
let fonts_handler = fonts_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).
|
||||
|
|
@ -1232,6 +1263,8 @@ impl App {
|
|||
#[cfg(feature = "net")]
|
||||
crate::store_commands::init(&handle, &config);
|
||||
crate::media_commands::init(&handle);
|
||||
#[cfg(feature = "net")]
|
||||
crate::fonts_commands::init(&handle);
|
||||
// Safe mode for this run: the launch argument, or Shift held while starting (Windows).
|
||||
crate::safe::set(crate::safe::at_launch(std::env::args(), host::shift_held()));
|
||||
// Focus and layering diagnostics for this run: `--diag` or WAYBETTER_DIAG=1 (app log folder, diag.log).
|
||||
|
|
@ -1250,6 +1283,8 @@ impl App {
|
|||
store_handler(invoke)
|
||||
} else if commands::MEDIA.contains(&invoke.message.command()) {
|
||||
media_handler(invoke)
|
||||
} else if commands::GFONTS.contains(&invoke.message.command()) {
|
||||
fonts_handler(invoke)
|
||||
} else if commands::is_host(invoke.message.command()) {
|
||||
host_handler(invoke)
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -82,9 +82,13 @@ pub const MEDIA: &[&str] = &[
|
|||
"clip_remove",
|
||||
];
|
||||
|
||||
/// Shell-only, optional: Google Fonts (what is installed, install, remove, the faces of a family and
|
||||
/// a preview), served when the app sets `AppConfig::fonts`; needs the `net` feature.
|
||||
pub const GFONTS: &[&str] = &["gfonts_installed", "gfonts_install", "gfonts_remove", "gfonts_faces", "gfonts_preview"];
|
||||
|
||||
/// Whether `command` is one of the host's (dispatched to the host, never to the app's handler).
|
||||
pub fn is_host(command: &str) -> bool {
|
||||
SHELL.contains(&command) || TAB.contains(&command) || SITE.contains(&command) || STORE.contains(&command) || MEDIA.contains(&command)
|
||||
SHELL.contains(&command) || TAB.contains(&command) || SITE.contains(&command) || STORE.contains(&command) || MEDIA.contains(&command) || GFONTS.contains(&command)
|
||||
}
|
||||
|
||||
/// The capability permission tauri-build generates for `command` (`tabs_sync` → `allow-tabs-sync`).
|
||||
|
|
@ -99,8 +103,8 @@ pub fn permission(command: &str) -> String {
|
|||
/// tauri_build::AppManifest::new().commands(waybetter_host::commands::manifest(&["draft_list"]))
|
||||
/// ```
|
||||
pub fn manifest(app: &[&'static str]) -> &'static [&'static str] {
|
||||
let mut all: Vec<&'static str> = Vec::with_capacity(app.len() + SHELL.len() + TAB.len() + SITE.len() + STORE.len() + MEDIA.len());
|
||||
for command in app.iter().chain(SHELL).chain(TAB).chain(SITE).chain(STORE).chain(MEDIA) {
|
||||
let mut all: Vec<&'static str> = Vec::with_capacity(app.len() + SHELL.len() + TAB.len() + SITE.len() + STORE.len() + MEDIA.len() + GFONTS.len());
|
||||
for command in app.iter().chain(SHELL).chain(TAB).chain(SITE).chain(STORE).chain(MEDIA).chain(GFONTS) {
|
||||
if !all.contains(command) {
|
||||
all.push(command);
|
||||
}
|
||||
|
|
@ -117,7 +121,7 @@ mod tests {
|
|||
let all = manifest(&["draft_list", "tabs_sync"]);
|
||||
assert_eq!(all[0], "draft_list");
|
||||
assert_eq!(all.iter().filter(|c| **c == "tabs_sync").count(), 1);
|
||||
for command in SHELL.iter().chain(TAB).chain(SITE).chain(STORE).chain(MEDIA) {
|
||||
for command in SHELL.iter().chain(TAB).chain(SITE).chain(STORE).chain(MEDIA).chain(GFONTS) {
|
||||
assert!(all.contains(command), "{command}");
|
||||
assert!(is_host(command));
|
||||
}
|
||||
|
|
@ -127,7 +131,7 @@ mod tests {
|
|||
|
||||
#[test]
|
||||
fn shell_and_tab_commands_do_not_overlap() {
|
||||
assert!(!SHELL.iter().any(|command| TAB.contains(command) || SITE.contains(command) || STORE.contains(command) || MEDIA.contains(command)));
|
||||
assert!(!SHELL.iter().any(|command| TAB.contains(command) || SITE.contains(command) || STORE.contains(command) || MEDIA.contains(command) || GFONTS.contains(command)));
|
||||
assert!(!TAB.iter().any(|command| SITE.contains(command)));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
66
crates/waybetter-host/src/fonts_commands.rs
Normal file
66
crates/waybetter-host/src/fonts_commands.rs
Normal file
|
|
@ -0,0 +1,66 @@
|
|||
//! Google Fonts, native side, for every app that sets [`crate::app::AppConfig::fonts`]: the
|
||||
//! shell-only `gfonts_*` commands ([`crate::commands::GFONTS`]) over [`crate::fonts`]'s downloads
|
||||
//! and cache (`fonts.googleapis.com` and `fonts.gstatic.com` only, app-data `fonts/`). Site tabs
|
||||
//! never request fonts and gain no command: native code hands them cached bytes
|
||||
//! ([`crate::fonts::page_script_for`]).
|
||||
//!
|
||||
//! When a font is installed or removed the app's [`crate::app::SiteHooks::fonts_changed`] runs, so
|
||||
//! it can give every site tab its theme (and the font bytes) again.
|
||||
|
||||
use crate::fonts::{self, InstalledFont};
|
||||
use crate::gfonts::Weights;
|
||||
use crate::host::shell_only;
|
||||
use tauri::{AppHandle, Manager, Webview};
|
||||
|
||||
/// Opens the font cache in app data. Does nothing unless the app set [`crate::app::AppConfig::fonts`].
|
||||
pub(crate) fn init(app: &AppHandle) {
|
||||
if !crate::app::config(app).fonts {
|
||||
return;
|
||||
}
|
||||
if let Ok(dir) = app.path().app_data_dir() {
|
||||
fonts::init(&dir);
|
||||
}
|
||||
}
|
||||
|
||||
fn changed(app: &AppHandle) {
|
||||
crate::app::hooks(app).fonts_changed(app);
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub(crate) async fn gfonts_installed(webview: Webview) -> Result<Vec<InstalledFont>, String> {
|
||||
shell_only(&webview)?;
|
||||
fonts::installed()
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub(crate) async fn gfonts_install(webview: Webview, app: AppHandle, family: String, weights: Weights) -> Result<InstalledFont, String> {
|
||||
shell_only(&webview)?;
|
||||
let installed = fonts::install(family, weights).await?;
|
||||
changed(&app);
|
||||
Ok(installed)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub(crate) async fn gfonts_remove(webview: Webview, app: AppHandle, family: String) -> Result<(), String> {
|
||||
shell_only(&webview)?;
|
||||
fonts::remove(&family)?;
|
||||
changed(&app);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub(crate) async fn gfonts_faces(webview: Webview, family: String) -> Result<serde_json::Value, String> {
|
||||
shell_only(&webview)?;
|
||||
fonts::faces(&family)
|
||||
}
|
||||
|
||||
#[tauri::command]
|
||||
pub(crate) async fn gfonts_preview(webview: Webview, family: String, weights: Weights, text: String) -> Result<Vec<serde_json::Value>, String> {
|
||||
shell_only(&webview)?;
|
||||
fonts::preview(family, weights, text).await
|
||||
}
|
||||
|
||||
/// The fonts commands ([`crate::commands::GFONTS`]).
|
||||
pub(crate) fn handler() -> impl Fn(tauri::ipc::Invoke<tauri::Wry>) -> bool + Send + Sync + 'static {
|
||||
tauri::generate_handler![gfonts_installed, gfonts_install, gfonts_remove, gfonts_faces, gfonts_preview]
|
||||
}
|
||||
|
|
@ -85,6 +85,8 @@ pub mod app;
|
|||
mod store_commands;
|
||||
#[cfg(feature = "app")]
|
||||
pub mod media_commands;
|
||||
#[cfg(all(feature = "app", feature = "net"))]
|
||||
mod fonts_commands;
|
||||
#[cfg(all(feature = "app", debug_assertions))]
|
||||
pub mod devloop;
|
||||
#[cfg(feature = "tauri")]
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue