From e3fdcb18e39f49410270023bff3d7e25d9ac659e Mon Sep 17 00:00:00 2001
From: TicClick <ya@ticclick.ch>
Date: Tue, 13 Feb 2024 16:05:57 +0100
Subject: [PATCH] Refresh window title on demand only (#94)

---
 crates/steel_core/src/ipc/client.rs |  2 +-
 crates/steel_core/src/ipc/server.rs |  2 +-
 crates/steel_core/src/ipc/ui.rs     |  2 +-
 src/app/mod.rs                      |  2 +-
 src/gui/chat.rs                     |  4 +--
 src/gui/chat_tabs.rs                |  8 +++--
 src/gui/state/mod.rs                | 12 +++++++-
 src/gui/window.rs                   | 48 +++++++++++++++++++----------
 8 files changed, 53 insertions(+), 27 deletions(-)

diff --git a/crates/steel_core/src/ipc/client.rs b/crates/steel_core/src/ipc/client.rs
index 3e2d0db..c5582ab 100644
--- a/crates/steel_core/src/ipc/client.rs
+++ b/crates/steel_core/src/ipc/client.rs
@@ -94,7 +94,7 @@ impl CoreClient {
             .unwrap();
     }
 
-    pub fn chat_switch_requested(&self, target: &str, message_id: usize) {
+    pub fn chat_switch_requested(&self, target: &str, message_id: Option<usize>) {
         self.server
             .blocking_send(AppMessageIn::UIChatSwitchRequested(
                 target.to_owned(),
diff --git a/crates/steel_core/src/ipc/server.rs b/crates/steel_core/src/ipc/server.rs
index 936ae07..d14490e 100644
--- a/crates/steel_core/src/ipc/server.rs
+++ b/crates/steel_core/src/ipc/server.rs
@@ -20,7 +20,7 @@ pub enum AppMessageIn {
     UIPrivateChatOpened(String),
     UIChatClosed(String),
     UIChatCleared(String),
-    UIChatSwitchRequested(String, usize),
+    UIChatSwitchRequested(String, Option<usize>),
     UIChatMessageSent { target: String, text: String },
     UIChatActionSent { target: String, text: String },
     UISettingsRequested,
diff --git a/crates/steel_core/src/ipc/ui.rs b/crates/steel_core/src/ipc/ui.rs
index 3fcd416..1f2b849 100644
--- a/crates/steel_core/src/ipc/ui.rs
+++ b/crates/steel_core/src/ipc/ui.rs
@@ -18,7 +18,7 @@ pub enum UIMessageIn {
         details: String,
     },
     NewChatRequested(String, ChatState, bool),
-    ChatSwitchRequested(String, usize),
+    ChatSwitchRequested(String, Option<usize>),
     ChannelJoined(String),
     ChatClosed(String),
     ChatCleared(String),
diff --git a/src/app/mod.rs b/src/app/mod.rs
index 30fc623..87095d6 100644
--- a/src/app/mod.rs
+++ b/src/app/mod.rs
@@ -133,7 +133,7 @@ impl Application {
         self.join_channel(&channel);
     }
 
-    pub fn ui_handle_chat_switch_requested(&self, chat: String, message_id: usize) {
+    pub fn ui_handle_chat_switch_requested(&self, chat: String, message_id: Option<usize>) {
         self.ui_queue
             .blocking_send(UIMessageIn::ChatSwitchRequested(chat, message_id))
             .unwrap();
diff --git a/src/gui/chat.rs b/src/gui/chat.rs
index 16b8852..700f768 100644
--- a/src/gui/chat.rs
+++ b/src/gui/chat.rs
@@ -529,9 +529,7 @@ fn format_chat_name(ui: &mut egui::Ui, state: &UIState, chat_name: &str, message
             }
         });
         if switch_requested {
-            state
-                .core
-                .chat_switch_requested(chat_name, message.id.unwrap());
+            state.core.chat_switch_requested(chat_name, message.id);
         }
     }
 }
diff --git a/src/gui/chat_tabs.rs b/src/gui/chat_tabs.rs
index 9b3bd0f..d15dd79 100644
--- a/src/gui/chat_tabs.rs
+++ b/src/gui/chat_tabs.rs
@@ -245,7 +245,9 @@ impl ChatTabs {
                                 (interleaved_pos, chat_tab.rect.center().y);
 
                             if chat_tab.clicked() {
-                                state.highlights.mark_as_read(&normalized_chat_name);
+                                state
+                                    .core
+                                    .chat_switch_requested(&state.active_chat_tab_name, None);
                             }
                             if matches!(chat_state, ChatState::JoinInProgress) {
                                 ui.spinner();
@@ -292,7 +294,9 @@ impl ChatTabs {
                 coloured_label,
             );
             if chat_tab.clicked() {
-                state.highlights.mark_as_read(&label);
+                state
+                    .core
+                    .chat_switch_requested(&state.active_chat_tab_name, None);
             }
         }
     }
diff --git a/src/gui/state/mod.rs b/src/gui/state/mod.rs
index 9972a3f..2b90750 100644
--- a/src/gui/state/mod.rs
+++ b/src/gui/state/mod.rs
@@ -147,14 +147,23 @@ impl UIState {
         }
     }
 
-    pub fn push_chat_message(&mut self, target: String, mut message: Message, ctx: &egui::Context) {
+    pub fn push_chat_message(
+        &mut self,
+        target: String,
+        mut message: Message,
+        ctx: &egui::Context,
+    ) -> bool {
         let normalized = target.to_lowercase();
         let tab_inactive = !self.is_active_tab(&normalized);
+
+        let mut name_updated = true;
+
         if let Some(pos) = self.name_to_chat.get(&normalized) {
             if let Some(ch) = self.chats.get_mut(*pos) {
                 // If the chat was open with an improper case, fix it!
                 if ch.name != target {
                     ch.name = target;
+                    name_updated = true;
                 }
 
                 message.id = Some(ch.messages.len());
@@ -189,6 +198,7 @@ impl UIState {
                 }
             }
         }
+        name_updated
     }
 
     pub fn validate_reference(&self, chat_name: &str, highlight: &Message) -> bool {
diff --git a/src/gui/window.rs b/src/gui/window.rs
index 22aeef1..211105d 100644
--- a/src/gui/window.rs
+++ b/src/gui/window.rs
@@ -160,6 +160,20 @@ impl ApplicationWindow {
         }
     }
 
+    fn refresh_window_title(&self, ctx: &egui::Context) {
+        let new_tab_title = match self.s.active_chat_tab_name.starts_with('$') {
+            true => format!("steel v{}", crate::VERSION),
+            false => {
+                if let Some(chat) = self.s.active_chat() {
+                    format!("{} – steel v{}", chat.name, crate::VERSION)
+                } else {
+                    format!("steel v{}", crate::VERSION)
+                }
+            }
+        };
+        ctx.send_viewport_cmd(egui::ViewportCommand::Title(new_tab_title));
+    }
+
     pub fn process_pending_events(&mut self, ctx: &egui::Context) {
         if self.date_announcer.should_announce() {
             let text = format!(
@@ -206,6 +220,9 @@ impl ApplicationWindow {
                     } else {
                         self.s.add_new_chat(name, state, switch_to_chat);
                     }
+                    if switch_to_chat {
+                        self.refresh_window_title(ctx);
+                    }
                 }
 
                 UIMessageIn::NewChatStatusReceived {
@@ -220,10 +237,14 @@ impl ApplicationWindow {
 
                 UIMessageIn::ChatSwitchRequested(name, message_id) => {
                     if self.s.has_chat(&name) {
-                        self.s.highlights.mark_as_read(&name);
-                        self.s.active_chat_tab_name = name;
-                        self.chat.scroll_to = Some(message_id);
+                        let lowercase_name = name.to_lowercase();
+                        self.s.highlights.mark_as_read(&lowercase_name);
+                        self.s.active_chat_tab_name = lowercase_name;
+                        if message_id.is_some() {
+                            self.chat.scroll_to = message_id;
+                        }
                     }
+                    self.refresh_window_title(ctx);
                 }
 
                 UIMessageIn::ChannelJoined(name) => {
@@ -235,8 +256,12 @@ impl ApplicationWindow {
                 }
 
                 UIMessageIn::NewMessageReceived { target, message } => {
-                    self.s
-                        .push_chat_message(target.clone(), message.clone(), ctx);
+                    let name_updated =
+                        self.s
+                            .push_chat_message(target.clone(), message.clone(), ctx);
+                    if name_updated {
+                        self.refresh_window_title(ctx);
+                    }
 
                     #[cfg(feature = "glass")]
                     match message.username == self.s.settings.chat.irc.username {
@@ -262,6 +287,7 @@ impl ApplicationWindow {
 
                 UIMessageIn::ChatClosed(name) => {
                     self.s.remove_chat(name);
+                    self.refresh_window_title(ctx);
                 }
 
                 UIMessageIn::ChatCleared(name) => {
@@ -304,18 +330,6 @@ impl eframe::App for ApplicationWindow {
         ctx.request_repaint_after(MIN_IDLE_FRAME_TIME);
         self.process_pending_events(ctx);
 
-        if !self.s.active_chat_tab_name.is_empty() {
-            let title = match self.s.active_chat_tab_name.starts_with('$') {
-                true => format!("steel v{}", crate::VERSION),
-                false => format!(
-                    "{} – steel v{}",
-                    self.s.active_chat_tab_name,
-                    crate::VERSION
-                ),
-            };
-            ctx.send_viewport_cmd(egui::ViewportCommand::Title(title));
-        }
-
         self.set_theme(ctx);
 
         self.usage_window