diff --git a/src/data_provider/card_stats.rs b/src/data_provider/card_stats.rs index 19efeb4..a4d2ad1 100644 --- a/src/data_provider/card_stats.rs +++ b/src/data_provider/card_stats.rs @@ -73,15 +73,6 @@ pub fn update_stat_score(stat: &CardStatistics, connection: &Connection) { println!("Updated stat: {}", time.elapsed().as_millis()); } -pub fn delete_stat(stat: &CardStatistics, connection: &Connection) { - if !stat.id.is_valid() { - return; - } - connection - .execute("DELETE FROM card_stats WHERE id = ?1", (&stat.id,)) - .unwrap(); -} - pub fn delete_stats(stat: &[CardStatistics], connection: &Connection) { if stat.is_empty() { return; diff --git a/src/data_provider/web_api.rs b/src/data_provider/web_api.rs index 5640474..983d54f 100644 --- a/src/data_provider/web_api.rs +++ b/src/data_provider/web_api.rs @@ -1,5 +1,6 @@ use crate::dictionary::app_data_dir; use std::io; +use reqwest::Error; use tokio::fs::{File, OpenOptions}; use tokio::io::{AsyncReadExt, AsyncWriteExt}; use zstd::{DEFAULT_COMPRESSION_LEVEL, Decoder, Encoder}; @@ -34,16 +35,16 @@ fn compress(data: Vec) -> Vec { encoder.finish().unwrap() } -pub async fn load_data(id: String, temp: bool) -> Result<(), ()> { +pub async fn load_data(id: String, temp: bool) -> Result<(), Error> { let api_url = API_URL.to_string(); let id_url = format!("{api_url}download/{id}"); let client = reqwest::Client::new(); let data = client .get(&id_url) .send() - .await.map_err(|_| ())? + .await? .bytes() - .await.map_err(|_| ())? + .await? .to_vec(); let data = decompress(data); @@ -51,16 +52,16 @@ pub async fn load_data(id: String, temp: bool) -> Result<(), ()> { let file_name = if temp { "data.db.tmp" } else { "data.db" }; let db_file = path.join(file_name); - tokio::fs::write(db_file, data).await.map_err(|_| ())?; + tokio::fs::write(db_file, data).await.unwrap(); let version_url = format!("{API_URL}{id}/version"); let version = client .get(&version_url) .send() - .await.map_err(|_| ())? + .await? .text() - .await.map_err(|_| ())?; - set_local_version(version.parse::().map_err(|_| ())?).await; + .await?; + set_local_version(version.parse::().unwrap_or_default()).await; Ok(()) } diff --git a/src/history.rs b/src/history.rs index 7399019..380477b 100644 --- a/src/history.rs +++ b/src/history.rs @@ -1,9 +1,8 @@ -use crate::data_provider::history::{HistoryItem, get_history_of_set}; -use crate::lang::WordData; +use crate::data_provider::history::{get_history_of_set, HistoryItem}; +use crate::lang::{WordData, INVALID_ID}; use crate::navigation::{NavigatedPage, Page}; use crate::styling::*; use crate::{AppState, RootMessage}; -use HistoryMessage::Back; use chrono::Local; use iced::alignment::Horizontal::Center; use iced::widget::space::horizontal; @@ -11,6 +10,7 @@ use iced::widget::*; use iced::{Element, Fill, FillPortion, Task}; use parking_lot::Mutex; use std::sync::Arc; +use HistoryMessage::Back; #[derive(Clone)] pub struct HistoryState { @@ -52,8 +52,19 @@ impl HistoryState { let history = get_history_of_set(id); let words = history .iter() - .filter_map(|item| state.dictionary.iter().find(|w| w.id == item.word_id)) - .cloned() + .map( + |item| match state.dictionary.iter().find(|w| w.id == item.word_id) { + None => WordData { + id, + key: "Удаленное слово".to_string(), + value: "Удаленное слово".to_string(), + tags: "Удаленное слово".to_string(), + additional: Default::default(), + group_id: INVALID_ID, + }, + Some(word) => word.clone(), + }, + ) .collect(); Self { @@ -64,7 +75,7 @@ impl HistoryState { fn history_lines(&self) -> Column<'_, HistoryMessage> { let mut column = Column::new(); - for (item, index) in self.list.iter().zip(0..self.list.len()) { + for (index, item) in self.list.iter().enumerate() { column = column.push( row![ iced::widget::column![ diff --git a/src/import.rs b/src/import.rs index 04c75c9..0b05ad3 100644 --- a/src/import.rs +++ b/src/import.rs @@ -489,7 +489,7 @@ impl ImportState { add_words(word, connection); index += 1; let mut progress = progress.lock(); - *progress = index as f32 / total_len; + *progress = (index as f32 / total_len).min(1.0); } state.dictionary.append(&mut words_list); diff --git a/src/lang.rs b/src/lang.rs index 4635267..dcf672c 100644 --- a/src/lang.rs +++ b/src/lang.rs @@ -1,10 +1,11 @@ +use crate::data_provider::card_stats::load_stats_of_deck; +use crate::data_provider::card_stats::update_stat_score; +use crate::data_provider::history::{push_note, HistoryItem}; use crate::AppState; -use crate::data_provider::card_stats::{delete_stat, load_stats_of_deck, update_stat_score}; -use crate::data_provider::history::{HistoryItem, push_note}; use chrono::{DateTime, Utc}; use parking_lot::Mutex; -use rand::distr::Distribution; use rand::distr::weighted::WeightedIndex; +use rand::distr::Distribution; use rand::prelude::SliceRandom; use rand::rng; use rand::rngs::ThreadRng; @@ -12,8 +13,8 @@ use rayon::iter::IndexedParallelIterator; use rayon::iter::IntoParallelRefIterator; use rayon::iter::ParallelIterator; use rhai::{Engine, Scope}; -use rusqlite::ToSql; use rusqlite::types::{FromSql, FromSqlError, FromSqlResult, ToSqlOutput, ValueRef}; +use rusqlite::ToSql; use std::cmp::PartialEq; use std::collections::HashMap; use std::fmt::{Display, Formatter}; diff --git a/src/navigation.rs b/src/navigation.rs index c628b50..19d9db8 100644 --- a/src/navigation.rs +++ b/src/navigation.rs @@ -1,8 +1,6 @@ use crate::data_provider::history::{get_history_of_set, history_dir}; use crate::data_provider::sqlite::{create_db, default_connection}; -use crate::data_provider::web_api::{ - get_local_version, get_web_version, load_data, set_local_version, -}; +use crate::data_provider::web_api::{get_local_version, get_web_version, load_data, set_local_version}; use crate::dictionary::{DictionaryMessage, DictionaryState, app_data_dir}; use crate::dictionary_quiz::{DictionaryQuizMessage, DictionaryQuizState}; use crate::history::{HistoryMessage, HistoryState}; @@ -154,7 +152,7 @@ impl ScreenState { println!("{} {}", local, web); if web > local { println!("Web version is newer than local version"); - load_data(string, true).await; + load_data(string, true).await?; set_local_version(web).await; } else { return Ok(false); diff --git a/src/repetition.rs b/src/repetition.rs index e5ea97e..298a3d2 100644 --- a/src/repetition.rs +++ b/src/repetition.rs @@ -9,8 +9,8 @@ use chrono::Local; use iced::alignment::Horizontal::Center; use iced::keyboard::key::Physical::Code; use iced::widget::text::Style; -use iced::widget::{Column, button, column, container, row, rule, space, text, tooltip}; -use iced::{Element, Fill, Task, Theme, alignment, keyboard}; +use iced::widget::{button, column, container, row, rule, space, text, tooltip, Column}; +use iced::{alignment, keyboard, Element, Fill, Task, Theme}; use parking_lot::Mutex; use rodio::MixerDeviceSink; use std::collections::HashSet; @@ -319,7 +319,9 @@ pub enum RepetitionMessage { async fn play_sound(sink: Arc, text: String) { if let Ok(data) = get_voice(text.as_str()).await { spawn_blocking(move || { - rodio::play(sink.mixer(), data).unwrap().sleep_until_end(); + if let Ok(play) = rodio::play(sink.mixer(), data) { + play.sleep_until_end() + } }) .await .unwrap();