Migrate to Id type
This commit is contained in:
@@ -1,4 +1,4 @@
|
|||||||
use crate::lang::{DeckSettings, OrderMode};
|
use crate::lang::{DeckSettings, OrderMode, INVALID_ID};
|
||||||
|
|
||||||
use rusqlite::Connection;
|
use rusqlite::Connection;
|
||||||
|
|
||||||
@@ -43,11 +43,11 @@ pub fn add_set(set: &mut DeckSettings, connection: &Connection) {
|
|||||||
)
|
)
|
||||||
.unwrap_or_else(|e| {println!("{}", e); 0});
|
.unwrap_or_else(|e| {println!("{}", e); 0});
|
||||||
|
|
||||||
set.id = index;
|
set.id = index.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_card_set(set: &mut DeckSettings, connection: &Connection) {
|
pub fn update_card_set(set: &mut DeckSettings, connection: &Connection) {
|
||||||
if set.id == 0 {
|
if set.id == INVALID_ID {
|
||||||
add_set(set, connection);
|
add_set(set, connection);
|
||||||
} else {
|
} else {
|
||||||
connection
|
connection
|
||||||
@@ -66,7 +66,7 @@ pub fn update_card_set(set: &mut DeckSettings, connection: &Connection) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_set(set: &DeckSettings, connection: &Connection) {
|
pub fn delete_set(set: &DeckSettings, connection: &Connection) {
|
||||||
if set.id == 0 {
|
if set.id == INVALID_ID {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
connection
|
connection
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::lang::{DeckSettings, CardStatistics};
|
use crate::lang::{DeckSettings, CardStatistics, INVALID_ID};
|
||||||
use rusqlite::Connection;
|
use rusqlite::Connection;
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
@@ -62,7 +62,7 @@ pub fn add_stat_list(stat: &mut [CardStatistics], connection: &Connection) {
|
|||||||
let start_index = last_index - (stat.len() as u32) + 1;
|
let start_index = last_index - (stat.len() as u32) + 1;
|
||||||
|
|
||||||
for (index, id) in (start_index..=last_index).enumerate() {
|
for (index, id) in (start_index..=last_index).enumerate() {
|
||||||
stat[index].id = id;
|
stat[index].id = id.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
println!("Added {} cards for {:?}", stat.len(), time.elapsed());
|
println!("Added {} cards for {:?}", stat.len(), time.elapsed());
|
||||||
@@ -103,7 +103,7 @@ pub fn update_stat_score(stat: &CardStatistics, connection: &Connection) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_stat(stat: &CardStatistics, connection: &Connection) {
|
pub fn delete_stat(stat: &CardStatistics, connection: &Connection) {
|
||||||
if stat.id == 0 {
|
if stat.id == INVALID_ID {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
connection
|
connection
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::dictionary::app_data_dir;
|
use crate::dictionary::app_data_dir;
|
||||||
use crate::lang::WordOpenMode;
|
use crate::lang::{Id, WordOpenMode};
|
||||||
use chrono::{DateTime, Utc};
|
use chrono::{DateTime, Utc};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::fs::{File, OpenOptions};
|
use std::fs::{File, OpenOptions};
|
||||||
@@ -7,7 +7,7 @@ use std::io::Write;
|
|||||||
use std::io::{BufRead, BufReader};
|
use std::io::{BufRead, BufReader};
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
pub fn get_history_of_set(id: u32) -> Vec<HistoryItem> {
|
pub fn get_history_of_set(id: Id) -> Vec<HistoryItem> {
|
||||||
let app_dir = history_dir();
|
let app_dir = history_dir();
|
||||||
let head = app_dir.clone().join(format!("set_{}_history.csv", id));
|
let head = app_dir.clone().join(format!("set_{}_history.csv", id));
|
||||||
let mut lines = Vec::new();
|
let mut lines = Vec::new();
|
||||||
@@ -32,7 +32,7 @@ fn parse_history_items(strings: Vec<String>) -> Vec<HistoryItem> {
|
|||||||
if let [time, word, mode, before, after] = string.split(';').collect::<Vec<&str>>()[..] {
|
if let [time, word, mode, before, after] = string.split(';').collect::<Vec<&str>>()[..] {
|
||||||
items.push(HistoryItem {
|
items.push(HistoryItem {
|
||||||
timestamp: DateTime::from_timestamp(time.parse().unwrap(), 0).unwrap(),
|
timestamp: DateTime::from_timestamp(time.parse().unwrap(), 0).unwrap(),
|
||||||
word_id: word.parse::<u32>().unwrap(),
|
word_id: word.parse::<u32>().unwrap().into(),
|
||||||
mode: match mode.parse::<u8>().unwrap() {
|
mode: match mode.parse::<u8>().unwrap() {
|
||||||
2 => WordOpenMode::Hard,
|
2 => WordOpenMode::Hard,
|
||||||
3 => WordOpenMode::Ok,
|
3 => WordOpenMode::Ok,
|
||||||
@@ -48,7 +48,7 @@ fn parse_history_items(strings: Vec<String>) -> Vec<HistoryItem> {
|
|||||||
items
|
items
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn push_note(set_id: u32, item: HistoryItem) {
|
pub fn push_note(set_id: Id, item: HistoryItem) {
|
||||||
let app_dir = history_dir();
|
let app_dir = history_dir();
|
||||||
let path = app_dir.clone().join(format!("set_{}_history.csv", set_id));
|
let path = app_dir.clone().join(format!("set_{}_history.csv", set_id));
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ pub fn history_dir() -> PathBuf {
|
|||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct HistoryItem {
|
pub struct HistoryItem {
|
||||||
pub timestamp: DateTime<Utc>,
|
pub timestamp: DateTime<Utc>,
|
||||||
pub word_id: u32,
|
pub word_id: Id,
|
||||||
pub mode: WordOpenMode,
|
pub mode: WordOpenMode,
|
||||||
pub before: u8,
|
pub before: u8,
|
||||||
pub after: u8,
|
pub after: u8,
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
use crate::lang::{WordData, WordGroup};
|
use crate::lang::{WordData, WordGroup, INVALID_ID};
|
||||||
use rusqlite::{Connection, params};
|
use rusqlite::{Connection, params};
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
@@ -20,7 +20,7 @@ pub fn add_word(word: &mut WordData, connection: &Connection) {
|
|||||||
0
|
0
|
||||||
});
|
});
|
||||||
|
|
||||||
word.id = index;
|
word.id = index.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn add_words(words: &mut [WordData], connection: &mut Connection) {
|
pub fn add_words(words: &mut [WordData], connection: &mut Connection) {
|
||||||
@@ -59,12 +59,12 @@ pub fn add_words(words: &mut [WordData], connection: &mut Connection) {
|
|||||||
let start_index = last_index - (count as u32) + 1;
|
let start_index = last_index - (count as u32) + 1;
|
||||||
|
|
||||||
for (index, id) in (start_index..=last_index).enumerate() {
|
for (index, id) in (start_index..=last_index).enumerate() {
|
||||||
words[index].id = id;
|
words[index].id = id.into();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_word(word: &mut WordData, connection: &Connection) {
|
pub fn update_word(word: &mut WordData, connection: &Connection) {
|
||||||
if word.id == 0 {
|
if word.id == INVALID_ID {
|
||||||
add_word(word, connection);
|
add_word(word, connection);
|
||||||
} else {
|
} else {
|
||||||
connection
|
connection
|
||||||
@@ -86,7 +86,7 @@ pub fn update_word(word: &mut WordData, connection: &Connection) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_word(word: &WordData, connection: &Connection) {
|
pub fn delete_word(word: &WordData, connection: &Connection) {
|
||||||
if word.id == 0 {
|
if word.id == INVALID_ID {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
connection
|
connection
|
||||||
@@ -156,11 +156,11 @@ pub fn add_group(group: &mut WordGroup, connection: &Connection) {
|
|||||||
0
|
0
|
||||||
});
|
});
|
||||||
|
|
||||||
group.id = index;
|
group.id = index.into();
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn update_group(group: &mut WordGroup, connection: &Connection) {
|
pub fn update_group(group: &mut WordGroup, connection: &Connection) {
|
||||||
if group.id == 0 {
|
if group.id == INVALID_ID {
|
||||||
add_group(group, connection);
|
add_group(group, connection);
|
||||||
} else {
|
} else {
|
||||||
connection
|
connection
|
||||||
@@ -176,7 +176,7 @@ pub fn update_group(group: &mut WordGroup, connection: &Connection) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn delete_group(group: &WordGroup, connection: &Connection) {
|
pub fn delete_group(group: &WordGroup, connection: &Connection) {
|
||||||
if group.id == 0 {
|
if group.id == INVALID_ID {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
connection
|
connection
|
||||||
|
|||||||
+8
-8
@@ -2,7 +2,7 @@ use crate::data_provider::words::{delete_group, delete_word, update_group, updat
|
|||||||
use crate::dictionary::DictionaryMessage::*;
|
use crate::dictionary::DictionaryMessage::*;
|
||||||
use crate::dictionary_test::DictionaryQuizState;
|
use crate::dictionary_test::DictionaryQuizState;
|
||||||
use crate::import::ImportState;
|
use crate::import::ImportState;
|
||||||
use crate::lang::{WordData, WordGroup};
|
use crate::lang::{WordData, WordGroup, INVALID_ID};
|
||||||
use crate::navigation::Page::{Import, Word};
|
use crate::navigation::Page::{Import, Word};
|
||||||
use crate::navigation::{NavigatedPage, Page};
|
use crate::navigation::{NavigatedPage, Page};
|
||||||
use crate::styling::*;
|
use crate::styling::*;
|
||||||
@@ -96,7 +96,7 @@ impl NavigatedPage<DictionaryMessage> for DictionaryState {
|
|||||||
let dict = &state.dictionary;
|
let dict = &state.dictionary;
|
||||||
word = dict[*index].clone();
|
word = dict[*index].clone();
|
||||||
}
|
}
|
||||||
if word.id != 0 {
|
if word.id != INVALID_ID {
|
||||||
return Some(Word(WordState::new(word, *index, self.state.clone())));
|
return Some(Word(WordState::new(word, *index, self.state.clone())));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -172,7 +172,7 @@ impl NavigatedPage<DictionaryMessage> for DictionaryState {
|
|||||||
}
|
}
|
||||||
Include(i, b) => self.include_map[i] = b,
|
Include(i, b) => self.include_map[i] = b,
|
||||||
IncludeTag(t, v) => {
|
IncludeTag(t, v) => {
|
||||||
let index: u32;
|
let index;
|
||||||
{
|
{
|
||||||
let state = self.state.lock().unwrap();
|
let state = self.state.lock().unwrap();
|
||||||
index = state.word_groups[self.selected_group_index].id;
|
index = state.word_groups[self.selected_group_index].id;
|
||||||
@@ -197,7 +197,7 @@ impl NavigatedPage<DictionaryMessage> for DictionaryState {
|
|||||||
let state = &mut self.state.lock().unwrap();
|
let state = &mut self.state.lock().unwrap();
|
||||||
|
|
||||||
state.word_groups.push(WordGroup {
|
state.word_groups.push(WordGroup {
|
||||||
id: 0,
|
id: 0.into(),
|
||||||
name: format!("Группа слов {}", random_range(100..1000)),
|
name: format!("Группа слов {}", random_range(100..1000)),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -222,7 +222,7 @@ impl NavigatedPage<DictionaryMessage> for DictionaryState {
|
|||||||
}
|
}
|
||||||
SelectGroup(i) => {
|
SelectGroup(i) => {
|
||||||
self.selected_group_index = i;
|
self.selected_group_index = i;
|
||||||
let index: u32;
|
let index;
|
||||||
{
|
{
|
||||||
let state = self.state.lock().unwrap();
|
let state = self.state.lock().unwrap();
|
||||||
index = state.word_groups[i].id;
|
index = state.word_groups[i].id;
|
||||||
@@ -423,7 +423,7 @@ impl DictionaryState {
|
|||||||
let line_button = || {
|
let line_button = || {
|
||||||
let action = WordAction(index);
|
let action = WordAction(index);
|
||||||
|
|
||||||
if data.id == 0 {
|
if data.id == INVALID_ID {
|
||||||
return button("-").on_press(action).style(|_x, _status| Style {
|
return button("-").on_press(action).style(|_x, _status| Style {
|
||||||
background: None,
|
background: None,
|
||||||
text_color: Color::BLACK,
|
text_color: Color::BLACK,
|
||||||
@@ -532,7 +532,7 @@ impl DictionaryState {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update_words_include(&mut self, group_id: u32) {
|
fn update_words_include(&mut self, group_id: crate::lang::Id) {
|
||||||
let include_tags = self
|
let include_tags = self
|
||||||
.tag_map
|
.tag_map
|
||||||
.iter()
|
.iter()
|
||||||
@@ -626,6 +626,6 @@ struct WordLineState {
|
|||||||
key: String,
|
key: String,
|
||||||
value: String,
|
value: String,
|
||||||
tags: String,
|
tags: String,
|
||||||
id: u32,
|
id: crate::lang::Id,
|
||||||
index: usize,
|
index: usize,
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -46,7 +46,7 @@ impl NavigatedPage<HistoryMessage> for HistoryState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl HistoryState {
|
impl HistoryState {
|
||||||
pub fn new(id: u32, state: Arc<Mutex<AppState>>) -> Self {
|
pub fn new(id: crate::lang::Id, state: Arc<Mutex<AppState>>) -> Self {
|
||||||
let state = state.lock().unwrap();
|
let state = state.lock().unwrap();
|
||||||
let history = get_history_of_set(id);
|
let history = get_history_of_set(id);
|
||||||
let words = history
|
let words = history
|
||||||
|
|||||||
+1
-1
@@ -446,7 +446,7 @@ impl ImportState {
|
|||||||
|
|
||||||
let map_indices = Self::get_mapping_indices(&group);
|
let map_indices = Self::get_mapping_indices(&group);
|
||||||
let mut group_entity = WordGroup {
|
let mut group_entity = WordGroup {
|
||||||
id: 0,
|
id: 0.into(),
|
||||||
name: group.name.clone(),
|
name: group.name.clone(),
|
||||||
};
|
};
|
||||||
{
|
{
|
||||||
|
|||||||
+60
-16
@@ -11,8 +11,11 @@ use rayon::iter::IndexedParallelIterator;
|
|||||||
use rayon::iter::IntoParallelRefIterator;
|
use rayon::iter::IntoParallelRefIterator;
|
||||||
use rayon::iter::ParallelIterator;
|
use rayon::iter::ParallelIterator;
|
||||||
use rhai::{Engine, Scope};
|
use rhai::{Engine, Scope};
|
||||||
use serde::{Deserialize, Serialize};
|
use rusqlite::types::{FromSql, FromSqlError, FromSqlResult, ToSqlOutput, ValueRef};
|
||||||
|
use rusqlite::ToSql;
|
||||||
|
use std::cmp::PartialEq;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
use std::fmt::{Display, Formatter};
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
|
|
||||||
@@ -20,6 +23,9 @@ const MAX_HISTORY_LEN: usize = 20;
|
|||||||
const MAX_HISTORY_LEN_PART: f32 = 0.33;
|
const MAX_HISTORY_LEN_PART: f32 = 0.33;
|
||||||
const MAX_SCORE: u8 = 25;
|
const MAX_SCORE: u8 = 25;
|
||||||
const FADE_PER_DAY: f32 = 0.95;
|
const FADE_PER_DAY: f32 = 0.95;
|
||||||
|
#[derive(Clone, PartialEq, Eq, Debug, Hash, Copy)]
|
||||||
|
pub(crate) struct Id(u32);
|
||||||
|
pub const INVALID_ID: Id = Id(0);
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct KanaSet {
|
pub struct KanaSet {
|
||||||
name: String,
|
name: String,
|
||||||
@@ -225,40 +231,40 @@ impl PartialEq<Self> for KanaSet {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Serialize, Deserialize)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct WordData {
|
pub struct WordData {
|
||||||
pub id: u32,
|
pub id: Id,
|
||||||
pub key: String,
|
pub key: String,
|
||||||
pub value: String,
|
pub value: String,
|
||||||
pub tags: String,
|
pub tags: String,
|
||||||
pub additional: HashMap<String, String>,
|
pub additional: HashMap<String, String>,
|
||||||
pub group_id: u32,
|
pub group_id: Id,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl WordData {
|
impl WordData {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
id: 0,
|
id: 0.into(),
|
||||||
key: String::new(),
|
key: String::new(),
|
||||||
value: String::new(),
|
value: String::new(),
|
||||||
tags: String::new(),
|
tags: String::new(),
|
||||||
additional: Default::default(),
|
additional: Default::default(),
|
||||||
group_id: 1,
|
group_id: 1.into(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct WordGroup {
|
pub struct WordGroup {
|
||||||
pub id: u32,
|
pub id: Id,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, PartialEq)]
|
#[derive(Clone, PartialEq)]
|
||||||
pub struct CardStatistics {
|
pub struct CardStatistics {
|
||||||
pub id: u32,
|
pub id: Id,
|
||||||
pub word_id: u32,
|
pub word_id: Id,
|
||||||
pub set_id: u32,
|
pub set_id: Id,
|
||||||
pub last_open: DateTime<Utc>,
|
pub last_open: DateTime<Utc>,
|
||||||
pub score: u8,
|
pub score: u8,
|
||||||
}
|
}
|
||||||
@@ -320,8 +326,8 @@ impl DeckData {
|
|||||||
.map(|w| state_locked.dictionary.get(*w).unwrap())
|
.map(|w| state_locked.dictionary.get(*w).unwrap())
|
||||||
.cloned()
|
.cloned()
|
||||||
.collect();
|
.collect();
|
||||||
let word_ids = last_list.iter().map(|l| l.id).collect::<Vec<u32>>();
|
let word_ids = last_list.iter().map(|l| l.id).collect::<Vec<Id>>();
|
||||||
|
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
for stat in current_set.clone() {
|
for stat in current_set.clone() {
|
||||||
if !word_ids.contains(&stat.word_id) {
|
if !word_ids.contains(&stat.word_id) {
|
||||||
@@ -410,7 +416,7 @@ impl DeckData {
|
|||||||
self.settings.id,
|
self.settings.id,
|
||||||
HistoryItem {
|
HistoryItem {
|
||||||
timestamp: Utc::now(),
|
timestamp: Utc::now(),
|
||||||
word_id: word.word_id,
|
word_id: word.word_id.into(),
|
||||||
mode: WordOpenMode::Easy,
|
mode: WordOpenMode::Easy,
|
||||||
before: old_score,
|
before: old_score,
|
||||||
after: new_score,
|
after: new_score,
|
||||||
@@ -606,7 +612,7 @@ impl WorstWordsSRSModule {
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct DeckSettings {
|
pub struct DeckSettings {
|
||||||
pub id: u32,
|
pub id: Id,
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub forward: String,
|
pub forward: String,
|
||||||
pub backward: String,
|
pub backward: String,
|
||||||
@@ -619,7 +625,7 @@ pub struct DeckSettings {
|
|||||||
impl DeckSettings {
|
impl DeckSettings {
|
||||||
pub(crate) fn with_name(name: String) -> DeckSettings {
|
pub(crate) fn with_name(name: String) -> DeckSettings {
|
||||||
DeckSettings {
|
DeckSettings {
|
||||||
id: 0,
|
id: 0.into(),
|
||||||
name,
|
name,
|
||||||
forward: "".to_string(),
|
forward: "".to_string(),
|
||||||
backward: "".to_string(),
|
backward: "".to_string(),
|
||||||
@@ -661,7 +667,7 @@ impl DeckSettings {
|
|||||||
}
|
}
|
||||||
let mut scope = Scope::new();
|
let mut scope = Scope::new();
|
||||||
scope
|
scope
|
||||||
.push_constant("id", word.id)
|
.push_constant("id", word.id.0)
|
||||||
.push_constant("key", word.key.clone())
|
.push_constant("key", word.key.clone())
|
||||||
.push_constant("value", word.value.clone())
|
.push_constant("value", word.value.clone())
|
||||||
.push_constant("tags", word.tags.clone())
|
.push_constant("tags", word.tags.clone())
|
||||||
@@ -691,3 +697,41 @@ impl DeckSettings {
|
|||||||
self.forward == "speech" || self.backward == "speech"
|
self.forward == "speech" || self.backward == "speech"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Into<Id> for u32{
|
||||||
|
fn into(self) -> Id {
|
||||||
|
Id(self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// impl From<u32> for Id{
|
||||||
|
// fn from(id: u32) -> Id{
|
||||||
|
// Id(id)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
impl Into<u32> for Id{
|
||||||
|
fn into(self) -> u32 {
|
||||||
|
self.0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl Display for Id {
|
||||||
|
fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
|
||||||
|
write!(f, "{}", self.0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl FromSql for Id{
|
||||||
|
fn column_result(value: ValueRef<'_>) -> FromSqlResult<Self> {
|
||||||
|
match value {
|
||||||
|
ValueRef::Integer(i) => Ok(Id(i as u32)),
|
||||||
|
_ => Err(FromSqlError::InvalidType),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ToSql for Id{
|
||||||
|
fn to_sql(&self) -> rusqlite::Result<ToSqlOutput<'_>> {
|
||||||
|
Ok(ToSqlOutput::from(self.0 as i64))
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-2
@@ -23,7 +23,7 @@ use crate::data_provider::card_sets::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::default_connection;
|
||||||
use crate::data_provider::words::{load_word_groups, load_words};
|
use crate::data_provider::words::{load_word_groups, load_words};
|
||||||
use crate::lang::{DeckSettings, WordData, WordGroup};
|
use crate::lang::{DeckSettings, Id, WordData, WordGroup};
|
||||||
use crate::navigation::{AppSettings, RootMessage, ScreenState};
|
use crate::navigation::{AppSettings, RootMessage, ScreenState};
|
||||||
use crate::quiz::*;
|
use crate::quiz::*;
|
||||||
use chrono::NaiveDate;
|
use chrono::NaiveDate;
|
||||||
@@ -85,7 +85,7 @@ pub struct AppState {
|
|||||||
pub word_groups: Vec<WordGroup>,
|
pub word_groups: Vec<WordGroup>,
|
||||||
pub connection: Connection,
|
pub connection: Connection,
|
||||||
pub sync_data: AppSettings,
|
pub sync_data: AppSettings,
|
||||||
pub activity: HashMap<u32, Vec<(NaiveDate, u32)>>,
|
pub activity: HashMap<Id, Vec<(NaiveDate, u32)>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for AppState {
|
impl Default for AppState {
|
||||||
|
|||||||
+4
-3
@@ -31,6 +31,7 @@ use hashbrown::HashMap;
|
|||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
use std::time::Instant;
|
use std::time::Instant;
|
||||||
use rusqlite::Connection;
|
use rusqlite::Connection;
|
||||||
|
use crate::lang::Id;
|
||||||
|
|
||||||
impl Default for ScreenState {
|
impl Default for ScreenState {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
@@ -60,7 +61,7 @@ pub enum RootMessage {
|
|||||||
RepetitionSettings(RepetitionSettingsMessage),
|
RepetitionSettings(RepetitionSettingsMessage),
|
||||||
Import(ImportMessage),
|
Import(ImportMessage),
|
||||||
Keyboard(Event),
|
Keyboard(Event),
|
||||||
DataLoaded(HashMap<u32, Vec<(NaiveDate, u32)>>),
|
DataLoaded(HashMap<Id, Vec<(NaiveDate, u32)>>),
|
||||||
None,
|
None,
|
||||||
UpdateData,
|
UpdateData,
|
||||||
}
|
}
|
||||||
@@ -126,9 +127,9 @@ impl ScreenState {
|
|||||||
for file in directory.read_dir().unwrap().flatten() {
|
for file in directory.read_dir().unwrap().flatten() {
|
||||||
let mut vec = vec![];
|
let mut vec = vec![];
|
||||||
let history_file_name = file.file_name().into_string().unwrap();
|
let history_file_name = file.file_name().into_string().unwrap();
|
||||||
let id = history_file_name[4..history_file_name.len() - 12]
|
let id : Id = history_file_name[4..history_file_name.len() - 12]
|
||||||
.parse::<u32>()
|
.parse::<u32>()
|
||||||
.unwrap();
|
.unwrap().into();
|
||||||
|
|
||||||
let history = get_history_of_set(id);
|
let history = get_history_of_set(id);
|
||||||
let by_date = history.chunk_by(|x, x1| {
|
let by_date = history.chunk_by(|x, x1| {
|
||||||
|
|||||||
+2
-1
@@ -13,6 +13,7 @@ use iced::{Element, Fill, Task, Theme, alignment, keyboard};
|
|||||||
use rodio::MixerDeviceSink;
|
use rodio::MixerDeviceSink;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::sync::{Arc, Mutex};
|
use std::sync::{Arc, Mutex};
|
||||||
|
use crate::lang::Id;
|
||||||
use tokio::task::spawn_blocking;
|
use tokio::task::spawn_blocking;
|
||||||
|
|
||||||
pub struct RepetitionState {
|
pub struct RepetitionState {
|
||||||
@@ -24,7 +25,7 @@ pub struct RepetitionState {
|
|||||||
open: bool,
|
open: bool,
|
||||||
can_play: bool,
|
can_play: bool,
|
||||||
sink: Arc<MixerDeviceSink>,
|
sink: Arc<MixerDeviceSink>,
|
||||||
opened: HashSet<u32>,
|
opened: HashSet<Id>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NavigatedPage<RepetitionMessage> for RepetitionState {
|
impl NavigatedPage<RepetitionMessage> for RepetitionState {
|
||||||
|
|||||||
+8
-10
@@ -27,14 +27,12 @@ use std::sync::{Arc, Mutex};
|
|||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
pub struct RepetitionsState {
|
pub struct RepetitionsState {
|
||||||
selected_set_index: Option<usize>,
|
|
||||||
correct_filters: Vec<bool>,
|
correct_filters: Vec<bool>,
|
||||||
current_sets_cards_cache: HashMap<usize, (Vec<usize>, Vec<usize>)>,
|
current_sets_cards_cache: HashMap<usize, (Vec<usize>, Vec<usize>)>,
|
||||||
word_id_index_map: HashMap<u32, usize>,
|
word_id_index_map: HashMap<u32, usize>,
|
||||||
local_settings: HashMap<u32, DeckLocalSetting>,
|
local_settings: HashMap<u32, DeckLocalSetting>,
|
||||||
view_data: Option<SetViewData>,
|
view_data: Option<SetViewData>,
|
||||||
pub state: Arc<Mutex<AppState>>,
|
state: Arc<Mutex<AppState>>,
|
||||||
set_names: Vec<String>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl NavigatedPage<RepetitionsMessage> for RepetitionsState {
|
impl NavigatedPage<RepetitionsMessage> for RepetitionsState {
|
||||||
@@ -89,7 +87,9 @@ impl NavigatedPage<RepetitionsMessage> for RepetitionsState {
|
|||||||
GoToHistory => {}
|
GoToHistory => {}
|
||||||
GoToSettings => {}
|
GoToSettings => {}
|
||||||
|
|
||||||
CreateSet => {}
|
CreateSet => {
|
||||||
|
|
||||||
|
}
|
||||||
DeleteSet => {}
|
DeleteSet => {}
|
||||||
SetName(_) => {}
|
SetName(_) => {}
|
||||||
SelectSet(_) => {}
|
SelectSet(_) => {}
|
||||||
@@ -209,15 +209,15 @@ impl RepetitionsState {
|
|||||||
button("Проверить фильтр")
|
button("Проверить фильтр")
|
||||||
.style(jl_button)
|
.style(jl_button)
|
||||||
.on_press(TryFilter),
|
.on_press(TryFilter),
|
||||||
self.count_view(&set),
|
self.count_view(set),
|
||||||
]
|
]
|
||||||
.spacing(QUARTER_SPACING),
|
.spacing(QUARTER_SPACING),
|
||||||
]
|
]
|
||||||
.spacing(DEFAULT_SPACING)
|
.spacing(DEFAULT_SPACING)
|
||||||
} else {
|
} else {
|
||||||
column![
|
column![
|
||||||
self.filled_set_data_view(&set),
|
self.filled_set_data_view(set),
|
||||||
self.word_append_panel(&set),
|
self.word_append_panel(set),
|
||||||
radio(
|
radio(
|
||||||
"Обычный режим",
|
"Обычный режим",
|
||||||
OrderMode::Default,
|
OrderMode::Default,
|
||||||
@@ -430,7 +430,6 @@ impl RepetitionsState {
|
|||||||
|
|
||||||
impl RepetitionsState {
|
impl RepetitionsState {
|
||||||
fn append_all_words(&self, set: &DeckSettings) {
|
fn append_all_words(&self, set: &DeckSettings) {
|
||||||
let index = self.selected_set_index.unwrap();
|
|
||||||
let cache = &self.current_sets_cards_cache[&index];
|
let cache = &self.current_sets_cards_cache[&index];
|
||||||
let mut created_set = HashSet::with_capacity(cache.0.len());
|
let mut created_set = HashSet::with_capacity(cache.0.len());
|
||||||
cache.0.iter().for_each(|c| {
|
cache.0.iter().for_each(|c| {
|
||||||
@@ -461,13 +460,12 @@ impl RepetitionsState {
|
|||||||
fn select_set(&mut self, index: usize) {
|
fn select_set(&mut self, index: usize) {
|
||||||
let state = self.state.lock().unwrap();
|
let state = self.state.lock().unwrap();
|
||||||
if let Some(set) = state.card_sets.get(index) {
|
if let Some(set) = state.card_sets.get(index) {
|
||||||
self.selected_set_index = Some(index);
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn clear_selection(&mut self) {
|
fn clear_selection(&mut self) {
|
||||||
self.selected_set_index = None;
|
self.view_data = None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|||||||
Reference in New Issue
Block a user