added option to react to messages

This commit is contained in:
Lars Neuhaus 2024-04-11 18:22:55 +02:00
parent d067ee702a
commit c4a7533315
5 changed files with 129 additions and 87 deletions

View File

@ -7,7 +7,7 @@ part 'sendMessageParams.g.dart';
@JsonSerializable(explicitToJson: true, includeIfNull: false) @JsonSerializable(explicitToJson: true, includeIfNull: false)
class SendMessageParams extends ApiParams { class SendMessageParams extends ApiParams {
String message; String message;
int? replyTo; String? replyTo;
SendMessageParams(this.message, {this.replyTo}); SendMessageParams(this.message, {this.replyTo});

View File

@ -9,7 +9,7 @@ part of 'sendMessageParams.dart';
SendMessageParams _$SendMessageParamsFromJson(Map<String, dynamic> json) => SendMessageParams _$SendMessageParamsFromJson(Map<String, dynamic> json) =>
SendMessageParams( SendMessageParams(
json['message'] as String, json['message'] as String,
replyTo: json['replyTo'] as int?, replyTo: json['replyTo'] as String?,
); );
Map<String, dynamic> _$SendMessageParamsToJson(SendMessageParams instance) { Map<String, dynamic> _$SendMessageParamsToJson(SendMessageParams instance) {

View File

@ -10,6 +10,8 @@ class ChatProps extends DataHolder {
GetChatResponse? _getChatResponse; GetChatResponse? _getChatResponse;
GetChatResponse get getChatResponse => _getChatResponse!; GetChatResponse get getChatResponse => _getChatResponse!;
int? referenceMessageId;
@override @override
List<ApiResponse?> properties() => [_getChatResponse]; List<ApiResponse?> properties() => [_getChatResponse];
@ -30,6 +32,11 @@ class ChatProps extends DataHolder {
); );
} }
void setReferenceMessageId(int? messageId) {
referenceMessageId = messageId;
run();
}
void setQueryToken(String token) { void setQueryToken(String token) {
_queryToken = token; _queryToken = token;
_getChatResponse = null; _getChatResponse = null;

View File

@ -288,6 +288,11 @@ class _ChatBubbleState extends State<ChatBubble> {
children: [ children: [
GestureDetector( GestureDetector(
onHorizontalDragEnd: (DragEndDetails details) {
if(widget.bubbleData.isReplyable) {
Provider.of<ChatProps>(context, listen: false).setReferenceMessageId(widget.bubbleData.id);
}
},
onLongPress: showOptionsDialog, onLongPress: showOptionsDialog,
onDoubleTap: showOptionsDialog, onDoubleTap: showOptionsDialog,
onTap: () { onTap: () {

View File

@ -78,6 +78,7 @@ class _ChatTextfieldState extends State<ChatTextfield> {
void initState() { void initState() {
super.initState(); super.initState();
settings = Provider.of<SettingsProvider>(context, listen: false); settings = Provider.of<SettingsProvider>(context, listen: false);
Provider.of<ChatProps>(context, listen: false).referenceMessageId = null;
} }
@override @override
@ -91,102 +92,131 @@ class _ChatTextfieldState extends State<ChatTextfield> {
child: Container( child: Container(
padding: const EdgeInsets.only(left: 10, bottom: 3, top: 3, right: 10), padding: const EdgeInsets.only(left: 10, bottom: 3, top: 3, right: 10),
width: double.infinity, width: double.infinity,
child: Row( child: Column(
children: <Widget>[ children: [
GestureDetector( Consumer<ChatProps>(
onTap: (){ builder: (context, data, child) {
showDialog(context: context, builder: (context) => SimpleDialog( // Text(data.referenceMessageId.toString());
if(data.referenceMessageId != null) {
var referenceMessage = data.getChatResponse.sortByTimestamp().where((element) => element.id == data.referenceMessageId).first;
return Row(
children: [ children: [
ListTile( IconButton(
leading: const Icon(Icons.file_open), onPressed: () => data.setReferenceMessageId(null),
title: const Text('Aus Dateien auswählen'), icon: const Icon(Icons.close_outlined),
onTap: () { padding: const EdgeInsets.only(left: 0),
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();
},
),
), ),
Text(referenceMessage.message),
], ],
)); );
} else {
return const SizedBox.shrink();
}
}, },
child: Material( ),
elevation: 5, Row(
shape: RoundedRectangleBorder( children: <Widget>[
borderRadius: BorderRadius.circular(30), 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( const SizedBox(width: 15),
height: 30, Expanded(
width: 30, child: TextField(
decoration: BoxDecoration( autocorrect: true,
color: Theme.of(context).primaryColor, textCapitalization: TextCapitalization.sentences,
borderRadius: BorderRadius.circular(30), 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),
), FloatingActionButton(
const SizedBox(width: 15), mini: true,
Expanded( onPressed: (){
child: TextField( if(_textBoxController.text.isEmpty) return;
autocorrect: true, if(isLoading) return;
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;
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
SendMessage(widget.sendToToken, SendMessageParams(_textBoxController.text)).run().then((value) { SendMessage(widget.sendToToken, SendMessageParams(
_query(); _textBoxController.text,
setState(() { replyTo: Provider.of<ChatProps>(context, listen: false).referenceMessageId.toString()
isLoading = false; )).run().then((value) {
}); _query();
_textBoxController.text = ''; setState(() {
setDraft(''); isLoading = false;
}); });
}, _textBoxController.text = '';
backgroundColor: Theme.of(context).primaryColor, setDraft('');
elevation: 5, });
child: isLoading Provider.of<ChatProps>(context, listen: false).referenceMessageId = null;
? Container(padding: const EdgeInsets.all(10), child: const CircularProgressIndicator(color: Colors.white, strokeWidth: 2)) },
: const Icon(Icons.send, color: Colors.white, size: 18), 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),
),
],
), ),
], ],
), ),
), ),
), ),
], ],