diff --git a/src/app/apps.rs b/src/app/apps.rs index 205e525..e9612a2 100644 --- a/src/app/apps.rs +++ b/src/app/apps.rs @@ -34,19 +34,20 @@ pub enum AppCommand { /// "run" the app. #[derive(Debug, Clone)] pub struct App { + pub ranking: i32, pub open_command: AppCommand, pub desc: String, pub icons: Option, - pub name: String, - pub name_lc: String, + pub display_name: String, + pub search_name: String, } impl PartialEq for App { fn eq(&self, other: &Self) -> bool { - self.name_lc == other.name_lc + self.search_name == other.search_name && self.icons == other.icons && self.desc == other.desc - && self.name == other.name + && self.display_name == other.display_name } } @@ -56,9 +57,10 @@ impl App { emojis::iter() .filter(|x| x.unicode_version() < emojis::UnicodeVersion::new(17, 13)) .map(|x| App { + ranking: 0, icons: None, - name: x.to_string(), - name_lc: x.name().to_string(), + display_name: x.to_string(), + search_name: x.name().to_string(), open_command: AppCommand::Function(Function::CopyToClipboard( ClipBoardContentType::Text(x.to_string()), )), @@ -74,46 +76,52 @@ impl App { vec![ App { + ranking: 0, open_command: AppCommand::Function(Function::Quit), desc: RUSTCAST_DESC_NAME.to_string(), icons: icons.clone(), - name: "Quit RustCast".to_string(), - name_lc: "quit".to_string(), + display_name: "Quit RustCast".to_string(), + search_name: "quit".to_string(), }, App { + ranking: 0, open_command: AppCommand::Function(Function::OpenPrefPane), desc: RUSTCAST_DESC_NAME.to_string(), icons: icons.clone(), - name: "Open RustCast Preferences".to_string(), - name_lc: "settings".to_string(), + display_name: "Open RustCast Preferences".to_string(), + search_name: "settings".to_string(), }, App { + ranking: 0, open_command: AppCommand::Message(Message::SwitchToPage(Page::EmojiSearch)), desc: RUSTCAST_DESC_NAME.to_string(), icons: icons.clone(), - name: "Search for an Emoji".to_string(), - name_lc: "emoji".to_string(), + display_name: "Search for an Emoji".to_string(), + search_name: "emoji".to_string(), }, App { + ranking: 0, open_command: AppCommand::Message(Message::SwitchToPage(Page::ClipboardHistory)), desc: RUSTCAST_DESC_NAME.to_string(), icons: icons.clone(), - name: "Clipboard History".to_string(), - name_lc: "clipboard".to_string(), + display_name: "Clipboard History".to_string(), + search_name: "clipboard".to_string(), }, App { + ranking: 0, open_command: AppCommand::Message(Message::ReloadConfig), desc: RUSTCAST_DESC_NAME.to_string(), icons: icons.clone(), - name: "Reload RustCast".to_string(), - name_lc: "refresh".to_string(), + display_name: "Reload RustCast".to_string(), + search_name: "refresh".to_string(), }, App { + ranking: 0, open_command: AppCommand::Display, desc: RUSTCAST_DESC_NAME.to_string(), icons: icons.clone(), - name: format!("Current RustCast Version: {app_version}"), - name_lc: "version".to_string(), + display_name: format!("Current RustCast Version: {app_version}"), + search_name: "version".to_string(), }, ] } @@ -131,7 +139,7 @@ impl App { let text_block = iced::widget::Column::new() .spacing(2) .push( - Text::new(self.name) + Text::new(self.display_name) .font(theme.font()) .size(16) .wrapping(Wrapping::WordOrGlyph) diff --git a/src/app/pages/clipboard.rs b/src/app/pages/clipboard.rs index 6bf5473..fc0af06 100644 --- a/src/app/pages/clipboard.rs +++ b/src/app/pages/clipboard.rs @@ -30,7 +30,7 @@ pub fn clipboard_view( Text::new( clipboard_content .get(focussed_id as usize) - .map(|x| x.to_app().name_lc) + .map(|x| x.to_app().search_name) .unwrap_or("".to_string()), ) .height(385) diff --git a/src/app/pages/emoji.rs b/src/app/pages/emoji.rs index 978167f..8bf517a 100644 --- a/src/app/pages/emoji.rs +++ b/src/app/pages/emoji.rs @@ -21,7 +21,7 @@ pub fn emoji_page( for emoji in emoji_row { let theme_clone = tile_theme.clone(); let element_column = Column::new().push( - Text::new(emoji.name.clone()) + Text::new(emoji.display_name.clone()) .font(tile_theme.font()) .size(30) .width(Length::Fill) @@ -37,7 +37,7 @@ pub fn emoji_page( .width(70) .height(70) .on_press(Message::RunFunction(Function::CopyToClipboard( - ClipBoardContentType::Text(emoji.name), + ClipBoardContentType::Text(emoji.display_name), ))) .style(move |_, _| emoji_button_style(&value)), ) diff --git a/src/app/tile.rs b/src/app/tile.rs index 311ca80..7ffffae 100644 --- a/src/app/tile.rs +++ b/src/app/tile.rs @@ -57,12 +57,20 @@ impl AppIndex { .take_while(move |(k, _)| k.starts_with(prefix)) .map(|(_, v)| v) } + fn update_ranking(&mut self, name: &str) { + let app = match self.by_name.get_mut(name) { + Some(a) => a, + None => return, + }; + + app.ranking += 5; + } /// Factory function for creating pub fn from_apps(options: Vec) -> Self { let mut bmap = BTreeMap::new(); for app in options { - bmap.insert(app.name_lc.clone(), app); + bmap.insert(app.search_name.clone(), app); } AppIndex { by_name: bmap } diff --git a/src/app/tile/elm.rs b/src/app/tile/elm.rs index bf80bcd..6cd68b5 100644 --- a/src/app/tile/elm.rs +++ b/src/app/tile/elm.rs @@ -46,7 +46,7 @@ pub fn new(hotkey: HotKey, config: &Config) -> (Tile, Task) { options.extend(App::basic_apps()); info!("Loaded basic apps / default apps"); - options.par_sort_by_key(|x| x.name.len()); + options.par_sort_by_key(|x| x.display_name.len()); let options = AppIndex::from_apps(options); let hotkeys = Hotkeys { diff --git a/src/app/tile/update.rs b/src/app/tile/update.rs index a3b7dfc..0b1b617 100644 --- a/src/app/tile/update.rs +++ b/src/app/tile/update.rs @@ -172,21 +172,34 @@ pub fn handle_update(tile: &mut Tile, message: Message) -> Task { ) } - Message::OpenFocused => match tile.results.get(tile.focus_id as usize) { - Some(App { - open_command: AppCommand::Function(func), - .. - }) => Task::done(Message::RunFunction(func.to_owned())), - Some(App { - open_command: AppCommand::Message(msg), - .. - }) => Task::done(msg.to_owned()), - Some(App { - open_command: AppCommand::Display, - .. - }) => Task::done(Message::ReturnFocus), - None => Task::none(), - }, + Message::OpenFocused => { + // TODO: update ranking here + match tile.results.get(tile.focus_id as usize) { + Some(App { + search_name: name, + open_command: AppCommand::Function(func), + .. + }) => { + info!("Updating ranking for: {name}"); + tile.options.update_ranking(name); + Task::done(Message::RunFunction(func.to_owned())) + } + Some(App { + search_name: name, + open_command: AppCommand::Message(msg), + .. + }) => { + info!("Updating ranking for: {name}"); + tile.options.update_ranking(name); + Task::done(msg.to_owned()) + } + Some(App { + open_command: AppCommand::Display, + .. + }) => Task::done(Message::ReturnFocus), + None => Task::none(), + } + } Message::ReloadConfig => { info!("Reloading config"); @@ -204,7 +217,7 @@ pub fn handle_update(tile: &mut Tile, message: Message) -> Task { let mut new_options = get_installed_apps(new_config.theme.show_icons); new_options.extend(new_config.shells.iter().map(|x| x.to_app())); new_options.extend(App::basic_apps()); - new_options.par_sort_by_key(|x| x.name.len()); + new_options.par_sort_by_key(|x| x.display_name.len()); tile.theme = new_config.theme.to_owned().into(); tile.config = new_config; @@ -351,29 +364,32 @@ pub fn handle_update(tile: &mut Tile, message: Message) -> Task { } else if tile.query_lc == "randomvar" { let rand_num = rand::random_range(0..100); tile.results = vec![App { + ranking: 0, open_command: AppCommand::Function(Function::RandomVar(rand_num)), desc: "Easter egg".to_string(), icons: None, - name: rand_num.to_string(), - name_lc: String::new(), + display_name: rand_num.to_string(), + search_name: String::new(), }]; return single_item_resize_task(id); } else if tile.query_lc == "67" { tile.results = vec![App { + ranking: 0, open_command: AppCommand::Function(Function::RandomVar(67)), desc: "Easter egg".to_string(), icons: None, - name: 67.to_string(), - name_lc: String::new(), + display_name: 67.to_string(), + search_name: String::new(), }]; return single_item_resize_task(id); } else if tile.query_lc.ends_with("?") { tile.results = vec![App { + ranking: 0, open_command: AppCommand::Function(Function::GoogleSearch(tile.query.clone())), icons: None, desc: "Web Search".to_string(), - name: format!("Search for: {}", tile.query), - name_lc: String::new(), + display_name: format!("Search for: {}", tile.query), + search_name: String::new(), }]; } else if tile.query_lc == "cbhist" { task = task.chain(Task::done(Message::SwitchToPage(Page::ClipboardHistory))); @@ -388,11 +404,12 @@ pub fn handle_update(tile: &mut Tile, message: Message) -> Task { && let Some(res) = Expr::from_str(&tile.query).ok() { tile.results.push(App { + ranking: 0, open_command: AppCommand::Function(Function::Calculate(res.clone())), desc: RUSTCAST_DESC_NAME.to_string(), icons: None, - name: res.eval().map(|x| x.to_string()).unwrap_or("".to_string()), - name_lc: "".to_string(), + display_name: res.eval().map(|x| x.to_string()).unwrap_or("".to_string()), + search_name: "".to_string(), }); } else if tile.results.is_empty() && let Some(conversions) = unit_conversion::convert_query(&tile.query) @@ -411,39 +428,43 @@ pub fn handle_update(tile: &mut Tile, message: Message) -> Task { conversion.target_unit.name ); App { + ranking: 0, open_command: AppCommand::Function(Function::CopyToClipboard( ClipBoardContentType::Text(target.clone()), )), desc: source, icons: None, - name: target, - name_lc: String::new(), + display_name: target, + search_name: String::new(), } }) .collect(); } else if tile.results.is_empty() && is_valid_url(&tile.query) { tile.results.push(App { + ranking: 0, open_command: AppCommand::Function(Function::OpenWebsite(tile.query.clone())), desc: "Web Browsing".to_string(), icons: None, - name: "Open Website: ".to_string() + &tile.query, - name_lc: "".to_string(), + display_name: "Open Website: ".to_string() + &tile.query, + search_name: "".to_string(), }); } else if tile.query_lc.split(' ').count() > 1 { tile.results.push(App { + ranking: 0, open_command: AppCommand::Function(Function::GoogleSearch(tile.query.clone())), icons: None, desc: "Web Search".to_string(), - name: format!("Search for: {}", tile.query), - name_lc: String::new(), + display_name: format!("Search for: {}", tile.query), + search_name: String::new(), }); } else if tile.results.is_empty() && tile.query_lc == "lemon" { tile.results.push(App { + ranking: 0, open_command: AppCommand::Display, desc: "Easter Egg".to_string(), icons: lemon_icon_handle(), - name: "Lemon".to_string(), - name_lc: "".to_string(), + display_name: "Lemon".to_string(), + search_name: "".to_string(), }); } if !tile.query_lc.is_empty() && tile.page == Page::EmojiSearch { @@ -454,6 +475,8 @@ pub fn handle_update(tile: &mut Tile, message: Message) -> Task { .collect(); } + tile.results.sort_by_key(|x| -x.ranking); + let new_length = tile.results.len(); let max_elem = min(5, new_length); diff --git a/src/clipboard.rs b/src/clipboard.rs index 979432e..458faa9 100644 --- a/src/clipboard.rs +++ b/src/clipboard.rs @@ -14,25 +14,26 @@ impl ClipBoardContentType { /// Returns the iced element for rendering the clipboard item, and the entire content since the /// display name is only the first line pub fn to_app(&self) -> App { - let mut name = match self { + let mut display_name = match self { ClipBoardContentType::Image(_) => "".to_string(), ClipBoardContentType::Text(a) => a.to_owned(), }; let self_clone = self.clone(); - let name_lc = name.clone(); + let search_name = display_name.clone(); // only get the first line from the contents - name = name.lines().next().unwrap_or("").to_string(); + display_name = display_name.lines().next().unwrap_or("").to_string(); App { + ranking: 0, open_command: crate::app::apps::AppCommand::Function(Function::CopyToClipboard( self_clone.to_owned(), )), desc: "Clipboard Item".to_string(), icons: None, - name_lc, - name, + display_name, + search_name, } } } diff --git a/src/config.rs b/src/config.rs index 1847d09..bbac88b 100644 --- a/src/config.rs +++ b/src/config.rs @@ -186,14 +186,15 @@ impl Shelly { } }); App { + ranking: 0, open_command: AppCommand::Function(Function::RunShellCommand( self_clone.command, self_clone.alias_lc.clone(), )), desc: "Shell Command".to_string(), icons: icon, - name: self_clone.alias, - name_lc: self_clone.alias_lc, + display_name: self_clone.alias, + search_name: self_clone.alias_lc, } } } diff --git a/src/platform/cross.rs b/src/platform/cross.rs index db99f27..e44375b 100644 --- a/src/platform/cross.rs +++ b/src/platform/cross.rs @@ -152,11 +152,12 @@ fn discover_apps( let name = file_name.strip_suffix(".app").unwrap().to_string(); Some(App { + ranking: 0, open_command: AppCommand::Function(Function::OpenApp(path_str)), desc: "Application".to_string(), icons, - name_lc: name.to_lowercase(), - name, + search_name: name.to_lowercase(), + display_name: name, }) }) } diff --git a/src/platform/macos/discovery.rs b/src/platform/macos/discovery.rs index a71d4d6..82f34ff 100644 --- a/src/platform/macos/discovery.rs +++ b/src/platform/macos/discovery.rs @@ -252,8 +252,9 @@ fn query_app(url: impl AsRef, store_icons: bool) -> Option { .flatten(); Some(App { - name: name.clone(), - name_lc: name.to_lowercase(), + ranking: 0, + display_name: name.clone(), + search_name: name.to_lowercase(), desc: "Application".to_string(), icons, open_command: AppCommand::Function(Function::OpenApp(path.to_string_lossy().into_owned())),