Skip to content

Commit

Permalink
fixup! TF-3047 Invoke saveToGallery method when click download icon o…
Browse files Browse the repository at this point in the history
…n attachment in EmailView
  • Loading branch information
dab246 committed Sep 16, 2024
1 parent 7ef6c12 commit a3d05bf
Show file tree
Hide file tree
Showing 5 changed files with 107 additions and 76 deletions.
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@

import 'package:core/core.dart';
import 'package:core/presentation/extensions/color_extension.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';

typedef OnCancelDownloadActionClick = void Function();
Expand Down Expand Up @@ -36,36 +35,73 @@ class DownloadingFileDialogBuilder {
}

Widget build() {
return CupertinoAlertDialog(
return Dialog(
key: _key ?? const Key('DownloadingFileBuilder'),
title: Text(_title, style: const TextStyle(fontSize: 17.0, color: Colors.black)),
content: Padding(
padding: const EdgeInsets.only(top: 16.0, left: 16.0, right: 16.0),
child: Center(
child: Column(
children: [
const SizedBox(
width: 20.0,
height: 20.0,
child: CupertinoActivityIndicator()),
const SizedBox(height: 16),
Text(
_content,
style: const TextStyle(fontSize: 13.0, color: Colors.black),
softWrap: false,
maxLines: 1)
],
),
)),
actions: [
if (_actionText.isNotEmpty)
Padding(
padding: const EdgeInsets.only(bottom: kIsWeb ? 16 : 0, top: kIsWeb ? 16 : 0),
child: TextButton(
onPressed: () => _onCancelDownloadActionClick?.call(),
child: Text(_actionText, style: const TextStyle(fontSize: 17.0, color: AppColor.appColor)),
))
],
backgroundColor: Colors.white,
shape: const RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(12))
),
alignment: Alignment.center,
child: SizedBox(
width: 250,
child: Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: [
Padding(
padding: const EdgeInsetsDirectional.symmetric(
horizontal: 12,
vertical: 20
),
child: Text(
_title,
style: const TextStyle(
fontSize: 17.0,
color: Colors.black,
fontWeight: FontWeight.bold
)
),
),
const SizedBox(
width: 20.0,
height: 20.0,
child: CupertinoActivityIndicator()
),
const SizedBox(height: 16),
Text(
_content,
style: const TextStyle(
fontSize: 13.0,
color: Colors.black,
),
textAlign: TextAlign.center,
overflow: TextOverflow.ellipsis,
maxLines: 2
),
const SizedBox(height: 16),
if (_actionText.isNotEmpty && _onCancelDownloadActionClick != null)
... [
const Divider(),
TextButton(
onPressed: _onCancelDownloadActionClick,
style: TextButton.styleFrom(
backgroundColor: Colors.white,
foregroundColor: AppColor.primaryColor,
overlayColor: Colors.black12,
fixedSize: const Size.fromWidth(250),
),
child: Text(
_actionText,
style: const TextStyle(
fontSize: 17.0,
color: AppColor.primaryColor
)
),
)
]
],
),
),
);
}
}
2 changes: 1 addition & 1 deletion ios/Runner/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@
<key>NSContactsUsageDescription</key>
<string>Used by Team-Mail for Email address auto-completion. You can easily to find the email address in your contact book to send the email.</string>
<key>NSPhotoLibraryAddUsageDescription</key>
<string>To save photo to library, we need permission to access your photo library.</string>
<string>To save photos or videos to library, we need permission to access your photo library.</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>To select and upload photo, we need permission to access your photo library.</string>
<key>UIBackgroundModes</key>
Expand Down
27 changes: 12 additions & 15 deletions lib/features/base/mixin/save_media_to_gallery_mixin.dart
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ import 'package:tmail_ui_user/main/permissions/storage_permission_service.dart';
typedef OnSaveCallbackAction = Function(bool isSuccess);

mixin SaveMediaToGalleryMixin {
Future<void> handleAndroidStoragePermission(BuildContext context) async {
Future<void> _handleAndroidStoragePermission(BuildContext context) async {
if (await StoragePermissionService().isUserHaveToRequestStoragePermissionAndroid()) {
final permission = await Permission.storage.request();

Expand All @@ -32,8 +32,7 @@ mixin SaveMediaToGalleryMixin {
AppLocalizations.of(context).app_name,
),
),
onAcceptButton: () =>
StoragePermissionService().goToSettingsForPermissionActions(),
onAcceptButton: StoragePermissionService().goToSettingsForPermissionActions,
);
},
);
Expand All @@ -46,7 +45,7 @@ mixin SaveMediaToGalleryMixin {
}
}

Future<void> handlePhotoPermissionIOS(BuildContext context) async {
Future<void> _handlePhotoPermissionIOS(BuildContext context) async {
final permissionStatus = await StoragePermissionService().requestPhotoAddOnlyPermissionIOS();
if (permissionStatus.isPermanentlyDenied && context.mounted) {
showDialog(
Expand All @@ -61,8 +60,7 @@ mixin SaveMediaToGalleryMixin {
AppLocalizations.of(context).app_name,
),
),
onAcceptButton: () =>
StoragePermissionService().goToSettingsForPermissionActions(),
onAcceptButton: StoragePermissionService().goToSettingsForPermissionActions,
);
},
);
Expand All @@ -72,36 +70,35 @@ mixin SaveMediaToGalleryMixin {
}
}

Future<void> saveMediaToGallery({
Future<void> _saveMediaToGallery({
required File fileInDownloadsInApp,
required MediaType mediaType,
OnSaveCallbackAction? onSaveCallbackAction
}) async {
if (mediaType.isImageFile()) {
await saveImageToGallery(file: fileInDownloadsInApp);
await _saveImageToGallery(file: fileInDownloadsInApp);
} else if (mediaType.isVideoFile()) {
await saveVideoToGallery(file: fileInDownloadsInApp);
await _saveVideoToGallery(file: fileInDownloadsInApp);
} else {
return;
}
onSaveCallbackAction?.call(true);
}

Future<void> saveImageToGallery({
Future<void> _saveImageToGallery({
required File file,
}) async {
log('SaveMediaToGalleryMixin::saveImageToGallery:file path: ${file.path}');
await Gal.putImage(file.path);
}

Future<void> saveVideoToGallery({
Future<void> _saveVideoToGallery({
required File file,
}) async {
log('SaveMediaToGalleryMixin::saveVideoToGallery:file path: ${file.path}');
await Gal.putVideo(file.path);
}


Future<void> saveToGallery({
required BuildContext context,
required String filePath,
Expand All @@ -110,17 +107,17 @@ mixin SaveMediaToGalleryMixin {
}) async {
try {
if (PlatformInfo.isAndroid) {
await handleAndroidStoragePermission(context);
await _handleAndroidStoragePermission(context);
} else if (PlatformInfo.isIOS) {
await handlePhotoPermissionIOS(context);
await _handlePhotoPermissionIOS(context);
} else {
return;
}

final fileInDownloadsInApp = File(filePath);

if (context.mounted) {
await saveMediaToGallery(
await _saveMediaToGallery(
mediaType: mediaType,
fileInDownloadsInApp: fileInDownloadsInApp,
onSaveCallbackAction: onSaveCallbackAction
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import 'package:better_open_file/better_open_file.dart' as open_file;
import 'package:core/core.dart';
import 'package:dartz/dartz.dart';
import 'package:dio/dio.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_svg/flutter_svg.dart';
import 'package:get/get.dart';
Expand Down Expand Up @@ -771,19 +770,21 @@ class SingleEmailController extends BaseController
final downloadDialog = DownloadingFileDialogBuilder()
..key(const Key('downloading_file_dialog'))
..title(downloadTitle)
..content(AppLocalizations.of(context).downloading_file(attachment.name ?? ''))
..actionText(AppLocalizations.of(context).cancel);
..content(AppLocalizations.of(context).downloading_file(attachment.name ?? ''));

if (cancelToken != null) {
downloadDialog.addCancelDownloadActionClick(() {
cancelToken.cancel([AppLocalizations.of(context).user_cancel_download_file]);
popBack();
});
downloadDialog
..actionText(AppLocalizations.of(context).cancel)
..addCancelDownloadActionClick(() {
cancelToken.cancel([AppLocalizations.of(context).user_cancel_download_file]);
popBack();
});
}

showCupertinoDialog(
context: context,
builder: (_) => PointerInterceptor(child: downloadDialog.build()));
Get.dialog(
barrierDismissible: false,
downloadDialog.build()
);
}

void _exportAttachmentAction({
Expand Down Expand Up @@ -822,7 +823,7 @@ class SingleEmailController extends BaseController
popBack();

if (success.isPreview) {
await _openDownloadedPreviewWorkGroupDocument(success.downloadedResponse);
await _openDownloadedDocument(success.downloadedResponse);
} else {
final mediaType = success.downloadedResponse.mediaType;
final filePath = success.downloadedResponse.filePath;
Expand All @@ -849,13 +850,13 @@ class SingleEmailController extends BaseController
}
);
} else {
await _openDownloadedPreviewWorkGroupDocument(success.downloadedResponse);
await _openDownloadedDocument(success.downloadedResponse);
}
}
}

Future<void> _openDownloadedPreviewWorkGroupDocument(DownloadedResponse downloadedResponse) async {
log('SingleEmailController::_openDownloadedPreviewWorkGroupDocument(): $downloadedResponse');
Future<void> _openDownloadedDocument(DownloadedResponse downloadedResponse) async {
log('SingleEmailController::_openDownloadedDocument(): $downloadedResponse');
if (downloadedResponse.mediaType == null) {
await Share.shareXFiles([XFile(downloadedResponse.filePath)]);
}
Expand All @@ -866,7 +867,7 @@ class SingleEmailController extends BaseController
uti: Platform.isIOS ? downloadedResponse.mediaType!.getDocumentUti().value : null);

if (openResult.type != open_file.ResultType.done) {
logError('SingleEmailController::_openDownloadedPreviewWorkGroupDocument(): no preview available');
logError('SingleEmailController::_openDownloadedDocument(): no preview available');
if (currentOverlayContext != null && currentContext != null) {
appToast.showToastErrorMessage(
currentOverlayContext!,
Expand Down
25 changes: 11 additions & 14 deletions lib/main/permissions/permission_dialog.dart
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,12 @@ class _PermissionDialogState extends State<PermissionDialog>
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
if (widget.icon != null) ...[
const SizedBox(
height: 24.0,
),
widget.icon!,
],
const SizedBox(
height: 16.0,
),
if (widget.icon != null)
...[
const SizedBox(height: 24.0),
widget.icon!,
],
const SizedBox(height: 16.0),
widget.explainTextRequestPermission,
const SizedBox(height: 24.0),
Expanded(
Expand All @@ -89,9 +86,9 @@ class _PermissionDialogState extends State<PermissionDialog>
if (widget.onAcceptButton != null) {
widget.onAcceptButton!.call();
} else {
await widget.permission.request().then(
(value) => Navigator.of(context).pop(),
);
await widget.permission
.request()
.then((value) => Navigator.of(context).pop());
}
},
),
Expand Down Expand Up @@ -129,8 +126,8 @@ class _PermissionTextButton extends StatelessWidget {
child: Text(
text,
style: Theme.of(context).textTheme.labelLarge?.copyWith(
color: Theme.of(context).colorScheme.primary,
),
color: Theme.of(context).colorScheme.primary,
),
),
),
),
Expand Down

0 comments on commit a3d05bf

Please sign in to comment.