Migrate from window.electron to tauri IPC functions across components

- Replaced `window.electron.invoke` calls with equivalent `tauri` function calls for all IPC interactions.
- Removed `electron.d.ts` TypeScript definitions as they are no longer needed.
- Updated related logic for offline/online state synchronization.
- Added `types.rs` and `shared/mod.rs` modules to support Tauri IPC integration with Rust enums and shared logic.
- Refactored IPC request queues to use updated handler names for consistency with Tauri.
This commit is contained in:
natreex
2026-03-21 09:34:13 -04:00
parent 1a15692e40
commit ee4438834c
144 changed files with 21258 additions and 876 deletions

View File

@@ -0,0 +1,239 @@
use serde::{Deserialize, Serialize};
use serde_json::Value;
use tauri::State;
use crate::db::connection::DbManager;
use crate::domains::chapter::service;
use crate::error::AppError;
use crate::helpers::timestamp_in_seconds;
use crate::shared::session::SessionState;
use crate::shared::types::Lang;
fn get_session(session: &State<SessionState>) -> Result<(String, Lang), AppError> {
let session_guard = session.lock().map_err(|e| AppError::Internal(format!("Session lock failed: {}", e)))?;
let user_id = session_guard.get_user_id().map_err(|e| AppError::Auth(e))?.to_string();
let lang = session_guard.lang;
Ok((user_id, lang))
}
// ─── Queries ──────────────────────────────────────────
#[tauri::command]
pub fn get_chapters(book_id: String, db: State<DbManager>, session: State<SessionState>) -> Result<Vec<service::ChapterProps>, AppError> {
let (user_id, lang) = get_session(&session)?;
let db_manager = db.lock().map_err(|e| AppError::Internal(format!("DB lock failed: {}", e)))?;
let conn = db_manager.get_connection(&user_id)?;
service::get_all_chapters_from_a_book(conn, &user_id, &book_id, lang)
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct GetWholeChapterData {
pub id: String,
pub version: i64,
pub book_id: String,
}
#[tauri::command]
pub fn get_whole_chapter(data: GetWholeChapterData, db: State<DbManager>, session: State<SessionState>) -> Result<service::ChapterProps, AppError> {
let (user_id, lang) = get_session(&session)?;
let db_manager = db.lock().map_err(|e| AppError::Internal(format!("DB lock failed: {}", e)))?;
let conn = db_manager.get_connection(&user_id)?;
service::get_whole_chapter(conn, &user_id, &data.id, data.version, Some(&data.book_id), lang)
}
#[tauri::command]
pub fn get_chapter_story(chapter_id: String, db: State<DbManager>, session: State<SessionState>) -> Result<Vec<service::ActStory>, AppError> {
let (user_id, lang) = get_session(&session)?;
let db_manager = db.lock().map_err(|e| AppError::Internal(format!("DB lock failed: {}", e)))?;
let conn = db_manager.get_connection(&user_id)?;
service::get_chapter_story(conn, &user_id, &chapter_id, lang)
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct GetCompanionData {
pub chapter_id: String,
pub version: i64,
}
#[tauri::command]
pub fn get_companion_content(data: GetCompanionData, db: State<DbManager>, session: State<SessionState>) -> Result<service::CompanionContent, AppError> {
let (user_id, lang) = get_session(&session)?;
let db_manager = db.lock().map_err(|e| AppError::Internal(format!("DB lock failed: {}", e)))?;
let conn = db_manager.get_connection(&user_id)?;
service::get_companion_content(conn, &user_id, &data.chapter_id, data.version, lang)
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct GetChapterContentData {
pub chapter_id: String,
pub version: i64,
}
#[tauri::command]
pub fn get_chapter_content(data: GetChapterContentData, db: State<DbManager>, session: State<SessionState>) -> Result<String, AppError> {
let (user_id, lang) = get_session(&session)?;
let db_manager = db.lock().map_err(|e| AppError::Internal(format!("DB lock failed: {}", e)))?;
let conn = db_manager.get_connection(&user_id)?;
service::get_chapter_content_by_version(conn, &user_id, &data.chapter_id, data.version, lang)
}
// ─── Mutations ────────────────────────────────────────
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct SaveChapterContentData {
pub chapter_id: String,
pub version: i64,
pub content: Value,
pub total_word_count: i64,
pub content_id: String,
}
#[tauri::command]
pub fn save_chapter_content(data: SaveChapterContentData, db: State<DbManager>, session: State<SessionState>) -> Result<bool, AppError> {
let (user_id, lang) = get_session(&session)?;
let db_manager = db.lock().map_err(|e| AppError::Internal(format!("DB lock failed: {}", e)))?;
let conn = db_manager.get_connection(&user_id)?;
let content_str = serde_json::to_string(&data.content).map_err(|e| AppError::Internal(format!("JSON serialize failed: {}", e)))?;
service::save_chapter_content(conn, &user_id, &data.chapter_id, data.version, &content_str, data.total_word_count, timestamp_in_seconds(), lang)
}
#[tauri::command]
pub fn get_last_chapter(book_id: String, db: State<DbManager>, session: State<SessionState>) -> Result<Option<service::ChapterProps>, AppError> {
let (user_id, lang) = get_session(&session)?;
let db_manager = db.lock().map_err(|e| AppError::Internal(format!("DB lock failed: {}", e)))?;
let conn = db_manager.get_connection(&user_id)?;
service::get_last_chapter(conn, &user_id, &book_id, lang)
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AddChapterData {
pub book_id: String,
pub title: String,
pub chapter_order: i64,
pub chapter_id: Option<String>,
}
#[tauri::command]
pub fn add_chapter(data: AddChapterData, db: State<DbManager>, session: State<SessionState>) -> Result<String, AppError> {
let (user_id, lang) = get_session(&session)?;
let db_manager = db.lock().map_err(|e| AppError::Internal(format!("DB lock failed: {}", e)))?;
let conn = db_manager.get_connection(&user_id)?;
service::add_chapter(conn, &user_id, &data.book_id, &data.title, 0, data.chapter_order, lang, data.chapter_id.as_deref())
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RemoveChapterData {
pub chapter_id: String,
pub book_id: String,
pub deleted_at: i64,
}
#[tauri::command]
pub fn remove_chapter(data: RemoveChapterData, db: State<DbManager>, session: State<SessionState>) -> Result<bool, AppError> {
let (user_id, lang) = get_session(&session)?;
let db_manager = db.lock().map_err(|e| AppError::Internal(format!("DB lock failed: {}", e)))?;
let conn = db_manager.get_connection(&user_id)?;
service::remove_chapter(conn, &user_id, &data.book_id, &data.chapter_id, data.deleted_at, lang)
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct UpdateChapterData {
pub chapter_id: String,
pub title: String,
pub chapter_order: i64,
}
#[tauri::command]
pub fn update_chapter(data: UpdateChapterData, db: State<DbManager>, session: State<SessionState>) -> Result<bool, AppError> {
let (user_id, lang) = get_session(&session)?;
let db_manager = db.lock().map_err(|e| AppError::Internal(format!("DB lock failed: {}", e)))?;
let conn = db_manager.get_connection(&user_id)?;
service::update_chapter(conn, &user_id, &data.chapter_id, &data.title, data.chapter_order, lang)
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct AddChapterInfoData {
pub chapter_id: String,
pub act_id: i64,
pub book_id: String,
pub plot_id: Option<String>,
pub incident_id: Option<String>,
pub chapter_info_id: Option<String>,
}
#[tauri::command]
pub fn add_chapter_information(data: AddChapterInfoData, db: State<DbManager>, session: State<SessionState>) -> Result<String, AppError> {
let (user_id, lang) = get_session(&session)?;
let db_manager = db.lock().map_err(|e| AppError::Internal(format!("DB lock failed: {}", e)))?;
let conn = db_manager.get_connection(&user_id)?;
service::add_chapter_information(conn, &user_id, &data.chapter_id, data.act_id, &data.book_id, data.plot_id.as_deref(), data.incident_id.as_deref(), lang, data.chapter_info_id.as_deref())
}
#[derive(Deserialize)]
#[serde(rename_all = "camelCase")]
pub struct RemoveChapterInfoData {
pub chapter_info_id: String,
pub book_id: String,
pub deleted_at: i64,
}
#[tauri::command]
pub fn remove_chapter_information(data: RemoveChapterInfoData, db: State<DbManager>, session: State<SessionState>) -> Result<bool, AppError> {
let (user_id, lang) = get_session(&session)?;
let db_manager = db.lock().map_err(|e| AppError::Internal(format!("DB lock failed: {}", e)))?;
let conn = db_manager.get_connection(&user_id)?;
service::remove_chapter_information(conn, &user_id, &data.book_id, &data.chapter_info_id, data.deleted_at, lang)
}
// ─── Book Tags (aggregate) ───────────────────────────
#[derive(Serialize)]
pub struct Tag {
pub label: String,
pub value: String,
}
#[derive(Serialize)]
#[serde(rename_all = "camelCase")]
pub struct BookTags {
pub characters: Vec<Tag>,
pub locations: Vec<Tag>,
pub objects: Vec<Tag>,
pub world_elements: Vec<Tag>,
}
#[tauri::command]
pub fn get_book_tags(book_id: String, db: State<DbManager>, session: State<SessionState>) -> Result<BookTags, AppError> {
let (user_id, lang) = get_session(&session)?;
let db_manager = db.lock().map_err(|e| AppError::Internal(format!("DB lock failed: {}", e)))?;
let conn = db_manager.get_connection(&user_id)?;
let character_response = crate::domains::character::service::get_character_list(conn, &user_id, &book_id, lang)?;
let character_tags: Vec<Tag> = character_response.characters.into_iter().map(|character| Tag { label: character.name, value: character.id }).collect();
let location_elements = crate::domains::location::service::get_location_tags(conn, &user_id, &book_id, lang)?;
let location_tags: Vec<Tag> = location_elements.into_iter().map(|element| Tag { label: element.name, value: element.id }).collect();
let spell_response = crate::domains::spell::service::get_spell_list(conn, &user_id, &book_id, lang)?;
let object_tags: Vec<Tag> = spell_response.spells.into_iter().map(|spell| Tag { label: spell.name, value: spell.id }).collect();
let world_response = crate::domains::world::service::get_worlds(conn, &user_id, &book_id, lang)?;
let mut world_tags: Vec<Tag> = Vec::new();
for world in &world_response.worlds {
for element_list in [&world.laws, &world.biomes, &world.issues, &world.customs, &world.kingdoms, &world.climate, &world.resources, &world.wildlife, &world.arts, &world.ethnic_groups, &world.social_classes, &world.important_characters] {
for element in element_list {
world_tags.push(Tag { label: element.name.clone(), value: element.id.clone() });
}
}
}
Ok(BookTags { characters: character_tags, locations: location_tags, objects: object_tags, world_elements: world_tags })
}