Files
jap_learn/src/history.rs
T

118 lines
3.2 KiB
Rust
Raw Normal View History

2026-07-05 01:52:19 +03:00
use crate::dictionary::app_data_dir;
use crate::lang::{WordData, WordOpenMode};
2026-07-05 01:22:19 +03:00
use crate::{AppState, NavigatedPage, Page, RootMessage};
2026-07-05 01:52:19 +03:00
use chrono::{DateTime, Utc};
2026-07-05 01:22:19 +03:00
use iced::widget::*;
use iced::{Element, Fill, Left, Task};
2026-07-05 01:52:19 +03:00
use std::fs::File;
use std::io::{BufRead, BufReader};
2026-07-05 01:22:19 +03:00
use std::sync::{Arc, Mutex};
use HistoryMessage::Back;
#[derive(Clone)]
pub struct HistoryState {
set_id: u32,
2026-07-05 01:52:19 +03:00
list: Vec<HistoryItem>,
2026-07-05 01:22:19 +03:00
}
impl NavigatedPage<HistoryMessage> for HistoryState {
fn navigate(&self, message: &HistoryMessage) -> Option<Page> {
match message {
Back => Some(Page::PreviousPage),
_ => None,
}
}
}
impl HistoryState {
pub fn new(id: u32, state: Arc<Mutex<AppState>>) -> Self {
2026-07-05 01:52:19 +03:00
Self {
set_id: id,
list: get_history_of_set(id, &state.lock().unwrap().dictionary),
}
2026-07-05 01:22:19 +03:00
}
pub fn update(&mut self, message: HistoryMessage) -> Task<RootMessage> {
Task::none()
}
pub fn view(&self) -> Element<'_, HistoryMessage> {
container(
iced::widget::column![
button("Назад").on_press(HistoryMessage::Back),
// column![
//
// ]
// .height(Fill)
// .width(Fill)
]
.align_x(Left)
.width(Fill),
)
.center_x(Fill)
.padding(10)
.into()
}
}
2026-07-05 01:52:19 +03:00
fn get_history_of_set(id: u32, words: &Vec<WordData>) -> Vec<HistoryItem> {
let app_dir = app_data_dir();
let head = app_dir.clone().join(format!("set_{}_history.csv", id));
let tail = app_dir.clone().join(format!("set_{}_history.csv", id));
let mut lines = Vec::new();
if tail.exists() {
let reader = BufReader::new(File::open(tail).unwrap());
for line in reader.lines() {
lines.push(line.unwrap());
}
}
if head.exists() {
let reader = BufReader::new(File::open(head).unwrap());
for line in reader.lines() {
lines.push(line.unwrap());
}
}
parse_history_items(lines, words)
}
fn parse_history_items(strings: Vec<String>, words: &Vec<WordData>) -> Vec<HistoryItem> {
let mut items = Vec::with_capacity(strings.len());
for string in strings {
if let [time, word, mode, before, after] = string.split(';').collect::<Vec<&str>>()[..] {
items.push(HistoryItem {
timestamp: DateTime::from_timestamp(time.parse().unwrap(), 0).unwrap(),
word: words
.iter()
.find(|w| w.id == word.parse::<u32>().unwrap())
.unwrap()
.clone(),
mode: match mode.parse::<u8>().unwrap() {
2 => WordOpenMode::Hard,
3 => WordOpenMode::Ok,
4 => WordOpenMode::Easy,
_ => WordOpenMode::None,
},
before: before.parse().unwrap(),
after: after.parse().unwrap(),
});
}
}
items
}
2026-07-05 01:22:19 +03:00
#[derive(Clone)]
pub enum HistoryMessage {
Back,
}
#[derive(Clone)]
2026-07-05 01:52:19 +03:00
pub struct HistoryItem {
timestamp: DateTime<Utc>,
word: WordData,
mode: WordOpenMode,
before: u8,
after: u8,
}