max / goingson
7 files changed,
+50 insertions,
-22 deletions
| @@ -34,3 +34,6 @@ CLAUDE.md | |||
| 34 | 34 | ||
| 35 | 35 | # Private working files — live in _private/, synced via Syncthing | |
| 36 | 36 | todo.md | |
| 37 | + | ||
| 38 | + | # Generated by src-tauri/build.rs from makeover's embedded theme set | |
| 39 | + | /src-tauri/themes/ |
| @@ -2172,6 +2172,7 @@ dependencies = [ | |||
| 2172 | 2172 | "lettre", | |
| 2173 | 2173 | "libsqlite3-sys", | |
| 2174 | 2174 | "mailparse", | |
| 2175 | + | "makeover", | |
| 2175 | 2176 | "notify", | |
| 2176 | 2177 | "notify-debouncer-mini", | |
| 2177 | 2178 | "open", | |
| @@ -2194,7 +2195,6 @@ dependencies = [ | |||
| 2194 | 2195 | "tauri-plugin-updater", | |
| 2195 | 2196 | "tauri-plugin-window-state", | |
| 2196 | 2197 | "tempfile", | |
| 2197 | - | "theme-common", | |
| 2198 | 2198 | "thiserror 2.0.18", | |
| 2199 | 2199 | "tokio", | |
| 2200 | 2200 | "tokio-native-tls", | |
| @@ -6877,14 +6877,6 @@ dependencies = [ | |||
| 6877 | 6877 | ] | |
| 6878 | 6878 | ||
| 6879 | 6879 | [[package]] | |
| 6880 | - | name = "theme-common" | |
| 6881 | - | version = "0.7.0" | |
| 6882 | - | dependencies = [ | |
| 6883 | - | "serde", | |
| 6884 | - | "toml 0.8.2", | |
| 6885 | - | ] | |
| 6886 | - | ||
| 6887 | - | [[package]] | |
| 6888 | 6880 | name = "thiserror" | |
| 6889 | 6881 | version = "1.0.69" | |
| 6890 | 6882 | source = "registry+https://github.com/rust-lang/crates.io-index" |
| @@ -69,7 +69,7 @@ tauri-plugin-process = "2" | |||
| 69 | 69 | # Filesystem watching (db change notifications) | |
| 70 | 70 | notify = "6.0" | |
| 71 | 71 | notify-debouncer-mini = "0.4" | |
| 72 | - | theme-common = { path = "../../MNW/shared/theme-common" } | |
| 72 | + | makeover = "0.9.0" | |
| 73 | 73 | toml = "0.8" | |
| 74 | 74 | ||
| 75 | 75 | # Enums |
| @@ -14,6 +14,7 @@ crate-type = ["staticlib", "cdylib", "lib"] | |||
| 14 | 14 | ||
| 15 | 15 | [build-dependencies] | |
| 16 | 16 | tauri-build = { workspace = true } | |
| 17 | + | makeover.workspace = true | |
| 17 | 18 | ||
| 18 | 19 | [dependencies] | |
| 19 | 20 | goingson-core = { workspace = true } | |
| @@ -70,7 +71,7 @@ icalendar = { workspace = true } | |||
| 70 | 71 | flate2 = { workspace = true } | |
| 71 | 72 | ||
| 72 | 73 | # Theme loading | |
| 73 | - | theme-common = { workspace = true } | |
| 74 | + | makeover = { workspace = true } | |
| 74 | 75 | toml = { workspace = true } | |
| 75 | 76 | # Browser opening | |
| 76 | 77 | open = { workspace = true } |
| @@ -1,3 +1,32 @@ | |||
| 1 | + | use std::path::Path; | |
| 2 | + | ||
| 3 | + | /// Write the themes `makeover` ships into `themes/`, where `tauri.conf.json` | |
| 4 | + | /// picks them up as a bundled resource. | |
| 5 | + | /// | |
| 6 | + | /// Tauri's resource globs are read by the Tauri CLI against the crate | |
| 7 | + | /// directory, so they cannot point into a registry checkout or `OUT_DIR`. | |
| 8 | + | /// Materializing the embedded set here keeps `makeover` the single source of | |
| 9 | + | /// truth without vendoring a second copy of the theme files into this repo. | |
| 10 | + | /// The directory is generated, and gitignored. | |
| 11 | + | fn materialize_themes() { | |
| 12 | + | let dir = Path::new(env!("CARGO_MANIFEST_DIR")).join("themes"); | |
| 13 | + | std::fs::create_dir_all(&dir).expect("create themes/"); | |
| 14 | + | ||
| 15 | + | // Clear stale files first, so a theme removed upstream (or renamed) does | |
| 16 | + | // not linger in the bundle from an earlier build. | |
| 17 | + | for entry in std::fs::read_dir(&dir).expect("read themes/").flatten() { | |
| 18 | + | let path = entry.path(); | |
| 19 | + | if path.extension().is_some_and(|e| e == "toml") { | |
| 20 | + | std::fs::remove_file(&path).expect("remove stale theme"); | |
| 21 | + | } | |
| 22 | + | } | |
| 23 | + | ||
| 24 | + | for (id, source) in makeover::embedded_themes() { | |
| 25 | + | std::fs::write(dir.join(format!("{id}.toml")), source).expect("write theme"); | |
| 26 | + | } | |
| 27 | + | } | |
| 28 | + | ||
| 1 | 29 | fn main() { | |
| 30 | + | materialize_themes(); | |
| 2 | 31 | tauri_build::build() | |
| 3 | 32 | } |
| @@ -1,4 +1,4 @@ | |||
| 1 | - | //! Theme loading commands — thin Tauri wrappers over `theme_common`. | |
| 1 | + | //! Theme loading commands — thin Tauri wrappers over `makeover`. | |
| 2 | 2 | ||
| 3 | 3 | use std::path::PathBuf; | |
| 4 | 4 | use tauri::{AppHandle, Manager}; | |
| @@ -6,7 +6,7 @@ use tracing::instrument; | |||
| 6 | 6 | ||
| 7 | 7 | use super::ApiError; | |
| 8 | 8 | ||
| 9 | - | pub use theme_common::{SemanticTokens, ThemeMeta}; | |
| 9 | + | pub use makeover::{SemanticTokens, ThemeMeta}; | |
| 10 | 10 | ||
| 11 | 11 | /// Returns theme directories in priority order (later overrides earlier by ID). | |
| 12 | 12 | /// Each entry is `(path, is_custom)`. | |
| @@ -21,9 +21,12 @@ fn theme_dirs(app: &AppHandle) -> Vec<(PathBuf, bool)> { | |||
| 21 | 21 | } | |
| 22 | 22 | } | |
| 23 | 23 | ||
| 24 | - | // 2. Dev fallback: CARGO_MANIFEST_DIR → 3 parents up → Git/themes/ | |
| 25 | - | if let Some(dev_path) = theme_common::dev_themes_dir(env!("CARGO_MANIFEST_DIR").as_ref(), 3) { | |
| 26 | - | dirs.push((dev_path, false)); | |
| 24 | + | // 2. Dev fallback: the themes build.rs materialized from makeover. In a | |
| 25 | + | // dev run there is no bundled resource dir, so this is what supplies the | |
| 26 | + | // stock set; in production it is redundant with (1) and harmless. | |
| 27 | + | let generated = PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("themes"); | |
| 28 | + | if generated.is_dir() { | |
| 29 | + | dirs.push((generated, false)); | |
| 27 | 30 | } | |
| 28 | 31 | ||
| 29 | 32 | // 3. User custom themes (highest priority) | |
| @@ -41,14 +44,14 @@ fn theme_dirs(app: &AppHandle) -> Vec<(PathBuf, bool)> { | |||
| 41 | 44 | #[instrument(skip_all)] | |
| 42 | 45 | pub fn list_themes(app: AppHandle) -> Result<Vec<ThemeMeta>, ApiError> { | |
| 43 | 46 | let dirs = theme_dirs(&app); | |
| 44 | - | Ok(theme_common::list_themes_from_dirs(&dirs)) | |
| 47 | + | Ok(makeover::list_themes_from_dirs(&dirs)) | |
| 45 | 48 | } | |
| 46 | 49 | ||
| 47 | 50 | #[tauri::command] | |
| 48 | 51 | #[instrument(skip_all)] | |
| 49 | 52 | pub fn get_theme(app: AppHandle, id: String) -> Result<SemanticTokens, ApiError> { | |
| 50 | 53 | let dirs = theme_dirs(&app); | |
| 51 | - | theme_common::load_semantic(&dirs, &id).map_err(ApiError::internal) | |
| 54 | + | makeover::load_semantic(&dirs, &id).map_err(ApiError::internal) | |
| 52 | 55 | } | |
| 53 | 56 | ||
| 54 | 57 | #[tauri::command] | |
| @@ -72,7 +75,7 @@ pub fn import_theme(app: AppHandle, path: String) -> Result<ThemeMeta, ApiError> | |||
| 72 | 75 | .app_config_dir() | |
| 73 | 76 | .map_err(|e| ApiError::internal(e.to_string()))? | |
| 74 | 77 | .join("themes"); | |
| 75 | - | theme_common::import_theme(std::path::Path::new(&path), &custom_dir) | |
| 78 | + | makeover::import_theme(std::path::Path::new(&path), &custom_dir) | |
| 76 | 79 | .map_err(ApiError::internal) | |
| 77 | 80 | } | |
| 78 | 81 | ||
| @@ -80,12 +83,12 @@ pub fn import_theme(app: AppHandle, path: String) -> Result<ThemeMeta, ApiError> | |||
| 80 | 83 | #[instrument(skip_all)] | |
| 81 | 84 | pub fn export_theme(app: AppHandle, id: String, path: String) -> Result<(), ApiError> { | |
| 82 | 85 | let dirs = theme_dirs(&app); | |
| 83 | - | theme_common::export_theme(&dirs, &id, std::path::Path::new(&path)) | |
| 86 | + | makeover::export_theme(&dirs, &id, std::path::Path::new(&path)) | |
| 84 | 87 | .map_err(ApiError::internal) | |
| 85 | 88 | } | |
| 86 | 89 | ||
| 87 | 90 | #[cfg(test)] | |
| 88 | 91 | mod tests { | |
| 89 | - | // Core theme logic tests live in theme-common crate. | |
| 92 | + | // Core theme logic tests live in makeover crate. | |
| 90 | 93 | // App-specific tests here only if needed for theme_dirs behavior. | |
| 91 | 94 | } |
| @@ -39,7 +39,7 @@ | |||
| 39 | 39 | "icons/icon.ico" | |
| 40 | 40 | ], | |
| 41 | 41 | "resources": [ | |
| 42 | - | "../../../MNW/shared/themes/*.toml" | |
| 42 | + | "themes/*.toml" | |
| 43 | 43 | ], | |
| 44 | 44 | "iOS": { | |
| 45 | 45 | "developmentTeam": "93C54W92UP" |