diff --git a/Cargo.lock b/Cargo.lock index 8323173..6bb6f03 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1115,6 +1115,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89a09f22a6c6069a18470eb92d2298acf25463f14256d24778e1230d789a2aec" dependencies = [ "bitflags 2.10.0", + "block2 0.6.2", + "libc", "objc2 0.6.3", ] @@ -2309,6 +2311,7 @@ dependencies = [ "iced_core", "rand", "reqwest", + "rfd", "rhai", "rodio", "rusqlite", @@ -3519,6 +3522,12 @@ dependencies = [ "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]] name = "portable-atomic" version = "1.13.1" @@ -3914,6 +3923,33 @@ dependencies = [ "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]] name = "rgb" version = "0.8.53" diff --git a/Cargo.toml b/Cargo.toml index 0d5a784..5eb0a70 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -20,6 +20,13 @@ tokio = { version = "1.53.1", features = ["rt", "rt-multi-thread", "macros"] } hex = "0.4.3" zstd = "0.13.3" zip = "8.6.0" +rfd = "0.17.2" + +[profile.super-release] +inherits = "release" +codegen-units = 1 +lto = true +opt-level = 3 [dev-dependencies] criterion = "0.8.2" @@ -28,8 +35,4 @@ criterion = "0.8.2" name = "split_bench" # Имя файла в benches/ без расширения harness = false # Отключаем стандартный тестовый раннер -[profile.super-release] -inherits = "release" -codegen-units = 1 -lto = true -opt-level = 3 + diff --git a/src/dictionary.rs b/src/dictionary.rs index 88f4be2..a910516 100644 --- a/src/dictionary.rs +++ b/src/dictionary.rs @@ -2,7 +2,7 @@ use crate::data_provider::words::{delete_group, delete_word, update_group, updat use crate::dictionary::DictionaryMessage::*; use crate::dictionary_test::DictionaryQuizState; use crate::lang::{WordData, WordGroup}; -use crate::navigation::Page::Word; +use crate::navigation::Page::{Import, Word}; use crate::navigation::{NavigatedPage, Page}; use crate::styling::*; use crate::word::WordState; @@ -22,6 +22,8 @@ use std::ops::Add; use std::path::PathBuf; use std::sync::{Arc, Mutex}; use std::time::{Duration, Instant}; +use iced_core::Length::Fill; +use crate::import::ImportState; #[derive(Clone)] pub struct DictionaryState { @@ -59,6 +61,7 @@ pub enum DictionaryMessage { DeleteGroup, ChangeDirection, TrySave(usize), + ToImport } impl NavigatedPage for DictionaryState { @@ -97,11 +100,13 @@ impl NavigatedPage for DictionaryState { return Some(Word(WordState::new(word, *index, self.state.clone()))); } } + if let ToImport = message { + return Some(Import(ImportState::new(self.state.clone()))) + } None } - fn navigated(&mut self) { - } + fn navigated(&mut self) {} fn update(&mut self, message: DictionaryMessage) -> Task { match message { @@ -245,24 +250,28 @@ impl NavigatedPage for DictionaryState { self.save_word(word_index); } } + ToImport => {} } Task::none() } - + fn view(&self) -> iced::Element<'_, DictionaryMessage> { back_overlay( row![ iced::widget::column![ self.groups_panel(), 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), self.filters(), ] - .spacing(DEFAULT_SPACING) - .into(), + .spacing(DEFAULT_SPACING) + .into(), Back, ) } @@ -308,8 +317,6 @@ impl DictionaryState { ) } - - fn words_list(&self) -> iced::Element<'_, DictionaryMessage> { let time = Instant::now(); let mut col = Column::new().width(Length::Fill); @@ -340,13 +347,13 @@ impl DictionaryState { continue; } - let word_line_data = WordLineState{ + let word_line_data = WordLineState { is_included: self.include_map[i], key: word.key.clone(), value: word.value.clone(), tags: word.tags.clone(), id: word.id, - index: i + index: i, }; let lazy_line = lazy(word_line_data, move |data| { @@ -416,9 +423,6 @@ impl DictionaryState { line }); - - - col = col.push(lazy_line); } @@ -592,11 +596,11 @@ pub fn app_data_dir() -> PathBuf { } #[derive(Hash, PartialEq, Eq)] -struct WordLineState{ +struct WordLineState { is_included: bool, key: String, value: String, tags: String, id: u32, index: usize, -} \ No newline at end of file +} diff --git a/src/import.rs b/src/import.rs index b0043ca..01efb16 100644 --- a/src/import.rs +++ b/src/import.rs @@ -1,14 +1,23 @@ +use std::sync::{Arc, Mutex}; use iced::{Element, Task}; +use iced::widget::scrollable; use crate::navigation::{NavigatedPage, Page, RootMessage}; - -struct ImportState {} -enum ImportMessage { +use crate::styling::*; +use iced::widget::{column, row, button, text }; +use crate::AppState; +use crate::import::ImportMessage::*; +#[derive(Clone)] +pub struct ImportState { + state: Arc> +} +#[derive(Clone)] +pub enum ImportMessage { Back } impl NavigatedPage for ImportState { fn navigate(&self, message: &ImportMessage) -> Option { - if let ImportMessage::Back = message { + if let Back = message { return Some(Page::PreviousPage) } None @@ -18,11 +27,18 @@ impl NavigatedPage for ImportState { } fn update(&mut self, message: ImportMessage) -> Task { - todo!() + Task::none() } fn view(&self) -> Element<'_, ImportMessage> { - todo!() + back_overlay(scrollable(column![]).into(), Back) + } +} +impl ImportState { + pub fn new(state: Arc>) -> ImportState { + ImportState{ + state + } } } diff --git a/src/main.rs b/src/main.rs index 0bb5868..8f5bbab 100644 --- a/src/main.rs +++ b/src/main.rs @@ -27,7 +27,7 @@ use crate::quiz::*; use crate::repetitions::CardSetSettings; use crate::RootMessage::Keyboard; use chrono::NaiveDate; -use iced::{keyboard, Subscription, Theme}; +use iced::{keyboard, Program, Subscription, Theme}; use iced::{window, Font}; use iced_core::window::Position; use iced_core::Size; @@ -39,15 +39,7 @@ const USER_FONT: Font = Font::with_name("Noto Sans JP"); fn main() -> iced::Result { println!("Welcome to JapLearn"); - 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() - }) + iced::application(ScreenState::boot, ScreenState::update, ScreenState::view).window(window_settings()) .subscription(subscription) .title("JapLearn") .settings(iced::Settings { @@ -56,8 +48,26 @@ fn main() -> iced::Result { }) .font(include_bytes!("../noto.ttf")) .default_font(USER_FONT) - .theme(Theme::GruvboxDark) - .run() + .theme(Theme::GruvboxDark).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 { diff --git a/src/navigation.rs b/src/navigation.rs index e9d2ff0..cc14fd7 100644 --- a/src/navigation.rs +++ b/src/navigation.rs @@ -27,6 +27,7 @@ use reqwest::Error; use std::collections::HashMap; use std::sync::{Arc, Mutex}; use std::time::Instant; +use crate::import::{ImportMessage, ImportState}; impl Default for ScreenState { fn default() -> Self { @@ -54,6 +55,7 @@ pub enum RootMessage { Sync(SyncMessage), History(HistoryMessage), RepetitionSettings(RepetitionSettingsMessage), + Import(ImportMessage), Keyboard(Event), DataLoaded(HashMap>), None, @@ -73,7 +75,7 @@ pub enum Page { Sync(SyncState), History(HistoryState), RepetitionSettings(RepetitionSettingsState), - + Import(ImportState), PreviousPage, } @@ -190,7 +192,8 @@ impl ScreenState { Word, Sync, History, - RepetitionSettings + RepetitionSettings, + Import ); } println!("Update took {:?}", time.elapsed()); @@ -213,7 +216,8 @@ impl ScreenState { Word, Sync, History, - RepetitionSettings + RepetitionSettings, + Import ) } @@ -233,7 +237,8 @@ impl ScreenState { Word, Sync, History, - RepetitionSettings + RepetitionSettings, + Import ); println!("View took {:?}", time.elapsed());