Import page base

This commit is contained in:
2026-08-13 22:38:48 +03:00
parent 4ca7aa7044
commit 4d0788e0f5
6 changed files with 117 additions and 43 deletions
Generated
+36
View File
@@ -1115,6 +1115,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec"
dependencies = [ dependencies = [
"bitflags 2.10.0", "bitflags 2.10.0",
"block2 0.6.2",
"libc",
"objc2 0.6.3", "objc2 0.6.3",
] ]
@@ -2309,6 +2311,7 @@ dependencies = [
"iced_core", "iced_core",
"rand", "rand",
"reqwest", "reqwest",
"rfd",
"rhai", "rhai",
"rodio", "rodio",
"rusqlite", "rusqlite",
@@ -3519,6 +3522,12 @@ dependencies = [
"windows-sys 0.61.2", "windows-sys 0.61.2",
] ]
[[package]]
name = "pollster"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2f3a9f18d041e6d0e102a0a46750538147e5e8992d3b4873aaafee2520b00ce3"
[[package]] [[package]]
name = "portable-atomic" name = "portable-atomic"
version = "1.13.1" version = "1.13.1"
@@ -3914,6 +3923,33 @@ dependencies = [
"zune-jpeg", "zune-jpeg",
] ]
[[package]]
name = "rfd"
version = "0.17.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20dafead71c16a34e1ff357ddefc8afc11e7d51d6d2b9fbd07eaa48e3e540220"
dependencies = [
"block2 0.6.2",
"dispatch2",
"js-sys",
"libc",
"log",
"objc2 0.6.3",
"objc2-app-kit 0.3.2",
"objc2-core-foundation",
"objc2-foundation 0.3.2",
"percent-encoding",
"pollster",
"raw-window-handle",
"wasm-bindgen",
"wasm-bindgen-futures",
"wayland-backend",
"wayland-client",
"wayland-protocols",
"web-sys",
"windows-sys 0.61.2",
]
[[package]] [[package]]
name = "rgb" name = "rgb"
version = "0.8.53" version = "0.8.53"
+8 -5
View File
@@ -20,6 +20,13 @@ tokio = { version = "1.53.1", features = ["rt", "rt-multi-thread", "macros"] }
hex = "0.4.3" hex = "0.4.3"
zstd = "0.13.3" zstd = "0.13.3"
zip = "8.6.0" zip = "8.6.0"
rfd = "0.17.2"
[profile.super-release]
inherits = "release"
codegen-units = 1
lto = true
opt-level = 3
[dev-dependencies] [dev-dependencies]
criterion = "0.8.2" criterion = "0.8.2"
@@ -28,8 +35,4 @@ criterion = "0.8.2"
name = "split_bench" # Имя файла в benches/ без расширения name = "split_bench" # Имя файла в benches/ без расширения
harness = false # Отключаем стандартный тестовый раннер harness = false # Отключаем стандартный тестовый раннер
[profile.super-release]
inherits = "release"
codegen-units = 1
lto = true
opt-level = 3
+18 -14
View File
@@ -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::lang::{WordData, WordGroup}; use crate::lang::{WordData, WordGroup};
use crate::navigation::Page::Word; use crate::navigation::Page::{Import, Word};
use crate::navigation::{NavigatedPage, Page}; use crate::navigation::{NavigatedPage, Page};
use crate::styling::*; use crate::styling::*;
use crate::word::WordState; use crate::word::WordState;
@@ -22,6 +22,8 @@ use std::ops::Add;
use std::path::PathBuf; use std::path::PathBuf;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::time::{Duration, Instant}; use std::time::{Duration, Instant};
use iced_core::Length::Fill;
use crate::import::ImportState;
#[derive(Clone)] #[derive(Clone)]
pub struct DictionaryState { pub struct DictionaryState {
@@ -59,6 +61,7 @@ pub enum DictionaryMessage {
DeleteGroup, DeleteGroup,
ChangeDirection, ChangeDirection,
TrySave(usize), TrySave(usize),
ToImport
} }
impl NavigatedPage<DictionaryMessage> for DictionaryState { impl NavigatedPage<DictionaryMessage> for DictionaryState {
@@ -97,11 +100,13 @@ impl NavigatedPage<DictionaryMessage> for DictionaryState {
return Some(Word(WordState::new(word, *index, self.state.clone()))); return Some(Word(WordState::new(word, *index, self.state.clone())));
} }
} }
if let ToImport = message {
return Some(Import(ImportState::new(self.state.clone())))
}
None None
} }
fn navigated(&mut self) { fn navigated(&mut self) {}
}
fn update(&mut self, message: DictionaryMessage) -> Task<RootMessage> { fn update(&mut self, message: DictionaryMessage) -> Task<RootMessage> {
match message { match message {
@@ -245,6 +250,7 @@ impl NavigatedPage<DictionaryMessage> for DictionaryState {
self.save_word(word_index); self.save_word(word_index);
} }
} }
ToImport => {}
} }
Task::none() Task::none()
@@ -256,13 +262,16 @@ impl NavigatedPage<DictionaryMessage> for DictionaryState {
iced::widget::column![ iced::widget::column![
self.groups_panel(), self.groups_panel(),
row![horizontal().width(8), self.words_list(),], row![horizontal().width(8), self.words_list(),],
button("Добавить слово").style(jl_button).on_press(NewWord), row![button("Добавить слово").style(jl_button).on_press(NewWord),
horizontal().width(Fill),
button("Импорт").style(jl_button).on_press(ToImport),
]
] ]
.spacing(5), .spacing(5),
self.filters(), self.filters(),
] ]
.spacing(DEFAULT_SPACING) .spacing(DEFAULT_SPACING)
.into(), .into(),
Back, Back,
) )
} }
@@ -308,8 +317,6 @@ impl DictionaryState {
) )
} }
fn words_list(&self) -> iced::Element<'_, DictionaryMessage> { fn words_list(&self) -> iced::Element<'_, DictionaryMessage> {
let time = Instant::now(); let time = Instant::now();
let mut col = Column::new().width(Length::Fill); let mut col = Column::new().width(Length::Fill);
@@ -340,13 +347,13 @@ impl DictionaryState {
continue; continue;
} }
let word_line_data = WordLineState{ let word_line_data = WordLineState {
is_included: self.include_map[i], is_included: self.include_map[i],
key: word.key.clone(), key: word.key.clone(),
value: word.value.clone(), value: word.value.clone(),
tags: word.tags.clone(), tags: word.tags.clone(),
id: word.id, id: word.id,
index: i index: i,
}; };
let lazy_line = lazy(word_line_data, move |data| { let lazy_line = lazy(word_line_data, move |data| {
@@ -416,9 +423,6 @@ impl DictionaryState {
line line
}); });
col = col.push(lazy_line); col = col.push(lazy_line);
} }
@@ -592,7 +596,7 @@ pub fn app_data_dir() -> PathBuf {
} }
#[derive(Hash, PartialEq, Eq)] #[derive(Hash, PartialEq, Eq)]
struct WordLineState{ struct WordLineState {
is_included: bool, is_included: bool,
key: String, key: String,
value: String, value: String,
+22 -6
View File
@@ -1,14 +1,23 @@
use std::sync::{Arc, Mutex};
use iced::{Element, Task}; use iced::{Element, Task};
use iced::widget::scrollable;
use crate::navigation::{NavigatedPage, Page, RootMessage}; use crate::navigation::{NavigatedPage, Page, RootMessage};
use crate::styling::*;
struct ImportState {} use iced::widget::{column, row, button, text };
enum ImportMessage { use crate::AppState;
use crate::import::ImportMessage::*;
#[derive(Clone)]
pub struct ImportState {
state: Arc<Mutex<AppState>>
}
#[derive(Clone)]
pub enum ImportMessage {
Back Back
} }
impl NavigatedPage<ImportMessage> for ImportState { impl NavigatedPage<ImportMessage> for ImportState {
fn navigate(&self, message: &ImportMessage) -> Option<Page> { fn navigate(&self, message: &ImportMessage) -> Option<Page> {
if let ImportMessage::Back = message { if let Back = message {
return Some(Page::PreviousPage) return Some(Page::PreviousPage)
} }
None None
@@ -18,11 +27,18 @@ impl NavigatedPage<ImportMessage> for ImportState {
} }
fn update(&mut self, message: ImportMessage) -> Task<RootMessage> { fn update(&mut self, message: ImportMessage) -> Task<RootMessage> {
todo!() Task::none()
} }
fn view(&self) -> Element<'_, ImportMessage> { fn view(&self) -> Element<'_, ImportMessage> {
todo!() back_overlay(scrollable(column![]).into(), Back)
}
}
impl ImportState {
pub fn new(state: Arc<Mutex<AppState>>) -> ImportState {
ImportState{
state
}
} }
} }
+22 -12
View File
@@ -27,7 +27,7 @@ use crate::quiz::*;
use crate::repetitions::CardSetSettings; use crate::repetitions::CardSetSettings;
use crate::RootMessage::Keyboard; use crate::RootMessage::Keyboard;
use chrono::NaiveDate; use chrono::NaiveDate;
use iced::{keyboard, Subscription, Theme}; use iced::{keyboard, Program, Subscription, Theme};
use iced::{window, Font}; use iced::{window, Font};
use iced_core::window::Position; use iced_core::window::Position;
use iced_core::Size; use iced_core::Size;
@@ -39,15 +39,7 @@ const USER_FONT: Font = Font::with_name("Noto Sans JP");
fn main() -> iced::Result { fn main() -> iced::Result {
println!("Welcome to JapLearn"); println!("Welcome to JapLearn");
iced::application(ScreenState::boot, ScreenState::update, ScreenState::view).window(window::Settings{ iced::application(ScreenState::boot, ScreenState::update, ScreenState::view).window(window_settings())
position: Position::Centered,
min_size: Some(Size::new(700.0_f32.into(), 700.0_f32.into())),
platform_specific: PlatformSpecific {
application_id: "JapLearn".to_string(),
override_redirect: false
},
.. Default::default()
})
.subscription(subscription) .subscription(subscription)
.title("JapLearn") .title("JapLearn")
.settings(iced::Settings { .settings(iced::Settings {
@@ -56,8 +48,26 @@ fn main() -> iced::Result {
}) })
.font(include_bytes!("../noto.ttf")) .font(include_bytes!("../noto.ttf"))
.default_font(USER_FONT) .default_font(USER_FONT)
.theme(Theme::GruvboxDark) .theme(Theme::GruvboxDark).run()
.run() }
fn window_settings() -> window::Settings {
let mut settings = window::Settings{
position: Position::Centered,
min_size: Some(Size::new(700.0_f32.into(), 700.0_f32.into())),
.. Default::default()
};
#[cfg(target_os = "linux")]
{
settings.platform_specific =
PlatformSpecific {
application_id: "JapLearn".to_string(),
override_redirect: false
};
}
settings
} }
fn subscription(_state: &ScreenState) -> Subscription<RootMessage> { fn subscription(_state: &ScreenState) -> Subscription<RootMessage> {
+9 -4
View File
@@ -27,6 +27,7 @@ use reqwest::Error;
use std::collections::HashMap; use std::collections::HashMap;
use std::sync::{Arc, Mutex}; use std::sync::{Arc, Mutex};
use std::time::Instant; use std::time::Instant;
use crate::import::{ImportMessage, ImportState};
impl Default for ScreenState { impl Default for ScreenState {
fn default() -> Self { fn default() -> Self {
@@ -54,6 +55,7 @@ pub enum RootMessage {
Sync(SyncMessage), Sync(SyncMessage),
History(HistoryMessage), History(HistoryMessage),
RepetitionSettings(RepetitionSettingsMessage), RepetitionSettings(RepetitionSettingsMessage),
Import(ImportMessage),
Keyboard(Event), Keyboard(Event),
DataLoaded(HashMap<u32, Vec<(NaiveDate, u32)>>), DataLoaded(HashMap<u32, Vec<(NaiveDate, u32)>>),
None, None,
@@ -73,7 +75,7 @@ pub enum Page {
Sync(SyncState), Sync(SyncState),
History(HistoryState), History(HistoryState),
RepetitionSettings(RepetitionSettingsState), RepetitionSettings(RepetitionSettingsState),
Import(ImportState),
PreviousPage, PreviousPage,
} }
@@ -190,7 +192,8 @@ impl ScreenState {
Word, Word,
Sync, Sync,
History, History,
RepetitionSettings RepetitionSettings,
Import
); );
} }
println!("Update took {:?}", time.elapsed()); println!("Update took {:?}", time.elapsed());
@@ -213,7 +216,8 @@ impl ScreenState {
Word, Word,
Sync, Sync,
History, History,
RepetitionSettings RepetitionSettings,
Import
) )
} }
@@ -233,7 +237,8 @@ impl ScreenState {
Word, Word,
Sync, Sync,
History, History,
RepetitionSettings RepetitionSettings,
Import
); );
println!("View took {:?}", time.elapsed()); println!("View took {:?}", time.elapsed());