Store kind "strings": string packs install like themes and plugins (dropped .strings.json, links, the signed Store), validated as plain data on this side (envelope, plain text, size caps, the app's own site), kept in app data strings/ with their order and which are on (at most 8); licence and credits are optional fields of every catalog item; five shell-only commands (strings_list, strings_read, strings_set, strings_remove, strings_apply); the shell's delivery (packs + the inventory slice) goes into site tabs' session storage by revision, as the first document-start layer of a site tab and never in safe mode

This commit is contained in:
CRTkafa 2026-10-01 03:56:54 +07:00
parent 55f1a7ede2
commit 82c91c6d10
10 changed files with 593 additions and 13 deletions

View file

@ -12,7 +12,7 @@ use crate::app::AppConfig;
use crate::host::{emit_shell, eval_in_site_tabs, shell_only};
use crate::plugins::ScriptPlugin;
use crate::policy;
use crate::store::{InstallOutcome, InstallPreview, InstallRecords, LinkEvent, Store, StoreItemRef, StoreView, EVENT_LINK};
use crate::store::{delivery_script, InstallOutcome, InstallPreview, InstallRecords, LinkEvent, Store, StoreItemRef, StoreView, StringsList, EVENT_LINK};
use tauri::{AppHandle, Manager, State, Webview};
use tauri_plugin_deep_link::DeepLinkExt;
@ -141,6 +141,55 @@ pub(crate) async fn store_stage(webview: Webview, app: AppHandle, item: StoreIte
store(&app)?.stage_item(&item).await
}
/// Installed string packs, in application order, with which are on.
#[tauri::command]
pub(crate) async fn strings_list(webview: Webview, app: AppHandle) -> Result<StringsList, String> {
shell_only(&webview)?;
Ok(store(&app)?.strings().list())
}
/// One installed string pack's JSON (the shell checks it against the site's inventory).
#[tauri::command]
pub(crate) async fn strings_read(webview: Webview, app: AppHandle, id: String) -> Result<String, String> {
shell_only(&webview)?;
let bytes = store(&app)?.strings().read(&id).ok_or("STRINGS: no such string pack")?;
String::from_utf8(bytes).map_err(|_| "STRINGS: not UTF-8".to_owned())
}
/// Sets the order of the installed string packs and which are on (at most 8).
#[tauri::command]
pub(crate) async fn strings_set(webview: Webview, app: AppHandle, order: Vec<String>, enabled: Vec<String>) -> Result<StringsList, String> {
shell_only(&webview)?;
store(&app)?.strings().set(&order, &enabled)
}
/// Removes an installed string pack.
#[tauri::command]
pub(crate) async fn strings_remove(webview: Webview, app: AppHandle, id: String) -> Result<StringsList, String> {
shell_only(&webview)?;
store(&app)?.remove_strings(&id)
}
/// The shell computed what site tabs get (the packs that are on, in order, with the slice of the
/// site's inventory their keys need; `None`: no pack on). It is kept for new tabs, and every site
/// tab gets it in its session storage and reloads, so X registers its strings through it from the
/// start. Data only; a site tab gains no command.
#[tauri::command]
pub(crate) async fn strings_apply(webview: Webview, app: AppHandle, delivery: Option<String>) -> Result<(), String> {
shell_only(&webview)?;
let rev = std::time::SystemTime::now().duration_since(std::time::UNIX_EPOCH).map(|d| d.as_millis() as u64).unwrap_or(0);
let stored = store(&app)?.strings().set_delivery(delivery.as_deref(), rev)?;
eval_in_site(&app, &delivery_script(crate::app::config(&app).site.hosts, &stored, true));
Ok(())
}
/// The document-start script that gives a new site tab the current string packs (none when the
/// shell never applied any). Part of the normal page layers, so safe mode leaves it out.
pub(crate) fn strings_init_script(app: &AppHandle) -> Option<String> {
let stored = app.try_state::<Store>()?.strings().delivery()?;
Some(delivery_script(crate::app::config(app).site.hosts, &stored, false))
}
/// The store's commands ([`crate::commands::STORE`]).
pub(crate) fn handler() -> impl Fn(tauri::ipc::Invoke<tauri::Wry>) -> bool + Send + Sync + 'static {
tauri::generate_handler![
@ -153,6 +202,11 @@ pub(crate) fn handler() -> impl Fn(tauri::ipc::Invoke<tauri::Wry>) -> bool + Sen
install_records,
install_forget,
store_catalog,
store_stage
store_stage,
strings_list,
strings_read,
strings_set,
strings_remove,
strings_apply
]
}