From f113d2b3d761af3b3f47ff8c6479620cd30b2419 Mon Sep 17 00:00:00 2001 From: Mikhail Mitrofanov Date: Sun, 23 Aug 2026 22:05:08 +0300 Subject: [PATCH] Change notification layout --- src/main.rs | 2 -- src/notification.rs | 37 ++++++++++++++++++++++++------------- src/repetition.rs | 44 +++++++++++++++++++++++++------------------- 3 files changed, 49 insertions(+), 34 deletions(-) diff --git a/src/main.rs b/src/main.rs index 0a8f722..359c5fd 100644 --- a/src/main.rs +++ b/src/main.rs @@ -21,7 +21,6 @@ pub mod app; use crate::app::start; use crate::navigation::RootMessage; -use crate::quiz::*; use mimalloc::MiMalloc; #[global_allocator] @@ -31,4 +30,3 @@ static GLOBAL: MiMalloc = MiMalloc; fn main() -> iced::Result { start() } - \ No newline at end of file diff --git a/src/notification.rs b/src/notification.rs index d4319ea..14ec5ec 100644 --- a/src/notification.rs +++ b/src/notification.rs @@ -2,13 +2,14 @@ use crate::navigation::RootMessage; use crate::styling::{BUTTON_RADIUS, HALF_SPACING}; use chrono::Utc; use iced::widget::container::Style; -use iced::widget::{column, container, scrollable, text, Column}; +use iced::widget::{Column, column, container, row, scrollable, text}; use iced::{Element, Task}; -use iced_core::alignment::Horizontal::Right; -use iced_core::alignment::Vertical; +use iced_core::Alignment::Center; use iced_core::Background::Color; use iced_core::Border; use iced_core::Length::Fill; +use iced_core::alignment::Horizontal::Right; +use iced_core::alignment::Vertical; pub struct NotificationManager { list: Vec<(u32, NotificationRequest, u32)>, @@ -43,9 +44,12 @@ impl NotificationManager { column = column.push(Self::draw_notif(id, notif, time)); } - container(scrollable(column)).width(Fill).height(Fill) + container(scrollable(column)) + .width(Fill) + .height(Fill) .align_x(Right) - .align_y(Vertical::Top).padding(HALF_SPACING) + .align_y(Vertical::Top) + .padding(HALF_SPACING) .into() } @@ -99,12 +103,15 @@ impl NotificationManager { } }; - let container = container(column![ - iced::widget::button("✕") - .on_press(NotificationMessage::Remove(*id)) - .style(iced::widget::button::text), - content - ].align_x(Right).padding(HALF_SPACING)); + let container = container( + row![ + content, + iced::widget::button("✕") + .on_press(NotificationMessage::Remove(*id)) + .style(iced::widget::button::text) + ].align_y(Center).width(300) + .padding(HALF_SPACING), + ); container .style(move |theme| { let color = match color_id { @@ -116,7 +123,10 @@ impl NotificationManager { Style { text_color: None, background: Some(Color(color.scale_alpha(0.3))), - border: Border::default().width(1).color(color).rounded(BUTTON_RADIUS), + border: Border::default() + .width(1) + .color(color) + .rounded(BUTTON_RADIUS), shadow: Default::default(), snap: false, } @@ -145,6 +155,7 @@ impl NotificationManager { text!("У приложение недостаточно прав") } } + .width(Fill) .into() } } @@ -163,5 +174,5 @@ pub enum NotificationData { ImportError, IncorrectAnkiFile, OpenFileError, - VoiceVoxUnavailable + VoiceVoxUnavailable, } diff --git a/src/repetition.rs b/src/repetition.rs index 55d4ceb..95e020a 100644 --- a/src/repetition.rs +++ b/src/repetition.rs @@ -1,21 +1,22 @@ +use crate::app::AppState; use crate::data_provider::voice::get_voice; use crate::lang::Id; use crate::lang::{CardStatistics, DeckData, DeckSettings, WordData, WordOpenMode}; use crate::navigation::Page::PreviousPage; use crate::navigation::{KeyPressedPage, NavigatedPage, Page, RootMessage}; +use crate::notification::{NotificationData, NotificationRequest}; use crate::styling::*; use chrono::Local; use iced::alignment::Horizontal::Center; use iced::keyboard::key::Physical::Code; use iced::widget::text::Style; -use iced::widget::{button, column, container, row, rule, space, text, tooltip, Column}; -use iced::{alignment, keyboard, Element, Fill, Task, Theme}; +use iced::widget::{Column, button, column, container, row, rule, space, text, tooltip}; +use iced::{Element, Fill, Task, Theme, alignment, keyboard}; use parking_lot::Mutex; use rodio::MixerDeviceSink; use std::collections::HashSet; use std::sync::Arc; use tokio::task::spawn_blocking; -use crate::app::AppState; pub struct RepetitionState { state: Arc>, @@ -52,8 +53,9 @@ impl NavigatedPage for RepetitionState { self.can_play = false; let value = self.current_word.key.clone(); if self.settings.require_speech() { - return Task::perform(play_sound(self.sink.clone(), value), |_| { - RootMessage::Repetition(RepetitionMessage::PlayFinished) + return Task::perform(play_sound(self.sink.clone(), value), |r| match r { + Ok(_) => RootMessage::Repetition(RepetitionMessage::PlayFinished), + Err(err) => RootMessage::PushNotification(NotificationRequest::Error(err)), }); } } @@ -146,8 +148,9 @@ impl RepetitionState { if self.settings.require_speech() && self.sink.is_some() { let sink = self.sink.clone(); let task = play_sound(sink, self.current_word.key.clone()); - return Task::perform(task, |_| { - RootMessage::Repetition(RepetitionMessage::PlayFinished) + return Task::perform(task, |r| match r { + Ok(_) => RootMessage::Repetition(RepetitionMessage::PlayFinished), + Err(err) => RootMessage::PushNotification(NotificationRequest::Error(err)), }); } self.increment_counter(); @@ -322,16 +325,19 @@ pub enum RepetitionMessage { PlayFinished, } -async fn play_sound(sink: Arc>, text: String) { - if let Ok(data) = get_voice(text.as_str()).await { - spawn_blocking(move || { - if let Some(sink) = sink.as_ref() - && let Ok(play) = rodio::play(sink.mixer(), data) - { - play.sleep_until_end() - } - }) - .await - .unwrap(); - } +async fn play_sound( + sink: Arc>, + text: String, +) -> Result<(), NotificationData> { + let data = get_voice(text.as_str()).await?; + spawn_blocking(move || { + if let Some(sink) = sink.as_ref() + && let Ok(play) = rodio::play(sink.mixer(), data) + { + play.sleep_until_end() + } + }) + .await + .unwrap(); + Ok(()) }