use crate::data::repositories::Repository; use crate::data_provider::card_states::CardStateRepository; use crate::data_provider::custom_fields::CustomFieldRepository; use crate::data_provider::decks::DeckRepository; use crate::data_provider::history::HistoryRepository; use crate::data_provider::settings::get_setting; use crate::data_provider::sqlite::SqliteConnection; use crate::data_provider::word_groups::WordGroupRepository; use crate::data_provider::words::WordRepository; use crate::navigation::RootMessage::Keyboard; use crate::navigation::{AppSettings, RootMessage, ScreenState}; use iced::{Subscription, keyboard, window}; use iced_core::window::Position; #[cfg(target_os = "linux")] use iced_core::window::settings::PlatformSpecific; use iced_core::{Font, Size, Theme}; use log::info; use parking_lot::{Mutex, RwLock}; use rusqlite::Connection; use std::sync::Arc; pub const USER_FONT: Font = Font::with_name("Noto Sans JP"); pub fn start() -> iced::Result { info!("Welcome to JapLearn"); iced::application(ScreenState::boot, ScreenState::update, ScreenState::view) .window(window_settings()) .subscription(subscription) .title("JapLearn") .settings(iced::Settings { default_text_size: iced::Pixels(18.0), ..iced::Settings::default() }) .font(include_bytes!("../noto.ttf")) .default_font(USER_FONT) .theme(Theme::GruvboxDark) .run() } #[allow(unused_mut)] fn window_settings() -> window::Settings { let mut settings = window::Settings { position: Position::Centered, min_size: Some(Size::new(700.0_f32, 700.0_f32)), ..Default::default() }; #[cfg(target_os = "linux")] { settings.platform_specific = PlatformSpecific { application_id: "JapLearn".to_string(), override_redirect: false, }; } settings } fn subscription(_state: &ScreenState) -> Subscription { keyboard::listen().map(Keyboard) } #[derive(Clone)] pub struct AppState { pub dictionary: WordRepository, pub decks: DeckRepository, pub word_groups: WordGroupRepository, pub card_states: CardStateRepository, pub custom_fields: CustomFieldRepository, pub connection: Arc>, pub sync_data: Arc>, pub history: HistoryRepository, } impl Default for AppState { fn default() -> Self { Self::new() } } impl AppState { pub fn new() -> Self { let connection = Arc::new(Mutex::new(SqliteConnection::default())); Self { dictionary: WordRepository::new(connection.clone()), decks: DeckRepository::new(connection.clone()), word_groups: WordGroupRepository::new(connection.clone()), card_states: CardStateRepository::new(connection.clone()), history: HistoryRepository::new(connection.clone()), custom_fields: CustomFieldRepository::new(connection.clone()), sync_data: Arc::new(RwLock::new(AppSettings { key: None, auto_web_fetch: false, })), connection, } } } pub fn fill_state(state: &mut AppState) { let connection = state.connection.lock(); let setting = load_settings(&connection); drop(connection); state.word_groups.write().start().unwrap(); state.dictionary.write().start().unwrap(); state.decks.write().start().unwrap(); state.history.write().start().unwrap(); state.card_states.write().start().unwrap(); state.custom_fields.write().start().unwrap(); state.sync_data = Arc::new(RwLock::new(setting)) } fn load_settings(connection: &Connection) -> AppSettings { let key = get_setting("SYNC_KEY".to_string(), connection); let fetch = get_setting("AUTO_WEB_FETCH".to_string(), connection) .unwrap_or("false".to_string()) .parse::() .unwrap(); AppSettings { key, auto_web_fetch: fetch, } }