From 08a2d95882f936c71ae0a05440788e0f3f3259cb Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Elias=20M=C3=BCller?= <elias@elias-mueller.com>
Date: Sat, 25 Feb 2023 14:11:46 +0100
Subject: [PATCH] Further restructuring of chatBubble.dart, added
 chatMessage.dart

---
 .../talk/chat/richObjectStringProcessor.dart  | 33 +-----------
 lib/screen/pages/talk/chatBubble.dart         | 32 ++++++------
 lib/screen/pages/talk/chatList.dart           |  2 +-
 lib/screen/pages/talk/chatMessage.dart        | 50 +++++++++++++++++++
 4 files changed, 67 insertions(+), 50 deletions(-)
 create mode 100644 lib/screen/pages/talk/chatMessage.dart

diff --git a/lib/api/marianumcloud/talk/chat/richObjectStringProcessor.dart b/lib/api/marianumcloud/talk/chat/richObjectStringProcessor.dart
index 91b2c07..0ae3834 100644
--- a/lib/api/marianumcloud/talk/chat/richObjectStringProcessor.dart
+++ b/lib/api/marianumcloud/talk/chat/richObjectStringProcessor.dart
@@ -1,12 +1,8 @@
-import 'dart:convert';
 
-import 'package:cached_network_image/cached_network_image.dart';
-import 'package:flutter/material.dart';
 import 'package:marianum_mobile/api/marianumcloud/talk/chat/getChatResponse.dart';
-import 'package:shared_preferences/shared_preferences.dart';
 
 class RichObjectStringProcessor {
-  static String parseTextPreview(String message, Map<String, RichObjectString>? data) {
+  static String parseToString(String message, Map<String, RichObjectString>? data) {
     if(data == null) return message;
 
     data.forEach((key, value) {
@@ -15,31 +11,4 @@ class RichObjectStringProcessor {
 
     return message;
   }
-
-  static Future<Widget> parseAnyToWidget(String message, Map<String, RichObjectString>? data) async {
-    if(data == null) return SelectableText(message);
-    if(!message.contains(RegExp("{file}"))) return Text(parseTextPreview(message, data));
-
-    SharedPreferences preferences = await SharedPreferences.getInstance();
-
-    Widget? back;
-    data.forEach((key, value) {
-      back = CachedNetworkImage(
-        errorWidget: (context, url, error) {
-          return Text("Datei: ${value.name}", style: const TextStyle(fontWeight: FontWeight.bold));
-        },
-        alignment: Alignment.center,
-        placeholder: (context, url) {
-          return const Padding(padding: EdgeInsets.all(10), child: CircularProgressIndicator());
-        },
-        fadeInDuration: const Duration(seconds: 1),
-        imageUrl: "https://cloud.marianum-fulda.de/core/preview?fileId=${value.id}&x=100&y=-1&a=1",
-        httpHeaders: {
-          "Authorization": "Basic ${base64.encode(utf8.encode("${preferences.getString("username")}:${preferences.getString("password")}"))}"
-        },
-      );
-    });
-
-    return back ?? Text("NOPE");
-  }
 }
\ No newline at end of file
diff --git a/lib/screen/pages/talk/chatBubble.dart b/lib/screen/pages/talk/chatBubble.dart
index 07ca981..aeba646 100644
--- a/lib/screen/pages/talk/chatBubble.dart
+++ b/lib/screen/pages/talk/chatBubble.dart
@@ -2,8 +2,8 @@ import 'package:bubble/bubble.dart';
 import 'package:flutter/material.dart';
 import 'package:jiffy/jiffy.dart';
 import 'package:marianum_mobile/api/marianumcloud/talk/chat/getChatResponse.dart';
+import 'package:marianum_mobile/screen/pages/talk/chatMessage.dart';
 
-import '../../../api/marianumcloud/talk/chat/richObjectStringProcessor.dart';
 import '../../../api/marianumcloud/talk/room/getRoomResponse.dart';
 
 class ChatBubble {
@@ -11,7 +11,7 @@ class ChatBubble {
     color: Color(0xffd4eaf4),
     borderWidth: 1,
     elevation: 2,
-    margin: BubbleEdges.only(top: 15),
+    margin: BubbleEdges.only(bottom: 15),
     alignment: Alignment.center,
   );
 
@@ -21,7 +21,7 @@ class ChatBubble {
       color: seamless ? Colors.transparent : Colors.white,
       borderWidth: seamless ? 0 : 1,
       elevation: seamless ? 0 : 1,
-      margin: const BubbleEdges.only(top: 15, left: 10, right: 50),
+      margin: const BubbleEdges.only(bottom: 15, left: 10, right: 50),
       alignment: Alignment.topLeft,
     );
   }
@@ -32,7 +32,7 @@ class ChatBubble {
       color: seamless ? Colors.transparent : const Color(0xffd9fdd3),
       borderWidth: seamless ? 0 : 1,
       elevation: seamless ? 0 : 1,
-      margin: const BubbleEdges.only(top: 15, right: 10, left: 50),
+      margin: const BubbleEdges.only(bottom: 15, right: 10, left: 50),
       alignment: Alignment.topRight,
     );
   }
@@ -41,50 +41,48 @@ class ChatBubble {
   bool isSender;
   GetChatResponseObject bubbleData;
   GetRoomResponseObject chatData;
+  late ChatMessage message;
 
   ChatBubble({
     required this.context,
     required this.isSender, 
     required this.bubbleData,
     required this.chatData,
-  });
+  }) {
+    message = ChatMessage(originalMessage: bubbleData.message, originalData: bubbleData.messageParameters);
+  }
 
   BubbleStyle getStyle() {
-    BubbleStyle currentStyle;
     if(bubbleData.messageType == GetRoomResponseObjectMessageType.comment) {
       if(isSender) {
-        currentStyle = getStyleSelf(bubbleData.messageParameters?.containsKey("file") ?? false);
+        return getStyleSelf(message.containsFile);
       } else {
-        currentStyle = getStyleOther(bubbleData.messageParameters?.containsKey("file") ?? false);
+        return getStyleOther(message.containsFile);
       }
     } else {
-      currentStyle = styleSystem;
+      return styleSystem;
     }
-
-    return currentStyle;
   }
 
   Bubble generateBubble() {
-
     bool showActorDisplayName = bubbleData.messageType == GetRoomResponseObjectMessageType.comment && chatData.type != GetRoomResponseObjectConversationType.oneToOne;
     bool showBubbleTime = bubbleData.messageType != GetRoomResponseObjectMessageType.system;
-    var _actorTextStyle = TextStyle(color: Theme.of(context).primaryColor, fontWeight: FontWeight.bold);
+    var actorTextStyle = TextStyle(color: Theme.of(context).primaryColor, fontWeight: FontWeight.bold);
 
     return Bubble(
-      margin: BubbleEdges.only(/*bottom: element == data.getChatResponse.sortByTimestamp().last ? 20 : 0*/),
 
       style: getStyle(),
       child: Container(
         constraints: BoxConstraints(
           maxWidth: MediaQuery.of(context).size.width * 0.9,
-          minWidth: showActorDisplayName ? _textSize(bubbleData.actorDisplayName, _actorTextStyle).width : 30,
+          minWidth: showActorDisplayName ? _textSize(bubbleData.actorDisplayName, actorTextStyle).width : 30,
         ),
         child: Stack(
           children: [
             Padding(
                 padding: EdgeInsets.only(bottom: showBubbleTime ? 18 : 0, top: showActorDisplayName ? 18 : 0),
                 child: FutureBuilder(
-                  future: RichObjectStringProcessor.parseAnyToWidget(bubbleData.message, bubbleData.messageParameters),
+                  future: message.getWidget(),
                   builder: (context, snapshot) {
                     if(!snapshot.hasData) return const CircularProgressIndicator();
                     return snapshot.data ?? const Icon(Icons.error);
@@ -99,7 +97,7 @@ class ChatBubble {
                 child: Text(
                   bubbleData.actorDisplayName,
                   textAlign: TextAlign.start,
-                  style: _actorTextStyle,
+                  style: actorTextStyle,
                 ),
               ),
             ),
diff --git a/lib/screen/pages/talk/chatList.dart b/lib/screen/pages/talk/chatList.dart
index d5d2d71..5f2cded 100644
--- a/lib/screen/pages/talk/chatList.dart
+++ b/lib/screen/pages/talk/chatList.dart
@@ -56,7 +56,7 @@ class _ChatListState extends State<ChatList> {
 
           chats.add(ListTile(
             title: Text(chatRoom.displayName),
-            subtitle: Text("${Jiffy.unixFromSecondsSinceEpoch(chatRoom.lastMessage.timestamp).fromNow()}: ${RichObjectStringProcessor.parseTextPreview(chatRoom.lastMessage.message.replaceAll("\n", " "), chatRoom.lastMessage.messageParameters)}", overflow: TextOverflow.ellipsis),
+            subtitle: Text("${Jiffy.unixFromSecondsSinceEpoch(chatRoom.lastMessage.timestamp).fromNow()}: ${RichObjectStringProcessor.parseToString(chatRoom.lastMessage.message.replaceAll("\n", " "), chatRoom.lastMessage.messageParameters)}", overflow: TextOverflow.ellipsis),
             trailing: Visibility(
               visible: chatRoom.unreadMessages > 0,
               child: Container(
diff --git a/lib/screen/pages/talk/chatMessage.dart b/lib/screen/pages/talk/chatMessage.dart
new file mode 100644
index 0000000..c75dc4a
--- /dev/null
+++ b/lib/screen/pages/talk/chatMessage.dart
@@ -0,0 +1,50 @@
+import 'dart:convert';
+
+import 'package:cached_network_image/cached_network_image.dart';
+import 'package:flutter/material.dart';
+import 'package:marianum_mobile/api/marianumcloud/talk/chat/richObjectStringProcessor.dart';
+import 'package:shared_preferences/shared_preferences.dart';
+
+import '../../../api/marianumcloud/talk/chat/getChatResponse.dart';
+
+class ChatMessage {
+  String originalMessage;
+  Map<String, RichObjectString>? originalData;
+
+  RichObjectString? file;
+  String content = "";
+
+  bool get containsFile => file != null;
+
+  ChatMessage({required this.originalMessage, this.originalData}) {
+    if(originalData?.containsKey("file") ?? false) {
+      file = originalData?['file'];
+      content = file?.name ?? "Datei";
+    } else {
+      content = RichObjectStringProcessor.parseToString(originalMessage, originalData);
+    }
+  }
+
+  Future<Widget> getWidget() async {
+    SharedPreferences preferences = await SharedPreferences.getInstance();
+
+    if(file == null) {
+      return SelectableText(content);
+    }
+
+    return CachedNetworkImage(
+      errorWidget: (context, url, error) {
+        return Text("Datei: ${file!.name}", style: const TextStyle(fontWeight: FontWeight.bold));
+      },
+      alignment: Alignment.center,
+      placeholder: (context, url) {
+        return const Padding(padding: EdgeInsets.all(10), child: CircularProgressIndicator());
+      },
+      fadeInDuration: const Duration(seconds: 1),
+      imageUrl: "https://cloud.marianum-fulda.de/core/preview?fileId=${file!.id}&x=100&y=-1&a=1",
+      httpHeaders: {
+        "Authorization": "Basic ${base64.encode(utf8.encode("${preferences.getString("username")}:${preferences.getString("password")}"))}"
+      },
+    );
+  }
+}
\ No newline at end of file