diff --git a/lib/screen/pages/files/fileElement.dart b/lib/screen/pages/files/fileElement.dart index 8cd50ad..681b411 100644 --- a/lib/screen/pages/files/fileElement.dart +++ b/lib/screen/pages/files/fileElement.dart @@ -18,7 +18,7 @@ class FileElement extends StatefulWidget { final List path; const FileElement(this.file, this.path, {Key? key}) : super(key: key); - static void download(String remotePath, String name, Function(double) onProgress, Function(OpenResult) onDone) async { + static Future download(String remotePath, String name, Function(double) onProgress, Function(OpenResult) onDone) async { Directory paths = await getApplicationDocumentsDirectory(); String local = paths.path + Platform.pathSeparator + name; @@ -40,7 +40,7 @@ class FileElement extends StatefulWidget { }, ); - await Flowder.download( + return await Flowder.download( "${await WebdavApi.webdavConnectString}$remotePath", options, ); diff --git a/lib/screen/pages/talk/chatBubble.dart b/lib/screen/pages/talk/chatBubble.dart index e170b11..35a7736 100644 --- a/lib/screen/pages/talk/chatBubble.dart +++ b/lib/screen/pages/talk/chatBubble.dart @@ -1,16 +1,35 @@ import 'package:better_open_file/better_open_file.dart'; import 'package:bubble/bubble.dart'; +import 'package:flowder/flowder.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:jiffy/jiffy.dart'; -import 'package:marianum_mobile/api/marianumcloud/talk/chat/getChatResponse.dart'; -import 'package:marianum_mobile/screen/pages/files/fileElement.dart'; -import 'package:marianum_mobile/screen/pages/talk/chatMessage.dart'; +import '../../../api/marianumcloud/talk/chat/getChatResponse.dart'; import '../../../api/marianumcloud/talk/room/getRoomResponse.dart'; import '../../settings/debug/jsonViewer.dart'; +import '../files/fileElement.dart'; +import 'chatMessage.dart'; -class ChatBubble { +class ChatBubble extends StatefulWidget { + BuildContext context; + bool isSender; + GetChatResponseObject bubbleData; + GetRoomResponseObject chatData; + + ChatBubble({ + required this.context, + required this.isSender, + required this.bubbleData, + required this.chatData, + Key? key}) : super(key: key); + + @override + State createState() => _ChatBubbleState(); +} + +class _ChatBubbleState extends State { static const styleSystem = BubbleStyle( color: Color(0xffd4eaf4), borderWidth: 1, @@ -41,25 +60,22 @@ class ChatBubble { ); } - BuildContext context; - bool isSender; - GetChatResponseObject bubbleData; - GetRoomResponseObject chatData; - double downloadProgress = 0; late ChatMessage message; + double downloadProgress = 0; + Future? downloadCore; - ChatBubble({ - required this.context, - required this.isSender, - required this.bubbleData, - required this.chatData, - }) { - message = ChatMessage(originalMessage: bubbleData.message, originalData: bubbleData.messageParameters); + Size _textSize(String text, TextStyle style) { + final TextPainter textPainter = TextPainter( + text: TextSpan(text: text, style: style), + maxLines: 1, + textDirection: TextDirection.ltr) + ..layout(minWidth: 0, maxWidth: double.infinity); + return textPainter.size; } BubbleStyle getStyle() { - if(bubbleData.messageType == GetRoomResponseObjectMessageType.comment) { - if(isSender) { + if(widget.bubbleData.messageType == GetRoomResponseObjectMessageType.comment) { + if(widget.isSender) { return getStyleSelf(message.containsFile); } else { return getStyleOther(message.containsFile); @@ -69,9 +85,12 @@ class ChatBubble { } } - Widget generateBubble() { - bool showActorDisplayName = bubbleData.messageType == GetRoomResponseObjectMessageType.comment && chatData.type != GetRoomResponseObjectConversationType.oneToOne; - bool showBubbleTime = bubbleData.messageType != GetRoomResponseObjectMessageType.system; + + @override + Widget build(BuildContext context) { + message = ChatMessage(originalMessage: widget.bubbleData.message, originalData: widget.bubbleData.messageParameters); + bool showActorDisplayName = widget.bubbleData.messageType == GetRoomResponseObjectMessageType.comment && widget.chatData.type != GetRoomResponseObjectConversationType.oneToOne; + bool showBubbleTime = widget.bubbleData.messageType != GetRoomResponseObjectMessageType.system; var actorTextStyle = TextStyle(color: Theme.of(context).primaryColor, fontWeight: FontWeight.bold); return GestureDetector( @@ -81,7 +100,7 @@ class ChatBubble { child: Container( constraints: BoxConstraints( maxWidth: MediaQuery.of(context).size.width * 0.9, - minWidth: showActorDisplayName ? _textSize(bubbleData.actorDisplayName, actorTextStyle).width : 30, + minWidth: showActorDisplayName ? _textSize(widget.bubbleData.actorDisplayName, actorTextStyle).width : 30, ), child: Stack( children: [ @@ -101,7 +120,7 @@ class ChatBubble { top: 0, left: 0, child: Text( - bubbleData.actorDisplayName, + widget.bubbleData.actorDisplayName, textAlign: TextAlign.start, style: actorTextStyle, ), @@ -112,19 +131,21 @@ class ChatBubble { child: Positioned( bottom: 0, right: 0, - child: Row( - children: [ - Visibility( - visible: downloadProgress > 0, - child: LinearProgressIndicator(value: downloadProgress), - ), - Text( - Jiffy.unixFromSecondsSinceEpoch(bubbleData.timestamp).format("HH:mm"), - textAlign: TextAlign.end, - style: const TextStyle(color: Colors.grey, fontSize: 12), - ), - ], - ) + child: Text( + Jiffy.unixFromSecondsSinceEpoch(widget.bubbleData.timestamp).format("HH:mm"), + textAlign: TextAlign.end, + style: const TextStyle(color: Colors.grey, fontSize: 12), + ), + ), + ), + Visibility( + visible: downloadProgress > 0, + child: Positioned( + top: 0, + left: 0, + right: 0, + bottom: 0, + child: Center(child: CircularProgressIndicator(value: downloadProgress/100)), ), ), ], @@ -136,28 +157,28 @@ class ChatBubble { return SimpleDialog( children: [ Visibility( - visible: !message.containsFile && bubbleData.messageType == GetRoomResponseObjectMessageType.comment, + visible: !message.containsFile && widget.bubbleData.messageType == GetRoomResponseObjectMessageType.comment, child: ListTile( leading: const Icon(Icons.copy), title: const Text("Nachricht kopieren"), onTap: () => { - Clipboard.setData(ClipboardData(text: bubbleData.message)), + Clipboard.setData(ClipboardData(text: widget.bubbleData.message)), Navigator.of(context).pop(), }, ), ), Visibility( - visible: !isSender && chatData.type != GetRoomResponseObjectConversationType.oneToOne, + visible: !widget.isSender && widget.chatData.type != GetRoomResponseObjectConversationType.oneToOne, child: ListTile( leading: const Icon(Icons.person), - title: Text("Private Nachricht an '${bubbleData.actorDisplayName}'"), + title: Text("Private Nachricht an '${widget.bubbleData.actorDisplayName}'"), onTap: () => {}, ), ), ListTile( leading: const Icon(Icons.bug_report_outlined), title: const Text("Debugdaten anzeigen"), - onTap: () => JsonViewer.asDialog(context, bubbleData.toJson()), + onTap: () => JsonViewer.asDialog(context, widget.bubbleData.toJson()), ) ], ); @@ -166,29 +187,53 @@ class ChatBubble { onTap: () { if(message.file == null) return; - FileElement.download(message.file!.path!, message.file!.name, (progress) => { - downloadProgress = progress, - }, (result) => { - downloadProgress = 0, + if(downloadProgress > 0) { + showDialog(context: context, builder: (context) { + return AlertDialog( + title: const Text("Download abbrechen?"), + content: const Text("Möchtest du den Download abbrechen?"), + actions: [ + TextButton(onPressed: () { + Navigator.of(context).pop(); + }, child: const Text("Nein")), + TextButton(onPressed: () { + downloadCore?.then((value) { + if(!value.isCancelled) value.cancel(); + setState(() { + downloadProgress = 0; + downloadCore = null; + }); + Navigator.of(context).pop(); + }); + }, child: const Text("Ja, Abbrechen")) + ], + ); + }); + + return; + } + + downloadProgress = 1; + downloadCore = FileElement.download(message.file!.path!, message.file!.name, (progress) { + if(progress > 1) { + setState(() { + downloadProgress = progress; + }); + } + }, (result) { + setState(() { + downloadProgress = 0; + }); + if(result.type != ResultType.done) { showDialog(context: context, builder: (context) { return AlertDialog( content: Text(result.message), ); - }) + }); } }); - }, ); } - - Size _textSize(String text, TextStyle style) { - final TextPainter textPainter = TextPainter( - text: TextSpan(text: text, style: style), - maxLines: 1, - textDirection: TextDirection.ltr) - ..layout(minWidth: 0, maxWidth: double.infinity); - return textPainter.size; - } -} \ No newline at end of file +} diff --git a/lib/screen/pages/talk/chatView.dart b/lib/screen/pages/talk/chatView.dart index b4203fc..89066b7 100644 --- a/lib/screen/pages/talk/chatView.dart +++ b/lib/screen/pages/talk/chatView.dart @@ -64,9 +64,9 @@ class _ChatViewState extends State { null ), chatData: widget.room - ).generateBubble()); + )); } - messages.add(ChatBubble(context: context, isSender: element.actorId == widget.selfId, bubbleData: element, chatData: widget.room).generateBubble()); + messages.add(ChatBubble(context: context, isSender: element.actorId == widget.selfId, bubbleData: element, chatData: widget.room)); }); }