From c4a7533315ceeb44c357cf1ca53ac272666159b3 Mon Sep 17 00:00:00 2001
From: Pupsi28 <larslukasneuhaus@gmx.de>
Date: Thu, 11 Apr 2024 18:22:55 +0200
Subject: [PATCH] added option to react to messages

---
 .../talk/sendMessage/sendMessageParams.dart   |   2 +-
 .../talk/sendMessage/sendMessageParams.g.dart |   2 +-
 lib/model/chatList/chatProps.dart             |   7 +
 .../pages/talk/components/chatBubble.dart     |   5 +
 .../pages/talk/components/chatTextfield.dart  | 200 ++++++++++--------
 5 files changed, 129 insertions(+), 87 deletions(-)

diff --git a/lib/api/marianumcloud/talk/sendMessage/sendMessageParams.dart b/lib/api/marianumcloud/talk/sendMessage/sendMessageParams.dart
index e9150c4..d467246 100644
--- a/lib/api/marianumcloud/talk/sendMessage/sendMessageParams.dart
+++ b/lib/api/marianumcloud/talk/sendMessage/sendMessageParams.dart
@@ -7,7 +7,7 @@ part 'sendMessageParams.g.dart';
 @JsonSerializable(explicitToJson: true, includeIfNull: false)
 class SendMessageParams extends ApiParams {
   String message;
-  int? replyTo;
+  String? replyTo;
 
   SendMessageParams(this.message, {this.replyTo});
 
diff --git a/lib/api/marianumcloud/talk/sendMessage/sendMessageParams.g.dart b/lib/api/marianumcloud/talk/sendMessage/sendMessageParams.g.dart
index 50255b4..76093c2 100644
--- a/lib/api/marianumcloud/talk/sendMessage/sendMessageParams.g.dart
+++ b/lib/api/marianumcloud/talk/sendMessage/sendMessageParams.g.dart
@@ -9,7 +9,7 @@ part of 'sendMessageParams.dart';
 SendMessageParams _$SendMessageParamsFromJson(Map<String, dynamic> json) =>
     SendMessageParams(
       json['message'] as String,
-      replyTo: json['replyTo'] as int?,
+      replyTo: json['replyTo'] as String?,
     );
 
 Map<String, dynamic> _$SendMessageParamsToJson(SendMessageParams instance) {
diff --git a/lib/model/chatList/chatProps.dart b/lib/model/chatList/chatProps.dart
index bd0a749..7fd2f6c 100644
--- a/lib/model/chatList/chatProps.dart
+++ b/lib/model/chatList/chatProps.dart
@@ -10,6 +10,8 @@ class ChatProps extends DataHolder {
   GetChatResponse? _getChatResponse;
   GetChatResponse get getChatResponse => _getChatResponse!;
 
+  int? referenceMessageId;
+
   @override
   List<ApiResponse?> properties() => [_getChatResponse];
 
@@ -30,6 +32,11 @@ class ChatProps extends DataHolder {
     );
   }
 
+  void setReferenceMessageId(int? messageId) {
+    referenceMessageId = messageId;
+    run();
+  }
+
   void setQueryToken(String token) {
     _queryToken = token;
     _getChatResponse = null;
diff --git a/lib/view/pages/talk/components/chatBubble.dart b/lib/view/pages/talk/components/chatBubble.dart
index 6c589c5..f8fb90c 100644
--- a/lib/view/pages/talk/components/chatBubble.dart
+++ b/lib/view/pages/talk/components/chatBubble.dart
@@ -288,6 +288,11 @@ class _ChatBubbleState extends State<ChatBubble> {
 
       children: [
         GestureDetector(
+          onHorizontalDragEnd: (DragEndDetails details) {
+            if(widget.bubbleData.isReplyable) {
+              Provider.of<ChatProps>(context, listen: false).setReferenceMessageId(widget.bubbleData.id);
+            }
+          },
           onLongPress: showOptionsDialog,
           onDoubleTap: showOptionsDialog,
           onTap: () {
diff --git a/lib/view/pages/talk/components/chatTextfield.dart b/lib/view/pages/talk/components/chatTextfield.dart
index 3628006..a4199cd 100644
--- a/lib/view/pages/talk/components/chatTextfield.dart
+++ b/lib/view/pages/talk/components/chatTextfield.dart
@@ -78,6 +78,7 @@ class _ChatTextfieldState extends State<ChatTextfield> {
   void initState() {
     super.initState();
     settings = Provider.of<SettingsProvider>(context, listen: false);
+    Provider.of<ChatProps>(context, listen: false).referenceMessageId = null;
   }
 
   @override
@@ -91,102 +92,131 @@ class _ChatTextfieldState extends State<ChatTextfield> {
           child: Container(
             padding: const EdgeInsets.only(left: 10, bottom: 3, top: 3, right: 10),
             width: double.infinity,
-            child: Row(
-              children: <Widget>[
-                GestureDetector(
-                  onTap: (){
-                    showDialog(context: context, builder: (context) => SimpleDialog(
+            child: Column(
+              children: [
+                Consumer<ChatProps>(
+                  builder: (context, data, child) {
+                    // Text(data.referenceMessageId.toString());
+                    if(data.referenceMessageId != null) {
+                      var referenceMessage = data.getChatResponse.sortByTimestamp().where((element) => element.id == data.referenceMessageId).first;
+                      return Row(
                         children: [
-                          ListTile(
-                            leading: const Icon(Icons.file_open),
-                            title: const Text('Aus Dateien auswählen'),
-                            onTap: () {
-                              FilePick.documentPick().then(mediaUpload);
-                              Navigator.of(context).pop();
-                            },
-                          ),
-                          Visibility(
-                            visible: !Platform.isIOS,
-                            child: ListTile(
-                              leading: const Icon(Icons.image),
-                              title: const Text('Aus Gallerie auswählen'),
-                              onTap: () {
-                                FilePick.multipleGalleryPick().then((value) {
-                                  if(value != null) mediaUpload(value.map((e) => e.path).toList());
-                                });
-                                Navigator.of(context).pop();
-                              },
-                            ),
+                          IconButton(
+                            onPressed: () => data.setReferenceMessageId(null),
+                            icon: const Icon(Icons.close_outlined),
+                            padding: const EdgeInsets.only(left: 0),
                           ),
+                          Text(referenceMessage.message),
                         ],
-                      ));
+                      );
+                    } else {
+                      return const SizedBox.shrink();
+                    }
                   },
-                  child: Material(
-                    elevation: 5,
-                    shape: RoundedRectangleBorder(
-                      borderRadius: BorderRadius.circular(30),
+                ),
+                Row(
+                  children: <Widget>[
+                    GestureDetector(
+                        onTap: (){
+                          showDialog(context: context, builder: (context) => SimpleDialog(
+                            children: [
+                              ListTile(
+                                leading: const Icon(Icons.file_open),
+                                title: const Text('Aus Dateien auswählen'),
+                                onTap: () {
+                                  FilePick.documentPick().then(mediaUpload);
+                                  Navigator.of(context).pop();
+                                },
+                              ),
+                              Visibility(
+                                visible: !Platform.isIOS,
+                                child: ListTile(
+                                  leading: const Icon(Icons.image),
+                                  title: const Text('Aus Gallerie auswählen'),
+                                  onTap: () {
+                                    FilePick.multipleGalleryPick().then((value) {
+                                      if(value != null) mediaUpload(value.map((e) => e.path).toList());
+                                    });
+                                    Navigator.of(context).pop();
+                                  },
+                                ),
+                              ),
+                            ],
+                          ));
+                        },
+                        child: Material(
+                          elevation: 5,
+                          shape: RoundedRectangleBorder(
+                            borderRadius: BorderRadius.circular(30),
+                          ),
+                          child: Container(
+                            height: 30,
+                            width: 30,
+                            decoration: BoxDecoration(
+                              color: Theme.of(context).primaryColor,
+                              borderRadius: BorderRadius.circular(30),
+                            ),
+                            child: const Icon(Icons.attach_file_outlined, color: Colors.white, size: 20, ),
+                          ),
+                        )
                     ),
-                    child: Container(
-                      height: 30,
-                      width: 30,
-                      decoration: BoxDecoration(
-                        color: Theme.of(context).primaryColor,
-                        borderRadius: BorderRadius.circular(30),
+                    const SizedBox(width: 15),
+                    Expanded(
+                      child: TextField(
+                        autocorrect: true,
+                        textCapitalization: TextCapitalization.sentences,
+                        controller: _textBoxController,
+                        maxLines: 7,
+                        minLines: 1,
+                        decoration: const InputDecoration(
+                          hintText: 'Nachricht schreiben...',
+                          border: InputBorder.none,
+                        ),
+                        onChanged: (String text) {
+                          if(text.trim().toLowerCase() == 'marbot marbot marbot') {
+                            var newText = 'Roboter sind cool und so, aber Marbots sind besser!';
+                            _textBoxController.text = newText;
+                            text = newText;
+                          }
+                          setDraft(text);
+                        },
+                        onTapOutside: (PointerDownEvent event) => FocusBehaviour.textFieldTapOutside(context),
                       ),
-                      child: const Icon(Icons.attach_file_outlined, color: Colors.white, size: 20, ),
                     ),
-                  )
-                ),
-                const SizedBox(width: 15),
-                Expanded(
-                  child: TextField(
-                    autocorrect: true,
-                    textCapitalization: TextCapitalization.sentences,
-                    controller: _textBoxController,
-                    maxLines: 7,
-                    minLines: 1,
-                    decoration: const InputDecoration(
-                      hintText: 'Nachricht schreiben...',
-                      border: InputBorder.none,
-                    ),
-                    onChanged: (String text) {
-                      if(text.trim().toLowerCase() == 'marbot marbot marbot') {
-                        var newText = 'Roboter sind cool und so, aber Marbots sind besser!';
-                        _textBoxController.text = newText;
-                        text = newText;
-                      }
-                      setDraft(text);
-                    },
-                    onTapOutside: (PointerDownEvent event) => FocusBehaviour.textFieldTapOutside(context),
-                  ),
-                ),
-                const SizedBox(width: 15),
-                FloatingActionButton(
-                  mini: true,
-                  onPressed: (){
-                    if(_textBoxController.text.isEmpty) return;
-                    if(isLoading) return;
+                    const SizedBox(width: 15),
+                    FloatingActionButton(
+                      mini: true,
+                      onPressed: (){
+                        if(_textBoxController.text.isEmpty) return;
+                        if(isLoading) return;
 
-                    setState(() {
-                      isLoading = true;
-                    });
-                    SendMessage(widget.sendToToken, SendMessageParams(_textBoxController.text)).run().then((value) {
-                      _query();
-                      setState(() {
-                        isLoading = false;
-                      });
-                      _textBoxController.text = '';
-                      setDraft('');
-                    });
-                  },
-                  backgroundColor: Theme.of(context).primaryColor,
-                  elevation: 5,
-                  child: isLoading
-                      ? Container(padding: const EdgeInsets.all(10), child: const CircularProgressIndicator(color: Colors.white, strokeWidth: 2))
-                      : const Icon(Icons.send, color: Colors.white, size: 18),
+                        setState(() {
+                          isLoading = true;
+                        });
+                        SendMessage(widget.sendToToken, SendMessageParams(
+                            _textBoxController.text,
+                            replyTo: Provider.of<ChatProps>(context, listen: false).referenceMessageId.toString()
+                        )).run().then((value) {
+                          _query();
+                          setState(() {
+                            isLoading = false;
+                          });
+                          _textBoxController.text = '';
+                          setDraft('');
+                        });
+                        Provider.of<ChatProps>(context, listen: false).referenceMessageId = null;
+                      },
+                      backgroundColor: Theme.of(context).primaryColor,
+                      elevation: 5,
+                      child: isLoading
+                          ? Container(padding: const EdgeInsets.all(10), child: const CircularProgressIndicator(color: Colors.white, strokeWidth: 2))
+                          : const Icon(Icons.send, color: Colors.white, size: 18),
+                    ),
+                  ],
                 ),
               ],
             ),
+
           ),
         ),
       ],