Repo integration #15
No files matched your search
+15
-11
@@ -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
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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
@@ -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,
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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
@@ -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
@@ -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 }
|
||||
}
|
||||
}
|
||||
|
||||
Reference in new issue
Block a user