diff --git a/lib/stores/chat_store.dart b/lib/stores/chat_store.dart index 24e3e95e..6a74a154 100644 --- a/lib/stores/chat_store.dart +++ b/lib/stores/chat_store.dart @@ -18,35 +18,41 @@ class ChatStore = _ChatStoreBase with _$ChatStore; abstract class _ChatStoreBase with Store { @readonly - var _messages = []; + var _autoScroll = true; - final _channel = WebSocketChannel.connect(Uri.parse('wss://irc-ws.chat.twitch.tv:443')); - get channel => _channel; + @readonly + var _messages = []; final _assetToUrl = {}; final _emoteIdToWord = {}; + final _scrollController = ScrollController(); + ScrollController get scrollController => _scrollController; + + final _textController = TextEditingController(); + TextEditingController get textController => _textController; + + final _channel = WebSocketChannel.connect(Uri.parse('wss://irc-ws.chat.twitch.tv:443')); + WebSocketChannel get channel => _channel; + + String? userState; + String? globalUserState; + final String channelName; final AuthStore auth; - final _scrollController = ScrollController(); - get scrollController => _scrollController; - - @readonly - var _autoScroll = true; - _ChatStoreBase({required this.auth, required this.channelName}) { channel.stream.listen( (event) => handleWebsocketData(event.toString()), onDone: () => debugPrint("DONE"), ); final commands = [ + 'CAP REQ :twitch.tv/tags twitch.tv/commands', + 'CAP END', 'PASS oauth:${auth.token}', 'NICK ${auth.isLoggedIn ? auth.user!.login : 'justinfan888'}', - 'CAP REQ :twitch.tv/tags twitch.tv/commands twitch.tv/membership', - 'CAP END', 'JOIN #$channelName', ]; @@ -96,37 +102,41 @@ abstract class _ChatStoreBase with Store { switch (parsedIRCMessage.command) { case 'CLEARCHAT': _messages = IRC.CLEARCHAT(messages: _messages, ircMessage: parsedIRCMessage); - break; + return; case 'CLEARMSG': - break; + _messages = IRC.CLEARMSG(messages: _messages, ircMessage: parsedIRCMessage); + return; case 'GLOBALUSERSTATE': - break; + // Updates the current global user state data (it includes user-id) + globalUserState = message; + return; case 'PRIVMSG': - if (_autoScroll) { - if (_messages.length > 100) { - _messages.removeRange(0, _messages.length - 100); - } - if (_scrollController.hasClients) { - SchedulerBinding.instance?.addPostFrameCallback((_) { - _scrollController.jumpTo(_scrollController.position.maxScrollExtent); - }); - } - } - _messages = IRC.PRIVMSG(messages: _messages, ircMessage: parsedIRCMessage); break; case 'ROOMSTATE': - IRC.USERNOTICE(messages: _messages, ircMessage: parsedIRCMessage); - break; + IRC.ROOMSTATE(messages: _messages, ircMessage: parsedIRCMessage); + return; case 'USERNOTICE': IRC.USERNOTICE(messages: _messages, ircMessage: parsedIRCMessage); break; case 'USERSTATE': - IRC.USERSTATE(messages: _messages, ircMessage: parsedIRCMessage); - break; + // Updates the current user-state data + userState = message; + return; } } else if (message.startsWith('P')) { channel.sink.add('PONG :tmi.twitch.tv'); + return; + } + } + if (_autoScroll) { + if (_messages.length > 100) { + _messages.removeRange(0, _messages.length - 80); + } + if (_scrollController.hasClients) { + SchedulerBinding.instance?.addPostFrameCallback((_) { + _scrollController.jumpTo(_scrollController.position.maxScrollExtent); + }); } } } @@ -222,11 +232,23 @@ abstract class _ChatStoreBase with Store { } return ChatMessage( - key: Key(ircMessage.tags['id']!), + // key: Key(ircMessage.tags['id']!), children: result, ); } + void sendMessage(String message) { + if (message.isEmpty) { + return; + } + + _channel.sink.add('PRIVMSG #$channelName :$message'); + + _messages = IRC.addMessage(messages: _messages, userState: userState!, sentMessage: message); + + _textController.clear(); + } + @action void resumeScroll() { _autoScroll = true; @@ -235,6 +257,12 @@ abstract class _ChatStoreBase with Store { _scrollController.jumpTo(_scrollController.position.maxScrollExtent); }); } + + void dispose() { + _channel.sink.close(); + _textController.dispose(); + _scrollController.dispose(); + } } // https://stackoverflow.com/questions/50081213/how-do-i-use-hexadecimal-color-strings-in-flutter diff --git a/lib/stores/chat_store.g.dart b/lib/stores/chat_store.g.dart index cc7265e7..2bc80d74 100644 --- a/lib/stores/chat_store.g.dart +++ b/lib/stores/chat_store.g.dart @@ -9,23 +9,6 @@ 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 { @@ -43,6 +26,23 @@ 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 _$_ChatStoreBaseActionController = ActionController(name: '_ChatStoreBase');