From 4c7bd1a9beef4d5e94585b959b0202875c94142b Mon Sep 17 00:00:00 2001 From: Carl Date: Fri, 6 Oct 2023 09:28:37 +1300 Subject: [PATCH] Some preliminary work for better error notification I need to fix the issue where it will ignore an MER older than 5 because it checks for the lock file in the MER first but 4 and older don't have it. In the meantime I started some prep work for better error notification to the user when something goes wrong. --- src/main.rs | 39 +++++++++++++++++++-- ui/appwindow.slint | 85 ++++++++++++++++++++++++++++++++++++++++++---- 2 files changed, 116 insertions(+), 8 deletions(-) diff --git a/src/main.rs b/src/main.rs index 266fc1d..39f4b2e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,7 +11,7 @@ use log::error; use rayon::prelude::{IntoParallelRefIterator, ParallelIterator}; use rfd::FileDialog; use simplelog::{CombinedLogger, Config, LevelFilter, SimpleLogger, WriteLogger}; -use slint::{Model, ModelRc, VecModel}; +use slint::{Model, ModelRc, Timer, TimerMode, VecModel}; use std::{ borrow::BorrowMut, cell::RefCell, collections::HashMap, fs::File, path::PathBuf, rc::Rc, }; @@ -99,6 +99,30 @@ fn main() -> Result<(), slint::PlatformError> { } }); + let info_file_model_start = file_model.clone(); + //let info_timer = vec![Timer::default(); file_model.row_count()]; + let mut info_timers: Vec = (0..file_model.row_count()).map(|_i|Timer::default()).collect(); + ui.on_slide_over(move |idx| { + let idx = idx as usize; + if idx >= info_timers.len() { + info_timers.extend((info_timers.len()..idx+1).map(|_| Timer::default())); + } + let info_file_model_stop = info_file_model_start.clone(); + let info_file_model_start = info_file_model_start.as_ref(); + if let Some(mut fi) = info_file_model_start.row_data(idx) { + fi.note_vis = true; + info_file_model_start.set_row_data(idx, fi); + } + info_timers[idx].start(TimerMode::SingleShot, std::time::Duration::from_secs(3), move || { + let info_file_model_stop = info_file_model_stop.clone(); + let info_file_model_stop = info_file_model_stop.as_ref(); + if let Some(mut fi) = info_file_model_stop.row_data(idx) { + fi.note_vis = false; + info_file_model_stop.set_row_data(idx, fi); + } + }) + }); + ui.run() } @@ -123,12 +147,16 @@ fn process_paths(files: Vec) -> HashMap { fn get_file_info(files: &HashMap) -> Vec { files .par_iter() + //need to do this differently....what if the version is older than 5 there the is_protected + //would return an error...but I still want to display the version .filter_map(|(name, file)| match is_protected(&file) { Ok(lckd) => match get_version(&file) { Ok(ver) => Some(file_info { locked: lckd, file_name: name.into(), file_ver: ver.to_string().into(), + note: "test".into(), + note_vis: false, }), Err(e) => { error!( @@ -143,7 +171,14 @@ fn get_file_info(files: &HashMap) -> Vec { "Unable to get file information from {}. Reason: {e}", file.display() ); - None + //None + Some(file_info { + locked: true, + file_name: name.into(), + file_ver: get_version(&file).unwrap().to_string().into(), + note: "test".into(), + note_vis: false, + }) } }) .collect() diff --git a/ui/appwindow.slint b/ui/appwindow.slint index 6bc76cb..64adf75 100644 --- a/ui/appwindow.slint +++ b/ui/appwindow.slint @@ -4,25 +4,69 @@ export struct file_info { locked: bool, file_name: string, file_ver: string, + note: string, + note_vis: bool, +} + +component SlideOver inherits Rectangle { + in property info: "test string"; + visible: false; + VerticalLayout { + Rectangle { + Text { + text: info; + vertical-alignment: center; + font-weight: 900; + horizontal-stretch: 1; + font-size: 10pt; + } + } + Rectangle { + height: 2%; + width: 100%; + background: yellow; + } + } } component FileInfo inherits HorizontalLayout { - in property info : { + + in-out property info : { locked: true, file-name: "My File.mer", file-ver: "12.0", + note: "test", + note_vis: false, }; property icon-color: info.locked ? #ff4343 : #107c10; callback unlock(string); + callback slide-over(); padding: 5px; - height: 48px; + height: 50px; Rectangle { border-width: 1px; - HorizontalLayout { + inf-so := SlideOver { + info: root.info.note; + visible: info.note-vis; + states [ + vis when self.visible : { + x: 0px; + } + not-vis when !self.visible : { + x: root.width * -1; + } + ] + + animate x { + duration: 1000ms; + easing: ease-in-out; + } + } + HorizontalBox { lbl := Text { text: "\{info.file_name}: (v\{info.file_ver})"; vertical-alignment: center; @@ -30,12 +74,25 @@ component FileInfo inherits HorizontalLayout { horizontal-stretch: 1; font-size: 10pt; } + info-icon := Image { + //this circle question icon is a temporary one while I'm offline, I just had it on my machine + source: @image-url("../assets/icons/circle-question.svg"); + colorize: yellow; + height: 100%; + width: self.height; + visible: info.note != ""; + info-ta := TouchArea { + clicked => { + slide-over(); + } + } + } icon := Image { - source: info.locked ? @image-url("../assets/icons/protected.svg" ) : @image-url("../assets/icons/unlocked.svg"); + source: info.locked ? @image-url("../assets/icons/protected.svg") : @image-url("../assets/icons/unlocked.svg"); colorize: icon-color; height: 100%; width: self.height; - y: 1px; + //y: 1px; horizontal-stretch: 0; icn-ta := TouchArea { @@ -58,6 +115,20 @@ component FileInfo inherits HorizontalLayout { } ] } + + states [ + vis when !inf-so.visible : { + x: 0px; + } + not-vis when inf-so.visible : { + x: root.width; + } + ] + + animate x { + duration: 1000ms; + easing: ease-in-out; + } } } } @@ -70,12 +141,14 @@ export component AppWindow inherits Window { callback unlock(string, int); callback select_files(); + callback slide_over(int); vl := VerticalLayout { ListView { for f_info[idx] in files : FileInfo { info: f_info; unlock => { unlock(f_info.file_name, idx); } + slide-over => { slide-over(idx); } } } Button { @@ -83,4 +156,4 @@ export component AppWindow inherits Window { clicked => { select_files(); } } } -} +} \ No newline at end of file