From 64fbfb5a32273724ede890fca1af31621e2059fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=9C=D0=B8=D1=85=D0=B0=D0=B8=D0=BB=20=D0=9C=D0=B8=D1=82?= =?UTF-8?q?=D1=80=D0=BE=D1=84=D0=B0=D0=BD=D0=BE=D0=B2?= Date: Sat, 1 Aug 2026 23:40:56 +0300 Subject: [PATCH] Visual changes --- Cargo.lock | 16 +------------- Cargo.toml | 2 +- src/data_provider/card_stats.rs | 38 ++++++++++++++++----------------- src/data_provider/history.rs | 6 +----- src/data_provider/sqlite.rs | 2 +- src/dictionary.rs | 22 ++++++------------- src/history.rs | 8 ++++--- src/main.rs | 4 ++-- src/selector.rs | 23 +++++++++++++++----- src/styling.rs | 2 +- 10 files changed, 55 insertions(+), 68 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 45dc57e..1a3f6b3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -765,7 +765,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "173852283a9a57a3cbe365d86e74dc428a09c50421477d5ad6fe9d9509e37737" dependencies = [ "bitflags 2.10.0", - "fontdb 0.23.0", + "fontdb", "harfrust", "linebender_resource_handle", "log", @@ -1200,19 +1200,6 @@ dependencies = [ "ttf-parser", ] -[[package]] -name = "fontdb" -version = "0.24.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2660c5e9157bf76d2db1294e4a9feba604ef610819a3b591088d0d8392a3290f" -dependencies = [ - "fontconfig-parser", - "log", - "memmap2", - "slotmap", - "tinyvec", -] - [[package]] name = "foreign-types" version = "0.3.2" @@ -2110,7 +2097,6 @@ dependencies = [ "chrono", "criterion", "dirs", - "fontdb 0.24.0", "hex", "iced", "iced_core", diff --git a/Cargo.toml b/Cargo.toml index ba71ca0..b479d96 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,7 @@ sha2 = "0.11.0" tokio = { version = "1.50.0", features = ["rt", "rt-multi-thread", "macros"] } hex = "0.4.3" zstd = "0.13.3" -fontdb = "0.24.0" + [dev-dependencies] criterion = "0.8.2" diff --git a/src/data_provider/card_stats.rs b/src/data_provider/card_stats.rs index febab17..ef4a3bb 100644 --- a/src/data_provider/card_stats.rs +++ b/src/data_provider/card_stats.rs @@ -64,29 +64,29 @@ pub fn add_stat_list(stat: &mut Vec, connection: &Connection) { let mut index = 0; for id in start_index..=last_index { - stat[index].id = id as u32; + stat[index].id = id; index += 1; } } -pub fn add_stat(stat: &mut CardStatistics, connection: &Connection) { - let time = Instant::now(); - let index = connection - .query_row( - "INSERT INTO card_stats (word_id, set_id, score, last_opened) VALUES (?1, ?2, ?3, ?4) RETURNING id", - ( - &stat.word_id, - &stat.set_id, - &stat.score, - &stat.last_open.timestamp(), - ), - |row| row.get(0) - ) - .unwrap_or_else(|e| {println!("{}", e); 0}); - - stat.id = index; - println!("Added stat: {}", time.elapsed().as_millis()); -} +// pub fn add_stat(stat: &mut CardStatistics, connection: &Connection) { +// let time = Instant::now(); +// let index = connection +// .query_row( +// "INSERT INTO card_stats (word_id, set_id, score, last_opened) VALUES (?1, ?2, ?3, ?4) RETURNING id", +// ( +// &stat.word_id, +// &stat.set_id, +// &stat.score, +// &stat.last_open.timestamp(), +// ), +// |row| row.get(0) +// ) +// .unwrap_or_else(|e| {println!("{}", e); 0}); +// +// stat.id = index; +// println!("Added stat: {}", time.elapsed().as_millis()); +// } pub fn update_stat_score(stat: &CardStatistics, connection: &Connection) { let time = Instant::now(); diff --git a/src/data_provider/history.rs b/src/data_provider/history.rs index 2d31971..539ab23 100644 --- a/src/data_provider/history.rs +++ b/src/data_provider/history.rs @@ -6,17 +6,13 @@ use std::io::Write; use std::io::{BufRead, BufReader}; use std::path::PathBuf; -const MAX_HISTORY_LENGTH: usize = 1000; - pub fn get_history_of_set(id: u32) -> Vec { 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_tail.csv", id)); let mut lines = Vec::new(); - append_lines_if_exists(tail, &mut lines); append_lines_if_exists(head, &mut lines); - + lines.reverse(); parse_history_items(lines) } diff --git a/src/data_provider/sqlite.rs b/src/data_provider/sqlite.rs index 0cd0b1a..ef20c1e 100644 --- a/src/data_provider/sqlite.rs +++ b/src/data_provider/sqlite.rs @@ -17,7 +17,7 @@ pub fn create_db() { } } -fn ensure_db_schema(conn: &Connection) {} +fn ensure_db_schema(_: &Connection) {} fn create_tables(conn: &Connection) { make_card_set(conn).unwrap(); diff --git a/src/dictionary.rs b/src/dictionary.rs index 96d54e6..2aea4a5 100644 --- a/src/dictionary.rs +++ b/src/dictionary.rs @@ -293,13 +293,14 @@ impl DictionaryState { row![ iced::widget::column![ self.groups_panel(), - self.words_list(), + row![horizontal().width(8), + self.words_list(),], button("Добавить слово").style(jl_button).on_press(NewWord), ] .spacing(5), self.filters(), ] - .spacing(5) + .spacing(DEFAULT_SPACING) .into(), Back, ) @@ -337,8 +338,7 @@ impl DictionaryState { let mut line = Row::new().width(Length::Fill).align_y(Center); line = line - .push(checkbox(self.include_map[i]).on_toggle(move |b| Include(i, b))) - .push(space().width(10)); + .push(checkbox(self.include_map[i]).label("").spacing(15).on_toggle(move |b| Include(i, b))); line = line.push( text_input("Слово", &word.key) @@ -536,7 +536,7 @@ impl DictionaryState { iced::widget::column![ scrollable(row).width(Length::Fill).horizontal(), row![ - button("⇳").on_press(ChangeDirection), + button("⇳").on_press(ChangeDirection).style(jl_button), text_input("Название группы слов", &group.name) .on_input(EditGroup) .width(250) @@ -544,7 +544,7 @@ impl DictionaryState { horizontal(), button("Удалить").style(danger).on_press(DeleteGroup), ] - .spacing(DEFAULT_SPACING) + .spacing(DEFAULT_SPACING / 2.0) ] .into() } @@ -566,13 +566,3 @@ pub fn app_data_dir() -> PathBuf { dir } - -// pub fn app_cache_dir() -> PathBuf { -// let mut dir = dirs::cache_dir().unwrap(); -// dir.push("jap_learn"); -// if !dir.exists() { -// fs::create_dir(dir.clone()).unwrap(); -// } -// -// dir -// } diff --git a/src/history.rs b/src/history.rs index b1214b9..ff4c141 100644 --- a/src/history.rs +++ b/src/history.rs @@ -1,14 +1,15 @@ -use crate::data_provider::history::{get_history_of_set, HistoryItem}; +use crate::data_provider::history::{HistoryItem, get_history_of_set}; use crate::lang::WordData; 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; use iced::widget::*; use iced::{Element, Fill, FillPortion, Task}; use std::sync::{Arc, Mutex}; -use HistoryMessage::Back; #[derive(Clone)] pub struct HistoryState { @@ -82,10 +83,11 @@ impl HistoryState { .align_x(Center), iced::widget::column![ text!("{} ➞ {}", item.before, item.after), - text!("{}", item.timestamp.format("%d.%m %H:%M")) + text!("{}", item.timestamp.with_timezone(&Local).format("%d.%m %H:%M")) ] .spacing(5) .align_x(Center) + ] .spacing(5), ); diff --git a/src/main.rs b/src/main.rs index a60f5b4..81e870c 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,4 @@ -// #![windows_subsystem = "windows"] +#![windows_subsystem = "windows"] mod data_provider; mod dictionary; mod dictionary_test; @@ -25,7 +25,7 @@ use crate::quiz::*; use crate::repetitions::CardSetSettings; use crate::RootMessage::Keyboard; use iced::Font; -use iced::{keyboard, Program, Subscription, Theme}; +use iced::{keyboard, Subscription, Theme}; use rusqlite::Connection; const USER_FONT: Font = Font::with_name("Noto Sans JP"); diff --git a/src/selector.rs b/src/selector.rs index 81e9759..8fb4001 100644 --- a/src/selector.rs +++ b/src/selector.rs @@ -9,8 +9,10 @@ use crate::styling::*; use crate::sync::SyncState; use crate::writing::WritingState; use crate::{AppState, QuizState, RootMessage}; +use iced::widget::button::{Status, Style}; use iced::widget::*; -use iced::{alignment, Element, Task}; +use iced::{Element, Task, alignment}; +use iced_core::{Background, Color}; use std::sync::{Arc, Mutex}; pub struct SelectorState { @@ -80,6 +82,17 @@ impl SelectorState { Task::none() } + fn nav_style(theme: &Theme, status: Status) -> Style { + let mut basic = button::text(theme, status); + basic.background = if status == Status::Hovered { + Some(Background::Color(Color::WHITE.scale_alpha(0.1))) + } else { + None + }; + basic.border.radius = BUTTON_RADIUS.into(); + basic + } + pub fn view(&self) -> Element<'_, SelectorMessage> { container( iced::widget::column![ @@ -89,16 +102,16 @@ impl SelectorState { .style(jl_button), button("Словарь") .on_press(SelectorMessage::ToDictionary) - .style(button::text), + .style(Self::nav_style), button("Рандомайзер") .on_press(SelectorMessage::ToRandomize) - .style(button::text), + .style(Self::nav_style), button("Повторение") .on_press(SelectorMessage::ToRepetitions) - .style(button::text), + .style(Self::nav_style), button("Синхронизация") .on_press(SelectorMessage::ToSync) - .style(button::text) + .style(Self::nav_style) ] .spacing(DEFAULT_SPACING), self.rows_selector(), diff --git a/src/styling.rs b/src/styling.rs index 2fd5020..9565e1d 100644 --- a/src/styling.rs +++ b/src/styling.rs @@ -9,7 +9,7 @@ use iced_core::{Border, Theme}; pub const DEFAULT_SPACING: f32 = 16.0; pub const ACCENT_FONT_SIZE: f32 = 22.0; -const BUTTON_RADIUS: f32 = 8.0; +pub const BUTTON_RADIUS: f32 = 8.0; pub fn jl_button(theme: &Theme, status: Status) -> Style { let mut style = primary(theme, status);