From 35f0251064bb645540c4c0ebb8c4dd362b7f8401 Mon Sep 17 00:00:00 2001 From: laurenspriem Date: Mon, 14 Jul 2025 13:19:58 +0200 Subject: [PATCH 1/8] Remove old todos --- mobile/apps/photos/lib/models/search/search_types.dart | 2 -- 1 file changed, 2 deletions(-) diff --git a/mobile/apps/photos/lib/models/search/search_types.dart b/mobile/apps/photos/lib/models/search/search_types.dart index 2a209cafc9..3485429bc2 100644 --- a/mobile/apps/photos/lib/models/search/search_types.dart +++ b/mobile/apps/photos/lib/models/search/search_types.dart @@ -108,7 +108,6 @@ extension SectionTypeExtensions on SectionType { } } - // TODO: lau: check if we should sort moment again bool get sortByName => this != SectionType.face && this != SectionType.magic && @@ -238,7 +237,6 @@ extension SectionTypeExtensions on SectionType { case SectionType.moment: if (flagService.internalUser) { - // TODO: lau: remove this whole smart memories and moment altogether return SearchService.instance.smartMemories(context!, limit); } return SearchService.instance.getRandomMomentsSearchResults(context!); From fa6694e2f944bb460816a7b70ea65185ccc1ddd2 Mon Sep 17 00:00:00 2001 From: laurenspriem Date: Mon, 14 Jul 2025 14:41:33 +0200 Subject: [PATCH 2/8] Remove moments and disable memories debug by default --- .../lib/models/search/search_types.dart | 34 +++++++++---------- .../ui/viewer/search_tab/moments_section.dart | 12 +++---- .../lib/ui/viewer/search_tab/search_tab.dart | 15 +++++--- .../apps/photos/lib/utils/local_settings.dart | 9 +++++ 4 files changed, 42 insertions(+), 28 deletions(-) diff --git a/mobile/apps/photos/lib/models/search/search_types.dart b/mobile/apps/photos/lib/models/search/search_types.dart index 3485429bc2..e0df25fe2c 100644 --- a/mobile/apps/photos/lib/models/search/search_types.dart +++ b/mobile/apps/photos/lib/models/search/search_types.dart @@ -44,8 +44,10 @@ enum SectionType { face, magic, location, - // includes year, month , day, event ResultType - moment, + + /// WARNING: Not for production purposes, only kept for debugging memories + memoriesDebug, + album, // People section shows the files shared by other persons contacts, @@ -60,8 +62,8 @@ extension SectionTypeExtensions on SectionType { return S.of(context).people; case SectionType.magic: return S.of(context).discover; - case SectionType.moment: - return S.of(context).moments; + case SectionType.memoriesDebug: + return "Debug memories (internal)"; case SectionType.location: return S.of(context).locations; case SectionType.contacts: @@ -79,8 +81,8 @@ extension SectionTypeExtensions on SectionType { return S.of(context).searchPersonsEmptySection; case SectionType.magic: return S.of(context).searchDiscoverEmptySection; - case SectionType.moment: - return S.of(context).searchDatesEmptySection; + case SectionType.memoriesDebug: + return "For debugging for internal users only"; case SectionType.location: return S.of(context).searchLocationEmptySection; case SectionType.contacts: @@ -98,7 +100,7 @@ extension SectionTypeExtensions on SectionType { switch (this) { case SectionType.face: case SectionType.magic: - case SectionType.moment: + case SectionType.memoriesDebug: case SectionType.fileTypesAndExtension: return false; case SectionType.location: @@ -111,14 +113,14 @@ extension SectionTypeExtensions on SectionType { bool get sortByName => this != SectionType.face && this != SectionType.magic && - this != SectionType.moment && + this != SectionType.memoriesDebug && this != SectionType.contacts; bool get isEmptyCTAVisible { switch (this) { case SectionType.face: case SectionType.magic: - case SectionType.moment: + case SectionType.memoriesDebug: case SectionType.fileTypesAndExtension: return false; case SectionType.location: @@ -136,8 +138,8 @@ extension SectionTypeExtensions on SectionType { case SectionType.magic: // todo: later return "temp"; - case SectionType.moment: - return S.of(context).addNew; + case SectionType.memoriesDebug: + return "Test memories"; case SectionType.location: return S.of(context).addNew; case SectionType.contacts: @@ -155,7 +157,7 @@ extension SectionTypeExtensions on SectionType { return Icons.adaptive.arrow_forward_outlined; case SectionType.magic: return null; - case SectionType.moment: + case SectionType.memoriesDebug: return null; case SectionType.location: return Icons.add_location_alt_outlined; @@ -234,13 +236,11 @@ extension SectionTypeExtensions on SectionType { return SearchService.instance.getAllFace(limit); case SectionType.magic: return SearchService.instance.getMagicSectionResults(context!); - - case SectionType.moment: - if (flagService.internalUser) { + case SectionType.memoriesDebug: + if (flagService.internalUser && localSettings.isDebugMemoriesEnabled) { return SearchService.instance.smartMemories(context!, limit); } - return SearchService.instance.getRandomMomentsSearchResults(context!); - + return Future.value([]); case SectionType.location: return SearchService.instance.getAllLocationTags(limit); diff --git a/mobile/apps/photos/lib/ui/viewer/search_tab/moments_section.dart b/mobile/apps/photos/lib/ui/viewer/search_tab/moments_section.dart index 8ac738d70e..85496fbc90 100644 --- a/mobile/apps/photos/lib/ui/viewer/search_tab/moments_section.dart +++ b/mobile/apps/photos/lib/ui/viewer/search_tab/moments_section.dart @@ -33,11 +33,11 @@ class _MomentsSectionState extends State { super.initState(); _momentsSearchResults = widget.momentsSearchResults; - final streamsToListenTo = SectionType.moment.sectionUpdateEvents(); + final streamsToListenTo = SectionType.memoriesDebug.sectionUpdateEvents(); for (Stream stream in streamsToListenTo) { streamSubscriptions.add( stream.listen((event) async { - _momentsSearchResults = (await SectionType.moment.getData( + _momentsSearchResults = (await SectionType.memoriesDebug.getData( context, limit: kSearchSectionLimit, )) as List; @@ -74,14 +74,14 @@ class _MomentsSectionState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - SectionType.moment.sectionTitle(context), + SectionType.memoriesDebug.sectionTitle(context), style: textTheme.largeBold, ), const SizedBox(height: 24), Padding( padding: const EdgeInsets.only(left: 4), child: Text( - SectionType.moment.getEmptyStateText(context), + SectionType.memoriesDebug.getEmptyStateText(context), style: textTheme.smallMuted, ), ), @@ -89,7 +89,7 @@ class _MomentsSectionState extends State { ), ), const SizedBox(width: 8), - const SearchSectionEmptyCTAIcon(SectionType.moment), + const SearchSectionEmptyCTAIcon(SectionType.memoriesDebug), ], ), ); @@ -100,7 +100,7 @@ class _MomentsSectionState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ SectionHeader( - SectionType.moment, + SectionType.memoriesDebug, hasMore: (_momentsSearchResults.length >= kSearchSectionLimit - 1), ), diff --git a/mobile/apps/photos/lib/ui/viewer/search_tab/search_tab.dart b/mobile/apps/photos/lib/ui/viewer/search_tab/search_tab.dart index 64643232c3..935e5c8064 100644 --- a/mobile/apps/photos/lib/ui/viewer/search_tab/search_tab.dart +++ b/mobile/apps/photos/lib/ui/viewer/search_tab/search_tab.dart @@ -130,11 +130,16 @@ class _AllSearchSectionsState extends State { snapshot.data!.elementAt(index) as List, ); - case SectionType.moment: - return MomentsSection( - snapshot.data!.elementAt(index) - as List, - ); + case SectionType.memoriesDebug: + if (flagService.internalUser && + localSettings.isDebugMemoriesEnabled) { + return MomentsSection( + snapshot.data!.elementAt(index) + as List, + ); + } else { + return const SizedBox.shrink(); + } case SectionType.location: return LocationsSection( snapshot.data!.elementAt(index) diff --git a/mobile/apps/photos/lib/utils/local_settings.dart b/mobile/apps/photos/lib/utils/local_settings.dart index 4133bf0087..b5f0031152 100644 --- a/mobile/apps/photos/lib/utils/local_settings.dart +++ b/mobile/apps/photos/lib/utils/local_settings.dart @@ -26,6 +26,7 @@ class LocalSettings { static const kRateUsShownCount = "rate_us_shown_count"; static const kEnableMultiplePart = "ls.enable_multiple_part"; static const kCuratedMemoriesEnabled = "ls.curated_memories_enabled"; + static const _kDebugMemoriesEnabled = "ls.debug_memories_enabled"; static const kOnThisDayNotificationsEnabled = "ls.on_this_day_notifications_enabled"; static const kBirthdayNotificationsEnabled = @@ -118,11 +119,19 @@ class LocalSettings { bool get isSmartMemoriesEnabled => _prefs.getBool(kCuratedMemoriesEnabled) ?? true; + bool get isDebugMemoriesEnabled => + _prefs.getBool(_kDebugMemoriesEnabled) ?? false; + Future setSmartMemories(bool value) async { await _prefs.setBool(kCuratedMemoriesEnabled, value); return value; } + Future toggleDebugMemories() async { + await _prefs.setBool(_kDebugMemoriesEnabled, !isDebugMemoriesEnabled); + return isDebugMemoriesEnabled; + } + bool get isOnThisDayNotificationsEnabled => _prefs.getBool(kOnThisDayNotificationsEnabled) ?? true; From 86f14f985becce0b91a053031d5d163ceadd5288 Mon Sep 17 00:00:00 2001 From: laurenspriem Date: Mon, 14 Jul 2025 14:46:18 +0200 Subject: [PATCH 3/8] Option to debug memories --- .../settings/debug/ml_debug_section_widget.dart | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/mobile/apps/photos/lib/ui/settings/debug/ml_debug_section_widget.dart b/mobile/apps/photos/lib/ui/settings/debug/ml_debug_section_widget.dart index 7cffcf77f0..ba0d300442 100644 --- a/mobile/apps/photos/lib/ui/settings/debug/ml_debug_section_widget.dart +++ b/mobile/apps/photos/lib/ui/settings/debug/ml_debug_section_widget.dart @@ -431,6 +431,23 @@ class _MLDebugSectionWidgetState extends State { }, ), sectionOptionSpacing, + MenuItemWidget( + captionedTextWidget: const CaptionedTextWidget( + title: "Debug memories section", + ), + trailingWidget: ToggleSwitchWidget( + value: () => localSettings.isDebugMemoriesEnabled, + onChanged: () async { + await localSettings.toggleDebugMemories(); + if (mounted) { + setState(() {}); + } + }, + ), + singleBorderRadius: 8, + isGestureDetectorDisabled: true, + ), + sectionOptionSpacing, MenuItemWidget( captionedTextWidget: const CaptionedTextWidget( title: "Sync person mappings ", From 1c780c4b0207e236c411063d7d33988402423ebc Mon Sep 17 00:00:00 2001 From: laurenspriem Date: Mon, 14 Jul 2025 14:52:58 +0200 Subject: [PATCH 4/8] Rename --- ...oments_section.dart => memories_debug_section.dart} | 10 +++++----- .../photos/lib/ui/viewer/search_tab/search_tab.dart | 4 ++-- 2 files changed, 7 insertions(+), 7 deletions(-) rename mobile/apps/photos/lib/ui/viewer/search_tab/{moments_section.dart => memories_debug_section.dart} (96%) diff --git a/mobile/apps/photos/lib/ui/viewer/search_tab/moments_section.dart b/mobile/apps/photos/lib/ui/viewer/search_tab/memories_debug_section.dart similarity index 96% rename from mobile/apps/photos/lib/ui/viewer/search_tab/moments_section.dart rename to mobile/apps/photos/lib/ui/viewer/search_tab/memories_debug_section.dart index 85496fbc90..98dddae6a1 100644 --- a/mobile/apps/photos/lib/ui/viewer/search_tab/moments_section.dart +++ b/mobile/apps/photos/lib/ui/viewer/search_tab/memories_debug_section.dart @@ -16,15 +16,15 @@ import "package:photos/ui/viewer/search/search_section_cta.dart"; import "package:photos/ui/viewer/search_tab/section_header.dart"; import "package:photos/utils/navigation_util.dart"; -class MomentsSection extends StatefulWidget { +class MemoriesDebugSection extends StatefulWidget { final List momentsSearchResults; - const MomentsSection(this.momentsSearchResults, {super.key}); + const MemoriesDebugSection(this.momentsSearchResults, {super.key}); @override - State createState() => _MomentsSectionState(); + State createState() => _MemoriesDebugSectionState(); } -class _MomentsSectionState extends State { +class _MemoriesDebugSectionState extends State { late List _momentsSearchResults; final streamSubscriptions = []; @@ -56,7 +56,7 @@ class _MomentsSectionState extends State { } @override - void didUpdateWidget(covariant MomentsSection oldWidget) { + void didUpdateWidget(covariant MemoriesDebugSection oldWidget) { super.didUpdateWidget(oldWidget); _momentsSearchResults = widget.momentsSearchResults; } diff --git a/mobile/apps/photos/lib/ui/viewer/search_tab/search_tab.dart b/mobile/apps/photos/lib/ui/viewer/search_tab/search_tab.dart index 935e5c8064..e849c2ead2 100644 --- a/mobile/apps/photos/lib/ui/viewer/search_tab/search_tab.dart +++ b/mobile/apps/photos/lib/ui/viewer/search_tab/search_tab.dart @@ -19,7 +19,7 @@ import 'package:photos/ui/viewer/search_tab/albums_section.dart'; import "package:photos/ui/viewer/search_tab/file_type_section.dart"; import "package:photos/ui/viewer/search_tab/locations_section.dart"; import "package:photos/ui/viewer/search_tab/magic_section.dart"; -import "package:photos/ui/viewer/search_tab/moments_section.dart"; +import "package:photos/ui/viewer/search_tab/memories_debug_section.dart"; import "package:photos/ui/viewer/search_tab/people_section.dart"; class SearchTab extends StatefulWidget { @@ -133,7 +133,7 @@ class _AllSearchSectionsState extends State { case SectionType.memoriesDebug: if (flagService.internalUser && localSettings.isDebugMemoriesEnabled) { - return MomentsSection( + return MemoriesDebugSection( snapshot.data!.elementAt(index) as List, ); From 82cc0559b41c865b615fa312d27ed705d14c0919 Mon Sep 17 00:00:00 2001 From: laurenspriem Date: Mon, 14 Jul 2025 14:53:16 +0200 Subject: [PATCH 5/8] Remove old moments calculation logic --- .../photos/lib/services/search_service.dart | 159 ------------------ 1 file changed, 159 deletions(-) diff --git a/mobile/apps/photos/lib/services/search_service.dart b/mobile/apps/photos/lib/services/search_service.dart index f0429ed947..30ef268bf2 100644 --- a/mobile/apps/photos/lib/services/search_service.dart +++ b/mobile/apps/photos/lib/services/search_service.dart @@ -3,7 +3,6 @@ import "dart:math"; import "package:flutter/cupertino.dart"; import "package:flutter/material.dart"; -import "package:intl/intl.dart"; import 'package:logging/logging.dart'; import "package:path_provider/path_provider.dart"; import "package:photos/core/configuration.dart"; @@ -261,56 +260,6 @@ class SearchService { } } - Future> getRandomMomentsSearchResults( - BuildContext context, - ) async { - try { - final nonNullSearchResults = []; - final randomYear = getRadomYearSearchResult(); - final randomMonth = getRandomMonthSearchResult(context); - final randomDate = getRandomDateResults(context); - final randomHoliday = getRandomHolidaySearchResult(context); - - final searchResults = await Future.wait( - [randomYear, randomMonth, randomDate, randomHoliday], - ); - - for (GenericSearchResult? searchResult in searchResults) { - if (searchResult != null) { - nonNullSearchResults.add(searchResult); - } - } - - return nonNullSearchResults; - } catch (e) { - _logger.severe("Error getting RandomMomentsSearchResult", e); - return []; - } - } - - Future getRadomYearSearchResult() async { - for (var yearData in YearsData.instance.yearsData..shuffle()) { - final List filesInYear = - await _getFilesInYear(yearData.duration); - if (filesInYear.isNotEmpty) { - return GenericSearchResult( - ResultType.year, - yearData.year, - filesInYear, - hierarchicalSearchFilter: TopLevelGenericFilter( - filterName: yearData.year, - occurrence: kMostRelevantFilter, - filterResultType: ResultType.year, - matchedUploadedIDs: filesToUploadedFileIDs(filesInYear), - filterIcon: Icons.calendar_month_outlined, - ), - ); - } - } - //todo this throws error - return null; - } - Future> getMonthSearchResults( BuildContext context, String query, @@ -343,35 +292,6 @@ class SearchService { return searchResults; } - Future getRandomMonthSearchResult( - BuildContext context, - ) async { - final months = getMonthData(context)..shuffle(); - for (MonthData month in months) { - final matchedFiles = - await FilesDB.instance.getFilesCreatedWithinDurations( - _getDurationsOfMonthInEveryYear(month.monthNumber), - ignoreCollections(), - order: 'DESC', - ); - if (matchedFiles.isNotEmpty) { - return GenericSearchResult( - ResultType.month, - month.name, - matchedFiles, - hierarchicalSearchFilter: TopLevelGenericFilter( - filterName: month.name, - occurrence: kMostRelevantFilter, - filterResultType: ResultType.month, - matchedUploadedIDs: filesToUploadedFileIDs(matchedFiles), - filterIcon: Icons.calendar_month_outlined, - ), - ); - } - } - return null; - } - Future> getHolidaySearchResults( BuildContext context, String query, @@ -411,35 +331,6 @@ class SearchService { return searchResults; } - Future getRandomHolidaySearchResult( - BuildContext context, - ) async { - final holidays = getHolidays(context)..shuffle(); - for (var holiday in holidays) { - final matchedFiles = - await FilesDB.instance.getFilesCreatedWithinDurations( - _getDurationsForCalendarDateInEveryYear(holiday.day, holiday.month), - ignoreCollections(), - order: 'DESC', - ); - if (matchedFiles.isNotEmpty) { - return GenericSearchResult( - ResultType.event, - holiday.name, - matchedFiles, - hierarchicalSearchFilter: TopLevelGenericFilter( - filterName: holiday.name, - occurrence: kMostRelevantFilter, - filterResultType: ResultType.event, - matchedUploadedIDs: filesToUploadedFileIDs(matchedFiles), - filterIcon: Icons.event_outlined, - ), - ); - } - } - return null; - } - Future> getFileTypeResults( BuildContext context, String query, @@ -1334,56 +1225,6 @@ class SearchService { return searchResults; } - Future getRandomDateResults( - BuildContext context, - ) async { - final allFiles = await getAllFilesForSearch(); - if (allFiles.isEmpty) return null; - - final length = allFiles.length; - final randomFile = allFiles[Random().nextInt(length)]; - final creationTime = randomFile.creationTime!; - - final originalDateTime = DateTime.fromMicrosecondsSinceEpoch(creationTime); - final startOfDay = DateTime( - originalDateTime.year, - originalDateTime.month, - originalDateTime.day, - ); - - final endOfDay = DateTime( - originalDateTime.year, - originalDateTime.month, - originalDateTime.day + 1, - ); - - final durationOfDay = [ - startOfDay.microsecondsSinceEpoch, - endOfDay.microsecondsSinceEpoch, - ]; - - final matchedFiles = await FilesDB.instance.getFilesCreatedWithinDurations( - [durationOfDay], - ignoreCollections(), - order: 'DESC', - ); - - final name = DateFormat.yMMMd(Localizations.localeOf(context).languageCode) - .format(originalDateTime.toLocal()); - return GenericSearchResult( - ResultType.event, - name, - matchedFiles, - hierarchicalSearchFilter: TopLevelGenericFilter( - filterName: name, - occurrence: kMostRelevantFilter, - filterResultType: ResultType.event, - matchedUploadedIDs: filesToUploadedFileIDs(matchedFiles), - filterIcon: Icons.event_outlined, - ), - ); - } - Future> getContactSearchResults( String query, ) async { From b8d69e79f061c7225d982088fd0fe6089c304089 Mon Sep 17 00:00:00 2001 From: laurenspriem Date: Tue, 15 Jul 2025 11:51:23 +0200 Subject: [PATCH 6/8] Add memories debug to debug section --- .../debug/ml_debug_section_widget.dart | 52 +++++++++++++------ 1 file changed, 35 insertions(+), 17 deletions(-) diff --git a/mobile/apps/photos/lib/ui/settings/debug/ml_debug_section_widget.dart b/mobile/apps/photos/lib/ui/settings/debug/ml_debug_section_widget.dart index ba0d300442..902b2f0a9a 100644 --- a/mobile/apps/photos/lib/ui/settings/debug/ml_debug_section_widget.dart +++ b/mobile/apps/photos/lib/ui/settings/debug/ml_debug_section_widget.dart @@ -2,16 +2,19 @@ import "dart:async"; import 'package:flutter/material.dart'; import "package:logging/logging.dart"; +import "package:photos/core/constants.dart"; import "package:photos/core/event_bus.dart"; import "package:photos/db/ml/db.dart"; import "package:photos/events/people_changed_event.dart"; import "package:photos/models/ml/face/person.dart"; +import "package:photos/models/search/generic_search_result.dart"; import "package:photos/service_locator.dart"; import "package:photos/services/machine_learning/face_ml/person/person_service.dart"; import "package:photos/services/machine_learning/ml_indexing_isolate.dart"; import 'package:photos/services/machine_learning/ml_service.dart'; import "package:photos/services/machine_learning/semantic_search/semantic_search_service.dart"; import "package:photos/services/notification_service.dart"; +import "package:photos/services/search_service.dart"; import 'package:photos/theme/ente_theme.dart'; import 'package:photos/ui/components/captioned_text_widget.dart'; import 'package:photos/ui/components/expandable_menu_item_widget.dart'; @@ -19,6 +22,7 @@ import 'package:photos/ui/components/menu_item_widget/menu_item_widget.dart'; import "package:photos/ui/components/toggle_switch_widget.dart"; import 'package:photos/ui/notification/toast.dart'; import 'package:photos/ui/settings/common_settings.dart'; +import "package:photos/ui/viewer/search_tab/memories_debug_section.dart"; import "package:photos/utils/dialog_util.dart"; import "package:photos/utils/ml_util.dart"; @@ -32,6 +36,7 @@ class MLDebugSectionWidget extends StatefulWidget { class _MLDebugSectionWidgetState extends State { Timer? _timer; bool isExpanded = false; + bool _showMemoriesDebugSection = false; final Logger logger = Logger("MLDebugSectionWidget"); late final mlDataDB = MLDataDB.instance; @override @@ -431,23 +436,6 @@ class _MLDebugSectionWidgetState extends State { }, ), sectionOptionSpacing, - MenuItemWidget( - captionedTextWidget: const CaptionedTextWidget( - title: "Debug memories section", - ), - trailingWidget: ToggleSwitchWidget( - value: () => localSettings.isDebugMemoriesEnabled, - onChanged: () async { - await localSettings.toggleDebugMemories(); - if (mounted) { - setState(() {}); - } - }, - ), - singleBorderRadius: 8, - isGestureDetectorDisabled: true, - ), - sectionOptionSpacing, MenuItemWidget( captionedTextWidget: const CaptionedTextWidget( title: "Sync person mappings ", @@ -595,6 +583,36 @@ class _MLDebugSectionWidgetState extends State { ); }, ), + sectionOptionSpacing, + MenuItemWidget( + captionedTextWidget: const CaptionedTextWidget( + title: "Toggle memories section", + ), + trailingWidget: ToggleSwitchWidget( + value: () => _showMemoriesDebugSection, + onChanged: () async { + _showMemoriesDebugSection = !_showMemoriesDebugSection; + if (mounted) { + setState(() {}); + } + }, + ), + singleBorderRadius: 8, + isGestureDetectorDisabled: true, + ), + if (_showMemoriesDebugSection) sectionOptionSpacing, + if (_showMemoriesDebugSection) + FutureBuilder>( + future: SearchService.instance + .smartMemories(context, kSearchSectionLimit), + builder: (context, snapshot) { + if (snapshot.hasData) { + final memories = snapshot.data!; + return MemoriesDebugSection(memories); + } + return const SizedBox.shrink(); + }, + ), ], ); } From 9696409b01ca2fcd7cf8746fbc9ee75dd3f008d4 Mon Sep 17 00:00:00 2001 From: laurenspriem Date: Tue, 15 Jul 2025 13:16:56 +0200 Subject: [PATCH 7/8] Remove memories debug from sections types --- .../lib/models/search/search_types.dart | 21 ------ .../debug/ml_debug_section_widget.dart | 16 ++++- .../search_tab/memories_debug_section.dart | 70 ++++++++++++------- .../lib/ui/viewer/search_tab/search_tab.dart | 12 ---- .../apps/photos/lib/utils/local_settings.dart | 9 --- 5 files changed, 56 insertions(+), 72 deletions(-) diff --git a/mobile/apps/photos/lib/models/search/search_types.dart b/mobile/apps/photos/lib/models/search/search_types.dart index e0df25fe2c..eb0cd0ea85 100644 --- a/mobile/apps/photos/lib/models/search/search_types.dart +++ b/mobile/apps/photos/lib/models/search/search_types.dart @@ -13,7 +13,6 @@ import "package:photos/models/collection/collection.dart"; import "package:photos/models/collection/collection_items.dart"; import "package:photos/models/search/search_result.dart"; import "package:photos/models/typedefs.dart"; -import "package:photos/service_locator.dart"; import "package:photos/services/collections_service.dart"; import "package:photos/services/search_service.dart"; import "package:photos/ui/viewer/gallery/collection_page.dart"; @@ -44,10 +43,6 @@ enum SectionType { face, magic, location, - - /// WARNING: Not for production purposes, only kept for debugging memories - memoriesDebug, - album, // People section shows the files shared by other persons contacts, @@ -62,8 +57,6 @@ extension SectionTypeExtensions on SectionType { return S.of(context).people; case SectionType.magic: return S.of(context).discover; - case SectionType.memoriesDebug: - return "Debug memories (internal)"; case SectionType.location: return S.of(context).locations; case SectionType.contacts: @@ -81,8 +74,6 @@ extension SectionTypeExtensions on SectionType { return S.of(context).searchPersonsEmptySection; case SectionType.magic: return S.of(context).searchDiscoverEmptySection; - case SectionType.memoriesDebug: - return "For debugging for internal users only"; case SectionType.location: return S.of(context).searchLocationEmptySection; case SectionType.contacts: @@ -100,7 +91,6 @@ extension SectionTypeExtensions on SectionType { switch (this) { case SectionType.face: case SectionType.magic: - case SectionType.memoriesDebug: case SectionType.fileTypesAndExtension: return false; case SectionType.location: @@ -113,14 +103,12 @@ extension SectionTypeExtensions on SectionType { bool get sortByName => this != SectionType.face && this != SectionType.magic && - this != SectionType.memoriesDebug && this != SectionType.contacts; bool get isEmptyCTAVisible { switch (this) { case SectionType.face: case SectionType.magic: - case SectionType.memoriesDebug: case SectionType.fileTypesAndExtension: return false; case SectionType.location: @@ -138,8 +126,6 @@ extension SectionTypeExtensions on SectionType { case SectionType.magic: // todo: later return "temp"; - case SectionType.memoriesDebug: - return "Test memories"; case SectionType.location: return S.of(context).addNew; case SectionType.contacts: @@ -157,8 +143,6 @@ extension SectionTypeExtensions on SectionType { return Icons.adaptive.arrow_forward_outlined; case SectionType.magic: return null; - case SectionType.memoriesDebug: - return null; case SectionType.location: return Icons.add_location_alt_outlined; case SectionType.contacts: @@ -236,11 +220,6 @@ extension SectionTypeExtensions on SectionType { return SearchService.instance.getAllFace(limit); case SectionType.magic: return SearchService.instance.getMagicSectionResults(context!); - case SectionType.memoriesDebug: - if (flagService.internalUser && localSettings.isDebugMemoriesEnabled) { - return SearchService.instance.smartMemories(context!, limit); - } - return Future.value([]); case SectionType.location: return SearchService.instance.getAllLocationTags(limit); diff --git a/mobile/apps/photos/lib/ui/settings/debug/ml_debug_section_widget.dart b/mobile/apps/photos/lib/ui/settings/debug/ml_debug_section_widget.dart index 902b2f0a9a..35e98683ba 100644 --- a/mobile/apps/photos/lib/ui/settings/debug/ml_debug_section_widget.dart +++ b/mobile/apps/photos/lib/ui/settings/debug/ml_debug_section_widget.dart @@ -37,6 +37,7 @@ class _MLDebugSectionWidgetState extends State { Timer? _timer; bool isExpanded = false; bool _showMemoriesDebugSection = false; + bool _showAllMemories = false; final Logger logger = Logger("MLDebugSectionWidget"); late final mlDataDB = MLDataDB.instance; @override @@ -603,12 +604,21 @@ class _MLDebugSectionWidgetState extends State { if (_showMemoriesDebugSection) sectionOptionSpacing, if (_showMemoriesDebugSection) FutureBuilder>( - future: SearchService.instance - .smartMemories(context, kSearchSectionLimit), + key: ValueKey(_showAllMemories), + future: SearchService.instance.smartMemories( + context, + _showAllMemories ? null : kSearchSectionLimit, + ), builder: (context, snapshot) { if (snapshot.hasData) { final memories = snapshot.data!; - return MemoriesDebugSection(memories); + return MemoriesDebugSection(memories, () async { + _showAllMemories = !_showAllMemories; + _timer?.cancel(); + if (mounted) { + setState(() {}); + } + }); } return const SizedBox.shrink(); }, diff --git a/mobile/apps/photos/lib/ui/viewer/search_tab/memories_debug_section.dart b/mobile/apps/photos/lib/ui/viewer/search_tab/memories_debug_section.dart index 98dddae6a1..c45a88d2c3 100644 --- a/mobile/apps/photos/lib/ui/viewer/search_tab/memories_debug_section.dart +++ b/mobile/apps/photos/lib/ui/viewer/search_tab/memories_debug_section.dart @@ -3,22 +3,22 @@ import "dart:math"; import "package:figma_squircle/figma_squircle.dart"; import "package:flutter/material.dart"; -import "package:photos/core/constants.dart"; -import "package:photos/events/event.dart"; import "package:photos/models/search/generic_search_result.dart"; import "package:photos/models/search/recent_searches.dart"; -import "package:photos/models/search/search_types.dart"; import "package:photos/theme/ente_theme.dart"; import "package:photos/ui/viewer/file/no_thumbnail_widget.dart"; import "package:photos/ui/viewer/file/thumbnail_widget.dart"; import "package:photos/ui/viewer/search/result/search_result_page.dart"; -import "package:photos/ui/viewer/search/search_section_cta.dart"; -import "package:photos/ui/viewer/search_tab/section_header.dart"; import "package:photos/utils/navigation_util.dart"; class MemoriesDebugSection extends StatefulWidget { final List momentsSearchResults; - const MemoriesDebugSection(this.momentsSearchResults, {super.key}); + final VoidCallback onTapCallback; + const MemoriesDebugSection( + this.momentsSearchResults, + this.onTapCallback, { + super.key, + }); @override State createState() => _MemoriesDebugSectionState(); @@ -32,19 +32,6 @@ class _MemoriesDebugSectionState extends State { void initState() { super.initState(); _momentsSearchResults = widget.momentsSearchResults; - - final streamsToListenTo = SectionType.memoriesDebug.sectionUpdateEvents(); - for (Stream stream in streamsToListenTo) { - streamSubscriptions.add( - stream.listen((event) async { - _momentsSearchResults = (await SectionType.memoriesDebug.getData( - context, - limit: kSearchSectionLimit, - )) as List; - setState(() {}); - }), - ); - } } @override @@ -74,14 +61,14 @@ class _MemoriesDebugSectionState extends State { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - SectionType.memoriesDebug.sectionTitle(context), + "Smart memories debug (I)", style: textTheme.largeBold, ), const SizedBox(height: 24), Padding( padding: const EdgeInsets.only(left: 4), child: Text( - SectionType.memoriesDebug.getEmptyStateText(context), + "Test memories", style: textTheme.smallMuted, ), ), @@ -89,7 +76,6 @@ class _MemoriesDebugSectionState extends State { ), ), const SizedBox(width: 8), - const SearchSectionEmptyCTAIcon(SectionType.memoriesDebug), ], ), ); @@ -99,11 +85,7 @@ class _MemoriesDebugSectionState extends State { child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ - SectionHeader( - SectionType.memoriesDebug, - hasMore: - (_momentsSearchResults.length >= kSearchSectionLimit - 1), - ), + _SectionHeader(widget.onTapCallback), const SizedBox(height: 2), SizedBox( child: SingleChildScrollView( @@ -129,6 +111,40 @@ class _MemoriesDebugSectionState extends State { } } +class _SectionHeader extends StatelessWidget { + final VoidCallback onTapCallback; + const _SectionHeader(this.onTapCallback); + + @override + Widget build(BuildContext context) { + return GestureDetector( + onTap: onTapCallback, + child: Row( + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Padding( + padding: const EdgeInsets.all(12), + child: Text( + "Smart memories debug (I)", + style: getEnteTextTheme(context).largeBold, + ), + ), + Container( + color: Colors.transparent, + child: Padding( + padding: const EdgeInsets.fromLTRB(24, 12, 12, 12), + child: Icon( + Icons.chevron_right_outlined, + color: getEnteColorScheme(context).blurStrokePressed, + ), + ), + ), + ], + ), + ); + } +} + class MomentRecommendation extends StatelessWidget { static const _width = 100.0; static const _height = 145.0; diff --git a/mobile/apps/photos/lib/ui/viewer/search_tab/search_tab.dart b/mobile/apps/photos/lib/ui/viewer/search_tab/search_tab.dart index e849c2ead2..81359099cc 100644 --- a/mobile/apps/photos/lib/ui/viewer/search_tab/search_tab.dart +++ b/mobile/apps/photos/lib/ui/viewer/search_tab/search_tab.dart @@ -19,7 +19,6 @@ import 'package:photos/ui/viewer/search_tab/albums_section.dart'; import "package:photos/ui/viewer/search_tab/file_type_section.dart"; import "package:photos/ui/viewer/search_tab/locations_section.dart"; import "package:photos/ui/viewer/search_tab/magic_section.dart"; -import "package:photos/ui/viewer/search_tab/memories_debug_section.dart"; import "package:photos/ui/viewer/search_tab/people_section.dart"; class SearchTab extends StatefulWidget { @@ -125,21 +124,10 @@ class _AllSearchSectionsState extends State { as List, ); case SectionType.album: - // return const SizedBox.shrink(); return AlbumsSection( snapshot.data!.elementAt(index) as List, ); - case SectionType.memoriesDebug: - if (flagService.internalUser && - localSettings.isDebugMemoriesEnabled) { - return MemoriesDebugSection( - snapshot.data!.elementAt(index) - as List, - ); - } else { - return const SizedBox.shrink(); - } case SectionType.location: return LocationsSection( snapshot.data!.elementAt(index) diff --git a/mobile/apps/photos/lib/utils/local_settings.dart b/mobile/apps/photos/lib/utils/local_settings.dart index b5f0031152..4133bf0087 100644 --- a/mobile/apps/photos/lib/utils/local_settings.dart +++ b/mobile/apps/photos/lib/utils/local_settings.dart @@ -26,7 +26,6 @@ class LocalSettings { static const kRateUsShownCount = "rate_us_shown_count"; static const kEnableMultiplePart = "ls.enable_multiple_part"; static const kCuratedMemoriesEnabled = "ls.curated_memories_enabled"; - static const _kDebugMemoriesEnabled = "ls.debug_memories_enabled"; static const kOnThisDayNotificationsEnabled = "ls.on_this_day_notifications_enabled"; static const kBirthdayNotificationsEnabled = @@ -119,19 +118,11 @@ class LocalSettings { bool get isSmartMemoriesEnabled => _prefs.getBool(kCuratedMemoriesEnabled) ?? true; - bool get isDebugMemoriesEnabled => - _prefs.getBool(_kDebugMemoriesEnabled) ?? false; - Future setSmartMemories(bool value) async { await _prefs.setBool(kCuratedMemoriesEnabled, value); return value; } - Future toggleDebugMemories() async { - await _prefs.setBool(_kDebugMemoriesEnabled, !isDebugMemoriesEnabled); - return isDebugMemoriesEnabled; - } - bool get isOnThisDayNotificationsEnabled => _prefs.getBool(kOnThisDayNotificationsEnabled) ?? true; From f06314fb13d2dc5c995afaf1d118cec519afdad5 Mon Sep 17 00:00:00 2001 From: laurenspriem Date: Tue, 15 Jul 2025 14:00:04 +0200 Subject: [PATCH 8/8] Move file --- .../debug/ml_debug_section_widget.dart | 2 +- .../search_tab/memories_debug_section.dart | 275 ------------------ 2 files changed, 1 insertion(+), 276 deletions(-) delete mode 100644 mobile/apps/photos/lib/ui/viewer/search_tab/memories_debug_section.dart diff --git a/mobile/apps/photos/lib/ui/settings/debug/ml_debug_section_widget.dart b/mobile/apps/photos/lib/ui/settings/debug/ml_debug_section_widget.dart index 35e98683ba..fd83bcc7e0 100644 --- a/mobile/apps/photos/lib/ui/settings/debug/ml_debug_section_widget.dart +++ b/mobile/apps/photos/lib/ui/settings/debug/ml_debug_section_widget.dart @@ -22,7 +22,7 @@ import 'package:photos/ui/components/menu_item_widget/menu_item_widget.dart'; import "package:photos/ui/components/toggle_switch_widget.dart"; import 'package:photos/ui/notification/toast.dart'; import 'package:photos/ui/settings/common_settings.dart'; -import "package:photos/ui/viewer/search_tab/memories_debug_section.dart"; +import "package:photos/ui/settings/debug/memories_debug_section.dart"; import "package:photos/utils/dialog_util.dart"; import "package:photos/utils/ml_util.dart"; diff --git a/mobile/apps/photos/lib/ui/viewer/search_tab/memories_debug_section.dart b/mobile/apps/photos/lib/ui/viewer/search_tab/memories_debug_section.dart deleted file mode 100644 index c45a88d2c3..0000000000 --- a/mobile/apps/photos/lib/ui/viewer/search_tab/memories_debug_section.dart +++ /dev/null @@ -1,275 +0,0 @@ -import "dart:async"; -import "dart:math"; - -import "package:figma_squircle/figma_squircle.dart"; -import "package:flutter/material.dart"; -import "package:photos/models/search/generic_search_result.dart"; -import "package:photos/models/search/recent_searches.dart"; -import "package:photos/theme/ente_theme.dart"; -import "package:photos/ui/viewer/file/no_thumbnail_widget.dart"; -import "package:photos/ui/viewer/file/thumbnail_widget.dart"; -import "package:photos/ui/viewer/search/result/search_result_page.dart"; -import "package:photos/utils/navigation_util.dart"; - -class MemoriesDebugSection extends StatefulWidget { - final List momentsSearchResults; - final VoidCallback onTapCallback; - const MemoriesDebugSection( - this.momentsSearchResults, - this.onTapCallback, { - super.key, - }); - - @override - State createState() => _MemoriesDebugSectionState(); -} - -class _MemoriesDebugSectionState extends State { - late List _momentsSearchResults; - final streamSubscriptions = []; - - @override - void initState() { - super.initState(); - _momentsSearchResults = widget.momentsSearchResults; - } - - @override - void dispose() { - for (var subscriptions in streamSubscriptions) { - subscriptions.cancel(); - } - super.dispose(); - } - - @override - void didUpdateWidget(covariant MemoriesDebugSection oldWidget) { - super.didUpdateWidget(oldWidget); - _momentsSearchResults = widget.momentsSearchResults; - } - - @override - Widget build(BuildContext context) { - if (_momentsSearchResults.isEmpty) { - final textTheme = getEnteTextTheme(context); - return Padding( - padding: const EdgeInsets.only(left: 12, right: 8), - child: Row( - children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - Text( - "Smart memories debug (I)", - style: textTheme.largeBold, - ), - const SizedBox(height: 24), - Padding( - padding: const EdgeInsets.only(left: 4), - child: Text( - "Test memories", - style: textTheme.smallMuted, - ), - ), - ], - ), - ), - const SizedBox(width: 8), - ], - ), - ); - } else { - return Padding( - padding: const EdgeInsets.symmetric(vertical: 8), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: [ - _SectionHeader(widget.onTapCallback), - const SizedBox(height: 2), - SizedBox( - child: SingleChildScrollView( - clipBehavior: Clip.none, - padding: const EdgeInsets.symmetric(horizontal: 4.5), - physics: const BouncingScrollPhysics(), - scrollDirection: Axis.horizontal, - child: Row( - crossAxisAlignment: CrossAxisAlignment.start, - children: _momentsSearchResults - .map( - (momentSearchResult) => - MomentRecommendation(momentSearchResult), - ) - .toList(), - ), - ), - ), - ], - ), - ); - } - } -} - -class _SectionHeader extends StatelessWidget { - final VoidCallback onTapCallback; - const _SectionHeader(this.onTapCallback); - - @override - Widget build(BuildContext context) { - return GestureDetector( - onTap: onTapCallback, - child: Row( - mainAxisAlignment: MainAxisAlignment.spaceBetween, - children: [ - Padding( - padding: const EdgeInsets.all(12), - child: Text( - "Smart memories debug (I)", - style: getEnteTextTheme(context).largeBold, - ), - ), - Container( - color: Colors.transparent, - child: Padding( - padding: const EdgeInsets.fromLTRB(24, 12, 12, 12), - child: Icon( - Icons.chevron_right_outlined, - color: getEnteColorScheme(context).blurStrokePressed, - ), - ), - ), - ], - ), - ); - } -} - -class MomentRecommendation extends StatelessWidget { - static const _width = 100.0; - static const _height = 145.0; - static const _borderWidth = 1.0; - static const _cornerRadius = 5.0; - static const _cornerSmoothing = 1.0; - final GenericSearchResult momentSearchResult; - const MomentRecommendation(this.momentSearchResult, {super.key}); - - @override - Widget build(BuildContext context) { - final heroTag = momentSearchResult.heroTag() + - (momentSearchResult.previewThumbnail()?.tag ?? ""); - final enteTextTheme = getEnteTextTheme(context); - return Padding( - padding: EdgeInsets.symmetric(horizontal: max(2.5 - _borderWidth, 0)), - child: GestureDetector( - onTap: () { - RecentSearches().add(momentSearchResult.name()); - if (momentSearchResult.onResultTap != null) { - momentSearchResult.onResultTap!(context); - } else { - routeToPage( - context, - SearchResultPage(momentSearchResult), - ); - } - }, - child: SizedBox( - width: _width + _borderWidth * 2, - height: _height + _borderWidth * 2, - child: Stack( - clipBehavior: Clip.none, - alignment: Alignment.center, - children: [ - ClipSmoothRect( - radius: SmoothBorderRadius( - cornerRadius: _cornerRadius + _borderWidth, - cornerSmoothing: _cornerSmoothing, - ), - child: Container( - color: Colors.white.withOpacity(0.16), - width: _width + _borderWidth * 2, - height: _height + _borderWidth * 2, - ), - ), - Container( - decoration: BoxDecoration( - boxShadow: [ - BoxShadow( - color: Colors.black.withOpacity(0.1), - blurRadius: 6.25, - offset: const Offset(-1.25, 2.5), - ), - ], - ), - child: ClipSmoothRect( - radius: SmoothBorderRadius( - cornerRadius: _cornerRadius, - cornerSmoothing: _cornerSmoothing, - ), - child: Stack( - alignment: Alignment.bottomCenter, - clipBehavior: Clip.none, - children: [ - SizedBox( - width: _width, - height: _height, - child: momentSearchResult.previewThumbnail() != null - ? Hero( - tag: heroTag, - child: ThumbnailWidget( - momentSearchResult.previewThumbnail()!, - shouldShowArchiveStatus: false, - shouldShowSyncStatus: false, - ), - ) - : const NoThumbnailWidget(), - ), - Container( - height: 145, - width: 100, - decoration: BoxDecoration( - gradient: LinearGradient( - begin: Alignment.topCenter, - end: Alignment.bottomCenter, - colors: [ - Colors.black.withOpacity(0), - Colors.black.withOpacity(0), - Colors.black.withOpacity(0.5), - ], - stops: const [ - 0, - 0.1, - 1, - ], - ), - ), - ), - ConstrainedBox( - constraints: const BoxConstraints( - maxWidth: 76, - ), - child: Padding( - padding: const EdgeInsets.only( - bottom: 8, - ), - child: Text( - momentSearchResult.name(), - style: enteTextTheme.small.copyWith( - color: Colors.white, - ), - maxLines: 3, - overflow: TextOverflow.fade, - ), - ), - ), - ], - ), - ), - ), - ], - ), - ), - ), - ); - } -}