diff --git a/.idea/libraries/Dart_Packages.xml b/.idea/libraries/Dart_Packages.xml index 2781667..84d9cc9 100644 --- a/.idea/libraries/Dart_Packages.xml +++ b/.idea/libraries/Dart_Packages.xml @@ -562,6 +562,13 @@ + + + + + + @@ -1512,6 +1519,7 @@ + diff --git a/lib/model/chatList/chatProps.dart b/lib/model/chatList/chatProps.dart index cdc4073..6a19713 100644 --- a/lib/model/chatList/chatProps.dart +++ b/lib/model/chatList/chatProps.dart @@ -32,4 +32,8 @@ class ChatProps extends DataHolder { run(); } + String currentToken() { + return _queryToken; + } + } \ No newline at end of file diff --git a/lib/view/pages/talk/chatList.dart b/lib/view/pages/talk/chatList.dart index dacee98..7de3d47 100644 --- a/lib/view/pages/talk/chatList.dart +++ b/lib/view/pages/talk/chatList.dart @@ -2,6 +2,7 @@ import 'dart:async'; import 'package:firebase_messaging/firebase_messaging.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_split_view/flutter_split_view.dart'; import 'package:provider/provider.dart'; import '../../../api/marianumcloud/talk/createRoom/createRoom.dart'; @@ -72,68 +73,70 @@ class _ChatListState extends State { Widget build(BuildContext context) { ChatListProps? latestData; - return Scaffold( - appBar: AppBar( - title: const Text("Talk"), - actions: [ - IconButton( - icon: const Icon(Icons.search), - onPressed: () async { - if(latestData == null) return; - showSearch(context: context, delegate: SearchChat(latestData!.getRoomsResponse.data.toList())); - }, - ) - ], - ), - floatingActionButton: FloatingActionButton( - heroTag: "createChat", - backgroundColor: Theme.of(context).primaryColor, - onPressed: () async { - showSearch(context: context, delegate: JoinChat()).then((username) { - if(username == null) return; - - ConfirmDialog( - title: "Chat starten", - content: "Möchtest du einen Chat mit Nutzer '$username' starten?", - confirmButton: "Chat starten", - onConfirm: () { - CreateRoom(CreateRoomParams( - roomType: 1, - invite: username, - )).run().then((value) { - _query(renew: true); - }); + return SplitView.material( + child: Scaffold( + appBar: AppBar( + title: const Text("Talk"), + actions: [ + IconButton( + icon: const Icon(Icons.search), + onPressed: () async { + if(latestData == null) return; + showSearch(context: context, delegate: SearchChat(latestData!.getRoomsResponse.data.toList())); }, - ).asDialog(context); - }); - }, - child: const Icon(Icons.add_comment_outlined), - ), - body: Consumer( - builder: (context, data, child) { + ) + ], + ), + floatingActionButton: FloatingActionButton( + heroTag: "createChat", + backgroundColor: Theme.of(context).primaryColor, + onPressed: () async { + showSearch(context: context, delegate: JoinChat()).then((username) { + if(username == null) return; - if(data.primaryLoading()) return const LoadingSpinner(); - latestData = data; - List chats = []; - for (var chatRoom in data.getRoomsResponse.sortBy( - lastActivity: true, - favoritesToTop: Provider.of(context).val().talkSettings.sortFavoritesToTop, - unreadToTop: Provider.of(context).val().talkSettings.sortUnreadToTop, - ) - ) { - bool hasDraft = settings.val().talkSettings.drafts.containsKey(chatRoom.token); - chats.add(ChatTile(data: chatRoom, query: _query, hasDraft: hasDraft)); - } + ConfirmDialog( + title: "Chat starten", + content: "Möchtest du einen Chat mit Nutzer '$username' starten?", + confirmButton: "Chat starten", + onConfirm: () { + CreateRoom(CreateRoomParams( + roomType: 1, + invite: username, + )).run().then((value) { + _query(renew: true); + }); + }, + ).asDialog(context); + }); + }, + child: const Icon(Icons.add_comment_outlined), + ), + body: Consumer( + builder: (context, data, child) { - return RefreshIndicator( - color: Theme.of(context).primaryColor, - onRefresh: () { - _query(renew: true); - return Future.delayed(const Duration(seconds: 3)); - }, - child: ListView(children: chats), - ); - }, + if(data.primaryLoading()) return const LoadingSpinner(); + latestData = data; + List chats = []; + for (var chatRoom in data.getRoomsResponse.sortBy( + lastActivity: true, + favoritesToTop: Provider.of(context).val().talkSettings.sortFavoritesToTop, + unreadToTop: Provider.of(context).val().talkSettings.sortUnreadToTop, + ) + ) { + bool hasDraft = settings.val().talkSettings.drafts.containsKey(chatRoom.token); + chats.add(ChatTile(data: chatRoom, query: _query, hasDraft: hasDraft)); + } + + return RefreshIndicator( + color: Theme.of(context).primaryColor, + onRefresh: () { + _query(renew: true); + return Future.delayed(const Duration(seconds: 3)); + }, + child: ListView(children: chats), + ); + }, + ), ), ); } diff --git a/lib/view/pages/talk/chatTile.dart b/lib/view/pages/talk/chatTile.dart index cb219a9..9d71294 100644 --- a/lib/view/pages/talk/chatTile.dart +++ b/lib/view/pages/talk/chatTile.dart @@ -1,7 +1,9 @@ + import 'package:flutter/material.dart'; +import 'package:flutter_split_view/flutter_split_view.dart'; import 'package:jiffy/jiffy.dart'; import 'package:marianum_mobile/widget/userAvatar.dart'; -import 'package:persistent_bottom_nav_bar/persistent_tab_view.dart'; +import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../../../api/marianumcloud/talk/chat/richObjectStringProcessor.dart'; @@ -10,6 +12,7 @@ import '../../../api/marianumcloud/talk/room/getRoomResponse.dart'; import '../../../api/marianumcloud/talk/setFavorite/setFavorite.dart'; import '../../../api/marianumcloud/talk/setReadMarker/setReadMarker.dart'; import '../../../api/marianumcloud/talk/setReadMarker/setReadMarkerParams.dart'; +import '../../../model/chatList/chatProps.dart'; import '../../../widget/confirmDialog.dart'; import '../../../widget/debug/debugTile.dart'; import 'chatView.dart'; @@ -52,134 +55,139 @@ class _ChatTileState extends State { bool isGroup = widget.data.type == GetRoomResponseObjectConversationType.oneToOne; UserAvatar circleAvatar = UserAvatar(username: widget.data.name, isGroup: isGroup); - return ListTile( - leading: Stack( - children: [ - circleAvatar, - Visibility( - visible: widget.data.isFavorite, - child: Positioned( - right: 0, - bottom: 0, - child: Container( - padding: const EdgeInsets.all(1), - decoration: BoxDecoration( - color: Theme.of(context).primaryColor.withAlpha(200), - borderRadius: BorderRadius.circular(90.0), - ), - child: const Icon(Icons.star, color: Colors.amberAccent, size: 15), - ), - ), - ) - ], - ), - title: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Text(widget.data.displayName), - if(widget.hasDraft) ...[ - const SizedBox(width: 5), - const Icon(Icons.edit_outlined, size: 15), - ], - ], - ), - subtitle: Text("${Jiffy.parseFromMillisecondsSinceEpoch(widget.data.lastMessage.timestamp * 1000).fromNow()}: ${RichObjectStringProcessor.parseToString(widget.data.lastMessage.message.replaceAll("\n", " "), widget.data.lastMessage.messageParameters)}", overflow: TextOverflow.ellipsis), - trailing: Row( - mainAxisSize: MainAxisSize.min, - children: [ - Visibility( - visible: widget.data.unreadMessages > 0, - child: Container( - padding: const EdgeInsets.all(1), - decoration: BoxDecoration( - color: Theme.of(context).primaryColor, - borderRadius: BorderRadius.circular(30), - ), - constraints: const BoxConstraints( - minWidth: 20, - minHeight: 20, - ), - child: Text( - "${widget.data.unreadMessages}", - style: const TextStyle( - color: Colors.white, - fontSize: 15, - ), - textAlign: TextAlign.center, - ), - ), - ), - ], - ), - onTap: () async { - setCurrentAsRead(); - PersistentNavBarNavigator.pushNewScreen( - context, - screen: ChatView(room: widget.data, selfId: username, avatar: circleAvatar), - withNavBar: false - ); - }, - onLongPress: () { - if(widget.disableContextActions) return; - showDialog(context: context, builder: (context) => SimpleDialog( + return Consumer(builder: (context, chatData, child) { + return ListTile( + style: ListTileStyle.list, + tileColor: chatData.currentToken() == widget.data.token + ? Theme.of(context).primaryColor.withAlpha(100) + : null, + leading: Stack( children: [ - Visibility( - visible: widget.data.unreadMessages > 0, - replacement: ListTile( - leading: const Icon(Icons.mark_chat_unread_outlined), - title: const Text("Als ungelesen markieren"), - onTap: () { - SetReadMarker(widget.data.token, false).run().then((value) => widget.query(renew: true)); - Navigator.of(context).pop(); - }, - ), - child: ListTile( - leading: const Icon(Icons.mark_chat_read_outlined), - title: const Text("Als gelesen markieren"), - onTap: () { - setCurrentAsRead(); - Navigator.of(context).pop(); - }, - ), - ), + circleAvatar, Visibility( visible: widget.data.isFavorite, - replacement: ListTile( - leading: const Icon(Icons.star_outline), - title: const Text("Zu Favoriten hinzufügen"), - onTap: () { - SetFavorite(widget.data.token, true).run().then((value) => widget.query(renew: true)); - Navigator.of(context).pop(); - }, - ), - child: ListTile( - leading: const Icon(Icons.stars_outlined), - title: const Text("Von Favoriten entfernen"), - onTap: () { - SetFavorite(widget.data.token, false).run().then((value) => widget.query(renew: true)); - Navigator.of(context).pop(); - }, + child: Positioned( + right: 0, + bottom: 0, + child: Container( + padding: const EdgeInsets.all(1), + decoration: BoxDecoration( + color: Theme.of(context).primaryColor.withAlpha(200), + borderRadius: BorderRadius.circular(90.0), + ), + child: const Icon(Icons.star, color: Colors.amberAccent, size: 15), + ), ), + ) + ], + ), + title: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Flexible( + child: Text(widget.data.displayName, overflow: TextOverflow.ellipsis), ), - ListTile( - leading: const Icon(Icons.delete_outline), - title: const Text("Konversation verlassen"), - onTap: () { - ConfirmDialog( - title: "Chat verlassen", - content: "Du benötigst ggf. eine Einladung um erneut beizutreten.", - confirmButton: "Löschen", - onConfirm: () { - LeaveRoom(widget.data.token).run().then((value) => widget.query(renew: true)); + if(widget.hasDraft) ...[ + const SizedBox(width: 5), + const Icon(Icons.edit_outlined, size: 15), + ], + ], + ), + subtitle: Text("${Jiffy.parseFromMillisecondsSinceEpoch(widget.data.lastMessage.timestamp * 1000).fromNow()}: ${RichObjectStringProcessor.parseToString(widget.data.lastMessage.message.replaceAll("\n", " "), widget.data.lastMessage.messageParameters)}", overflow: TextOverflow.ellipsis), + trailing: widget.data.unreadMessages <= 0 + ? null + : Container( + padding: const EdgeInsets.all(1), + decoration: BoxDecoration( + color: Theme.of(context).primaryColor, + borderRadius: BorderRadius.circular(30), + ), + constraints: const BoxConstraints( + minWidth: 20, + minHeight: 20, + ), + child: Text( + "${widget.data.unreadMessages}", + style: const TextStyle( + color: Colors.white, + fontSize: 15, + ), + textAlign: TextAlign.center, + ), + ), + onTap: () async { + setCurrentAsRead(); + SplitView.of(context).setSecondary(ChatView(room: widget.data, selfId: username, avatar: circleAvatar)); + Provider.of(context, listen: false).setQueryToken(widget.data.token); + + // PersistentNavBarNavigator.pushNewScreen( + // context, + // screen: ChatView(room: widget.data, selfId: username, avatar: circleAvatar), + // withNavBar: false + // ); + }, + onLongPress: () { + if(widget.disableContextActions) return; + showDialog(context: context, builder: (context) => SimpleDialog( + children: [ + Visibility( + visible: widget.data.unreadMessages > 0, + replacement: ListTile( + leading: const Icon(Icons.mark_chat_unread_outlined), + title: const Text("Als ungelesen markieren"), + onTap: () { + SetReadMarker(widget.data.token, false).run().then((value) => widget.query(renew: true)); Navigator.of(context).pop(); }, - ).asDialog(context); - }, - ), - DebugTile(context).jsonData(widget.data.toJson()), - ], - )); - }, - ); + ), + child: ListTile( + leading: const Icon(Icons.mark_chat_read_outlined), + title: const Text("Als gelesen markieren"), + onTap: () { + setCurrentAsRead(); + Navigator.of(context).pop(); + }, + ), + ), + Visibility( + visible: widget.data.isFavorite, + replacement: ListTile( + leading: const Icon(Icons.star_outline), + title: const Text("Zu Favoriten hinzufügen"), + onTap: () { + SetFavorite(widget.data.token, true).run().then((value) => widget.query(renew: true)); + Navigator.of(context).pop(); + }, + ), + child: ListTile( + leading: const Icon(Icons.stars_outlined), + title: const Text("Von Favoriten entfernen"), + onTap: () { + SetFavorite(widget.data.token, false).run().then((value) => widget.query(renew: true)); + Navigator.of(context).pop(); + }, + ), + ), + ListTile( + leading: const Icon(Icons.delete_outline), + title: const Text("Konversation verlassen"), + onTap: () { + ConfirmDialog( + title: "Chat verlassen", + content: "Du benötigst ggf. eine Einladung um erneut beizutreten.", + confirmButton: "Löschen", + onConfirm: () { + LeaveRoom(widget.data.token).run().then((value) => widget.query(renew: true)); + Navigator.of(context).pop(); + }, + ).asDialog(context); + }, + ), + DebugTile(context).jsonData(widget.data.toJson()), + ], + )); + }, + ); + }); } } diff --git a/lib/view/pages/talk/chatView.dart b/lib/view/pages/talk/chatView.dart index 9acf6d7..f11b86a 100644 --- a/lib/view/pages/talk/chatView.dart +++ b/lib/view/pages/talk/chatView.dart @@ -1,4 +1,6 @@ +import 'dart:developer'; + import 'package:flutter/material.dart'; import 'package:loader_overlay/loader_overlay.dart'; import 'package:provider/provider.dart'; @@ -30,7 +32,7 @@ class _ChatViewState extends State { @override void initState() { super.initState(); - + log("init state for ${widget.room.name}"); WidgetsBinding.instance.addPostFrameCallback((timeStamp) { _query(); }); diff --git a/pubspec.yaml b/pubspec.yaml index 5af5935..02e24e0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -88,6 +88,7 @@ dependencies: fluttertoast: ^8.2.2 fast_rsa: ^3.6.1 share_plus: ^7.1.0 + flutter_split_view: ^0.1.2 dev_dependencies: flutter_test: