Created
May 13, 2024 11:55
-
-
Save TasyaShark/880ef102cf11be8196959e4893a09f8e to your computer and use it in GitHub Desktop.
main.dart
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import 'dart:async'; | |
import 'package:connectycube_sdk/connectycube_sdk.dart'; | |
import 'package:flutter/material.dart'; | |
import 'package:intl/intl.dart'; | |
const String appId = "476"; | |
const String authKey = "PDZjPBzAO8WPfCp"; | |
const String authSecret = "6247kjxXCLRaua6"; | |
const String userArgName = 'user'; | |
const String dialogArgName = 'dialog'; | |
Future<void> main() async { | |
WidgetsFlutterBinding.ensureInitialized(); | |
runApp(const App()); | |
} | |
class App extends StatefulWidget { | |
const App({super.key}); | |
@override | |
State<StatefulWidget> createState() { | |
return _AppState(); | |
} | |
} | |
class _AppState extends State<App> { | |
AppLifecycleState? appState; | |
@override | |
Widget build(BuildContext context) { | |
return MaterialApp( | |
theme: ThemeData( | |
colorScheme: ColorScheme.fromSeed(seedColor: Colors.green), | |
), | |
home: const LoginScreen(), | |
onGenerateRoute: (settings) { | |
String? name = settings.name; | |
Map<String, dynamic>? args = | |
settings.arguments as Map<String, dynamic>?; | |
MaterialPageRoute pageRout; | |
switch (name) { | |
case 'chat_dialog': | |
pageRout = MaterialPageRoute( | |
builder: (context) => | |
ChatScreen(args![userArgName], args[dialogArgName])); | |
break; | |
case 'select_dialog': | |
pageRout = MaterialPageRoute<bool>( | |
builder: (context) => ChatsListScreen(args![userArgName])); | |
break; | |
case 'login': | |
pageRout = | |
MaterialPageRoute(builder: (context) => const LoginScreen()); | |
break; | |
default: | |
pageRout = | |
MaterialPageRoute(builder: (context) => const LoginScreen()); | |
break; | |
} | |
return pageRout; | |
}, | |
); | |
} | |
@override | |
void initState() { | |
super.initState(); | |
init(appId, authKey, authSecret); | |
} | |
} | |
class LoginScreen extends StatefulWidget { | |
const LoginScreen({super.key}); | |
@override | |
State<StatefulWidget> createState() => LoginScreenState(); | |
} | |
class LoginScreenState extends State<LoginScreen> { | |
final TextEditingController _loginEditingController = TextEditingController(); | |
final TextEditingController _passwordEditingController = | |
TextEditingController(); | |
bool _isLoginContinues = false; | |
@override | |
Widget build(BuildContext context) { | |
if (_isLoginContinues) { | |
return Scaffold( | |
body: Center( | |
child: Container( | |
margin: const EdgeInsets.only(left: 8), | |
height: 18, | |
width: 18, | |
child: const CircularProgressIndicator( | |
strokeWidth: 2, | |
), | |
), | |
), | |
); | |
} | |
return Scaffold( | |
body: Center( | |
child: SingleChildScrollView( | |
child: Container( | |
padding: const EdgeInsets.symmetric(horizontal: 16.0), | |
child: ConstrainedBox( | |
constraints: const BoxConstraints(maxWidth: 400), | |
child: Column( | |
children: <Widget>[ | |
TextField( | |
keyboardType: TextInputType.text, | |
controller: _loginEditingController, | |
decoration: const InputDecoration(labelText: 'Login'), | |
), | |
TextField( | |
keyboardType: TextInputType.visiblePassword, | |
controller: _passwordEditingController, | |
decoration: const InputDecoration(labelText: 'Password'), | |
obscureText: true, | |
enableSuggestions: false, | |
autocorrect: false, | |
onSubmitted: (_) { | |
_login(); | |
}, | |
), | |
Container( | |
margin: const EdgeInsets.only(top: 8), | |
child: ElevatedButton( | |
onPressed: _login, | |
child: const Text('Login'), | |
), | |
) | |
], | |
), | |
)), | |
), | |
), | |
); | |
} | |
void _login() { | |
var userToLogin = CubeUser() | |
..login = _loginEditingController.text | |
..password = _passwordEditingController.text; | |
setState(() { | |
_isLoginContinues = true; | |
}); | |
createSession(userToLogin).then((cubeSession) async { | |
print("createSession cubeSession: $cubeSession"); | |
CubeChatConnection.instance | |
.login(userToLogin..id = cubeSession.user!.id) | |
.then((cubeUser) { | |
setState(() { | |
_isLoginContinues = false; | |
}); | |
Navigator.pushReplacementNamed( | |
context, | |
'select_dialog', | |
arguments: {userArgName: cubeUser}, | |
); | |
}).catchError((error) { | |
// process creating Chat session error | |
print("loginChat error: $error"); | |
setState(() { | |
_isLoginContinues = false; | |
}); | |
}); | |
}).catchError((error) { | |
// process creating API session error | |
print("createSession error: $error"); | |
setState(() { | |
_isLoginContinues = false; | |
}); | |
}); | |
} | |
} | |
class ChatsListScreen extends StatelessWidget { | |
final CubeUser currentUser; | |
const ChatsListScreen(this.currentUser, {super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
automaticallyImplyLeading: false, | |
title: Text( | |
'Logged in as ${currentUser.fullName ?? currentUser.login}', | |
), | |
), | |
body: ChatsListBody(currentUser), | |
); | |
} | |
} | |
class ChatsListBody extends StatefulWidget { | |
final CubeUser currentUser; | |
const ChatsListBody(this.currentUser, {super.key}); | |
@override | |
State<StatefulWidget> createState() { | |
return _ChatsListBodyState(); | |
} | |
} | |
class _ChatsListBodyState extends State<ChatsListBody> { | |
List<CubeDialog> dialogList = []; | |
bool _isDialogsLoafingContinues = true; | |
@override | |
void initState() { | |
super.initState(); | |
getDialogs().then((pagedResult) { | |
if (mounted) { | |
setState(() { | |
dialogList = pagedResult?.items ?? []; | |
}); | |
} | |
}).whenComplete(() { | |
setState(() { | |
_isDialogsLoafingContinues = false; | |
}); | |
}); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
body: Container( | |
padding: const EdgeInsets.only(top: 2), | |
child: Column( | |
children: [ | |
Visibility( | |
visible: _isDialogsLoafingContinues, | |
child: Container( | |
margin: const EdgeInsets.all(40), | |
alignment: FractionalOffset.center, | |
child: const CircularProgressIndicator( | |
strokeWidth: 2, | |
), | |
), | |
), | |
Visibility( | |
visible: dialogList.isEmpty, | |
child: Container( | |
margin: const EdgeInsets.all(40), | |
alignment: FractionalOffset.center, | |
child: const Text( | |
'No dialogs yet', | |
style: TextStyle(fontSize: 20), | |
), | |
), | |
), | |
Visibility( | |
visible: dialogList.isNotEmpty, | |
child: Flexible( | |
child: ListView.separated( | |
itemCount: dialogList.length, | |
itemBuilder: (BuildContext context, int index) { | |
return getDialogItemTile(dialogList[index]); | |
}, | |
separatorBuilder: (context, index) { | |
return const Divider( | |
thickness: 1, | |
indent: 68, | |
height: 1, | |
); | |
}, | |
), | |
), | |
), | |
], | |
), | |
), | |
floatingActionButton: FloatingActionButton( | |
heroTag: "New dialog", | |
backgroundColor: Colors.blue, | |
onPressed: () => _createNewDialog(context), | |
child: const Icon( | |
Icons.add_comment, | |
color: Colors.white, | |
), | |
), | |
); | |
} | |
void _createNewDialog(BuildContext context) async { | |
showDialog<int>( | |
context: context, | |
barrierDismissible: false, | |
builder: (context) { | |
var userIdEditingController = TextEditingController(); | |
return AlertDialog( | |
title: const Text('Type participant\'s ID'), | |
content: TextField( | |
keyboardType: TextInputType.number, | |
controller: userIdEditingController, | |
decoration: const InputDecoration(labelText: 'Participant ID'), | |
), | |
actions: [ | |
TextButton( | |
onPressed: () => Navigator.pop(context, null), | |
child: const Text('Cancel'), | |
), | |
TextButton( | |
onPressed: () => Navigator.pop( | |
context, int.tryParse(userIdEditingController.text)), | |
child: const Text('Ok'), | |
), | |
], | |
); | |
}, | |
).then((participantId) { | |
if (participantId != null) { | |
var newDialog = | |
CubeDialog(CubeDialogType.PRIVATE, occupantsIds: [participantId]); | |
createDialog(newDialog).then((createdDialog) { | |
Navigator.pushNamed(context, 'chat_dialog', arguments: { | |
userArgName: widget.currentUser, | |
dialogArgName: createdDialog | |
}); | |
}); | |
} | |
}); | |
} | |
Widget getDialogItemTile(CubeDialog dialog) { | |
Widget getDialogIcon() { | |
return Icon( | |
dialog.type == CubeDialogType.PRIVATE ? Icons.person : Icons.group, | |
size: 40.0, | |
color: Colors.grey, | |
); | |
} | |
Widget getAvatarWidget(String? imageUrl, String? name, double radius) { | |
return CircleAvatar( | |
backgroundColor: const Color.fromARGB(20, 100, 100, 100), | |
radius: radius, | |
child: ClipRRect( | |
borderRadius: BorderRadius.circular(radius), | |
child: Image.network( | |
imageUrl ?? '', | |
fit: BoxFit.cover, | |
width: radius * 2, | |
height: radius * 2, | |
loadingBuilder: (context, child, loadingProgress) { | |
return getDialogIcon(); | |
}, | |
errorBuilder: | |
(BuildContext context, Object error, StackTrace? stackTrace) { | |
return getDialogIcon(); | |
}, | |
), | |
), | |
); | |
} | |
Widget getDialogAvatar() { | |
return getAvatarWidget(dialog.photo, dialog.name, 25); | |
} | |
Widget getMessageStateWidget(MessageState? state) { | |
Widget result; | |
switch (state) { | |
case MessageState.read: | |
result = const Stack(children: <Widget>[ | |
Icon( | |
Icons.check_rounded, | |
size: 15.0, | |
color: Colors.green, | |
), | |
Padding( | |
padding: EdgeInsets.only( | |
left: 4, | |
), | |
child: Icon( | |
Icons.check_rounded, | |
size: 15.0, | |
color: Colors.green, | |
), | |
) | |
]); | |
break; | |
case MessageState.delivered: | |
result = const Stack(children: <Widget>[ | |
Icon( | |
Icons.check_rounded, | |
size: 15.0, | |
color: Colors.grey, | |
), | |
Padding( | |
padding: EdgeInsets.only(left: 4), | |
child: Icon( | |
Icons.check_rounded, | |
size: 15.0, | |
color: Colors.grey, | |
), | |
) | |
]); | |
break; | |
case MessageState.sent: | |
result = const Icon( | |
Icons.check_rounded, | |
size: 15.0, | |
color: Colors.grey, | |
); | |
break; | |
default: | |
result = const SizedBox.shrink(); | |
break; | |
} | |
return result; | |
} | |
return Container( | |
padding: const EdgeInsets.symmetric(vertical: 5, horizontal: 10), | |
child: GestureDetector( | |
behavior: HitTestBehavior.translucent, | |
child: Row( | |
children: <Widget>[ | |
getDialogAvatar(), | |
Flexible( | |
child: Container( | |
margin: const EdgeInsets.only(left: 8.0), | |
child: Column( | |
children: <Widget>[ | |
Container( | |
alignment: Alignment.centerLeft, | |
child: Text( | |
dialog.name ?? 'Unknown name', | |
style: TextStyle( | |
color: Colors.blueGrey.shade800, | |
fontWeight: FontWeight.bold, | |
fontSize: 16.0, | |
overflow: TextOverflow.ellipsis), | |
maxLines: 1, | |
), | |
), | |
Container( | |
alignment: Alignment.centerLeft, | |
child: Text( | |
dialog.lastMessage ?? '', | |
style: TextStyle( | |
color: Colors.blueGrey.shade800, | |
overflow: TextOverflow.ellipsis), | |
maxLines: 2, | |
), | |
), | |
], | |
), | |
), | |
), | |
Column( | |
crossAxisAlignment: CrossAxisAlignment.end, | |
children: [ | |
Row( | |
children: [ | |
getMessageStateWidget(dialog.lastMessageState), | |
Text( | |
DateFormat('MMM dd').format( | |
dialog.lastMessageDateSent != null | |
? DateTime.fromMillisecondsSinceEpoch( | |
dialog.lastMessageDateSent! * 1000) | |
: dialog.updatedAt!), | |
style: TextStyle(color: Colors.blueGrey.shade800), | |
), | |
], | |
), | |
if (dialog.unreadMessageCount != null && | |
dialog.unreadMessageCount != 0) | |
Padding( | |
padding: const EdgeInsets.only(top: 4), | |
child: Container( | |
padding: const EdgeInsets.symmetric( | |
vertical: 2, horizontal: 6), | |
decoration: BoxDecoration( | |
color: Colors.green, | |
borderRadius: BorderRadius.circular(10.0)), | |
child: Text( | |
dialog.unreadMessageCount.toString(), | |
style: const TextStyle(color: Colors.white), | |
), | |
), | |
), | |
], | |
), | |
], | |
), | |
onTap: () { | |
Navigator.pushNamed(context, 'chat_dialog', arguments: { | |
userArgName: widget.currentUser, | |
dialogArgName: dialog, | |
}); | |
}, | |
), | |
); | |
} | |
} | |
class ChatScreen extends StatelessWidget { | |
final CubeUser _cubeUser; | |
final CubeDialog _cubeDialog; | |
const ChatScreen(this._cubeUser, this._cubeDialog, {super.key}); | |
@override | |
Widget build(BuildContext context) { | |
return Scaffold( | |
appBar: AppBar( | |
title: Text(_cubeDialog.name ?? ''), | |
), | |
body: ChatScreenBody(_cubeUser, _cubeDialog), | |
); | |
} | |
} | |
class ChatScreenBody extends StatefulWidget { | |
final CubeUser currentUser; | |
final CubeDialog cubeDialog; | |
const ChatScreenBody(this.currentUser, this.cubeDialog, {super.key}); | |
@override | |
State createState() => ChatScreenBodyState(); | |
} | |
class ChatScreenBodyState extends State<ChatScreenBody> { | |
final Map<int?, CubeUser?> _occupants = {}; | |
late bool isLoading; | |
List<CubeMessage> listMessage = []; | |
String userStatus = ''; | |
final TextEditingController textEditingController = TextEditingController(); | |
final ScrollController listScrollController = ScrollController(); | |
StreamSubscription<CubeMessage>? msgSubscription; | |
StreamSubscription<MessageStatus>? deliveredSubscription; | |
StreamSubscription<MessageStatus>? readSubscription; | |
@override | |
void initState() { | |
super.initState(); | |
_initCubeChat(); | |
isLoading = false; | |
} | |
@override | |
void dispose() { | |
msgSubscription?.cancel(); | |
deliveredSubscription?.cancel(); | |
readSubscription?.cancel(); | |
textEditingController.dispose(); | |
super.dispose(); | |
} | |
void onReceiveMessage(CubeMessage message) { | |
if (message.dialogId != widget.cubeDialog.dialogId) return; | |
addMessageToListView(message); | |
} | |
void onDeliveredMessage(MessageStatus status) { | |
updateReadDeliveredStatusMessage(status, false); | |
} | |
void onReadMessage(MessageStatus status) { | |
updateReadDeliveredStatusMessage(status, true); | |
} | |
void onSendChatMessage(String content) { | |
if (content.trim() != '') { | |
final message = createCubeMsg(); | |
message.body = content.trim(); | |
onSendMessage(message); | |
} else { | |
print('Nothing to send'); | |
} | |
} | |
CubeMessage createCubeMsg() { | |
var message = CubeMessage(); | |
message.dateSent = DateTime.now().millisecondsSinceEpoch ~/ 1000; | |
message.markable = true; | |
message.saveToHistory = true; | |
return message; | |
} | |
void onSendMessage(CubeMessage message) async { | |
textEditingController.clear(); | |
await widget.cubeDialog.sendMessage(message); | |
message.senderId = widget.currentUser.id; | |
addMessageToListView(message); | |
listScrollController.animateTo(0.0, | |
duration: const Duration(milliseconds: 300), curve: Curves.easeOut); | |
} | |
updateReadDeliveredStatusMessage(MessageStatus status, bool isRead) { | |
setState(() { | |
CubeMessage? msg = listMessage | |
.where((msg) => msg.messageId == status.messageId) | |
.firstOrNull; | |
if (msg == null) return; | |
if (isRead) { | |
msg.readIds == null | |
? msg.readIds = [status.userId] | |
: msg.readIds?.add(status.userId); | |
} else { | |
msg.deliveredIds == null | |
? msg.deliveredIds = [status.userId] | |
: msg.deliveredIds?.add(status.userId); | |
} | |
}); | |
} | |
addMessageToListView(CubeMessage message) { | |
setState(() { | |
isLoading = false; | |
int existMessageIndex = listMessage.indexWhere((cubeMessage) { | |
return cubeMessage.messageId == message.messageId; | |
}); | |
if (existMessageIndex != -1) { | |
listMessage[existMessageIndex] = message; | |
} else { | |
listMessage.insert(0, message); | |
} | |
}); | |
} | |
@override | |
Widget build(BuildContext context) { | |
return SafeArea( | |
child: Stack( | |
children: <Widget>[ | |
Column( | |
children: <Widget>[ | |
buildListMessage(), | |
buildInput(), | |
], | |
), | |
buildLoading(), | |
], | |
), | |
); | |
} | |
Widget buildItem(int index, CubeMessage message) { | |
markAsReadIfNeed() { | |
var isOpponentMsgRead = message.readIds != null && | |
message.readIds!.contains(widget.currentUser.id); | |
if (message.senderId != widget.currentUser.id && !isOpponentMsgRead) { | |
if (message.readIds == null) { | |
message.readIds = [widget.currentUser.id!]; | |
} else { | |
message.readIds!.add(widget.currentUser.id!); | |
} | |
if (CubeChatConnection.instance.chatConnectionState == | |
CubeChatConnectionState.Ready) { | |
widget.cubeDialog.readMessage(message); | |
} | |
} | |
} | |
Widget getReadDeliveredWidget() { | |
bool messageIsRead() { | |
if (widget.cubeDialog.type == CubeDialogType.PRIVATE) { | |
return message.readIds != null && | |
(message.recipientId == null || | |
message.readIds!.contains(message.recipientId)); | |
} | |
return message.readIds != null && | |
message.readIds!.any((int id) => | |
id != widget.currentUser.id && _occupants.keys.contains(id)); | |
} | |
bool messageIsDelivered() { | |
if (widget.cubeDialog.type == CubeDialogType.PRIVATE) { | |
return message.deliveredIds != null && | |
(message.recipientId == null || | |
message.deliveredIds!.contains(message.recipientId)); | |
} | |
return message.deliveredIds != null && | |
message.deliveredIds!.any((int id) => | |
id != widget.currentUser.id && _occupants.keys.contains(id)); | |
} | |
if (messageIsRead()) { | |
return getMessageStateWidget(MessageState.read); | |
} else if (messageIsDelivered()) { | |
return getMessageStateWidget(MessageState.delivered); | |
} else { | |
return getMessageStateWidget(MessageState.sent); | |
} | |
} | |
Widget getDateWidget() { | |
return Text( | |
DateFormat('HH:mm').format( | |
DateTime.fromMillisecondsSinceEpoch(message.dateSent! * 1000)), | |
style: const TextStyle( | |
color: Colors.grey, fontSize: 12.0, fontStyle: FontStyle.italic), | |
); | |
} | |
Widget getMessageBubble(bool isOwnMessage) { | |
if (!isOwnMessage) { | |
markAsReadIfNeed(); | |
} | |
return Column( | |
key: Key('${message.messageId}'), | |
children: <Widget>[ | |
Row( | |
mainAxisAlignment: | |
isOwnMessage ? MainAxisAlignment.end : MainAxisAlignment.start, | |
children: <Widget>[ | |
Flexible( | |
child: Container( | |
constraints: const BoxConstraints(maxWidth: 480), | |
padding: const EdgeInsets.fromLTRB(8.0, 4.0, 8.0, 4.0), | |
decoration: BoxDecoration( | |
color: isOwnMessage | |
? Colors.grey.shade200 | |
: Colors.blueGrey.shade800, | |
borderRadius: BorderRadius.circular(8.0)), | |
margin: EdgeInsets.only( | |
bottom: isOwnMessage ? 20.0 : 10.0, | |
right: isOwnMessage ? 10.0 : 0, | |
left: isOwnMessage ? 0 : 10.0), | |
child: Column( | |
crossAxisAlignment: isOwnMessage | |
? CrossAxisAlignment.end | |
: CrossAxisAlignment.start, | |
children: [ | |
Text( | |
message.body!, | |
style: TextStyle( | |
color: isOwnMessage | |
? Colors.blueGrey.shade800 | |
: Colors.grey.shade200), | |
), | |
Row( | |
mainAxisSize: MainAxisSize.min, | |
children: [ | |
getDateWidget(), | |
if (isOwnMessage) getReadDeliveredWidget(), | |
], | |
), | |
]), | |
), | |
) | |
], | |
), | |
], | |
); | |
} | |
return getMessageBubble(message.senderId == widget.currentUser.id); | |
} | |
Widget buildLoading() { | |
return Positioned( | |
child: isLoading | |
? Container( | |
color: Colors.white.withOpacity(0.8), | |
child: const Center( | |
child: CircularProgressIndicator( | |
valueColor: AlwaysStoppedAnimation<Color>(Colors.green), | |
), | |
)) | |
: const SizedBox.shrink()); | |
} | |
Widget buildInput() { | |
return Container( | |
width: double.infinity, | |
height: 50.0, | |
decoration: BoxDecoration( | |
border: Border( | |
top: BorderSide(color: Colors.blueGrey.shade800, width: 0.5)), | |
color: Colors.white), | |
child: Row( | |
children: <Widget>[ | |
Flexible( | |
child: TextField( | |
autofocus: true, | |
keyboardType: TextInputType.multiline, | |
maxLines: null, | |
style: TextStyle(color: Colors.blueGrey.shade800, fontSize: 15.0), | |
controller: textEditingController, | |
decoration: const InputDecoration.collapsed( | |
hintText: 'Type your message...', | |
hintStyle: TextStyle(color: Colors.grey), | |
), | |
), | |
), | |
// Button send message | |
Material( | |
color: Colors.white, | |
child: Container( | |
margin: const EdgeInsets.only(left: 4, right: 2.0), | |
child: IconButton( | |
icon: const Icon(Icons.send), | |
onPressed: () => onSendChatMessage(textEditingController.text), | |
color: Colors.blueGrey.shade800, | |
), | |
), | |
), | |
], | |
), | |
); | |
} | |
Widget buildListMessage() { | |
getWidgetMessages(listMessage) { | |
return ListView.builder( | |
padding: const EdgeInsets.all(10.0), | |
itemBuilder: (context, index) => buildItem(index, listMessage[index]), | |
itemCount: listMessage.length, | |
reverse: true, | |
controller: listScrollController, | |
); | |
} | |
return Flexible( | |
child: StreamBuilder<List<CubeMessage>>( | |
stream: getMessagesList().asStream(), | |
builder: (context, snapshot) { | |
if (!snapshot.hasData) { | |
return const Center( | |
child: CircularProgressIndicator( | |
valueColor: AlwaysStoppedAnimation<Color>(Colors.green))); | |
} else { | |
listMessage = snapshot.data ?? []; | |
return getWidgetMessages(listMessage); | |
} | |
}, | |
), | |
); | |
} | |
Future<List<CubeMessage>> getMessagesList() { | |
if (listMessage.isNotEmpty) return Future.value(listMessage); | |
var params = GetMessagesParameters(); | |
params.sorter = RequestSorter('desc', '', 'date_sent'); | |
return getMessages( | |
widget.cubeDialog.dialogId!, params.getRequestParameters()) | |
.then((getMessagesResult) { | |
return getAllUsersByIds(widget.cubeDialog.occupantsIds!.toSet()) | |
.then((getUsersResult) { | |
_occupants | |
.addAll({for (var item in getUsersResult!.items) item.id: item}); | |
return getMessagesResult?.items ?? []; | |
}); | |
}); | |
} | |
_initCubeChat() { | |
msgSubscription = CubeChatConnection | |
.instance.chatMessagesManager!.chatMessagesStream | |
.listen(onReceiveMessage); | |
deliveredSubscription = CubeChatConnection | |
.instance.messagesStatusesManager!.deliveredStream | |
.listen(onDeliveredMessage); | |
readSubscription = CubeChatConnection | |
.instance.messagesStatusesManager!.readStream | |
.listen(onReadMessage); | |
} | |
} | |
Widget getMessageStateWidget(MessageState? state) { | |
Widget result; | |
switch (state) { | |
case MessageState.read: | |
result = const Stack(children: <Widget>[ | |
Icon( | |
Icons.check_rounded, | |
size: 15.0, | |
color: Colors.green, | |
), | |
Padding( | |
padding: EdgeInsets.only( | |
left: 4, | |
), | |
child: Icon( | |
Icons.check_rounded, | |
size: 15.0, | |
color: Colors.green, | |
), | |
) | |
]); | |
break; | |
case MessageState.delivered: | |
result = Stack(children: <Widget>[ | |
Icon( | |
Icons.check_rounded, | |
size: 15.0, | |
color: Colors.grey.shade700, | |
), | |
Padding( | |
padding: const EdgeInsets.only(left: 4), | |
child: Icon( | |
Icons.check_rounded, | |
size: 15.0, | |
color: Colors.grey.shade700, | |
), | |
) | |
]); | |
break; | |
case MessageState.sent: | |
result = Icon( | |
Icons.check_rounded, | |
size: 15.0, | |
color: Colors.grey.shade700, | |
); | |
break; | |
default: | |
result = const SizedBox.shrink(); | |
break; | |
} | |
return result; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment