Client/lib/view/pages/talk/components/chatTextfield.dart

271 lines
11 KiB
Dart

import 'dart:io';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:nextcloud/nextcloud.dart';
import 'package:persistent_bottom_nav_bar_v2/persistent_bottom_nav_bar_v2.dart';
import 'package:provider/provider.dart';
import '../../../../api/marianumcloud/files-sharing/fileSharingApi.dart';
import '../../../../api/marianumcloud/files-sharing/fileSharingApiParams.dart';
import '../../../../api/marianumcloud/talk/sendMessage/sendMessage.dart';
import '../../../../api/marianumcloud/talk/sendMessage/sendMessageParams.dart';
import '../../../../api/marianumcloud/webdav/webdavApi.dart';
import '../../../../model/chatList/chatProps.dart';
import '../../../../storage/base/settingsProvider.dart';
import '../../../../widget/filePick.dart';
import '../../../../widget/focusBehaviour.dart';
import '../../files/filesUploadDialog.dart';
class ChatTextfield extends StatefulWidget {
final String sendToToken;
final String? selfId;
const ChatTextfield(this.sendToToken, {this.selfId, super.key});
@override
State<ChatTextfield> createState() => _ChatTextfieldState();
}
class _ChatTextfieldState extends State<ChatTextfield> {
late SettingsProvider settings;
final TextEditingController _textBoxController = TextEditingController();
bool isLoading = false;
void _query() {
Provider.of<ChatProps>(context, listen: false).run();
}
void share(String shareFolder, List<String> filePaths) {
for (var element in filePaths) {
var fileName = element.split(Platform.pathSeparator).last;
FileSharingApi().share(FileSharingApiParams(
shareType: 10,
shareWith: widget.sendToToken,
path: '$shareFolder/$fileName',
)).then((value) => _query());
}
}
Future<void> mediaUpload(List<String>? paths) async {
if (paths == null) return;
var shareFolder = 'MarianumMobile';
WebdavApi.webdav.then((webdav) {
webdav.mkcol(PathUri.parse('/$shareFolder'));
});
pushScreen(
context,
withNavBar: false,
screen: FilesUploadDialog(
filePaths: paths,
remotePath: shareFolder,
onUploadFinished: (uploadedFilePaths) {
share(shareFolder, uploadedFilePaths);
},
uniqueNames: true,
),
);
}
void setDraft(String text) {
if(text.isNotEmpty) {
settings.val(write: true).talkSettings.drafts[widget.sendToToken] = text;
} else {
settings.val(write: true).talkSettings.drafts.removeWhere((key, value) => key == widget.sendToToken);
}
}
@override
void initState() {
super.initState();
settings = Provider.of<SettingsProvider>(context, listen: false);
Provider.of<ChatProps>(context, listen: false).referenceMessageId = null;
}
@override
Widget build(BuildContext context) {
_textBoxController.text = settings.val().talkSettings.drafts[widget.sendToToken] ?? '';
return Stack(
children: <Widget>[
Align(
alignment: Alignment.bottomLeft,
child: Container(
padding: const EdgeInsets.only(left: 10, bottom: 3, top: 3, right: 10),
width: double.infinity,
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: [
IconButton(
onPressed: () => data.setReferenceMessageId(null),
icon: const Icon(Icons.close_outlined),
padding: const EdgeInsets.only(left: 0),
),
Flexible(
child: DecoratedBox(
decoration: BoxDecoration(
color: referenceMessage.actorId == widget.selfId
? Colors.green.withOpacity(0.2)
: Colors.orange.withOpacity(0.2),
borderRadius: const BorderRadius.all(Radius.circular(5)),
border: Border(left: BorderSide(
color: referenceMessage.actorId == widget.selfId
? Colors.green
: Colors.orange,
width: 5
)),
),
child: Padding(
padding: const EdgeInsets.all(5).add(const EdgeInsets.only(left: 5)),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
referenceMessage.actorDisplayName,
maxLines: 1,
style: TextStyle(
overflow: TextOverflow.ellipsis,
color: referenceMessage.actorId == widget.selfId
? Colors.green
: Colors.orange,
fontSize: 12,
),
),
Text(
referenceMessage.message,
maxLines: 2,
style: TextStyle(
overflow: TextOverflow.ellipsis,
color: Theme.of(context).colorScheme.onSurface.withOpacity(0.9),
fontSize: 12,
),
),
],
),
),
),
),
],
);
} else {
return const SizedBox.shrink();
}
},
),
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, ),
),
)
),
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;
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),
),
],
),
],
),
),
),
],
);
}
}