Fixed numerous bugs within talk and file upload

This commit is contained in:
Elias Müller 2023-08-09 20:59:37 +02:00
parent 03a930cf83
commit 987734626c
7 changed files with 74 additions and 48 deletions

View File

@ -43,7 +43,6 @@ class _FileUploadDialogState extends State<FileUploadDialog> {
setState(() { setState(() {
state = FileUploadState.checkConflict; state = FileUploadState.checkConflict;
}); });
//await (await WebdavApi.webdav).mkcol(widget.remotePath.join("/")); // TODO is this needed? It does not work anymore...
List<WebDavResponse> result = (await webdavClient.propfind(widget.remotePath.join("/"))).responses; List<WebDavResponse> result = (await webdavClient.propfind(widget.remotePath.join("/"))).responses;
if(result.any((element) => element.href!.endsWith("/$targetFileName"))) { if(result.any((element) => element.href!.endsWith("/$targetFileName"))) {
setState(() { setState(() {

View File

@ -177,32 +177,41 @@ class _ChatBubbleState extends State<ChatBubble> {
onLongPress: () { onLongPress: () {
showDialog(context: context, builder: (context) { showDialog(context: context, builder: (context) {
List<String> commonReactions = ["👍", "👎", "😆", "❤️", "💔", "😍"]; List<String> commonReactions = ["👍", "👎", "😆", "❤️", "💔", "😍"];
bool reactable = widget.bubbleData.messageType == GetRoomResponseObjectMessageType.comment;
return SimpleDialog( return SimpleDialog(
children: [ children: [
Wrap(
alignment: WrapAlignment.center,
children: [
...commonReactions.map((e) => TextButton(
style: TextButton.styleFrom(
padding: EdgeInsets.zero,
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
minimumSize: const Size(40, 40)
),
onPressed: () {
Navigator.of(context).pop();
ReactMessage(
chatToken: widget.chatData.token,
messageId: widget.bubbleData.id,
params: ReactMessageParams(e),
).run().then((value) => widget.refetch(renew: true));
},
child: Text(e)),
),
],
),
const Divider(),
Visibility( Visibility(
visible: true, visible: reactable,
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
Wrap(
alignment: WrapAlignment.center,
children: [
...commonReactions.map((e) => TextButton(
style: TextButton.styleFrom(
padding: EdgeInsets.zero,
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
minimumSize: const Size(40, 40)
),
onPressed: () {
Navigator.of(context).pop();
ReactMessage(
chatToken: widget.chatData.token,
messageId: widget.bubbleData.id,
params: ReactMessageParams(e),
).run().then((value) => widget.refetch(renew: true));
},
child: Text(e)),
),
],
),
const Divider(),
],
)
),
Visibility(
visible: reactable,
child: ListTile( child: ListTile(
leading: const Icon(Icons.add_reaction_outlined), leading: const Icon(Icons.add_reaction_outlined),
title: const Text("Reaktionen"), title: const Text("Reaktionen"),
@ -215,7 +224,7 @@ class _ChatBubbleState extends State<ChatBubble> {
), ),
), ),
Visibility( Visibility(
visible: !message.containsFile && widget.bubbleData.messageType == GetRoomResponseObjectMessageType.comment, visible: !message.containsFile,
child: ListTile( child: ListTile(
leading: const Icon(Icons.copy), leading: const Icon(Icons.copy),
title: const Text("Nachricht kopieren"), title: const Text("Nachricht kopieren"),
@ -234,7 +243,7 @@ class _ChatBubbleState extends State<ChatBubble> {
), ),
), ),
Visibility( Visibility(
visible: widget.isSender, visible: widget.isSender && DateTime.fromMillisecondsSinceEpoch(widget.bubbleData.timestamp * 1000).add(const Duration(hours: 6)).isAfter(DateTime.now()),
child: ListTile( child: ListTile(
leading: const Icon(Icons.delete_outline), leading: const Icon(Icons.delete_outline),
title: const Text("Nachricht löschen"), title: const Text("Nachricht löschen"),

View File

@ -30,7 +30,7 @@ class ChatMessage {
Widget getWidget() { Widget getWidget() {
if(file == null) { if(file == null) {
return SelectableLinkify( return Linkify(
text: content, text: content,
onOpen: onOpen, onOpen: onOpen,
); );
@ -49,10 +49,7 @@ class ChatMessage {
placeholder: (context, url) { placeholder: (context, url) {
return const Padding(padding: EdgeInsets.all(10), child: CircularProgressIndicator()); return const Padding(padding: EdgeInsets.all(10), child: CircularProgressIndicator());
}, },
imageUrl: "https://${EndpointData().nextcloud().full()}/core/preview?fileId=${file!.id}&x=100&y=-1&a=1", imageUrl: "https://${AccountData().buildHttpAuthString()}@${EndpointData().nextcloud().full()}/index.php/core/preview?fileId=${file!.id}&x=100&y=-1&a=1",
httpHeaders: {
"Authorization": "Basic ${AccountData().buildHttpAuthString()}"
},
); );
} }

View File

@ -1,4 +1,5 @@
import 'dart:io';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:loader_overlay/loader_overlay.dart'; import 'package:loader_overlay/loader_overlay.dart';
import 'package:provider/provider.dart'; import 'package:provider/provider.dart';
@ -8,6 +9,7 @@ import '../../../api/marianumcloud/files-sharing/fileSharingApi.dart';
import '../../../api/marianumcloud/files-sharing/fileSharingApiParams.dart'; import '../../../api/marianumcloud/files-sharing/fileSharingApiParams.dart';
import '../../../api/marianumcloud/talk/sendMessage/sendMessage.dart'; import '../../../api/marianumcloud/talk/sendMessage/sendMessage.dart';
import '../../../api/marianumcloud/talk/sendMessage/sendMessageParams.dart'; import '../../../api/marianumcloud/talk/sendMessage/sendMessageParams.dart';
import '../../../api/marianumcloud/webdav/webdavApi.dart';
import '../../../model/chatList/chatProps.dart'; import '../../../model/chatList/chatProps.dart';
import '../../../widget/filePick.dart'; import '../../../widget/filePick.dart';
import '../files/fileUploadDialog.dart'; import '../files/fileUploadDialog.dart';
@ -38,6 +40,10 @@ class _ChatTextfieldState extends State<ChatTextfield> {
String filename = "${path.split("/").last.split(".").first}-${const Uuid().v4()}.${path.split(".").last}"; String filename = "${path.split("/").last.split(".").first}-${const Uuid().v4()}.${path.split(".").last}";
String shareFolder = "MarianumMobile"; String shareFolder = "MarianumMobile";
WebdavApi.webdav.then((webdav) {
webdav.mkcol("/$shareFolder");
});
showDialog(context: context, builder: (context) => FileUploadDialog( showDialog(context: context, builder: (context) => FileUploadDialog(
doShowFinish: false, doShowFinish: false,
fileName: filename, fileName: filename,
@ -45,9 +51,9 @@ class _ChatTextfieldState extends State<ChatTextfield> {
remotePath: [shareFolder], remotePath: [shareFolder],
onUploadFinished: () { onUploadFinished: () {
FileSharingApi().share(FileSharingApiParams( FileSharingApi().share(FileSharingApiParams(
shareType: 10, shareType: 10,
shareWith: widget.sendToToken, shareWith: widget.sendToToken,
path: "$shareFolder/$filename", path: "$shareFolder/$filename",
)).then((value) => _query()); )).then((value) => _query());
}, },
), barrierDismissible: false); ), barrierDismissible: false);
@ -81,16 +87,19 @@ class _ChatTextfieldState extends State<ChatTextfield> {
Navigator.of(context).pop(); Navigator.of(context).pop();
}, },
), ),
ListTile( Visibility(
leading: const Icon(Icons.image), visible: !Platform.isIOS,
title: const Text("Aus Gallerie auswählen"), child: ListTile(
onTap: () { leading: const Icon(Icons.image),
context.loaderOverlay.show(); title: const Text("Aus Gallerie auswählen"),
FilePick.galleryPick().then((value) { onTap: () {
mediaUpload(value?.path); context.loaderOverlay.show();
}); FilePick.galleryPick().then((value) {
Navigator.of(context).pop(); mediaUpload(value?.path);
}, });
Navigator.of(context).pop();
},
),
), ),
], ],
); );

View File

@ -48,10 +48,12 @@ class _ChatTileState extends State<ChatTile> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
bool useRemotePicture = widget.data.type == GetRoomResponseObjectConversationType.oneToOne;
CircleAvatar circleAvatar = CircleAvatar( CircleAvatar circleAvatar = CircleAvatar(
foregroundImage: widget.data.type == GetRoomResponseObjectConversationType.oneToOne ? Image.network("https://${EndpointData().nextcloud().full()}/avatar/${widget.data.name}/128").image : null, foregroundImage: useRemotePicture ? Image.network("https://${EndpointData().nextcloud().full()}/avatar/${widget.data.name}/128").image : null,
backgroundColor: Theme.of(context).primaryColor, backgroundColor: Theme.of(context).primaryColor,
foregroundColor: Colors.white, foregroundColor: Colors.white,
onForegroundImageError: useRemotePicture ? (o, t) {} : null,
child: widget.data.type == GetRoomResponseObjectConversationType.group ? const Icon(Icons.group) : const Icon(Icons.person), child: widget.data.type == GetRoomResponseObjectConversationType.group ? const Icon(Icons.group) : const Icon(Icons.person),
); );

View File

@ -57,13 +57,21 @@ class _ChatViewState extends State<ChatView> {
lastDate = elementDate; lastDate = elementDate;
messages.add(ChatBubble( messages.add(ChatBubble(
context: context, context: context,
isSender: true, isSender: false,
bubbleData: GetChatResponseObject.getDateDummy(element.timestamp), bubbleData: GetChatResponseObject.getDateDummy(element.timestamp),
chatData: widget.room, chatData: widget.room,
refetch: _query, refetch: _query,
)); ));
} }
messages.add(ChatBubble(context: context, isSender: element.actorId == widget.selfId, bubbleData: element, chatData: widget.room, refetch: _query)); messages.add(
ChatBubble(
context: context,
isSender: element.actorId == widget.selfId && element.messageType == GetRoomResponseObjectMessageType.comment,
bubbleData: element,
chatData: widget.room,
refetch: _query
)
);
}); });
} }

View File

@ -7,6 +7,7 @@ import '../../../api/marianumcloud/talk/getReactions/getReactionsResponse.dart';
import '../../../model/accountData.dart'; import '../../../model/accountData.dart';
import '../../../widget/centeredLeading.dart'; import '../../../widget/centeredLeading.dart';
import '../../../widget/loadingSpinner.dart'; import '../../../widget/loadingSpinner.dart';
import '../../../widget/placeholderView.dart';
import '../../../widget/unimplementedDialog.dart'; import '../../../widget/unimplementedDialog.dart';
class MessageReactions extends StatefulWidget { class MessageReactions extends StatefulWidget {
@ -36,7 +37,8 @@ class _MessageReactionsState extends State<MessageReactions> {
body: FutureBuilder( body: FutureBuilder(
future: data, future: data,
builder: (context, snapshot) { builder: (context, snapshot) {
if(snapshot.data == null) return const LoadingSpinner(); if(snapshot.connectionState == ConnectionState.waiting) return const LoadingSpinner();
if(snapshot.data == null) return const PlaceholderView(icon: Icons.search_off_outlined, text: "Keine Reaktionen gefunden!");
return ListView( return ListView(
children: [ children: [
...snapshot.data!.data.entries.map<Widget>((entry) { ...snapshot.data!.data.entries.map<Widget>((entry) {