fix 7TV emote mutations on computed map, fix search store disposer leak, fix typo

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Tommy Chow 2026-02-08 20:34:49 -08:00
parent f9302b0d82
commit 9119a69b17
5 changed files with 52 additions and 8 deletions

View file

@ -443,5 +443,19 @@ abstract class ChatAssetsStoreBase with Store {
}
}
/// Adds a channel emote (e.g., from a live 7TV event).
/// Mutates the observable `_channelEmoteToObject` so `emoteToObject` recomputes.
@action
void addChannelEmote(Emote emote) {
_channelEmoteToObject[emote.name] = emote;
}
/// Removes a channel emote by name (e.g., from a live 7TV event).
/// Mutates the observable `_channelEmoteToObject` so `emoteToObject` recomputes.
@action
void removeChannelEmote(String emoteName) {
_channelEmoteToObject.remove(emoteName);
}
void dispose() => _disposeReaction();
}

View file

@ -320,6 +320,35 @@ mixin _$ChatAssetsStore on ChatAssetsStoreBase, Store {
);
}
late final _$ChatAssetsStoreBaseActionController = ActionController(
name: 'ChatAssetsStoreBase',
context: context,
);
@override
void addChannelEmote(Emote emote) {
final _$actionInfo = _$ChatAssetsStoreBaseActionController.startAction(
name: 'ChatAssetsStoreBase.addChannelEmote',
);
try {
return super.addChannelEmote(emote);
} finally {
_$ChatAssetsStoreBaseActionController.endAction(_$actionInfo);
}
}
@override
void removeChannelEmote(String emoteName) {
final _$actionInfo = _$ChatAssetsStoreBaseActionController.startAction(
name: 'ChatAssetsStoreBase.removeChannelEmote',
);
try {
return super.removeChannelEmote(emoteName);
} finally {
_$ChatAssetsStoreBaseActionController.endAction(_$actionInfo);
}
}
@override
String toString() {
return '''

View file

@ -750,7 +750,7 @@ abstract class ChatStoreBase with Store {
final emote = Emote.from7TV(pushedEmote, EmoteType.sevenTVChannel);
assetsStore.emoteToObject[emote.name] = emote;
assetsStore.addChannelEmote(emote);
messageBuffer.add(
IRCMessage.createNotice(
@ -763,9 +763,7 @@ abstract class ChatStoreBase with Store {
if (pulledEmote == null) return;
assetsStore.emoteToObject.removeWhere(
(name, _) => name == pulledEmote.name,
);
assetsStore.removeChannelEmote(pulledEmote.name);
messageBuffer.add(
IRCMessage.createNotice(

View file

@ -23,6 +23,8 @@ abstract class SearchStoreBase with Store {
Timer? _debounceTimer;
ReactionDisposer? _disposeReaction;
@readonly
var _searchText = '';
@ -53,7 +55,7 @@ abstract class SearchStoreBase with Store {
ObservableList<String>();
// Create a reaction that will limit the history to 8 entries and update it to local storage automatically.
autorun((_) {
_disposeReaction = autorun((_) {
if (_searchHistory.length > 8) _searchHistory.removeLast();
prefs.setStringList('search_history', _searchHistory);
});
@ -136,6 +138,7 @@ abstract class SearchStoreBase with Store {
}
void dispose() {
_disposeReaction?.call();
_debounceTimer?.cancel();
textEditingController.dispose();
textFieldFocusNode.dispose();

View file

@ -143,7 +143,7 @@ abstract class ListStoreBase with Store {
@readonly
String? _error;
ReactionDisposer? _pinnedStreamsReactioniDisposer;
ReactionDisposer? _pinnedStreamsReactionDisposer;
ReactionDisposer? _offlineChannelsExpansionDisposer;
ListStoreBase({
@ -166,7 +166,7 @@ abstract class ListStoreBase with Store {
}
if (listType == ListType.followed) {
_pinnedStreamsReactioniDisposer = reaction(
_pinnedStreamsReactionDisposer = reaction(
(_) => settingsStore.pinnedChannelIds,
(_) => getPinnedStreams(),
);
@ -347,7 +347,7 @@ abstract class ListStoreBase with Store {
}
void dispose() {
_pinnedStreamsReactioniDisposer?.call();
_pinnedStreamsReactionDisposer?.call();
_offlineChannelsExpansionDisposer?.call();
scrollController?.dispose();