Repo integration #15

Merged
micialware merged 35 commits from repo-integration into master 2026-09-09 12:47:42 +03:00
13 changed files with 75 additions and 49 deletions
Showing only changes of commit 0c4aec3dc0 - Show all commits

No files matched your search

+15 -11
View File
@@ -1,9 +1,10 @@
use std::sync::Arc;
use crate::data::Id;
use crate::data::entities::DeckSettings;
use crate::data::entities::{WordData, WordGroup};
use crate::data_provider::decks::load_sets;
use crate::data_provider::settings::get_setting;
use crate::data_provider::sqlite::default_connection;
use crate::data_provider::sqlite::{SqliteConnection};
use crate::data_provider::words::{load_word_groups, load_words};
use crate::navigation::RootMessage::Keyboard;
use crate::navigation::{AppSettings, RootMessage, ScreenState};
@@ -15,6 +16,7 @@ use iced_core::window::Position;
use iced_core::window::settings::PlatformSpecific;
use iced_core::{Font, Size, Theme};
use log::info;
use parking_lot::RwLock;
use rusqlite::Connection;
pub const USER_FONT: Font = Font::with_name("Noto Sans JP");
@@ -57,12 +59,13 @@ fn subscription(_state: &ScreenState) -> Subscription<RootMessage> {
keyboard::listen().map(Keyboard)
}
#[derive(Clone)]
pub struct AppState {
pub dictionary: Vec<WordData>,
pub decks: Vec<DeckSettings>,
pub word_groups: Vec<WordGroup>,
pub connection: Connection,
pub sync_data: AppSettings,
pub connection: Arc<RwLock<SqliteConnection>>,
pub sync_data: Arc<RwLock<AppSettings>>,
pub activity: HashMap<Id, Vec<(NaiveDate, u32)>>,
}
@@ -78,26 +81,27 @@ impl AppState {
dictionary: vec![],
decks: vec![],
word_groups: vec![],
connection: default_connection(),
sync_data: AppSettings {
connection: Arc::new(RwLock::new(Default::default())),
sync_data: Arc::new(RwLock::new(AppSettings {
key: None,
auto_web_fetch: false,
},
})),
activity: Default::default(),
}
}
}
pub fn fill_state(state: &mut AppState) {
let list = load_words(&state.connection);
let sets = load_sets(&state.connection);
let groups = load_word_groups(&state.connection);
let setting = load_settings(&state.connection);
let connection = state.connection.read();
let list = load_words(&connection);
let sets = load_sets(&connection);
let groups = load_word_groups(&connection);
let setting = load_settings(&connection);
state.dictionary = list.unwrap_or_default();
state.decks = sets.unwrap_or_default();
state.word_groups = groups.unwrap_or_default();
state.sync_data = setting
state.sync_data = Arc::new(RwLock::new(setting))
}
fn load_settings(connection: &Connection) -> AppSettings {
+6 -9
View File
@@ -9,15 +9,13 @@ use crate::data_provider::card_states::{load_stats_of_deck, update_stat_score};
use crate::data_provider::history::push_note;
use crate::notification::{MaybeError, NotificationData};
use chrono::Utc;
use parking_lot::Mutex;
use std::sync::Arc;
#[derive(Clone)]
pub struct DeckData {
pub(crate) words: Vec<WordData>,
pub(crate) set: Vec<CardState>,
current_word_index: Option<usize>,
state: Arc<Mutex<AppState>>,
state: AppState,
order_module: OrderModule,
open_mode: OrderMode,
settings: DeckSettings,
@@ -25,21 +23,20 @@ pub struct DeckData {
impl DeckData {
pub fn new(
settings: &DeckSettings,
state: Arc<Mutex<AppState>>,
state: AppState,
) -> Result<Self, NotificationData> {
let state_for = state.clone();
let state_locked = state.lock();
let stats = load_stats_of_deck(settings, &state_locked.connection)?;
let stats = load_stats_of_deck(settings, &state.connection.read())?;
let words = stats
.iter()
.map(|stat| {
state_locked
state
.dictionary
.binary_search_by_key(&stat.word_id, |w| w.id)
.expect("No word found in dictionary")
})
.map(|index| &state_locked.dictionary[index])
.map(|index| &state.dictionary[index])
.cloned()
.collect();
@@ -117,7 +114,7 @@ impl DeckData {
OrderMode::FullRandom => RandomSRS(RandomSRSModule::new()),
}
}
update_stat_score(word, &self.state.lock().connection)?;
update_stat_score(word, &self.state.connection.read())?;
let _ = push_note(
self.settings.id,
HistoryItem {
+27
View File
@@ -1,5 +1,6 @@
use crate::fs::*;
use rusqlite::Connection;
use std::ops::{Deref, DerefMut};
pub fn create_db() {
let db_file = db_path();
@@ -84,3 +85,29 @@ pub fn default_connection() -> Connection {
.expect("Failed to set PRAGMA");
connection
}
pub struct SqliteConnection(Option<Connection>);
impl Deref for SqliteConnection {
type Target = Connection;
fn deref(&self) -> &Self::Target {
self.0.as_ref().unwrap()
}
}
impl DerefMut for SqliteConnection {
fn deref_mut(&mut self) -> &mut Self::Target {
self.0.as_mut().unwrap()
}
}
impl Default for SqliteConnection {
fn default() -> Self {
SqliteConnection(Some(default_connection()))
}
}
impl SqliteConnection {
pub fn finish(&mut self) {
self.0 = None;
}
}
+10 -12
View File
@@ -1,7 +1,7 @@
use crate::app::{AppState, fill_state};
use crate::data::Id;
use crate::data_provider::history::get_history_of_set;
use crate::data_provider::sqlite::{create_db, default_connection};
use crate::data_provider::sqlite::{create_db, default_connection, SqliteConnection};
use crate::data_provider::web_api::{
get_local_version, get_web_version, load_data, set_local_version,
};
@@ -47,7 +47,6 @@ impl Default for ScreenState {
fn default() -> Self {
let mut state = AppState::new();
fill_state(&mut state);
let state = Arc::new(Mutex::new(state));
ScreenState {
stack: vec![Selector(SelectorState::new(state.clone()))],
app_state: state.clone(),
@@ -99,7 +98,7 @@ pub enum Page {
pub struct ScreenState {
stack: Vec<Page>,
app_state: Arc<Mutex<AppState>>,
app_state: AppState,
notification_manager: NotificationManager,
}
@@ -114,9 +113,9 @@ impl ScreenState {
});
let mut final_task = reading_additional_task;
let state_guard = state.app_state.lock();
if state_guard.sync_data.auto_web_fetch
&& let Some(key) = state_guard.sync_data.key.clone()
let state_guard = &state.app_state;
if state_guard.sync_data.read().auto_web_fetch
&& let Some(key) = state_guard.sync_data.read().key.clone()
{
final_task = Task::batch([
final_task,
@@ -133,7 +132,6 @@ impl ScreenState {
]);
}
drop(state_guard);
info!("Boot finished");
(state, final_task)
}
@@ -192,15 +190,15 @@ impl ScreenState {
}
if let DataLoaded(data) = message {
self.app_state.lock().activity = data;
self.app_state.activity = data;
return Task::none();
}
if let UpdateData = message {
info!("Loading data");
let mut state = self.app_state.lock();
let state = &mut self.app_state;
if cfg!(windows) {
state.connection = Connection::open_in_memory().unwrap();
state.connection.write().finish();
}
let db_file = db_path();
let temp_db_file = temp_db_path();
@@ -208,8 +206,8 @@ impl ScreenState {
return push_error_task!(PermissionDenied);
}
state.connection = default_connection();
fill_state(&mut state);
state.connection = Default::default();
fill_state(state);
return Task::none();
}
+2 -2
View File
@@ -30,7 +30,7 @@ use std::time::{Duration, Instant};
#[derive(Clone)]
pub struct DictionaryState {
state: Arc<Mutex<AppState>>,
state: AppState,
include_map: Vec<bool>,
tag_map: HashMap<String, bool>,
reverse: bool,
@@ -300,7 +300,7 @@ impl NavigatedPage<DictionaryMessage> for DictionaryState {
}
impl DictionaryState {
pub fn new(state: Arc<Mutex<AppState>>) -> Self {
pub fn new(state: AppState) -> Self {
let len = state.lock().dictionary.len();
let mut result = DictionaryState {
+1 -1
View File
@@ -48,7 +48,7 @@ impl NavigatedPage<HistoryMessage> for HistoryState {
}
impl HistoryState {
pub fn new(id: crate::data::Id, state: Arc<Mutex<AppState>>) -> Self {
pub fn new(id: crate::data::Id, state: AppState) -> Self {
let state = state.lock();
let history = get_history_of_set(id).unwrap_or_default();
let words = history
+2 -2
View File
@@ -34,7 +34,7 @@ const DEFAULT_FIELDS: [&str; 6] = ["key", "value", "tags", "reading", "context",
#[derive(Clone)]
pub struct ImportState {
state: Arc<Mutex<AppState>>,
state: AppState,
path: Option<PathBuf>,
import_data: Option<ImportData>,
selected_index: usize,
@@ -318,7 +318,7 @@ impl ImportState {
}
impl ImportState {
pub fn new(state: Arc<Mutex<AppState>>) -> ImportState {
pub fn new(state: AppState) -> ImportState {
ImportState {
state,
path: None,
+2 -2
View File
@@ -22,7 +22,7 @@ use std::sync::Arc;
use tokio::task::spawn_blocking;
pub struct RepetitionState {
state: Arc<Mutex<AppState>>,
state: AppState,
pub settings: DeckSettings,
pub set: DeckData,
current_word: WordData,
@@ -104,7 +104,7 @@ impl NavigatedPage<RepetitionMessage> for RepetitionState {
impl RepetitionState {
pub(crate) fn new(
set: DeckSettings,
state: Arc<Mutex<AppState>>,
state: AppState,
) -> Result<RepetitionState, NotificationData> {
let mut card_set = DeckData::new(&set, state.clone())?;
let (word, stat) = card_set.next();
+2 -2
View File
@@ -21,14 +21,14 @@ use std::time::Duration;
pub struct RepetitionSettingsState {
set: DeckSettings,
index: usize,
state: Arc<Mutex<AppState>>,
state: AppState,
real_delete: bool,
correct_filter: bool,
filter_changed: bool,
}
impl RepetitionSettingsState {
pub(crate) fn new(index: usize, state: Arc<Mutex<AppState>>) -> RepetitionSettingsState {
pub(crate) fn new(index: usize, state: AppState) -> RepetitionSettingsState {
let set;
{
let local_state = state.lock();
+2 -2
View File
@@ -36,7 +36,7 @@ pub struct RepetitionsState {
word_id_index_map: HashMap<Id, usize>,
selected_deck_index: Option<usize>,
decks: Vec<DeckViewData>,
state: Arc<Mutex<AppState>>,
state: AppState,
}
impl NavigatedPage<RepetitionsMessage> for RepetitionsState {
@@ -257,7 +257,7 @@ impl NavigatedPage<RepetitionsMessage> for RepetitionsState {
}
impl RepetitionsState {
pub(crate) fn new(state: Arc<Mutex<AppState>>) -> RepetitionsState {
pub(crate) fn new(state: AppState) -> RepetitionsState {
let state_ = state.lock();
let mut map = HashMap::with_capacity(state_.dictionary.len());
+2 -2
View File
@@ -22,7 +22,7 @@ use std::sync::Arc;
pub struct SelectorState {
pub set: KanaSet,
is_writing: bool,
state: Arc<Mutex<AppState>>,
state: AppState,
}
#[derive(Debug, Clone)]
@@ -114,7 +114,7 @@ impl NavigatedPage<SelectorMessage> for SelectorState {
}
impl SelectorState {
pub fn new(state: Arc<Mutex<AppState>>) -> Self {
pub fn new(state: AppState) -> Self {
Self {
set: Default::default(),
is_writing: false,
+2 -2
View File
@@ -34,7 +34,7 @@ pub enum SyncMessage {
}
#[derive(Clone)]
pub struct SyncState {
state: Arc<Mutex<AppState>>,
state: AppState,
auto_fetch: bool,
frozen: bool,
progress: f32,
@@ -177,7 +177,7 @@ impl NavigatedPage<SyncMessage> for SyncState {
}
impl SyncState {
pub fn new(state: Arc<Mutex<AppState>>) -> SyncState {
pub fn new(state: AppState) -> SyncState {
let auto_fetch;
{
auto_fetch = state.lock().sync_data.auto_web_fetch;
+2 -2
View File
@@ -15,7 +15,7 @@ use std::sync::Arc;
#[derive(Clone)]
pub struct WordState {
state: Arc<Mutex<AppState>>,
state: AppState,
index: usize,
word: WordData,
}
@@ -136,7 +136,7 @@ impl NavigatedPage<WordMessage> for WordState {
}
impl WordState {
pub(crate) fn new(word: WordData, index: usize, state: Arc<Mutex<AppState>>) -> WordState {
pub(crate) fn new(word: WordData, index: usize, state: AppState) -> WordState {
WordState { state, index, word }
}
}