From 611f763147ffff2d06f8fd945ce7c40d175b30c8 Mon Sep 17 00:00:00 2001 From: Observer KRypt0n_ Date: Sat, 28 Jan 2023 14:12:31 +0200 Subject: [PATCH] Discord RPC: added icon selection option --- assets/ui/preferences/enhancements.blp | 4 +- src/lib/config/launcher/discord_rpc.rs | 127 ++++++++++++++++++++++++- src/lib/config/launcher/mod.rs | 3 +- src/lib/discord_rpc.rs | 15 +-- src/ui/main.rs | 2 +- src/ui/preferences/enhancements.rs | 41 +++++--- 6 files changed, 162 insertions(+), 30 deletions(-) diff --git a/assets/ui/preferences/enhancements.blp b/assets/ui/preferences/enhancements.blp index 41cd7c2..696cc8a 100644 --- a/assets/ui/preferences/enhancements.blp +++ b/assets/ui/preferences/enhancements.blp @@ -103,11 +103,11 @@ Adw.PreferencesPage page { Adw.PreferencesGroup { title: "Discord RPC"; - Adw.ActionRow discord_rpc_row { + Adw.ComboRow discord_rpc_combo { title: "Enabled"; subtitle: "Discord RPC allows you to provide Discord the info that you are currently playing the game to let your friends know"; - Gtk.Switch discord_rpc_switch { + Gtk.Switch discord_rpc_switcher { valign: center; } } diff --git a/src/lib/config/launcher/discord_rpc.rs b/src/lib/config/launcher/discord_rpc.rs index dbffa5b..c96bef4 100644 --- a/src/lib/config/launcher/discord_rpc.rs +++ b/src/lib/config/launcher/discord_rpc.rs @@ -1,6 +1,123 @@ use serde::{Deserialize, Serialize}; use serde_json::Value as JsonValue; +#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Serialize, Deserialize)] +pub enum DiscordRpcIcons { + Launcher, + Game, + + Amber1, + Amber2, + + Beidou, + + Klee1, + Klee2, + Klee3, + + Raiden, + + YaeMiko1, + YaeMiko2, + + LiYue, + + Inazuma1, + Inazuma2, + Inazuma3, + Inazuma4, + Inazuma5 +} + +impl DiscordRpcIcons { + pub fn list() -> Vec { + vec![ + Self::Launcher, + Self::Game, + + Self::Amber1, + Self::Amber2, + + Self::Beidou, + + Self::Klee1, + Self::Klee2, + Self::Klee3, + + Self::Raiden, + + Self::YaeMiko1, + Self::YaeMiko2, + + Self::LiYue, + + Self::Inazuma1, + Self::Inazuma2, + Self::Inazuma3, + Self::Inazuma4, + Self::Inazuma5 + ] + } + + pub fn get_model() -> gtk::StringList { + let model = gtk::StringList::new(&[]); + + for icon in Self::list() { + model.append(&icon.to_string()); + } + + model + } + + /// Get Discord RPC icon name + pub fn get_icon_name(&self) -> &'static str { + match self { + Self::Launcher => "launcher", + Self::Game => "gi-icon", + + Self::Amber1 => "artgame", + Self::Amber2 => "artgame3", + + Self::Beidou => "beidougame", + + Self::Klee1 => "kleegame", + Self::Klee2 => "kleegame2", + Self::Klee3 => "artgame2", + + Self::Raiden => "baal1", + + Self::YaeMiko1 => "yaemiko1", + Self::YaeMiko2 => "yaemiko2", + + Self::LiYue => "liyuegame", + + Self::Inazuma1 => "inazuma1", + Self::Inazuma2 => "inazuma2", + Self::Inazuma3 => "inazuma3", + Self::Inazuma4 => "inazuma4", + Self::Inazuma5 => "inazuma5" + } + } +} + +impl Default for DiscordRpcIcons { + fn default() -> Self { + Self::Launcher + } +} + +impl From<&JsonValue> for DiscordRpcIcons { + fn from(value: &JsonValue) -> Self { + serde_json::from_value(value.clone()).unwrap_or_default() + } +} + +impl std::fmt::Display for DiscordRpcIcons { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + f.write_str(&format!("{:?}", self)) + } +} + #[derive(Debug, Clone, Serialize, Deserialize)] pub struct DiscordRpc { pub app_id: u64, @@ -8,7 +125,7 @@ pub struct DiscordRpc { pub title: String, pub subtitle: String, - pub image: String + pub icon: DiscordRpcIcons } impl Default for DiscordRpc { @@ -19,7 +136,7 @@ impl Default for DiscordRpc { title: String::from("Researching the world"), subtitle: String::from("of Teyvat"), - image: String::from("gi-icon") + icon: DiscordRpcIcons::default() } } } @@ -49,9 +166,9 @@ impl From<&JsonValue> for DiscordRpc { None => default.subtitle }, - image: match value.get("image") { - Some(value) => value.as_str().unwrap_or(&default.image).to_string(), - None => default.image + icon: match value.get("icon") { + Some(value) => value.into(), + None => default.icon } } } diff --git a/src/lib/config/launcher/mod.rs b/src/lib/config/launcher/mod.rs index 07bb20e..65a61cc 100644 --- a/src/lib/config/launcher/mod.rs +++ b/src/lib/config/launcher/mod.rs @@ -11,9 +11,10 @@ pub mod repairer; pub mod discord_rpc; pub mod prelude { + pub use super::discord_rpc::*; + pub use super::Launcher; pub use super::repairer::Repairer; - pub use super::discord_rpc::DiscordRpc; } use prelude::*; diff --git a/src/lib/discord_rpc.rs b/src/lib/discord_rpc.rs index e4fb40f..8de6a70 100644 --- a/src/lib/discord_rpc.rs +++ b/src/lib/discord_rpc.rs @@ -7,9 +7,12 @@ use discord_rich_presence::{ DiscordIpcClient }; -use super::config::prelude::DiscordRpc as DiscordRpcConfig; +use super::config::prelude::{ + DiscordRpc as DiscordRpcConfig, + DiscordRpcIcons +}; -#[derive(Debug, Clone, PartialEq, Eq)] +#[derive(Debug, Clone)] pub enum RpcUpdates { /// Establish RPC connection Connect, @@ -21,7 +24,7 @@ pub enum RpcUpdates { UpdateActivity { title: String, subtitle: String, - image: String + icon: DiscordRpcIcons }, /// Clear RPC activity @@ -65,10 +68,10 @@ impl DiscordRpc { } } - RpcUpdates::UpdateActivity { title, subtitle, image } => { + RpcUpdates::UpdateActivity { title, subtitle, icon } => { config.title = title; config.subtitle = subtitle; - config.image = image; + config.icon = icon; if connected { client.set_activity(Self::get_activity(&config)) @@ -92,7 +95,7 @@ impl DiscordRpc { Activity::new() .details(&config.title) .state(&config.subtitle) - .assets(Assets::new().large_image(&config.image)) + .assets(Assets::new().large_image(config.icon.get_icon_name())) } pub fn update(&self, update: RpcUpdates) -> Result<(), SendError> { diff --git a/src/ui/main.rs b/src/ui/main.rs index c2502a9..03bb9ea 100644 --- a/src/ui/main.rs +++ b/src/ui/main.rs @@ -316,7 +316,7 @@ impl App { let result = this.widgets.preferences_stack.enhancements_page.discord_rpc.update(RpcUpdates::UpdateActivity { title: config.launcher.discord_rpc.title, subtitle: config.launcher.discord_rpc.subtitle, - image: config.launcher.discord_rpc.image + icon: config.launcher.discord_rpc.icon }); let this = this.clone(); diff --git a/src/ui/preferences/enhancements.rs b/src/ui/preferences/enhancements.rs index b056208..8df52f0 100644 --- a/src/ui/preferences/enhancements.rs +++ b/src/ui/preferences/enhancements.rs @@ -43,17 +43,17 @@ pub struct AppWidgets { pub gamescope_app: GamescopeApp, + pub discord_rpc_combo: adw::ComboRow, + pub discord_rpc_switcher: gtk::Switch, + pub discord_rpc_title: adw::EntryRow, + pub discord_rpc_subtitle: adw::EntryRow, + pub fps_unlocker_combo: adw::ComboRow, pub fps_unlocker_switcher: gtk::Switch, pub fps_unlocker_power_saving_switcher: gtk::Switch, pub fps_unlocker_monitor_num: gtk::SpinButton, pub fps_unlocker_window_mode_combo: adw::ComboRow, - pub fps_unlocker_priority_combo: adw::ComboRow, - - pub discord_rpc_row: adw::ActionRow, - pub discord_rpc: gtk::Switch, - pub discord_rpc_title: adw::EntryRow, - pub discord_rpc_subtitle: adw::EntryRow + pub fps_unlocker_priority_combo: adw::ComboRow } impl AppWidgets { @@ -82,17 +82,17 @@ impl AppWidgets { gamescope_app: GamescopeApp::new(window)?, + discord_rpc_combo: get_object(&builder, "discord_rpc_combo")?, + discord_rpc_switcher: get_object(&builder,"discord_rpc_switcher")?, + discord_rpc_title: get_object(&builder, "discord_rpc_title")?, + discord_rpc_subtitle: get_object(&builder, "discord_rpc_subtitle")?, + fps_unlocker_combo: get_object(&builder, "fps_unlocker_combo")?, fps_unlocker_switcher: get_object(&builder, "fps_unlocker_switcher")?, fps_unlocker_power_saving_switcher: get_object(&builder, "fps_unlocker_power_saving_switcher")?, fps_unlocker_monitor_num: get_object(&builder, "fps_unlocker_monitor_num")?, fps_unlocker_window_mode_combo: get_object(&builder, "fps_unlocker_window_mode_combo")?, - fps_unlocker_priority_combo: get_object(&builder, "fps_unlocker_priority_combo")?, - - discord_rpc_row: get_object(&builder, "discord_rpc_row")?, - discord_rpc: get_object(&builder,"discord_rpc_switch")?, - discord_rpc_title: get_object(&builder, "discord_rpc_title")?, - discord_rpc_subtitle: get_object(&builder, "discord_rpc_subtitle")?, + fps_unlocker_priority_combo: get_object(&builder, "fps_unlocker_priority_combo")? }; // Set availale wine languages @@ -101,6 +101,9 @@ impl AppWidgets { // Set availale virtual desktop resolutions result.virtual_desktop_row.set_model(Some(&Resolution::get_model())); + // Set discord rpc icons + result.discord_rpc_combo.set_model(Some(&DiscordRpcIcons::get_model())); + // Set availale fps unlocker limits result.fps_unlocker_combo.set_model(Some(&Fps::get_model())); @@ -238,10 +241,17 @@ impl App { } }); - // TODO: update RPC here or after preferences window's closing + // Discord RPC icon + self.widgets.discord_rpc_combo.connect_selected_notify(move |row| { + if let Ok(mut config) = config::get() { + config.launcher.discord_rpc.icon = DiscordRpcIcons::list()[row.selected() as usize]; + + config::update(config); + } + }); // Discord RPC switching - self.widgets.discord_rpc.connect_state_notify(move |switch| { + self.widgets.discord_rpc_switcher.connect_state_notify(move |switch| { if let Ok(mut config) = config::get() { config.launcher.discord_rpc.enabled = switch.state(); @@ -398,7 +408,8 @@ impl App { self.widgets.fsr_switcher.set_state(config.game.enhancements.fsr.enabled); // Discord RPC - self.widgets.discord_rpc.set_state(config.launcher.discord_rpc.enabled); + self.widgets.discord_rpc_combo.set_selected(DiscordRpcIcons::list().binary_search(&config.launcher.discord_rpc.icon).unwrap() as u32); + self.widgets.discord_rpc_switcher.set_state(config.launcher.discord_rpc.enabled); self.widgets.discord_rpc_title.set_text(&config.launcher.discord_rpc.title); self.widgets.discord_rpc_subtitle.set_text(&config.launcher.discord_rpc.subtitle);