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 json) => SendMessageParams( json['message'] as String, - replyTo: json['replyTo'] as int?, + replyTo: json['replyTo'] as String?, ); Map _$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 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 { children: [ GestureDetector( + onHorizontalDragEnd: (DragEndDetails details) { + if(widget.bubbleData.isReplyable) { + Provider.of(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 { void initState() { super.initState(); settings = Provider.of(context, listen: false); + Provider.of(context, listen: false).referenceMessageId = null; } @override @@ -91,102 +92,131 @@ class _ChatTextfieldState extends State { child: Container( padding: const EdgeInsets.only(left: 10, bottom: 3, top: 3, right: 10), width: double.infinity, - child: Row( - children: [ - GestureDetector( - onTap: (){ - showDialog(context: context, builder: (context) => SimpleDialog( + child: Column( + children: [ + Consumer( + 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: [ + 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(context, listen: false).referenceMessageId.toString() + )).run().then((value) { + _query(); + setState(() { + isLoading = false; + }); + _textBoxController.text = ''; + setDraft(''); + }); + Provider.of(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), + ), + ], ), ], ), + ), ), ],