From 6bd307a2cddd4879872106c180e114dc24ac3c5a Mon Sep 17 00:00:00 2001 From: Aman Raj Singh Mourya Date: Sat, 8 Jun 2024 14:09:00 +0530 Subject: [PATCH 1/4] Optimize image upload by using XFile.fromData instead of saving to file --- .../file_selection_actions_widget.dart | 43 +++---------------- mobile/lib/utils/share_util.dart | 12 ++++-- 2 files changed, 14 insertions(+), 41 deletions(-) diff --git a/mobile/lib/ui/viewer/actions/file_selection_actions_widget.dart b/mobile/lib/ui/viewer/actions/file_selection_actions_widget.dart index d162ec9ba4..153a6eb8e3 100644 --- a/mobile/lib/ui/viewer/actions/file_selection_actions_widget.dart +++ b/mobile/lib/ui/viewer/actions/file_selection_actions_widget.dart @@ -1,5 +1,4 @@ import "dart:async"; -import "dart:io"; import 'package:fast_base58/fast_base58.dart'; import "package:flutter/cupertino.dart"; @@ -7,7 +6,6 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import "package:logging/logging.dart"; import "package:modal_bottom_sheet/modal_bottom_sheet.dart"; -import "package:path_provider/path_provider.dart"; import 'package:photos/core/configuration.dart'; import "package:photos/core/event_bus.dart"; import "package:photos/events/people_changed_event.dart"; @@ -78,7 +76,7 @@ class _FileSelectionActionsWidgetState late CollectionActions collectionActions; late bool isCollectionOwner; final ScreenshotController screenshotController = ScreenshotController(); - late String? placeholderPath; + late Uint8List? placeholderBytes; // _cachedCollectionForSharedLink is primarily used to avoid creating duplicate // links if user keeps on creating Create link button after selecting // few files. This link is reset on any selection changed; @@ -610,23 +608,7 @@ class _FileSelectionActionsWidgetState } } - Future saveImage(Uint8List bytes) async { - String path = ""; - try { - final Directory root = await getTemporaryDirectory(); - final String directoryPath = '${root.path}/enteTempFiles'; - final DateTime timeStamp = DateTime.now(); - await Directory(directoryPath).create(recursive: true); - final String filePath = '$directoryPath/$timeStamp.jpg'; - final file = await File(filePath).writeAsBytes(bytes); - path = file.path; - } catch (e) { - _logger.severe("Failed to save placeholder image", e); - } - return path; - } - - Future _createPlaceholder( + Future _createPlaceholder( List ownedSelectedFiles, ) async { final Widget imageWidget = LinkPlaceholder( @@ -640,10 +622,7 @@ class _FileSelectionActionsWidgetState targetSize: MediaQuery.sizeOf(context), delay: const Duration(milliseconds: 100), ); - - final String onCreatedPlaceholderPath = - await saveImage(bytesOfImageToWidget); - return onCreatedPlaceholderPath; + return bytesOfImageToWidget; } Future _onSendLinkTapped() async { @@ -664,7 +643,7 @@ class _FileSelectionActionsWidgetState .createSharedCollectionLink(context, split.ownedByCurrentUser); final List ownedSelectedFiles = split.ownedByCurrentUser; - placeholderPath = await _createPlaceholder(ownedSelectedFiles); + placeholderBytes = await _createPlaceholder(ownedSelectedFiles); await dialog.hide(); await _sendLink(); widget.selectedFiles.clearAll(); @@ -778,23 +757,11 @@ class _FileSelectionActionsWidgetState "${_cachedCollectionForSharedLink!.publicURLs?.first?.url}#$collectionKey"; unawaited(Clipboard.setData(ClipboardData(text: url))); await shareImageAndUrl( - placeholderPath!, + placeholderBytes!, url, context: context, key: sendLinkButtonKey, ); - if (placeholderPath != null) { - final file = File(placeholderPath!); - try { - if (file.existsSync()) { - file.deleteSync(); - } - } catch (e) { - _logger.warning("Failed to delete the file: $e"); - } finally { - placeholderPath = null; - } - } } } diff --git a/mobile/lib/utils/share_util.dart b/mobile/lib/utils/share_util.dart index b55730439a..ab39fedf11 100644 --- a/mobile/lib/utils/share_util.dart +++ b/mobile/lib/utils/share_util.dart @@ -1,5 +1,6 @@ import 'dart:async'; import "dart:io"; +import "dart:typed_data"; import 'package:flutter/widgets.dart'; import 'package:logging/logging.dart'; @@ -228,15 +229,20 @@ void shareSelected( } Future shareImageAndUrl( - String imagePath, + Uint8List imageBytes, String url, { BuildContext? context, GlobalKey? key, }) async { final sharePosOrigin = _sharePosOrigin(context, key); - await Share.shareXFiles( - [XFile(imagePath)], + [ + XFile.fromData( + imageBytes, + name: 'placeholder_image.png', + mimeType: 'image/png', + ), + ], text: url, sharePositionOrigin: sharePosOrigin, ); From 9c1ae27a21cd4f33c435637562b365044ddb6b8d Mon Sep 17 00:00:00 2001 From: Aman Raj Singh Mourya Date: Mon, 10 Jun 2024 11:05:47 +0530 Subject: [PATCH 2/4] [mob][photos] increased delay form 100ms to 200ms for widget to image --- mobile/lib/ui/viewer/actions/file_selection_actions_widget.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mobile/lib/ui/viewer/actions/file_selection_actions_widget.dart b/mobile/lib/ui/viewer/actions/file_selection_actions_widget.dart index 153a6eb8e3..dba165a6e6 100644 --- a/mobile/lib/ui/viewer/actions/file_selection_actions_widget.dart +++ b/mobile/lib/ui/viewer/actions/file_selection_actions_widget.dart @@ -614,7 +614,7 @@ class _FileSelectionActionsWidgetState final Widget imageWidget = LinkPlaceholder( files: ownedSelectedFiles, ); - await Future.delayed(const Duration(milliseconds: 100)); + await Future.delayed(const Duration(milliseconds: 200)); final double pixelRatio = MediaQuery.of(context).devicePixelRatio; final bytesOfImageToWidget = await screenshotController.captureFromWidget( imageWidget, From e18c79c895117d768ab647c171a3749a87243251 Mon Sep 17 00:00:00 2001 From: Aman Raj Singh Mourya Date: Mon, 10 Jun 2024 15:33:19 +0530 Subject: [PATCH 3/4] [mob][photos] removed unnecessary delay --- .../ui/viewer/actions/file_selection_actions_widget.dart | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/mobile/lib/ui/viewer/actions/file_selection_actions_widget.dart b/mobile/lib/ui/viewer/actions/file_selection_actions_widget.dart index dba165a6e6..3894ecd85f 100644 --- a/mobile/lib/ui/viewer/actions/file_selection_actions_widget.dart +++ b/mobile/lib/ui/viewer/actions/file_selection_actions_widget.dart @@ -608,19 +608,18 @@ class _FileSelectionActionsWidgetState } } - Future _createPlaceholder( + Future _createPlaceholder( List ownedSelectedFiles, ) async { final Widget imageWidget = LinkPlaceholder( files: ownedSelectedFiles, ); - await Future.delayed(const Duration(milliseconds: 200)); - final double pixelRatio = MediaQuery.of(context).devicePixelRatio; + final double pixelRatio = MediaQuery.devicePixelRatioOf(context); final bytesOfImageToWidget = await screenshotController.captureFromWidget( imageWidget, pixelRatio: pixelRatio, targetSize: MediaQuery.sizeOf(context), - delay: const Duration(milliseconds: 100), + delay: const Duration(milliseconds: 300), ); return bytesOfImageToWidget; } From b8c6a67faa30fbfda1ed62115597677865f24b30 Mon Sep 17 00:00:00 2001 From: Aman Raj Singh Mourya Date: Mon, 10 Jun 2024 16:00:57 +0530 Subject: [PATCH 4/4] [mob][photos] remove null check from non-nullabe variables --- .../lib/ui/viewer/actions/file_selection_actions_widget.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mobile/lib/ui/viewer/actions/file_selection_actions_widget.dart b/mobile/lib/ui/viewer/actions/file_selection_actions_widget.dart index 3894ecd85f..c760d88f3e 100644 --- a/mobile/lib/ui/viewer/actions/file_selection_actions_widget.dart +++ b/mobile/lib/ui/viewer/actions/file_selection_actions_widget.dart @@ -76,7 +76,7 @@ class _FileSelectionActionsWidgetState late CollectionActions collectionActions; late bool isCollectionOwner; final ScreenshotController screenshotController = ScreenshotController(); - late Uint8List? placeholderBytes; + late Uint8List placeholderBytes; // _cachedCollectionForSharedLink is primarily used to avoid creating duplicate // links if user keeps on creating Create link button after selecting // few files. This link is reset on any selection changed; @@ -756,7 +756,7 @@ class _FileSelectionActionsWidgetState "${_cachedCollectionForSharedLink!.publicURLs?.first?.url}#$collectionKey"; unawaited(Clipboard.setData(ClipboardData(text: url))); await shareImageAndUrl( - placeholderBytes!, + placeholderBytes, url, context: context, key: sendLinkButtonKey,