From d5e8d0c6c5d761d97ac9f8777ed26f8db1838e63 Mon Sep 17 00:00:00 2001 From: Tommy Chow Date: Thu, 8 Sep 2022 16:04:13 -0400 Subject: [PATCH] Enable zero width emotes by default --- lib/models/irc.dart | 232 ++++++++---------- .../channel/chat/widgets/chat_message.dart | 3 - lib/screens/settings/chat_settings.dart | 12 - .../settings/stores/settings_store.dart | 7 - .../settings/stores/settings_store.g.dart | 19 -- 5 files changed, 104 insertions(+), 169 deletions(-) diff --git a/lib/models/irc.dart b/lib/models/irc.dart index 2493dc9f..e0f2a795 100644 --- a/lib/models/irc.dart +++ b/lib/models/irc.dart @@ -114,7 +114,6 @@ class IRCMessage { required bool launchExternal, required void Function()? onLongPressName, bool showMessage = true, - bool useZeroWidth = false, bool useReadableColors = false, TimestampType timestamp = TimestampType.disabled, }) { @@ -311,161 +310,138 @@ class IRCMessage { // Add the message and any emotes to the span. if (words != null) { - if (useZeroWidth) { - // Keep a local span which will be reversed and added to the final span. - final localSpan = []; + // Keep a local span which will be reversed and added to the final span. + final localSpan = []; - // Iterate through the words in reverse-order. - // Index starts at the last word in the message. - var index = words.length - 1; + // Iterate through the words in reverse-order. + // Index starts at the last word in the message. + var index = words.length - 1; - // Terminate after the first word in the message reached. - while (index != -1) { - // Check if current word is a valid emote. - final word = words[index]; - final emote = emoteToObject[word] ?? localEmotes?[word]; + // Terminate after the first word in the message reached. + while (index != -1) { + // Check if current word is a valid emote. + final word = words[index]; + final emote = emoteToObject[word] ?? localEmotes?[word]; - if (emote != null) { - // If the emote is zero-width and not the first word, process the stack. - if (emote.zeroWidth && index != 0) { - final emoteStack = []; + if (emote != null) { + // If the emote is zero-width and not the first word, process the stack. + if (emote.zeroWidth && index != 0) { + final emoteStack = []; - // Handle stacking consecutive zero-width emotes. - Emote? nextEmote = emote; - while (nextEmote != null && nextEmote.zeroWidth && index != 0) { - emoteStack.add(nextEmote); - index--; - nextEmote = emoteToObject[words[index]] ?? localEmotes?[words[index]]; - } + // Handle stacking consecutive zero-width emotes. + Emote? nextEmote = emote; + while (nextEmote != null && nextEmote.zeroWidth && index != 0) { + emoteStack.add(nextEmote); + index--; + nextEmote = emoteToObject[words[index]] ?? localEmotes?[words[index]]; + } - // If there's one more emote thats NOT zero-width, add it to the base of the stack. - if (nextEmote != null) emoteStack.add(nextEmote); + // If there's one more emote thats NOT zero-width, add it to the base of the stack. + if (nextEmote != null) emoteStack.add(nextEmote); - // Check if the next word is an emoji to be added to the stack. - final nextWordIsEmoji = regexEmoji.hasMatch(words[index]); + // Check if the next word is an emoji to be added to the stack. + final nextWordIsEmoji = regexEmoji.hasMatch(words[index]); - // Create the stack of emotes with the base emoji if there is one. - // Will be used as the children of the Stack widget. - final children = [ - if (nextWordIsEmoji) - Text( - words[index], - style: textStyle?.copyWith(fontSize: emoteSize - 5), - ), - ...emoteStack.reversed.map( - (emote) => CachedNetworkImage( - imageUrl: emote.url, - fadeInDuration: const Duration(), - height: emote.height != null ? emote.height! * emoteScale : emoteSize, - width: emote.width != null ? emote.width! * emoteScale : emoteSize, - ), - ) - ]; + // Create the stack of emotes with the base emoji if there is one. + // Will be used as the children of the Stack widget. + final children = [ + if (nextWordIsEmoji) + Text( + words[index], + style: textStyle?.copyWith(fontSize: emoteSize - 5), + ), + ...emoteStack.reversed.map( + (emote) => CachedNetworkImage( + imageUrl: emote.url, + fadeInDuration: const Duration(), + height: emote.height != null ? emote.height! * emoteScale : emoteSize, + width: emote.width != null ? emote.width! * emoteScale : emoteSize, + ), + ) + ]; - // Create the message for the tooltip - final message = emoteStack.reversed.map((emote) => '${emote.name} - ${emoteType[emote.type.index]}'); - localSpan.add( - WidgetSpan( - alignment: PlaceholderAlignment.middle, - child: Tooltip( - richMessage: WidgetSpan( - child: Padding( - padding: const EdgeInsets.all(5.0), - child: Column( - children: [ - Stack( - alignment: AlignmentDirectional.center, - children: [ - if (nextWordIsEmoji) - Text( - words[index], - style: textStyle?.copyWith(fontSize: 75), - ), - ...emoteStack.reversed.map( - (emote) => CachedNetworkImage( - imageUrl: emote.url, - fadeInDuration: const Duration(), - height: 80, - ), - ) - ], - ), - const SizedBox(height: 5.0), - Column( - children: [ + // Create the message for the tooltip + final message = emoteStack.reversed.map((emote) => '${emote.name} - ${emoteType[emote.type.index]}'); + localSpan.add( + WidgetSpan( + alignment: PlaceholderAlignment.middle, + child: Tooltip( + richMessage: WidgetSpan( + child: Padding( + padding: const EdgeInsets.all(5.0), + child: Column( + children: [ + Stack( + alignment: AlignmentDirectional.center, + children: [ + if (nextWordIsEmoji) Text( - nextWordIsEmoji ? '${words[index]} - Emoji' : '${emoteStack.last.name} - ${emoteType[emoteStack.last.type.index]}', - style: const TextStyle(color: Colors.black), + words[index], + style: textStyle?.copyWith(fontSize: 75), ), - Text( - nextWordIsEmoji ? message.join(', ') : message.skip(1).join(', '), - style: const TextStyle(color: Colors.black), + ...emoteStack.reversed.map( + (emote) => CachedNetworkImage( + imageUrl: emote.url, + fadeInDuration: const Duration(), + height: 80, ), - ], - ), - ], - ), + ) + ], + ), + const SizedBox(height: 5.0), + Column( + children: [ + Text( + nextWordIsEmoji ? '${words[index]} - Emoji' : '${emoteStack.last.name} - ${emoteType[emoteStack.last.type.index]}', + style: const TextStyle(color: Colors.black), + ), + Text( + nextWordIsEmoji ? message.join(', ') : message.skip(1).join(', '), + style: const TextStyle(color: Colors.black), + ), + ], + ), + ], ), ), - preferBelow: false, - child: Stack( - alignment: AlignmentDirectional.center, - children: children, - ), + ), + preferBelow: false, + child: Stack( + alignment: AlignmentDirectional.center, + children: children, ), ), - ); + ), + ); - // If the next word is neither an emote or emoji, add it as a text span. - if (nextEmote == null && !nextWordIsEmoji) { - localSpan.add(const TextSpan(text: ' ')); - localSpan.add(_createTextSpan(text: words[index], style: textStyle, launchExternal: launchExternal)); - } - } else { - localSpan.add( - _createEmoteSpan( - emote: emote, - height: emote.height != null ? emote.height! * emoteScale : emoteSize, - width: emote.width != null ? emote.width! * emoteScale : null, - ), - ); + // If the next word is neither an emote or emoji, add it as a text span. + if (nextEmote == null && !nextWordIsEmoji) { + localSpan.add(const TextSpan(text: ' ')); + localSpan.add(_createTextSpan(text: words[index], style: textStyle, launchExternal: launchExternal)); } } else { - if (regexEmoji.hasMatch(word)) { - localSpan.add(_createEmojiSpan(emoji: word, style: textStyle?.copyWith(fontSize: emoteSize - 5))); - } else { - localSpan.add(_createTextSpan(text: word, style: textStyle, launchExternal: launchExternal)); - } - } - localSpan.add(const TextSpan(text: ' ')); - index--; - } - - // Add the the local span reversed to the final span. - span.addAll(localSpan.reversed); - } else { - // Iterate through the words and add to the span based on word, emote, and emoji. - for (final word in words) { - span.add(const TextSpan(text: ' ')); - - final emote = emoteToObject[word] ?? localEmotes?[word]; - if (emote != null) { - span.add( + localSpan.add( _createEmoteSpan( emote: emote, height: emote.height != null ? emote.height! * emoteScale : emoteSize, width: emote.width != null ? emote.width! * emoteScale : null, ), ); + } + } else { + if (regexEmoji.hasMatch(word)) { + localSpan.add(_createEmojiSpan(emoji: word, style: textStyle?.copyWith(fontSize: emoteSize - 5))); } else { - if (regexEmoji.hasMatch(word)) { - span.add(_createEmojiSpan(emoji: word, style: textStyle?.copyWith(fontSize: emoteSize - 5))); - } else { - span.add(_createTextSpan(text: word, style: textStyle, launchExternal: launchExternal)); - } + localSpan.add(_createTextSpan(text: word, style: textStyle, launchExternal: launchExternal)); } } + + localSpan.add(const TextSpan(text: ' ')); + index--; } + + // Add the the local span reversed to the final span. + span.addAll(localSpan.reversed); } } diff --git a/lib/screens/channel/chat/widgets/chat_message.dart b/lib/screens/channel/chat/widgets/chat_message.dart index 4e240316..4c1a4ea7 100644 --- a/lib/screens/channel/chat/widgets/chat_message.dart +++ b/lib/screens/channel/chat/widgets/chat_message.dart @@ -72,7 +72,6 @@ class ChatMessage extends StatelessWidget { assetsStore: chatStore.assetsStore, emoteScale: chatStore.settings.emoteScale, badgeScale: chatStore.settings.badgeScale, - useZeroWidth: chatStore.settings.showZeroWidth, useReadableColors: chatStore.settings.useReadableColors, isLightTheme: Theme.of(context).brightness == Brightness.light, launchExternal: chatStore.settings.launchUrlExternal, @@ -167,7 +166,6 @@ class ChatMessage extends StatelessWidget { emoteScale: chatStore.settings.emoteScale, badgeScale: chatStore.settings.badgeScale, showMessage: chatStore.settings.showDeletedMessages, - useZeroWidth: chatStore.settings.showZeroWidth, useReadableColors: chatStore.settings.useReadableColors, isLightTheme: Theme.of(context).brightness == Brightness.light, launchExternal: chatStore.settings.launchUrlExternal, @@ -221,7 +219,6 @@ class ChatMessage extends StatelessWidget { assetsStore: chatStore.assetsStore, emoteScale: chatStore.settings.emoteScale, badgeScale: chatStore.settings.badgeScale, - useZeroWidth: chatStore.settings.showZeroWidth, useReadableColors: chatStore.settings.useReadableColors, isLightTheme: Theme.of(context).brightness == Brightness.light, launchExternal: chatStore.settings.launchUrlExternal, diff --git a/lib/screens/settings/chat_settings.dart b/lib/screens/settings/chat_settings.dart index 9fcd5b48..c9fcbc09 100644 --- a/lib/screens/settings/chat_settings.dart +++ b/lib/screens/settings/chat_settings.dart @@ -169,18 +169,6 @@ class _ChatSettingsState extends State { ], ), ), - const SectionHeader( - 'Emotes', - padding: sectionPadding, - showDivider: true, - ), - SwitchListTile.adaptive( - isThreeLine: true, - title: const Text('Zero-width emotes'), - subtitle: const Text('Shows "stacked" emotes from BetterTTV and 7TV.'), - value: settingsStore.showZeroWidth, - onChanged: (newValue) => settingsStore.showZeroWidth = newValue, - ), const SectionHeader( 'Message Appearance', padding: sectionPadding, diff --git a/lib/screens/settings/stores/settings_store.dart b/lib/screens/settings/stores/settings_store.dart index fe7e1283..59ec7477 100644 --- a/lib/screens/settings/stores/settings_store.dart +++ b/lib/screens/settings/stores/settings_store.dart @@ -97,8 +97,6 @@ abstract class _SettingsStoreBase with Store { static const defaultChatWidth = 0.3; static const defaultFullScreenChatOverlayOpacity = 0.5; - static const defaultShowZeroWidth = false; - static const defaultUseReadableColors = true; static const defaultShowDeletedMessages = false; static const defaultShowChatMessageDividers = false; @@ -153,10 +151,6 @@ abstract class _SettingsStoreBase with Store { @observable var fullScreenChatOverlayOpacity = defaultFullScreenChatOverlayOpacity; - @JsonKey(defaultValue: defaultShowZeroWidth) - @observable - var showZeroWidth = defaultShowZeroWidth; - @JsonKey(defaultValue: defaultUseReadableColors) @observable var useReadableColors = defaultUseReadableColors; @@ -213,7 +207,6 @@ abstract class _SettingsStoreBase with Store { landscapeCutout = defaultLandscapeCutout; chatWidth = defaultChatWidth; fullScreenChatOverlayOpacity = defaultFullScreenChatOverlayOpacity; - showZeroWidth = defaultShowZeroWidth; useReadableColors = defaultUseReadableColors; showDeletedMessages = defaultShowDeletedMessages; showChatMessageDividers = defaultShowChatMessageDividers; diff --git a/lib/screens/settings/stores/settings_store.g.dart b/lib/screens/settings/stores/settings_store.g.dart index 694edcef..a1235744 100644 --- a/lib/screens/settings/stores/settings_store.g.dart +++ b/lib/screens/settings/stores/settings_store.g.dart @@ -34,7 +34,6 @@ SettingsStore _$SettingsStoreFromJson(Map json) => ..chatWidth = (json['chatWidth'] as num?)?.toDouble() ?? 0.3 ..fullScreenChatOverlayOpacity = (json['fullScreenChatOverlayOpacity'] as num?)?.toDouble() ?? 0.5 - ..showZeroWidth = json['showZeroWidth'] as bool? ?? false ..useReadableColors = json['useReadableColors'] as bool? ?? true ..showDeletedMessages = json['showDeletedMessages'] as bool? ?? false ..showChatMessageDividers = @@ -79,7 +78,6 @@ Map _$SettingsStoreToJson(SettingsStore instance) => _$LandscapeCutoutTypeEnumMap[instance.landscapeCutout]!, 'chatWidth': instance.chatWidth, 'fullScreenChatOverlayOpacity': instance.fullScreenChatOverlayOpacity, - 'showZeroWidth': instance.showZeroWidth, 'useReadableColors': instance.useReadableColors, 'showDeletedMessages': instance.showDeletedMessages, 'showChatMessageDividers': instance.showChatMessageDividers, @@ -450,22 +448,6 @@ mixin _$SettingsStore on _SettingsStoreBase, Store { }); } - late final _$showZeroWidthAtom = - Atom(name: '_SettingsStoreBase.showZeroWidth', context: context); - - @override - bool get showZeroWidth { - _$showZeroWidthAtom.reportRead(); - return super.showZeroWidth; - } - - @override - set showZeroWidth(bool value) { - _$showZeroWidthAtom.reportWrite(value, super.showZeroWidth, () { - super.showZeroWidth = value; - }); - } - late final _$useReadableColorsAtom = Atom(name: '_SettingsStoreBase.useReadableColors', context: context); @@ -801,7 +783,6 @@ chatNotificationsOnBottom: ${chatNotificationsOnBottom}, landscapeCutout: ${landscapeCutout}, chatWidth: ${chatWidth}, fullScreenChatOverlayOpacity: ${fullScreenChatOverlayOpacity}, -showZeroWidth: ${showZeroWidth}, useReadableColors: ${useReadableColors}, showDeletedMessages: ${showDeletedMessages}, showChatMessageDividers: ${showChatMessageDividers},