From 810a953a5ab6e7e66689017331f2aa5ce36e75e8 Mon Sep 17 00:00:00 2001 From: Varga Marcell <128537619+marci1175@users.noreply.github.com> Date: Fri, 12 Jan 2024 22:19:46 +0100 Subject: [PATCH] added searching options, voice recording lenght displaying --- build_info.matthias_build | 2 +- src/app/backend.rs | 20 +++- src/app/ui/client.rs | 100 +++++++++++++++++- .../widgets/message_tray/message_tray_main.rs | 11 +- 4 files changed, 121 insertions(+), 12 deletions(-) diff --git a/build_info.matthias_build b/build_info.matthias_build index a42d907d..26b83045 100644 --- a/build_info.matthias_build +++ b/build_info.matthias_build @@ -1 +1 @@ -2024.01.12. 21:48 \ No newline at end of file +2024.01.12. 22:19 \ No newline at end of file diff --git a/src/app/backend.rs b/src/app/backend.rs index 83079516..a0239edf 100644 --- a/src/app/backend.rs +++ b/src/app/backend.rs @@ -1,9 +1,8 @@ -use chrono::Utc; +use chrono::{Utc, DateTime}; use egui::Color32; use rand::rngs::ThreadRng; use rodio::{OutputStream, OutputStreamHandle, Sink}; -use std::any::Any; use std::collections::BTreeMap; use std::fmt::Display; use std::io; @@ -319,6 +318,9 @@ pub struct Client { ///Used to decide whether the reactive emoji button should switch emojis (Like discords implementation) pub random_generated: bool, + + #[serde(skip)] + pub voice_recording_start: Option>, } impl Default for Client { fn default() -> Self { @@ -327,6 +329,7 @@ impl Default for Client { search_settings_panel: false, search_buffer: String::new(), search_mode: false, + message_group_is_hovered: false, emoji_reaction_tray_rect: egui::Rect::NOTHING, emoji_reaction_should_open: false, @@ -364,6 +367,8 @@ impl Default for Client { usr_msg: String::new(), replying_to: None, incoming_msg: ServerMaster::default(), + + voice_recording_start: None, } } } @@ -930,16 +935,21 @@ pub enum SearchType { Name, Message, Date, + Reply, + File, } impl Display for SearchType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - std::fmt::Display::fmt(&format!("{}", match self { + f.write_str( + match self { SearchType::Name => "Name", SearchType::Message => "Message", SearchType::Date => "Date", - }), - f) + SearchType::Reply => "Replies", + SearchType::File => "File", + } + ) } } #[derive(serde::Serialize, serde::Deserialize, Debug, Clone, PartialEq)] diff --git a/src/app/ui/client.rs b/src/app/ui/client.rs index 03431c97..715b86b5 100644 --- a/src/app/ui/client.rs +++ b/src/app/ui/client.rs @@ -152,11 +152,15 @@ impl TemplateApp { egui::SidePanel::right("search_panel").exact_width(ctx.used_size().x / 3.5).show(ctx, |ui|{ ui.separator(); ui.horizontal(|ui|{ - ui.allocate_ui(vec2(ui.available_width() / 2., ui.available_height()), |ui| { - ui.add( - egui::widgets::TextEdit::singleline(&mut self.client_ui.search_buffer).hint_text("Search for: ") - ); - }); + + //Dont allow displaying search buffer when in file or reply searching + if !(self.client_ui.search_parameters.search_type == SearchType::File || self.client_ui.search_parameters.search_type == SearchType::Reply) { + ui.allocate_ui(vec2(ui.available_width() / 2., ui.available_height()), |ui| { + ui.add( + egui::widgets::TextEdit::singleline(&mut self.client_ui.search_buffer).hint_text("Search for: ") + ); + }); + } egui::ComboBox::from_id_source("search_filter") // .icon(|ui, rect, widget_visuals, is_open, above_or_belov| {}) @@ -165,6 +169,8 @@ impl TemplateApp { ui.selectable_value(&mut self.client_ui.search_parameters.search_type, SearchType::Message , "Message"); ui.selectable_value(&mut self.client_ui.search_parameters.search_type, SearchType::Date, "Date"); ui.selectable_value(&mut self.client_ui.search_parameters.search_type, SearchType::Name, "Name"); + ui.selectable_value(&mut self.client_ui.search_parameters.search_type, SearchType::Reply, "Reply"); + ui.selectable_value(&mut self.client_ui.search_parameters.search_type, SearchType::File, "File"); }); }); ui.separator(); @@ -244,6 +250,90 @@ impl TemplateApp { } } }, + SearchType::Reply => { + if let ServerMessageType::Normal(inner_message) = &message.MessageType { + if message.replying_to.is_some() && !self.client_ui.search_buffer.trim().is_empty() { + let group = ui.group(|ui|{ + ui.label(RichText::from(message.Author.to_string()).size(self.font_size / 1.3).color(Color32::WHITE)); + ui.label(RichText::from(format!("{}", inner_message.message))); + ui.small(&message.MessageDate); + }); + + if group.response.interact(Sense::click()).clicked() { + self.client_ui.scroll_to_message_index = Some(index) + }; + + group.response.on_hover_text("Click to jump to message"); + + has_search = true; + } + } + } + + SearchType::File => { + if let ServerMessageType::Upload(inner_message) = &message.MessageType { + let group = ui.group(|ui|{ + ui.label(RichText::from(message.Author.to_string()).size(self.font_size / 1.3).color(Color32::WHITE)); + + //This button shouldnt actually do anything becuase when this message group gets clicked it throws you to the message + if ui.small_button(format!("{}", inner_message.file_name)).clicked() { + self.client_ui.scroll_to_message_index = Some(index) + }; + + ui.small(&message.MessageDate); + }); + + if group.response.interact(Sense::click()).clicked() { + self.client_ui.scroll_to_message_index = Some(index) + }; + + group.response.on_hover_text("Click to jump to message"); + + has_search = true; + } + /* Inner value shouldnt actaully be used since its only used for asking for a file, and to stay compact i wont implement image displaying in search mode */ + if let ServerMessageType::Image( _ ) = &message.MessageType { + let group = ui.group(|ui|{ + ui.label(RichText::from(message.Author.to_string()).size(self.font_size / 1.3).color(Color32::WHITE)); + + //This button shouldnt actually do anything becuase when this message group gets clicked it throws you to the message + if ui.small_button("Image").clicked() { + self.client_ui.scroll_to_message_index = Some(index) + }; + + ui.small(&message.MessageDate); + }); + + if group.response.interact(Sense::click()).clicked() { + self.client_ui.scroll_to_message_index = Some(index) + }; + + group.response.on_hover_text("Click to jump to message"); + + has_search = true; + } + if let ServerMessageType::Audio( _ ) = &message.MessageType { + let group = ui.group(|ui|{ + ui.label(RichText::from(message.Author.to_string()).size(self.font_size / 1.3).color(Color32::WHITE)); + + //This button shouldnt actually do anything becuase when this message group gets clicked it throws you to the message + if ui.small_button("Audio").clicked() { + self.client_ui.scroll_to_message_index = Some(index) + }; + + ui.small(&message.MessageDate); + }); + + if group.response.interact(Sense::click()).clicked() { + self.client_ui.scroll_to_message_index = Some(index) + }; + + group.response.on_hover_text("Click to jump to message"); + + has_search = true; + } + + } } } diff --git a/src/app/ui/client_ui/widgets/message_tray/message_tray_main.rs b/src/app/ui/client_ui/widgets/message_tray/message_tray_main.rs index ed2d5a64..ce866c99 100644 --- a/src/app/ui/client_ui/widgets/message_tray/message_tray_main.rs +++ b/src/app/ui/client_ui/widgets/message_tray/message_tray_main.rs @@ -1,6 +1,7 @@ use crate::app::backend::{ClientMessage, TemplateApp}; use crate::app::client::{self}; use crate::app::ui::client_ui::client_actions::audio_recording::audio_recroding; +use chrono::Utc; use device_query::Keycode; use egui::{ vec2, Align, Align2, Area, Button, Color32, FontFamily, FontId, Key, Layout, RichText, @@ -178,7 +179,11 @@ impl TemplateApp { { if let Some(atx) = self.atx.clone() { ui.horizontal_centered(|ui| { - ui.label(RichText::from("Recording").size(self.font_size)); + ui.label(RichText::from("Recording").size(self.font_size).color(Color32::RED)); + + //Display lenght + ui.label(RichText::from(format!("{}s", Utc::now().signed_duration_since(self.client_ui.voice_recording_start.unwrap()).num_seconds())).size(self.font_size)); + if ui .add( egui::ImageButton::new(egui::include_image!( @@ -215,7 +220,11 @@ impl TemplateApp { self.atx = Some(tx); + //Set audio recording start + self.client_ui.voice_recording_start = Some(Utc::now()); + audio_recroding(rx, self.audio_file.clone()); + } } });