diff --git a/lib/view/pages/talk/chatTile.dart b/lib/view/pages/talk/chatTile.dart new file mode 100644 index 0000000..02f4a49 --- /dev/null +++ b/lib/view/pages/talk/chatTile.dart @@ -0,0 +1,190 @@ +import 'package:flutter/material.dart'; +import 'package:jiffy/jiffy.dart'; +import 'package:persistent_bottom_nav_bar/persistent_tab_view.dart'; +import 'package:shared_preferences/shared_preferences.dart'; + +import '../../../api/marianumcloud/talk/chat/richObjectStringProcessor.dart'; +import '../../../api/marianumcloud/talk/leaveRoom/leaveRoom.dart'; +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 '../../../widget/confirmDialog.dart'; +import 'chatView.dart'; + +class ChatTile { + ListTile getTile(GetRoomResponseObject data, void Function({bool renew}) query) async { + CircleAvatar circleAvatar = CircleAvatar( + foregroundImage: widget.data.type == GetRoomResponseObjectConversationType.oneToOne ? Image.network("https://cloud.marianum-fulda.de/avatar/${widget.data.name}/128").image : null, + backgroundColor: Theme.of(context).primaryColor, + foregroundColor: Colors.white, + child: widget.data.type == GetRoomResponseObjectConversationType.group ? const Icon(Icons.group) : const Icon(Icons.person), + ); + + String username = (await SharedPreferences.getInstance()).getString("username")!; + void setCurrentAsRead() { + SetReadMarker( + data.token, + true, + setReadMarkerParams: SetReadMarkerParams( + lastReadMessage: data.lastMessage.id + ) + ).run().then((value) => query(renew: true)); + } + return ListTile( + leading: Stack( + children: [ + circleAvatar, + Visibility( + visible: 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: Text(data.displayName), + subtitle: Text("${Jiffy.parseFromMillisecondsSinceEpoch(data.lastMessage.timestamp * 1000).fromNow()}: ${RichObjectStringProcessor.parseToString(data.lastMessage.message.replaceAll("\n", " "), data.lastMessage.messageParameters)}", overflow: TextOverflow.ellipsis), + trailing: Row( + mainAxisSize: MainAxisSize.min, + children: [ + Visibility( + visible: 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( + "${data.unreadMessages}", + style: const TextStyle( + color: Colors.white, + fontSize: 15, + ), + textAlign: TextAlign.center, + ), + ), + ), + ], + ), + onTap: () async { + setCurrentAsRead(); + PersistentNavBarNavigator.pushNewScreen( + context, + screen: ChatView(room: data, selfId: username, avatar: circleAvatar), + withNavBar: false + ); + }, + onLongPress: () { + showDialog(context: context, builder: (context) => SimpleDialog( + children: [ + Visibility( + visible: data.unreadMessages > 0, + replacement: ListTile( + leading: const Icon(Icons.mark_chat_unread_outlined), + title: const Text("Als ungelesen markieren"), + onTap: () { + SetReadMarker(data.token, false).run().then((value) => 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(); + }, + ), + ), + Visibility( + visible: data.isFavorite, + replacement: ListTile( + leading: const Icon(Icons.star_outline), + title: const Text("Zu favoriten hinzufügen"), + onTap: () { + SetFavorite(data.token, true).run().then((value) => query(renew: true)); + Navigator.of(context).pop(); + }, + ), + child: ListTile( + leading: const Icon(Icons.stars_outlined), + title: const Text("Von favoriten entfernen"), + onTap: () { + SetFavorite(data.token, false).run().then((value) => 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(data.token).run().then((value) => query(renew: true)); + Navigator.of(context).pop(); + }, + ).asDialog(context); + }, + ), + ], + )); + }, + ); + } +} + +class ChatTile extends StatefulWidget { + final GetRoomResponseObject data; + final void Function({bool renew}) query; + + const ChatTile({Key? key, required this.data, required this.query}) : super(key: key); + + @override + State<ChatTile> createState() => _ChatTileState(); +} + +class _ChatTileState extends State<ChatTile> { + + late CircleAvatar circleAvatar; + late String username; + + @override + void initState() { + SharedPreferences.getInstance().then((value) => { + username = value.getString("username")! + }); + + circleAvatar = CircleAvatar( + foregroundImage: data.type == GetRoomResponseObjectConversationType.oneToOne ? Image.network("https://cloud.marianum-fulda.de/avatar/${data.name}/128").image : null, + backgroundColor: Theme.of(context).primaryColor, + foregroundColor: Colors.white, + child: data.type == GetRoomResponseObjectConversationType.group ? const Icon(Icons.group) : const Icon(Icons.person), + ); + } + + + + @override + Widget build(BuildContext context) { + + } +} diff --git a/lib/view/pages/talk/searchChat.dart b/lib/view/pages/talk/searchChat.dart new file mode 100644 index 0000000..7579b08 --- /dev/null +++ b/lib/view/pages/talk/searchChat.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; +import 'package:marianum_mobile/view/pages/talk/chatTile.dart'; + +import '../../../api/marianumcloud/talk/room/getRoomResponse.dart'; + +class SearchChat extends SearchDelegate { + List<GetRoomResponseObject> chats; + + SearchChat(this.chats); + + @override + List<Widget>? buildActions(BuildContext context) { + return [ + if(query.isNotEmpty) IconButton(onPressed: () => query = "", icon: const Icon(Icons.delete)), + ]; + } + + @override + Widget? buildLeading(BuildContext context) { + return null; + } + + @override + Widget buildResults(BuildContext context) { + var items = chats.where( + (e) => e.displayName.toString().toLowerCase().contains(query.toLowerCase()) || e.name.toString().toLowerCase().contains(query.toLowerCase()) + ).toList()..sort((a, b) => b.lastActivity.compareTo(a.lastActivity)); + return ListView.builder( + itemCount: items.length, + itemBuilder: (context, index) { + var item = items.elementAt(index); + return ChatTile(data: item, query: ({bool renew = true}) {}); + }, + ); + } + + @override + Widget buildSuggestions(BuildContext context) { + return buildResults(context); + } +} \ No newline at end of file