History page drawing
This commit is contained in:
+62
-72
@@ -1,18 +1,18 @@
|
||||
use crate::dictionary::app_data_dir;
|
||||
use crate::lang::{WordData, WordOpenMode};
|
||||
use crate::{AppState, NavigatedPage, Page, RootMessage};
|
||||
use chrono::{DateTime, Utc};
|
||||
use iced::widget::*;
|
||||
use iced::{Element, Fill, Left, Task};
|
||||
use std::fs::File;
|
||||
use std::io::{BufRead, BufReader};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use crate::data_provider::history::{HistoryItem, get_history_of_set};
|
||||
use crate::lang::WordData;
|
||||
use crate::{AppState, DEFAULT_SPACING, NavigatedPage, Page, RootMessage};
|
||||
use HistoryMessage::Back;
|
||||
use iced::alignment::Horizontal::Center;
|
||||
use iced::widget::space::horizontal;
|
||||
use iced::widget::*;
|
||||
use iced::{Element, Fill, FillPortion, Left, Task};
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct HistoryState {
|
||||
set_id: usize,
|
||||
set_id: u32,
|
||||
list: Vec<HistoryItem>,
|
||||
words: Vec<WordData>,
|
||||
}
|
||||
|
||||
impl NavigatedPage<HistoryMessage> for HistoryState {
|
||||
@@ -25,10 +25,25 @@ impl NavigatedPage<HistoryMessage> for HistoryState {
|
||||
}
|
||||
|
||||
impl HistoryState {
|
||||
pub fn new(id: usize, state: Arc<Mutex<AppState>>) -> Self {
|
||||
pub fn new(id: u32, state: Arc<Mutex<AppState>>) -> Self {
|
||||
let state = state.lock().unwrap();
|
||||
let history = get_history_of_set(id);
|
||||
let words = history
|
||||
.iter()
|
||||
.map(|item| {
|
||||
state
|
||||
.dictionary
|
||||
.iter()
|
||||
.find(|w| w.id == item.word_id)
|
||||
.unwrap()
|
||||
.clone()
|
||||
})
|
||||
.collect();
|
||||
|
||||
Self {
|
||||
set_id: id,
|
||||
list: get_history_of_set(id, &state.lock().unwrap().dictionary),
|
||||
list: history,
|
||||
words,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,12 +54,16 @@ impl HistoryState {
|
||||
pub fn view(&self) -> Element<'_, HistoryMessage> {
|
||||
container(
|
||||
iced::widget::column![
|
||||
button("Назад").on_press(HistoryMessage::Back),
|
||||
// column![
|
||||
//
|
||||
// ]
|
||||
// .height(Fill)
|
||||
// .width(Fill)
|
||||
button("Назад").on_press(Back),
|
||||
iced::widget::row![
|
||||
horizontal().width(FillPortion(1)),
|
||||
scrollable(self.history_lines().padding(DEFAULT_SPACING))
|
||||
.height(Fill)
|
||||
.width(FillPortion(5)),
|
||||
horizontal().width(FillPortion(1))
|
||||
]
|
||||
.height(Fill)
|
||||
.width(Fill)
|
||||
]
|
||||
.align_x(Left)
|
||||
.width(Fill),
|
||||
@@ -53,66 +72,37 @@ impl HistoryState {
|
||||
.padding(10)
|
||||
.into()
|
||||
}
|
||||
}
|
||||
|
||||
fn get_history_of_set(id: usize, 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());
|
||||
fn history_lines(&self) -> Column<'_, HistoryMessage> {
|
||||
let mut column = Column::new();
|
||||
for (item, index) in self.list.iter().zip(0..self.list.len()) {
|
||||
column = column.push(
|
||||
row![
|
||||
iced::widget::column![
|
||||
text!("{}", self.words[index].key)
|
||||
.width(Fill)
|
||||
.align_x(Center),
|
||||
text!("{}", self.words[index].value)
|
||||
.width(Fill)
|
||||
.align_x(Center),
|
||||
]
|
||||
.align_x(Center),
|
||||
iced::widget::column![
|
||||
text!("{} ➞ {}", item.before, item.after),
|
||||
text!("{}", item.timestamp.format("%d.%m %H:%M"))
|
||||
]
|
||||
.spacing(5)
|
||||
.align_x(Center)
|
||||
]
|
||||
.spacing(5),
|
||||
);
|
||||
column = column.push(rule::horizontal(1));
|
||||
}
|
||||
column.spacing(5)
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum HistoryMessage {
|
||||
Back,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct HistoryItem {
|
||||
timestamp: DateTime<Utc>,
|
||||
word: WordData,
|
||||
mode: WordOpenMode,
|
||||
before: u8,
|
||||
after: u8,
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user