fix(tabs): preserve runtime channel across Settings Save, deep-clone seeded CurrentChannel
Smoke-test round 4 surfaced a clean reproducer: a Party or Linkshell tab with channel /p, then Settings → Save, popped the input back to /tell <pinned-partner> on the next interaction. Two bugs combined: 1. Configuration.UpdateFrom captured only Messages+LastSendUnread from the live state during the persistent-tab merge. CurrentChannel was not preserved, so a Settings save overwrote the runtime channel state with the settings-time snapshot. If the user switched channel in-game between Settings-open and Settings-save, that switch was lost. Live CurrentChannel now joins Messages and LastSendUnread in the per-Identifier preservation tuple. 2. TabSwitched seeded a new tab's CurrentChannel from previousTab via reference copy (`newTab.CurrentChannel = previousTab.CurrentChannel`). That left both tabs sharing the same UsedChannel instance, so a later mutation on one bled into the other — exactly the path that carried a pinned tell-target onto Party. Switched to a deep clone (UsedChannel.Clone(), same Cherry-Pick-Patch-B pattern from v1.4.6) plus a Debug log so the next smoke can confirm at a glance which previous tab donated its channel state. Pre-existing ChatTwo upstream pattern; v1.4.7 just made it visible because pinned tabs are now the kind of long-lived tell-target that sticks around for the seed path to grab.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user