diff --git a/HellionChat/Configuration.cs b/HellionChat/Configuration.cs index 5381ed4..2cc1cda 100755 --- a/HellionChat/Configuration.cs +++ b/HellionChat/Configuration.cs @@ -293,11 +293,14 @@ public class Configuration : IPluginConfiguration // not destroy open tell conversations. Pinned TempTabs are persistent // and come through `other` like regular tabs; unpinned TempTabs are // session-only and held from the local state. For persistent tabs - // (incl. pinned), capture live MessageList + LastSendUnread by - // Identifier and restore them onto the freshly cloned tabs. + // (incl. pinned), capture live runtime state by Identifier and restore + // it onto the freshly cloned tabs — CurrentChannel is critical because + // the user may have switched channel in-game between settings-open + // and settings-save, and we'd otherwise overwrite that with the + // settings-time snapshot. var liveUnpinnedTempTabs = Tabs.Where(TabLifecycleHelpers.IsInUnpinnedPool).ToList(); var livePersistentSession = Tabs.Where(t => !TabLifecycleHelpers.IsInUnpinnedPool(t)) - .ToDictionary(t => t.Identifier, t => (t.Messages, t.LastSendUnread)); + .ToDictionary(t => t.Identifier, t => (t.Messages, t.LastSendUnread, t.CurrentChannel)); Tabs = other .Tabs.Where(t => !t.IsTempTab || t.IsPinned) @@ -308,6 +311,7 @@ public class Configuration : IPluginConfiguration { clone.Messages = live.Messages; clone.LastSendUnread = live.LastSendUnread; + clone.CurrentChannel = live.CurrentChannel; } return clone; }) diff --git a/HellionChat/Ui/ChatLogWindow.cs b/HellionChat/Ui/ChatLogWindow.cs index e67f85c..3d2a502 100644 --- a/HellionChat/Ui/ChatLogWindow.cs +++ b/HellionChat/Ui/ChatLogWindow.cs @@ -441,11 +441,24 @@ public sealed class ChatLogWindow : Window private void TabSwitched(Tab newTab, Tab previousTab) { - // Use the fixed channel if set by the user, or set it to the current tabs channel if this tab wasn't accessed before + // Use the fixed channel if set by the user. Otherwise, if the new tab + // has no channel state yet (fresh from JSON, never selected this + // session), seed from the previous tab — but deep-clone so we don't + // share TellTarget with the previous tab. Without the clone, a later + // /tell on the new tab would mutate the pinned tab's TellTarget and + // the Party/Linkshell channel would pop back to the pinned tell-mark. if (newTab.Channel is not null) + { newTab.CurrentChannel.Channel = newTab.Channel.Value; + } else if (newTab.CurrentChannel.Channel is InputChannel.Invalid) - newTab.CurrentChannel = previousTab.CurrentChannel; + { + newTab.CurrentChannel = previousTab.CurrentChannel.Clone(); + Plugin.LogProxy.Debug( + $"[Tab] '{newTab.Name}' seeded channel from '{previousTab.Name}' " + + $"(Channel={newTab.CurrentChannel.Channel}, TellTarget={newTab.CurrentChannel.TellTarget?.ToTargetString() ?? "null"})" + ); + } SetChannel(newTab.CurrentChannel.Channel); }