mirror of
https://gitlab.com/nkming2/nc-photos.git
synced 2025-03-25 00:14:42 +01:00
Support sharing a reduced quality preview
This commit is contained in:
parent
3f3f5b9f81
commit
c47880be37
10 changed files with 202 additions and 16 deletions
|
@ -1,6 +1,7 @@
|
||||||
package com.nkming.nc_photos
|
package com.nkming.nc_photos
|
||||||
|
|
||||||
import android.app.Activity
|
import android.app.Activity
|
||||||
|
import android.content.ClipData
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
import io.flutter.plugin.common.MethodCall
|
import io.flutter.plugin.common.MethodCall
|
||||||
|
@ -54,14 +55,26 @@ class ShareChannelHandler(activity: Activity) :
|
||||||
val shareIntent = if (uris.size == 1) Intent().apply {
|
val shareIntent = if (uris.size == 1) Intent().apply {
|
||||||
action = Intent.ACTION_SEND
|
action = Intent.ACTION_SEND
|
||||||
putExtra(Intent.EXTRA_STREAM, uris[0])
|
putExtra(Intent.EXTRA_STREAM, uris[0])
|
||||||
|
// setting clipdata is needed for FLAG_GRANT_READ_URI_PERMISSION to
|
||||||
|
// work, see: https://developer.android.com/reference/android/content/Intent#ACTION_SEND
|
||||||
|
clipData =
|
||||||
|
ClipData.newUri(_context.contentResolver, "Share", uris[0])
|
||||||
type = mimeTypes[0] ?: "*/*"
|
type = mimeTypes[0] ?: "*/*"
|
||||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||||
addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
|
addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
|
||||||
} else Intent().apply {
|
} else Intent().apply {
|
||||||
action = Intent.ACTION_SEND_MULTIPLE
|
action = Intent.ACTION_SEND_MULTIPLE
|
||||||
putParcelableArrayListExtra(Intent.EXTRA_STREAM, ArrayList(uris))
|
putParcelableArrayListExtra(Intent.EXTRA_STREAM, ArrayList(uris))
|
||||||
type =
|
clipData =
|
||||||
if (mimeTypes.all { it?.startsWith("image/") == true }) "image/*" else "*/*"
|
ClipData.newUri(_context.contentResolver, "Share", uris[0])
|
||||||
|
.apply {
|
||||||
|
for (uri in uris.subList(1, uris.size)) {
|
||||||
|
addItem(ClipData.Item(uri))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
type = if (mimeTypes.all {
|
||||||
|
it?.startsWith("image/") == true
|
||||||
|
}) "image/*" else "*/*"
|
||||||
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
addFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
|
||||||
addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
|
addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<paths>
|
<paths>
|
||||||
<external-path name="downloads" path="Download"/>
|
<external-path name="downloads" path="Download"/>
|
||||||
|
<cache-path name="previews" path="largeImageCache"/>
|
||||||
</paths>
|
</paths>
|
||||||
|
|
|
@ -51,6 +51,7 @@ class ThumbnailCacheManager {
|
||||||
/// very large in size. Since large images are only viewed one by one (unlike
|
/// very large in size. Since large images are only viewed one by one (unlike
|
||||||
/// thumbnails), they are less critical to the overall app responsiveness
|
/// thumbnails), they are less critical to the overall app responsiveness
|
||||||
class LargeImageCacheManager {
|
class LargeImageCacheManager {
|
||||||
|
// used in file_paths.xml, must not change
|
||||||
static const key = "largeImageCache";
|
static const key = "largeImageCache";
|
||||||
static CacheManager inst = CacheManager(
|
static CacheManager inst = CacheManager(
|
||||||
Config(
|
Config(
|
||||||
|
|
|
@ -906,11 +906,16 @@
|
||||||
"@shareMethodDialogTitle": {
|
"@shareMethodDialogTitle": {
|
||||||
"description": "Let the user pick how they want to share"
|
"description": "Let the user pick how they want to share"
|
||||||
},
|
},
|
||||||
"shareMethodFileTitle": "File",
|
"shareMethodPreviewTitle": "Preview",
|
||||||
"@shareMethodFileTitle": {
|
"@shareMethodPreviewTitle": {
|
||||||
"description": "Share the actual file"
|
"description": "Share the preview of a file"
|
||||||
},
|
},
|
||||||
"shareMethodFileDescription": "Download the file and share it to other apps",
|
"shareMethodPreviewDescription": "Share a reduced quality preview to other apps (only support images)",
|
||||||
|
"shareMethodOriginalFileTitle": "Original file",
|
||||||
|
"@shareMethodOriginalFileTitle": {
|
||||||
|
"description": "Share the original file"
|
||||||
|
},
|
||||||
|
"shareMethodOriginalFileDescription": "Download the original file and share it to other apps",
|
||||||
"shareMethodPublicLinkTitle": "Public link",
|
"shareMethodPublicLinkTitle": "Public link",
|
||||||
"@shareMethodPublicLinkTitle": {
|
"@shareMethodPublicLinkTitle": {
|
||||||
"description": "Create a share link on server and share it"
|
"description": "Create a share link on server and share it"
|
||||||
|
|
|
@ -41,6 +41,10 @@
|
||||||
"sortOptionFilenameDescendingLabel",
|
"sortOptionFilenameDescendingLabel",
|
||||||
"sortOptionManualLabel",
|
"sortOptionManualLabel",
|
||||||
"helpButtonLabel",
|
"helpButtonLabel",
|
||||||
|
"shareMethodPreviewTitle",
|
||||||
|
"shareMethodPreviewDescription",
|
||||||
|
"shareMethodOriginalFileTitle",
|
||||||
|
"shareMethodOriginalFileDescription",
|
||||||
"collectionSharingLabel",
|
"collectionSharingLabel",
|
||||||
"fileLastSharedDescription",
|
"fileLastSharedDescription",
|
||||||
"fileLastSharedByOthersDescription",
|
"fileLastSharedByOthersDescription",
|
||||||
|
@ -210,8 +214,10 @@
|
||||||
"slideshowSetupDialogRepeatTitle",
|
"slideshowSetupDialogRepeatTitle",
|
||||||
"linkCopiedNotification",
|
"linkCopiedNotification",
|
||||||
"shareMethodDialogTitle",
|
"shareMethodDialogTitle",
|
||||||
"shareMethodFileTitle",
|
"shareMethodPreviewTitle",
|
||||||
"shareMethodFileDescription",
|
"shareMethodPreviewDescription",
|
||||||
|
"shareMethodOriginalFileTitle",
|
||||||
|
"shareMethodOriginalFileDescription",
|
||||||
"shareMethodPublicLinkTitle",
|
"shareMethodPublicLinkTitle",
|
||||||
"shareMethodPublicLinkDescription",
|
"shareMethodPublicLinkDescription",
|
||||||
"shareMethodPasswordLinkTitle",
|
"shareMethodPasswordLinkTitle",
|
||||||
|
@ -346,6 +352,10 @@
|
||||||
"settingsMemoriesRangeTitle",
|
"settingsMemoriesRangeTitle",
|
||||||
"settingsMemoriesRangeValueText",
|
"settingsMemoriesRangeValueText",
|
||||||
"settingsDoubleTapExitTitle",
|
"settingsDoubleTapExitTitle",
|
||||||
|
"shareMethodPreviewTitle",
|
||||||
|
"shareMethodPreviewDescription",
|
||||||
|
"shareMethodOriginalFileTitle",
|
||||||
|
"shareMethodOriginalFileDescription",
|
||||||
"enhanceStyleTransferStyleDialogTitle",
|
"enhanceStyleTransferStyleDialogTitle",
|
||||||
"doubleTapExitNotification",
|
"doubleTapExitNotification",
|
||||||
"imageEditDiscardDialogTitle",
|
"imageEditDiscardDialogTitle",
|
||||||
|
@ -397,6 +407,10 @@
|
||||||
"settingsMemoriesRangeTitle",
|
"settingsMemoriesRangeTitle",
|
||||||
"settingsMemoriesRangeValueText",
|
"settingsMemoriesRangeValueText",
|
||||||
"rootPickerSkipConfirmationDialogContent2",
|
"rootPickerSkipConfirmationDialogContent2",
|
||||||
|
"shareMethodPreviewTitle",
|
||||||
|
"shareMethodPreviewDescription",
|
||||||
|
"shareMethodOriginalFileTitle",
|
||||||
|
"shareMethodOriginalFileDescription",
|
||||||
"imageEditToolbarColorLabel",
|
"imageEditToolbarColorLabel",
|
||||||
"imageEditToolbarTransformLabel",
|
"imageEditToolbarTransformLabel",
|
||||||
"imageEditTransformOrientation",
|
"imageEditTransformOrientation",
|
||||||
|
@ -415,6 +429,10 @@
|
||||||
"settingsPhotosPageTitle",
|
"settingsPhotosPageTitle",
|
||||||
"settingsMemoriesRangeTitle",
|
"settingsMemoriesRangeTitle",
|
||||||
"settingsMemoriesRangeValueText",
|
"settingsMemoriesRangeValueText",
|
||||||
|
"shareMethodPreviewTitle",
|
||||||
|
"shareMethodPreviewDescription",
|
||||||
|
"shareMethodOriginalFileTitle",
|
||||||
|
"shareMethodOriginalFileDescription",
|
||||||
"imageEditToolbarColorLabel",
|
"imageEditToolbarColorLabel",
|
||||||
"imageEditToolbarTransformLabel",
|
"imageEditToolbarTransformLabel",
|
||||||
"imageEditTransformOrientation",
|
"imageEditTransformOrientation",
|
||||||
|
@ -451,6 +469,10 @@
|
||||||
"helpTooltip",
|
"helpTooltip",
|
||||||
"helpButtonLabel",
|
"helpButtonLabel",
|
||||||
"removeFromAlbumTooltip",
|
"removeFromAlbumTooltip",
|
||||||
|
"shareMethodPreviewTitle",
|
||||||
|
"shareMethodPreviewDescription",
|
||||||
|
"shareMethodOriginalFileTitle",
|
||||||
|
"shareMethodOriginalFileDescription",
|
||||||
"enhanceTooltip",
|
"enhanceTooltip",
|
||||||
"enhanceButtonLabel",
|
"enhanceButtonLabel",
|
||||||
"enhanceIntroDialogTitle",
|
"enhanceIntroDialogTitle",
|
||||||
|
@ -527,6 +549,10 @@
|
||||||
"settingsPhotosTabSortByNameTitle",
|
"settingsPhotosTabSortByNameTitle",
|
||||||
"sortOptionFilenameAscendingLabel",
|
"sortOptionFilenameAscendingLabel",
|
||||||
"sortOptionFilenameDescendingLabel",
|
"sortOptionFilenameDescendingLabel",
|
||||||
|
"shareMethodPreviewTitle",
|
||||||
|
"shareMethodPreviewDescription",
|
||||||
|
"shareMethodOriginalFileTitle",
|
||||||
|
"shareMethodOriginalFileDescription",
|
||||||
"createCollectionTooltip",
|
"createCollectionTooltip",
|
||||||
"createCollectionDialogAlbumLabel",
|
"createCollectionDialogAlbumLabel",
|
||||||
"createCollectionDialogAlbumDescription",
|
"createCollectionDialogAlbumDescription",
|
||||||
|
@ -624,6 +650,10 @@
|
||||||
"settingsPhotosTabSortByNameTitle",
|
"settingsPhotosTabSortByNameTitle",
|
||||||
"sortOptionFilenameAscendingLabel",
|
"sortOptionFilenameAscendingLabel",
|
||||||
"sortOptionFilenameDescendingLabel",
|
"sortOptionFilenameDescendingLabel",
|
||||||
|
"shareMethodPreviewTitle",
|
||||||
|
"shareMethodPreviewDescription",
|
||||||
|
"shareMethodOriginalFileTitle",
|
||||||
|
"shareMethodOriginalFileDescription",
|
||||||
"enhanceTooltip",
|
"enhanceTooltip",
|
||||||
"enhanceButtonLabel",
|
"enhanceButtonLabel",
|
||||||
"enhanceIntroDialogTitle",
|
"enhanceIntroDialogTitle",
|
||||||
|
@ -700,6 +730,10 @@
|
||||||
"settingsPhotosTabSortByNameTitle",
|
"settingsPhotosTabSortByNameTitle",
|
||||||
"sortOptionFilenameAscendingLabel",
|
"sortOptionFilenameAscendingLabel",
|
||||||
"sortOptionFilenameDescendingLabel",
|
"sortOptionFilenameDescendingLabel",
|
||||||
|
"shareMethodPreviewTitle",
|
||||||
|
"shareMethodPreviewDescription",
|
||||||
|
"shareMethodOriginalFileTitle",
|
||||||
|
"shareMethodOriginalFileDescription",
|
||||||
"enhanceTooltip",
|
"enhanceTooltip",
|
||||||
"enhanceButtonLabel",
|
"enhanceButtonLabel",
|
||||||
"enhanceIntroDialogTitle",
|
"enhanceIntroDialogTitle",
|
||||||
|
@ -776,6 +810,10 @@
|
||||||
"settingsPhotosTabSortByNameTitle",
|
"settingsPhotosTabSortByNameTitle",
|
||||||
"sortOptionFilenameAscendingLabel",
|
"sortOptionFilenameAscendingLabel",
|
||||||
"sortOptionFilenameDescendingLabel",
|
"sortOptionFilenameDescendingLabel",
|
||||||
|
"shareMethodPreviewTitle",
|
||||||
|
"shareMethodPreviewDescription",
|
||||||
|
"shareMethodOriginalFileTitle",
|
||||||
|
"shareMethodOriginalFileDescription",
|
||||||
"enhanceTooltip",
|
"enhanceTooltip",
|
||||||
"enhanceButtonLabel",
|
"enhanceButtonLabel",
|
||||||
"enhanceIntroDialogTitle",
|
"enhanceIntroDialogTitle",
|
||||||
|
@ -852,6 +890,10 @@
|
||||||
"settingsPhotosTabSortByNameTitle",
|
"settingsPhotosTabSortByNameTitle",
|
||||||
"sortOptionFilenameAscendingLabel",
|
"sortOptionFilenameAscendingLabel",
|
||||||
"sortOptionFilenameDescendingLabel",
|
"sortOptionFilenameDescendingLabel",
|
||||||
|
"shareMethodPreviewTitle",
|
||||||
|
"shareMethodPreviewDescription",
|
||||||
|
"shareMethodOriginalFileTitle",
|
||||||
|
"shareMethodOriginalFileDescription",
|
||||||
"enhanceTooltip",
|
"enhanceTooltip",
|
||||||
"enhanceButtonLabel",
|
"enhanceButtonLabel",
|
||||||
"enhanceIntroDialogTitle",
|
"enhanceIntroDialogTitle",
|
||||||
|
|
|
@ -10,6 +10,7 @@ import 'package:nc_photos/app_localizations.dart';
|
||||||
import 'package:nc_photos/debug_util.dart';
|
import 'package:nc_photos/debug_util.dart';
|
||||||
import 'package:nc_photos/di_container.dart';
|
import 'package:nc_photos/di_container.dart';
|
||||||
import 'package:nc_photos/entity/file.dart';
|
import 'package:nc_photos/entity/file.dart';
|
||||||
|
import 'package:nc_photos/entity/file_util.dart' as file_util;
|
||||||
import 'package:nc_photos/entity/local_file.dart';
|
import 'package:nc_photos/entity/local_file.dart';
|
||||||
import 'package:nc_photos/entity/share.dart';
|
import 'package:nc_photos/entity/share.dart';
|
||||||
import 'package:nc_photos/entity/share/data_source.dart';
|
import 'package:nc_photos/entity/share/data_source.dart';
|
||||||
|
@ -24,6 +25,7 @@ import 'package:nc_photos/use_case/copy.dart';
|
||||||
import 'package:nc_photos/use_case/create_dir.dart';
|
import 'package:nc_photos/use_case/create_dir.dart';
|
||||||
import 'package:nc_photos/use_case/create_share.dart';
|
import 'package:nc_photos/use_case/create_share.dart';
|
||||||
import 'package:nc_photos/use_case/download_file.dart';
|
import 'package:nc_photos/use_case/download_file.dart';
|
||||||
|
import 'package:nc_photos/use_case/download_preview.dart';
|
||||||
import 'package:nc_photos/use_case/share_local.dart';
|
import 'package:nc_photos/use_case/share_local.dart';
|
||||||
import 'package:nc_photos/widget/processing_dialog.dart';
|
import 'package:nc_photos/widget/processing_dialog.dart';
|
||||||
import 'package:nc_photos/widget/share_link_multiple_files_dialog.dart';
|
import 'package:nc_photos/widget/share_link_multiple_files_dialog.dart';
|
||||||
|
@ -67,7 +69,7 @@ class ShareHandler {
|
||||||
|
|
||||||
Future<void> shareFiles(Account account, List<File> files) async {
|
Future<void> shareFiles(Account account, List<File> files) async {
|
||||||
try {
|
try {
|
||||||
final method = await _askShareMethod();
|
final method = await _askShareMethod(files);
|
||||||
if (method == null) {
|
if (method == null) {
|
||||||
// user canceled
|
// user canceled
|
||||||
return;
|
return;
|
||||||
|
@ -75,6 +77,8 @@ class ShareHandler {
|
||||||
return await _shareAsLink(account, files, false);
|
return await _shareAsLink(account, files, false);
|
||||||
} else if (method == ShareMethod.passwordLink) {
|
} else if (method == ShareMethod.passwordLink) {
|
||||||
return await _shareAsLink(account, files, true);
|
return await _shareAsLink(account, files, true);
|
||||||
|
} else if (method == ShareMethod.preview) {
|
||||||
|
return await _shareAsPreview(account, files);
|
||||||
} else {
|
} else {
|
||||||
return await _shareAsFile(account, files);
|
return await _shareAsFile(account, files);
|
||||||
}
|
}
|
||||||
|
@ -91,9 +95,59 @@ class ShareHandler {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<ShareMethod?> _askShareMethod() {
|
Future<ShareMethod?> _askShareMethod(List<File> files) {
|
||||||
return showDialog<ShareMethod>(
|
return showDialog<ShareMethod>(
|
||||||
context: context, builder: (context) => const ShareMethodDialog());
|
context: context,
|
||||||
|
builder: (context) => ShareMethodDialog(
|
||||||
|
isSupportPerview: files.any((f) => file_util.isSupportedImageFormat(f)),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> _shareAsPreview(Account account, List<File> files) async {
|
||||||
|
assert(platform_k.isAndroid);
|
||||||
|
final controller = StreamController<String>();
|
||||||
|
unawaited(
|
||||||
|
showDialog(
|
||||||
|
context: context,
|
||||||
|
builder: (context) => StreamBuilder(
|
||||||
|
stream: controller.stream,
|
||||||
|
builder: (context, snapshot) => ProcessingDialog(
|
||||||
|
text: L10n.global().shareDownloadingDialogContent +
|
||||||
|
(snapshot.hasData ? " ${snapshot.data}" : ""),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
final results = <Tuple2<File, dynamic>>[];
|
||||||
|
for (final pair in files.withIndex()) {
|
||||||
|
final i = pair.item1, f = pair.item2;
|
||||||
|
controller.add("($i/${files.length})");
|
||||||
|
try {
|
||||||
|
final dynamic uri;
|
||||||
|
if (file_util.isSupportedImageFormat(f) &&
|
||||||
|
f.contentType != "image/gif") {
|
||||||
|
uri = await DownloadPreview()(account, f);
|
||||||
|
} else {
|
||||||
|
uri = await DownloadFile()(account, f);
|
||||||
|
}
|
||||||
|
results.add(Tuple2(f, uri));
|
||||||
|
} catch (e, stacktrace) {
|
||||||
|
_log.shout(
|
||||||
|
"[_shareAsPreview] Failed while DownloadPreview", e, stacktrace);
|
||||||
|
SnackBarManager().showSnackBar(SnackBar(
|
||||||
|
content: Text(exception_util.toUserString(e)),
|
||||||
|
duration: k.snackBarDurationNormal,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// dismiss the dialog
|
||||||
|
Navigator.of(context).pop();
|
||||||
|
|
||||||
|
final share = AndroidFileShare(
|
||||||
|
results.map((e) => e.item2 as String).toList(),
|
||||||
|
results.map((e) => e.item1.contentType).toList());
|
||||||
|
return share.share();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _shareAsFile(Account account, List<File> files) async {
|
Future<void> _shareAsFile(Account account, List<File> files) async {
|
||||||
|
|
26
app/lib/use_case/download_preview.dart
Normal file
26
app/lib/use_case/download_preview.dart
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import 'package:nc_photos/account.dart';
|
||||||
|
import 'package:nc_photos/api/api.dart';
|
||||||
|
import 'package:nc_photos/api/api_util.dart' as api_util;
|
||||||
|
import 'package:nc_photos/cache_manager_util.dart';
|
||||||
|
import 'package:nc_photos/entity/file.dart';
|
||||||
|
import 'package:nc_photos/k.dart' as k;
|
||||||
|
import 'package:nc_photos/platform/k.dart' as platform_k;
|
||||||
|
import 'package:nc_photos_plugin/nc_photos_plugin.dart';
|
||||||
|
|
||||||
|
class DownloadPreview {
|
||||||
|
Future<dynamic> call(Account account, File file) async {
|
||||||
|
assert(platform_k.isAndroid);
|
||||||
|
final previewUrl = api_util.getFilePreviewUrl(
|
||||||
|
account,
|
||||||
|
file,
|
||||||
|
width: k.photoLargeSize,
|
||||||
|
height: k.photoLargeSize,
|
||||||
|
a: true,
|
||||||
|
);
|
||||||
|
final fileInfo =
|
||||||
|
await LargeImageCacheManager.inst.getSingleFile(previewUrl, headers: {
|
||||||
|
"authorization": Api.getAuthorizationHeaderValue(account),
|
||||||
|
});
|
||||||
|
return ContentUri.getUriForFile(fileInfo.absolute.path);
|
||||||
|
}
|
||||||
|
}
|
|
@ -4,30 +4,43 @@ import 'package:nc_photos/platform/k.dart' as platform_k;
|
||||||
|
|
||||||
enum ShareMethod {
|
enum ShareMethod {
|
||||||
file,
|
file,
|
||||||
|
preview,
|
||||||
publicLink,
|
publicLink,
|
||||||
passwordLink,
|
passwordLink,
|
||||||
}
|
}
|
||||||
|
|
||||||
class ShareMethodDialog extends StatelessWidget {
|
class ShareMethodDialog extends StatelessWidget {
|
||||||
const ShareMethodDialog({
|
const ShareMethodDialog({
|
||||||
Key? key,
|
super.key,
|
||||||
}) : super(key: key);
|
required this.isSupportPerview,
|
||||||
|
});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
build(BuildContext context) {
|
build(BuildContext context) {
|
||||||
return SimpleDialog(
|
return SimpleDialog(
|
||||||
title: Text(L10n.global().shareMethodDialogTitle),
|
title: Text(L10n.global().shareMethodDialogTitle),
|
||||||
children: [
|
children: [
|
||||||
if (platform_k.isAndroid)
|
if (platform_k.isAndroid) ...[
|
||||||
|
if (isSupportPerview)
|
||||||
|
SimpleDialogOption(
|
||||||
|
child: ListTile(
|
||||||
|
title: Text(L10n.global().shareMethodPreviewTitle),
|
||||||
|
subtitle: Text(L10n.global().shareMethodPreviewDescription),
|
||||||
|
),
|
||||||
|
onPressed: () {
|
||||||
|
Navigator.of(context).pop(ShareMethod.preview);
|
||||||
|
},
|
||||||
|
),
|
||||||
SimpleDialogOption(
|
SimpleDialogOption(
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
title: Text(L10n.global().shareMethodFileTitle),
|
title: Text(L10n.global().shareMethodOriginalFileTitle),
|
||||||
subtitle: Text(L10n.global().shareMethodFileDescription),
|
subtitle: Text(L10n.global().shareMethodOriginalFileDescription),
|
||||||
),
|
),
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop(ShareMethod.file);
|
Navigator.of(context).pop(ShareMethod.file);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
|
],
|
||||||
SimpleDialogOption(
|
SimpleDialogOption(
|
||||||
child: ListTile(
|
child: ListTile(
|
||||||
title: Text(L10n.global().shareMethodPublicLinkTitle),
|
title: Text(L10n.global().shareMethodPublicLinkTitle),
|
||||||
|
@ -49,4 +62,6 @@ class ShareMethodDialog extends StatelessWidget {
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final bool isSupportPerview;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,8 +2,10 @@ package com.nkming.nc_photos.plugin
|
||||||
|
|
||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.net.Uri
|
import android.net.Uri
|
||||||
|
import androidx.core.content.FileProvider
|
||||||
import io.flutter.plugin.common.MethodCall
|
import io.flutter.plugin.common.MethodCall
|
||||||
import io.flutter.plugin.common.MethodChannel
|
import io.flutter.plugin.common.MethodChannel
|
||||||
|
import java.io.File
|
||||||
import java.io.FileNotFoundException
|
import java.io.FileNotFoundException
|
||||||
|
|
||||||
class ContentUriChannelHandler(context: Context) :
|
class ContentUriChannelHandler(context: Context) :
|
||||||
|
@ -24,6 +26,14 @@ class ContentUriChannelHandler(context: Context) :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
"getUriForFile" -> {
|
||||||
|
try {
|
||||||
|
getUriForFile(call.argument("filePath")!!, result)
|
||||||
|
} catch (e: Throwable) {
|
||||||
|
result.error("systemException", e.toString(), null)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
else -> result.notImplemented()
|
else -> result.notImplemented()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -46,5 +56,18 @@ class ContentUriChannelHandler(context: Context) :
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun getUriForFile(filePath: String, result: MethodChannel.Result) {
|
||||||
|
try {
|
||||||
|
val file = File(filePath)
|
||||||
|
val contentUri = FileProvider.getUriForFile(
|
||||||
|
context, "${context.packageName}.fileprovider", file
|
||||||
|
)
|
||||||
|
result.success(contentUri.toString())
|
||||||
|
} catch (e: IllegalArgumentException) {
|
||||||
|
logE(TAG, "[getUriForFile] Unsupported file path: $filePath")
|
||||||
|
throw e
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private val context = context
|
private val context = context
|
||||||
}
|
}
|
||||||
|
|
|
@ -20,6 +20,12 @@ class ContentUri {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future<String> getUriForFile(String filePath) async {
|
||||||
|
return await _methodChannel.invokeMethod("getUriForFile", <String, dynamic>{
|
||||||
|
"filePath": filePath,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
static const _methodChannel = MethodChannel("${k.libId}/content_uri_method");
|
static const _methodChannel = MethodChannel("${k.libId}/content_uri_method");
|
||||||
|
|
||||||
static const _exceptionFileNotFound = "fileNotFoundException";
|
static const _exceptionFileNotFound = "fileNotFoundException";
|
||||||
|
|
Loading…
Add table
Reference in a new issue