feat(ui): Show a toast when a file cannot be opened
This commit is contained in:
parent
009ec759a3
commit
cb13c9faa4
@ -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": {
|
||||||
|
@ -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": {
|
||||||
|
@ -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,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -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,24 +83,24 @@ 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 ?
|
EdgeInsets.zero :
|
||||||
EdgeInsets.zero :
|
const EdgeInsets.all(8),
|
||||||
const EdgeInsets.all(8),
|
child: buildMessageWidget(
|
||||||
child: buildMessageWidget(
|
message,
|
||||||
message,
|
maxWidth,
|
||||||
maxWidth,
|
borderRadius,
|
||||||
borderRadius,
|
sentBySelf,
|
||||||
sentBySelf,
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
@ -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,
|
||||||
),
|
),
|
||||||
|
@ -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!);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
|
||||||
},
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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(),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user