feat(ui): Show a toast when a file cannot be opened

This commit is contained in:
PapaTutuWawa 2022-12-21 22:39:50 +01:00
parent 009ec759a3
commit cb13c9faa4
9 changed files with 55 additions and 33 deletions

View File

@ -73,7 +73,9 @@
"fileNotEncrypted": "The chat is encrypted but the file is not encrypted"
},
"conversation": {
"audioRecordingError": "Failed to finalize audio recording"
"audioRecordingError": "Failed to finalize audio recording",
"openFileNoAppError": "No app found to open this file",
"openFileGenericError": "Failed to open file"
}
},
"warnings": {

View File

@ -73,7 +73,9 @@
"fileNotEncrypted": "Der Chat ist verschlüsselt, aber die Datei wurde unverschlüsselt übertragen"
},
"conversation": {
"audioRecordingError": "Fehler beim Fertigstellen der Audioaufnahme"
"audioRecordingError": "Fehler beim Fertigstellen der Audioaufnahme",
"openFileNoAppError": "Keine App vorhanden, um die Datei zu öffnen",
"openFileGenericError": "Fehler beim Öffnen der Datei"
}
},
"warnings": {

View File

@ -1,5 +1,6 @@
import 'dart:async';
import 'dart:typed_data';
import 'package:better_open_file/better_open_file.dart';
import 'package:cryptography/cryptography.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart';
@ -353,3 +354,24 @@ Future<void> handleUri(String uriString) async {
mode: LaunchMode.externalNonBrowserApplication,
);
}
/// Open the file [path] using the system native means. Shows a toast if the
/// file cannot be opened.
Future<void> openFile(String path) async {
final result = await OpenFile.open(path);
if (result.type != ResultType.done) {
String message;
if (result.type == ResultType.noAppToOpen) {
message = t.errors.conversation.openFileNoAppError;
} else {
message = t.errors.conversation.openFileGenericError;
}
await Fluttertoast.showToast(
msg: message,
toastLength: Toast.LENGTH_SHORT,
gravity: ToastGravity.SNACKBAR,
);
}
}

View File

@ -57,8 +57,8 @@ class RawChatBubble extends StatelessWidget {
return message.stickerPackId != null && message.stickerHashKey != null;
}
Color? _getBubbleColor(BuildContext context) {
if (_shouldNotColorBubble()) return null;
Color _getBubbleColor(BuildContext context) {
if (_shouldNotColorBubble()) return Colors.transparent;
// Color the bubble red if it should be encrypted but is not.
if (chatEncrypted && !message.encrypted) {
@ -83,24 +83,24 @@ class RawChatBubble extends StatelessWidget {
@override
Widget build(BuildContext context) {
final borderRadius = getBorderRadius(sentBySelf, start, between, end);
return Container(
return ConstrainedBox(
constraints: BoxConstraints(
maxWidth: maxWidth,
),
decoration: BoxDecoration(
child: Material(
color: _getBubbleColor(context),
borderRadius: borderRadius,
),
child: Padding(
// NOTE: Images don't work well with padding here
padding: message.isMedia || message.quotes != null ?
EdgeInsets.zero :
const EdgeInsets.all(8),
child: buildMessageWidget(
message,
maxWidth,
borderRadius,
sentBySelf,
child: Padding(
// NOTE: Images don't work well with padding here
padding: message.isMedia || message.quotes != null ?
EdgeInsets.zero :
const EdgeInsets.all(8),
child: buildMessageWidget(
message,
maxWidth,
borderRadius,
sentBySelf,
),
),
),
);

View File

@ -49,7 +49,7 @@ class MediaBaseChatWidget extends StatelessWidget {
if (onTap != null) {
return IntrinsicWidth(
child: InkResponse(
child: InkWell(
onTap: onTap,
child: content,
),

View File

@ -1,11 +1,11 @@
import 'dart:core';
import 'package:auto_size_text/auto_size_text.dart';
import 'package:better_open_file/better_open_file.dart';
import 'package:flutter/material.dart';
import 'package:moxplatform/moxplatform.dart';
import 'package:moxxyv2/shared/commands.dart';
import 'package:moxxyv2/shared/helpers.dart';
import 'package:moxxyv2/shared/models/message.dart';
import 'package:moxxyv2/ui/helpers.dart';
import 'package:moxxyv2/ui/widgets/chat/bottom.dart';
import 'package:moxxyv2/ui/widgets/chat/downloadbutton.dart';
import 'package:moxxyv2/ui/widgets/chat/media/base.dart';
@ -130,7 +130,7 @@ class FileChatWidget extends StatelessWidget {
maxWidth,
sent,
onTap: () {
OpenFile.open(message.mediaUrl);
openFile(message.mediaUrl!);
},
);
}

View File

@ -1,11 +1,11 @@
import 'dart:io';
import 'package:better_open_file/better_open_file.dart';
import 'package:flutter/material.dart';
import 'package:flutter_blurhash/flutter_blurhash.dart';
import 'package:moxplatform/moxplatform.dart';
import 'package:moxxyv2/shared/commands.dart';
import 'package:moxxyv2/shared/helpers.dart';
import 'package:moxxyv2/shared/models/message.dart';
import 'package:moxxyv2/ui/helpers.dart';
import 'package:moxxyv2/ui/widgets/chat/bottom.dart';
import 'package:moxxyv2/ui/widgets/chat/downloadbutton.dart';
import 'package:moxxyv2/ui/widgets/chat/helpers.dart';
@ -87,9 +87,7 @@ class ImageChatWidget extends StatelessWidget {
image,
MessageBubbleBottom(message, sent),
radius,
onTap: () {
OpenFile.open(message.mediaUrl);
},
onTap: () => openFile(message.mediaUrl!),
);
}

View File

@ -1,7 +1,7 @@
import 'package:better_open_file/better_open_file.dart';
import 'package:flutter/material.dart';
import 'package:moxxyv2/shared/models/media.dart';
import 'package:moxxyv2/shared/models/message.dart';
import 'package:moxxyv2/ui/helpers.dart';
import 'package:moxxyv2/ui/widgets/chat/media/audio.dart';
import 'package:moxxyv2/ui/widgets/chat/media/file.dart';
import 'package:moxxyv2/ui/widgets/chat/media/image.dart';
@ -116,25 +116,25 @@ Widget buildSharedMediaWidget(SharedMedium medium, String conversationJid) {
if (medium.mime!.startsWith('image/')) {
return SharedImageWidget(
medium.path,
onTap: () => OpenFile.open(medium.path),
onTap: () => openFile(medium.path),
);
} else if (medium.mime!.startsWith('video/')) {
return SharedVideoWidget(
medium.path,
conversationJid,
medium.mime!,
onTap: () => OpenFile.open(medium.path),
onTap: () => openFile(medium.path),
child: const PlayButton(size: 32),
);
} else if (medium.mime!.startsWith('audio/')) {
return SharedAudioWidget(
medium.path,
onTap: () => OpenFile.open(medium.path),
onTap: () => openFile(medium.path),
);
}
return SharedFileWidget(
medium.path,
onTap: () => OpenFile.open(medium.path),
onTap: () => openFile(medium.path),
);
}

View File

@ -1,11 +1,11 @@
import 'dart:io';
import 'package:better_open_file/better_open_file.dart';
import 'package:flutter/material.dart';
import 'package:flutter_blurhash/flutter_blurhash.dart';
import 'package:moxplatform/moxplatform.dart';
import 'package:moxxyv2/shared/commands.dart';
import 'package:moxxyv2/shared/helpers.dart';
import 'package:moxxyv2/shared/models/message.dart';
import 'package:moxxyv2/ui/helpers.dart';
import 'package:moxxyv2/ui/widgets/chat/bottom.dart';
import 'package:moxxyv2/ui/widgets/chat/downloadbutton.dart';
import 'package:moxxyv2/ui/widgets/chat/helpers.dart';
@ -94,9 +94,7 @@ class VideoChatWidget extends StatelessWidget {
),
MessageBubbleBottom(message, sent),
radius,
onTap: () {
OpenFile.open(message.mediaUrl);
},
onTap: () => openFile(message.mediaUrl!),
extra: const PlayButton(),
);
}