diff --git a/lib/stores/chat_store.dart b/lib/stores/chat_store.dart index c2a56d27..17fe4e86 100644 --- a/lib/stores/chat_store.dart +++ b/lib/stores/chat_store.dart @@ -17,9 +17,11 @@ part 'chat_store.g.dart'; class ChatStore = _ChatStoreBase with _$ChatStore; abstract class _ChatStoreBase with Store { - final messages = []; + @readonly + var _messages = []; - final channel = WebSocketChannel.connect(Uri.parse('wss://irc-ws.chat.twitch.tv:443')); + final _channel = WebSocketChannel.connect(Uri.parse('wss://irc-ws.chat.twitch.tv:443')); + get channel => _channel; final _assetToUrl = {}; @@ -29,7 +31,8 @@ abstract class _ChatStoreBase with Store { final AuthStore auth; - final scrollController = ScrollController(); + final _scrollController = ScrollController(); + get scrollController => _scrollController; @readonly var _autoScroll = true; @@ -38,9 +41,7 @@ abstract class _ChatStoreBase with Store { final commands = [ 'PASS oauth:${auth.token}', 'NICK ${auth.isLoggedIn ? auth.user!.login : 'justinfan888'}', - 'CAP REQ :twitch.tv/tags', - 'CAP REQ :twitch.tv/commands', - // 'CAP REQ :twitch.tv/membership', + 'CAP REQ :twitch.tv/tags twitch.tv/commands twitch.tv/membership', 'CAP END', 'JOIN #$channelName', ]; @@ -48,17 +49,15 @@ abstract class _ChatStoreBase with Store { for (final command in commands) { channel.sink.add(command); } - - scrollController.addListener(() { - if (!scrollController.position.atEdge && scrollController.position.pixels < scrollController.position.maxScrollExtent) { + _scrollController.addListener(() { + if (!_scrollController.position.atEdge && _scrollController.position.pixels < _scrollController.position.maxScrollExtent) { _autoScroll = false; - } else if (scrollController.position.atEdge && scrollController.position.pixels != scrollController.position.minScrollExtent) { + } else if (_scrollController.position.atEdge && _scrollController.position.pixels != _scrollController.position.minScrollExtent) { _autoScroll = true; } }); } - @action Future getAssets() async { final channelInfo = await Twitch.getUser(userLogin: channelName, headers: auth.headersTwitch); @@ -84,15 +83,15 @@ abstract class _ChatStoreBase with Store { } } - void handleWebsocketData(Object? data) { - final ircMessages = data.toString(); + void handleWebsocketData(String ircMessages) { for (final message in ircMessages.substring(0, ircMessages.length - 2).split('\r\n')) { + debugPrint(message); if (message.startsWith('@')) { - final parsed = Irc.parse(message); + final parsedIRCMessage = IRC.parse(message); - switch (parsed.command) { + switch (parsedIRCMessage.command) { case 'CLEARCHAT': - clearChat(ircMessage: parsed); + _messages = IRC.CLEARCHAT(messages: _messages, ircMessage: parsedIRCMessage); break; case 'CLEARMSG': break; @@ -100,20 +99,20 @@ abstract class _ChatStoreBase with Store { break; case 'PRIVMSG': if (_autoScroll) { - if (messages.length > 100) { - messages.removeRange(0, messages.length - 100); + if (_messages.length > 100) { + _messages.removeRange(0, _messages.length - 100); } - SchedulerBinding.instance?.addPostFrameCallback((_) { - scrollController.jumpTo(scrollController.position.maxScrollExtent); - }); } - messages.add(parsed); + _messages = IRC.PRIVMSG(messages: _messages, ircMessage: parsedIRCMessage); break; case 'ROOMSTATE': + IRC.USERNOTICE(messages: _messages, ircMessage: parsedIRCMessage); break; case 'USERNOTICE': + IRC.USERNOTICE(messages: _messages, ircMessage: parsedIRCMessage); break; case 'USERSTATE': + IRC.USERSTATE(messages: _messages, ircMessage: parsedIRCMessage); break; } } else if (message.startsWith('P')) { @@ -122,31 +121,7 @@ abstract class _ChatStoreBase with Store { } } - void clearChat({required IrcMessage ircMessage}) { - // If there is no message, it means that entire chat was cleared. - if (ircMessage.message == null) { - // messages.clear(); - messages[0].message = 'User was permabanned!'; - return; - } - - final bannedUser = ircMessage.message; - final banDuration = ircMessage.tags['ban-duration']; - - debugPrint('$bannedUser was banned'); - - messages.asMap().forEach((i, message) { - if (message.user! == bannedUser) { - if (banDuration == null) { - messages[i].message = 'User was permabanned!'; - } else { - messages[i].message = 'User was timed out for $banDuration seconds!'; - } - } - }); - } - - ChatMessage renderChatMessage({required IrcMessage ircMessage}) { + ChatMessage renderChatMessage(IRCMessage ircMessage) { final result = []; final emoteTags = ircMessage.tags['emotes']; @@ -245,9 +220,9 @@ abstract class _ChatStoreBase with Store { @action void resumeScroll() { _autoScroll = true; - scrollController.jumpTo(scrollController.position.maxScrollExtent); + _scrollController.jumpTo(_scrollController.position.maxScrollExtent); SchedulerBinding.instance?.addPostFrameCallback((_) { - scrollController.jumpTo(scrollController.position.maxScrollExtent); + _scrollController.jumpTo(_scrollController.position.maxScrollExtent); }); } } diff --git a/lib/stores/chat_store.g.dart b/lib/stores/chat_store.g.dart index b972713e..cc7265e7 100644 --- a/lib/stores/chat_store.g.dart +++ b/lib/stores/chat_store.g.dart @@ -9,6 +9,23 @@ part of 'chat_store.dart'; // ignore_for_file: non_constant_identifier_names, unnecessary_brace_in_string_interps, unnecessary_lambdas, prefer_expression_function_bodies, lines_longer_than_80_chars, avoid_as, avoid_annotating_with_dynamic mixin _$ChatStore on _ChatStoreBase, Store { + final _$_messagesAtom = Atom(name: '_ChatStoreBase._messages'); + + List get messages { + _$_messagesAtom.reportRead(); + return super._messages; + } + + @override + List get _messages => messages; + + @override + set _messages(List value) { + _$_messagesAtom.reportWrite(value, super._messages, () { + super._messages = value; + }); + } + final _$_autoScrollAtom = Atom(name: '_ChatStoreBase._autoScroll'); bool get autoScroll { @@ -26,13 +43,6 @@ mixin _$ChatStore on _ChatStoreBase, Store { }); } - final _$getAssetsAsyncAction = AsyncAction('_ChatStoreBase.getAssets'); - - @override - Future getAssets() { - return _$getAssetsAsyncAction.run(() => super.getAssets()); - } - final _$_ChatStoreBaseActionController = ActionController(name: '_ChatStoreBase');