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