Add chat send message feature, refactoring
- Added userState and globalUserState fields to keep track of user data while chatting - Adjusted CAP REQ commands to receive GLOBALUSERSTATE - Adjusted return and break statements in switch and general cleanup - Added sendMessage and dispose method
This commit is contained in:
parent
5ff1744cb9
commit
65611469f3
2 changed files with 75 additions and 47 deletions
|
|
@ -18,35 +18,41 @@ class ChatStore = _ChatStoreBase with _$ChatStore;
|
|||
|
||||
abstract class _ChatStoreBase with Store {
|
||||
@readonly
|
||||
var _messages = <IRCMessage>[];
|
||||
var _autoScroll = true;
|
||||
|
||||
final _channel = WebSocketChannel.connect(Uri.parse('wss://irc-ws.chat.twitch.tv:443'));
|
||||
get channel => _channel;
|
||||
@readonly
|
||||
var _messages = <IRCMessage>[];
|
||||
|
||||
final _assetToUrl = <String, String>{};
|
||||
|
||||
final _emoteIdToWord = <String, String>{};
|
||||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -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<IRCMessage> get messages {
|
||||
_$_messagesAtom.reportRead();
|
||||
return super._messages;
|
||||
}
|
||||
|
||||
@override
|
||||
List<IRCMessage> get _messages => messages;
|
||||
|
||||
@override
|
||||
set _messages(List<IRCMessage> 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<IRCMessage> get messages {
|
||||
_$_messagesAtom.reportRead();
|
||||
return super._messages;
|
||||
}
|
||||
|
||||
@override
|
||||
List<IRCMessage> get _messages => messages;
|
||||
|
||||
@override
|
||||
set _messages(List<IRCMessage> value) {
|
||||
_$_messagesAtom.reportWrite(value, super._messages, () {
|
||||
super._messages = value;
|
||||
});
|
||||
}
|
||||
|
||||
final _$_ChatStoreBaseActionController =
|
||||
ActionController(name: '_ChatStoreBase');
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue