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" "fileNotEncrypted": "The chat is encrypted but the file is not encrypted"
}, },
"conversation": { "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": { "warnings": {

View File

@ -73,7 +73,9 @@
"fileNotEncrypted": "Der Chat ist verschlüsselt, aber die Datei wurde unverschlüsselt übertragen" "fileNotEncrypted": "Der Chat ist verschlüsselt, aber die Datei wurde unverschlüsselt übertragen"
}, },
"conversation": { "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": { "warnings": {

View File

@ -1,5 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'dart:typed_data'; import 'dart:typed_data';
import 'package:better_open_file/better_open_file.dart';
import 'package:cryptography/cryptography.dart'; import 'package:cryptography/cryptography.dart';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
@ -353,3 +354,24 @@ Future<void> handleUri(String uriString) async {
mode: LaunchMode.externalNonBrowserApplication, 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; return message.stickerPackId != null && message.stickerHashKey != null;
} }
Color? _getBubbleColor(BuildContext context) { Color _getBubbleColor(BuildContext context) {
if (_shouldNotColorBubble()) return null; if (_shouldNotColorBubble()) return Colors.transparent;
// Color the bubble red if it should be encrypted but is not. // Color the bubble red if it should be encrypted but is not.
if (chatEncrypted && !message.encrypted) { if (chatEncrypted && !message.encrypted) {
@ -83,14 +83,13 @@ class RawChatBubble extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final borderRadius = getBorderRadius(sentBySelf, start, between, end); final borderRadius = getBorderRadius(sentBySelf, start, between, end);
return Container( return ConstrainedBox(
constraints: BoxConstraints( constraints: BoxConstraints(
maxWidth: maxWidth, maxWidth: maxWidth,
), ),
decoration: BoxDecoration( child: Material(
color: _getBubbleColor(context), color: _getBubbleColor(context),
borderRadius: borderRadius, borderRadius: borderRadius,
),
child: Padding( child: Padding(
// NOTE: Images don't work well with padding here // NOTE: Images don't work well with padding here
padding: message.isMedia || message.quotes != null ? padding: message.isMedia || message.quotes != null ?
@ -103,6 +102,7 @@ class RawChatBubble extends StatelessWidget {
sentBySelf, sentBySelf,
), ),
), ),
),
); );
} }
} }

View File

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

View File

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

View File

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

View File

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

View File

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