From 2a895e92454451e1f7fcc1454a9fba38e07312de Mon Sep 17 00:00:00 2001 From: ashilkn Date: Mon, 11 Mar 2024 16:39:09 +0530 Subject: [PATCH] create HomeWidgetService --- mobile/lib/core/configuration.dart | 4 +- mobile/lib/main.dart | 7 +- mobile/lib/services/favorites_service.dart | 8 - mobile/lib/services/home_widget_service.dart | 156 +++++++++++++++++++ mobile/lib/utils/home_widget_util.dart | 147 ----------------- 5 files changed, 162 insertions(+), 160 deletions(-) create mode 100644 mobile/lib/services/home_widget_service.dart delete mode 100644 mobile/lib/utils/home_widget_util.dart diff --git a/mobile/lib/core/configuration.dart b/mobile/lib/core/configuration.dart index f82486631..cd6b5156e 100644 --- a/mobile/lib/core/configuration.dart +++ b/mobile/lib/core/configuration.dart @@ -24,6 +24,7 @@ import 'package:photos/models/private_key_attributes.dart'; import 'package:photos/services/billing_service.dart'; import 'package:photos/services/collections_service.dart'; import 'package:photos/services/favorites_service.dart'; +import "package:photos/services/home_widget_service.dart"; import 'package:photos/services/ignored_files_service.dart'; import 'package:photos/services/machine_learning/semantic_search/semantic_search_service.dart'; import 'package:photos/services/memories_service.dart'; @@ -31,7 +32,6 @@ import 'package:photos/services/search_service.dart'; import 'package:photos/services/sync_service.dart'; import 'package:photos/utils/crypto_util.dart'; import 'package:photos/utils/file_uploader.dart'; -import "package:photos/utils/home_widget_util.dart"; import 'package:photos/utils/validator_util.dart'; import 'package:shared_preferences/shared_preferences.dart'; import "package:tuple/tuple.dart"; @@ -175,7 +175,7 @@ class Configuration { MemoriesService.instance.clearCache(); BillingService.instance.clearCache(); SearchService.instance.clearCache(); - unawaited(clearHomeWidget()); + unawaited(HomeWidgetService.instance.clearHomeWidget()); Bus.instance.fire(UserLoggedOutEvent()); } else { await _preferences.setBool("auto_logout", true); diff --git a/mobile/lib/main.dart b/mobile/lib/main.dart index 90fc60d96..83cb7a9bf 100644 --- a/mobile/lib/main.dart +++ b/mobile/lib/main.dart @@ -27,6 +27,7 @@ import 'package:photos/services/collections_service.dart'; import "package:photos/services/entity_service.dart"; import 'package:photos/services/favorites_service.dart'; import 'package:photos/services/feature_flag_service.dart'; +import 'package:photos/services/home_widget_service.dart'; import 'package:photos/services/local_file_update_service.dart'; import 'package:photos/services/local_sync_service.dart'; import "package:photos/services/location_service.dart"; @@ -46,7 +47,6 @@ import 'package:photos/ui/tools/app_lock.dart'; import 'package:photos/ui/tools/lock_screen.dart'; import 'package:photos/utils/crypto_util.dart'; import 'package:photos/utils/file_uploader.dart'; -import "package:photos/utils/home_widget_util.dart"; import 'package:photos/utils/local_settings.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -110,8 +110,8 @@ ThemeMode _themeMode(AdaptiveThemeMode? savedThemeMode) { Future _homeWidgetSync() async { if (!Platform.isAndroid) return; try { - if (await countHomeWidgets() != 0) { - await initHomeWidget(); + if (await HomeWidgetService.instance.countHomeWidgets() != 0) { + await HomeWidgetService.instance.initHomeWidget(); } } catch (e, s) { _logger.severe("Error in initSlideshowWidget", e, s); @@ -210,6 +210,7 @@ Future _init(bool isBackground, {String via = ''}) async { LocalFileUpdateService.instance.init(preferences); SearchService.instance.init(); StorageBonusService.instance.init(preferences); + HomeWidgetService.instance.initHomeWidget(); if (Platform.isIOS) { // ignore: unawaited_futures PushService.instance.init().then((_) { diff --git a/mobile/lib/services/favorites_service.dart b/mobile/lib/services/favorites_service.dart index 6163aa614..5388a6e67 100644 --- a/mobile/lib/services/favorites_service.dart +++ b/mobile/lib/services/favorites_service.dart @@ -15,7 +15,6 @@ import 'package:photos/services/collections_service.dart'; import 'package:photos/services/remote_sync_service.dart'; import 'package:photos/ui/actions/collection/collection_sharing_actions.dart'; import 'package:photos/utils/crypto_util.dart'; -import "package:photos/utils/home_widget_util.dart"; class FavoritesService { late Configuration _config; @@ -52,7 +51,6 @@ class FavoritesService { } }); await _warmUpCache(); - await _checkHomeWidget(); } void dispose() { @@ -68,12 +66,6 @@ class FavoritesService { } } - Future _checkHomeWidget() async { - if (await countHomeWidgets() > 0 && hasFavorites()) { - await initHomeWidget(); - } - } - bool hasFavorites() { return _cachedFavUploadedIDs.isNotEmpty; } diff --git a/mobile/lib/services/home_widget_service.dart b/mobile/lib/services/home_widget_service.dart new file mode 100644 index 000000000..415e8ed40 --- /dev/null +++ b/mobile/lib/services/home_widget_service.dart @@ -0,0 +1,156 @@ +import "dart:math"; + +import "package:flutter/material.dart"; +import 'package:home_widget/home_widget.dart' as hw; +import "package:logging/logging.dart"; +import "package:photos/core/configuration.dart"; +import "package:photos/core/constants.dart"; +import "package:photos/db/files_db.dart"; +import "package:photos/models/file/file_type.dart"; +import "package:photos/services/favorites_service.dart"; +import "package:photos/utils/file_util.dart"; +import "package:photos/utils/preload_util.dart"; + +class HomeWidgetService { + final Logger _logger = Logger((HomeWidgetService).toString()); + + HomeWidgetService._privateConstructor(); + + static final HomeWidgetService instance = + HomeWidgetService._privateConstructor(); + Future countHomeWidgets() async { + return await hw.HomeWidget.getWidgetCount( + name: 'SlideshowWidgetProvider', + androidName: 'SlideshowWidgetProvider', + qualifiedAndroidName: 'io.ente.photos.SlideshowWidgetProvider', + iOSName: 'SlideshowWidget', + ) ?? + 0; + } + + Future initHomeWidget() async { + final isLoggedIn = Configuration.instance.isLoggedIn(); + + if (!isLoggedIn) { + await clearHomeWidget(); + _logger.info("user not logged in"); + return; + } + + final collectionID = + await FavoritesService.instance.getFavoriteCollectionID(); + if (collectionID == null) { + await clearHomeWidget(); + _logger.info("Favorite collection not found"); + throw Exception("Favorite collection not found"); + } + + try { + await hw.HomeWidget.setAppGroupId(iOSGroupID); + final res = await FilesDB.instance.getFilesInCollection( + collectionID, + galleryLoadStartTime, + galleryLoadEndTime, + ); + + final previousGeneratedId = + await hw.HomeWidget.getWidgetData("home_widget_last_img"); + + if (res.files.length == 1 && + res.files[0].generatedID == previousGeneratedId) { + _logger + .info("Only one image found and it's the same as the previous one"); + return; + } + if (res.files.isEmpty) { + await clearHomeWidget(); + _logger.info("No images found"); + return; + } + final files = res.files.where( + (element) => + element.generatedID != previousGeneratedId && + element.fileType == FileType.image, + ); + + final randomNumber = Random().nextInt(files.length); + final randomFile = files.elementAt(randomNumber); + final fullImage = await getFileFromServer(randomFile); + if (fullImage == null) throw Exception("File not found"); + + Image img = Image.file(fullImage); + var imgProvider = img.image; + await PreloadImage.loadImage(imgProvider); + + img = Image.file(fullImage); + imgProvider = img.image; + + final image = await decodeImageFromList(await fullImage.readAsBytes()); + final width = image.width.toDouble(); + final height = image.height.toDouble(); + final size = min(min(width, height), 1024.0); + + final widget = ClipRRect( + borderRadius: BorderRadius.circular(32), + child: Container( + width: size, + height: size, + decoration: BoxDecoration( + color: Colors.black, + image: DecorationImage(image: imgProvider, fit: BoxFit.cover), + ), + ), + ); + + await hw.HomeWidget.renderFlutterWidget( + widget, + logicalSize: Size(size, size), + key: "slideshow", + ); + + if (randomFile.generatedID != null) { + await hw.HomeWidget.saveWidgetData( + "home_widget_last_img", + randomFile.generatedID!, + ); + } + + await hw.HomeWidget.updateWidget( + name: 'SlideshowWidgetProvider', + androidName: 'SlideshowWidgetProvider', + qualifiedAndroidName: 'io.ente.photos.SlideshowWidgetProvider', + iOSName: 'SlideshowWidget', + ); + + _logger.info( + ">>> SlideshowWidget rendered with size ${width}x$height", + ); + } catch (_) { + throw Exception("Error rendering widget"); + } + } + + Future clearHomeWidget() async { + final previousGeneratedId = + await hw.HomeWidget.getWidgetData("home_widget_last_img"); + if (previousGeneratedId == null) return; + + _logger.info("Clearing SlideshowWidget"); + await hw.HomeWidget.saveWidgetData( + "slideshow", + null, + ); + + await hw.HomeWidget.updateWidget( + name: 'SlideshowWidgetProvider', + androidName: 'SlideshowWidgetProvider', + qualifiedAndroidName: 'io.ente.photos.SlideshowWidgetProvider', + iOSName: 'SlideshowWidget', + ); + await hw.HomeWidget.saveWidgetData( + "home_widget_last_img", + null, + ); + _logger.info(">>> SlideshowWidget cleared"); + } +} diff --git a/mobile/lib/utils/home_widget_util.dart b/mobile/lib/utils/home_widget_util.dart deleted file mode 100644 index 74839540f..000000000 --- a/mobile/lib/utils/home_widget_util.dart +++ /dev/null @@ -1,147 +0,0 @@ -import "dart:math"; - -import "package:flutter/material.dart"; -import 'package:home_widget/home_widget.dart' as hw; -import "package:logging/logging.dart"; -import "package:photos/core/configuration.dart"; -import "package:photos/core/constants.dart"; -import "package:photos/db/files_db.dart"; -import "package:photos/models/file/file_type.dart"; -import "package:photos/services/favorites_service.dart"; -import "package:photos/utils/file_util.dart"; -import "package:photos/utils/preload_util.dart"; - -Future countHomeWidgets() async { - return await hw.HomeWidget.getWidgetCount( - name: 'SlideshowWidgetProvider', - androidName: 'SlideshowWidgetProvider', - qualifiedAndroidName: 'io.ente.photos.SlideshowWidgetProvider', - iOSName: 'SlideshowWidget', - ) ?? - 0; -} - -Future initHomeWidget() async { - final Logger logger = Logger("initHomeWidget"); - final user = Configuration.instance.getUserID(); - - if (user == null) { - await clearHomeWidget(); - throw Exception("User not found"); - } - - final collectionID = - await FavoritesService.instance.getFavoriteCollectionID(); - if (collectionID == null) { - await clearHomeWidget(); - throw Exception("Collection not found"); - } - - try { - await hw.HomeWidget.setAppGroupId(iOSGroupID); - final res = await FilesDB.instance.getFilesInCollection( - collectionID, - galleryLoadStartTime, - galleryLoadEndTime, - ); - - final previousGeneratedId = - await hw.HomeWidget.getWidgetData("home_widget_last_img"); - - if (res.files.length == 1 && - res.files[0].generatedID == previousGeneratedId) { - logger.info("Only one image found and it's the same as the previous one"); - return; - } - if (res.files.isEmpty) { - await clearHomeWidget(); - return; - } - final files = res.files.where( - (element) => - element.generatedID != previousGeneratedId && - element.fileType == FileType.image, - ); - - final randomNumber = Random().nextInt(files.length); - final randomFile = files.elementAt(randomNumber); - final fullImage = await getFileFromServer(randomFile); - if (fullImage == null) throw Exception("File not found"); - - Image img = Image.file(fullImage); - var imgProvider = img.image; - await PreloadImage.loadImage(imgProvider); - - img = Image.file(fullImage); - imgProvider = img.image; - - final image = await decodeImageFromList(await fullImage.readAsBytes()); - final width = image.width.toDouble(); - final height = image.height.toDouble(); - final size = min(min(width, height), 1024.0); - - final widget = ClipRRect( - borderRadius: BorderRadius.circular(32), - child: Container( - width: size, - height: size, - decoration: BoxDecoration( - color: Colors.black, - image: DecorationImage(image: imgProvider, fit: BoxFit.cover), - ), - ), - ); - - await hw.HomeWidget.renderFlutterWidget( - widget, - logicalSize: Size(size, size), - key: "slideshow", - ); - - if (randomFile.generatedID != null) { - await hw.HomeWidget.saveWidgetData( - "home_widget_last_img", - randomFile.generatedID!, - ); - } - - await hw.HomeWidget.updateWidget( - name: 'SlideshowWidgetProvider', - androidName: 'SlideshowWidgetProvider', - qualifiedAndroidName: 'io.ente.photos.SlideshowWidgetProvider', - iOSName: 'SlideshowWidget', - ); - - logger.info( - ">>> SlideshowWidget rendered with size ${width}x$height", - ); - } catch (_) { - throw Exception("Error rendering widget"); - } -} - -Future clearHomeWidget() async { - final previousGeneratedId = - await hw.HomeWidget.getWidgetData("home_widget_last_img"); - if (previousGeneratedId == null) return; - - final Logger logger = Logger("clearHomeWidget"); - - logger.info("Clearing SlideshowWidget"); - await hw.HomeWidget.saveWidgetData( - "slideshow", - null, - ); - - await hw.HomeWidget.updateWidget( - name: 'SlideshowWidgetProvider', - androidName: 'SlideshowWidgetProvider', - qualifiedAndroidName: 'io.ente.photos.SlideshowWidgetProvider', - iOSName: 'SlideshowWidget', - ); - await hw.HomeWidget.saveWidgetData( - "home_widget_last_img", - null, - ); - logger.info(">>> SlideshowWidget cleared"); -}