diff --git a/mobile/lib/data/db/main/database.dart b/mobile/lib/data/db/main/database.dart index 195146fc5..bebac570b 100644 --- a/mobile/lib/data/db/main/database.dart +++ b/mobile/lib/data/db/main/database.dart @@ -45,7 +45,6 @@ import 'package:immich_mobile/infrastructure/repositories/partner.repository.dar import 'package:immich_mobile/infrastructure/repositories/remote_album.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/remote_asset.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/remote_exif.repository.dart'; -import 'package:immich_mobile/infrastructure/repositories/stack.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/store.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/sync_migration.repository.dart'; import 'package:immich_mobile/infrastructure/repositories/sync_stream.repository.dart'; @@ -101,7 +100,6 @@ import 'package:sqlite_async/sqlite_async.dart'; RemoteAlbumRepository, RemoteAssetRepository, RemoteExifRepository, - StackRepository, StoreRepository, SyncMigrationRepository, SyncStreamRepository, diff --git a/mobile/lib/domain/services/local_album.service.dart b/mobile/lib/domain/services/local_album.service.dart index 8661a8d10..60cf74590 100644 --- a/mobile/lib/domain/services/local_album.service.dart +++ b/mobile/lib/domain/services/local_album.service.dart @@ -22,16 +22,4 @@ class LocalAlbumService { Future getCount() { return _repository.getCount(); } - - Future unlinkRemoteAlbum(String id) async { - return _repository.unlinkRemoteAlbum(id); - } - - Future linkRemoteAlbum(String localAlbumId, String remoteAlbumId) async { - return _repository.linkRemoteAlbum(localAlbumId, remoteAlbumId); - } - - Future> getBackupAlbums() { - return _repository.getBackupAlbums(); - } } diff --git a/mobile/lib/domain/services/search.service.dart b/mobile/lib/domain/services/search.service.dart index 745455cdf..3959c4815 100644 --- a/mobile/lib/domain/services/search.service.dart +++ b/mobile/lib/domain/services/search.service.dart @@ -4,7 +4,6 @@ import 'package:immich_mobile/extensions/string_extensions.dart'; import 'package:immich_mobile/infrastructure/repositories/search_api.repository.dart'; import 'package:immich_mobile/models/search/search_filter.model.dart'; import 'package:logging/logging.dart'; -import 'package:openapi/api.dart' hide AssetVisibility, SearchFilter; class SearchService { final _log = Logger("SearchService"); @@ -12,27 +11,6 @@ class SearchService { SearchService(this._searchApiRepository); - Future?> getSearchSuggestions( - SearchSuggestionType type, { - String? country, - String? state, - String? make, - String? model, - }) async { - try { - return await _searchApiRepository.getSearchSuggestions( - type, - country: country, - state: state, - make: make, - model: model, - ); - } catch (e) { - _log.warning("Failed to get search suggestions", e); - } - return []; - } - Future search(SearchFilter filter, int page) async { try { final response = await _searchApiRepository.search(filter, page); diff --git a/mobile/lib/domain/services/setting.service.dart b/mobile/lib/domain/services/setting.service.dart index 1823e46cf..1fedf692b 100644 --- a/mobile/lib/domain/services/setting.service.dart +++ b/mobile/lib/domain/services/setting.service.dart @@ -12,8 +12,4 @@ class SettingsService { const SettingsService({required this._storeService}); T get(Setting setting) => _storeService.get(setting.storeKey, setting.defaultValue); - - Future set(Setting setting, T value) => _storeService.put(setting.storeKey, value); - - Stream watch(Setting setting) => _storeService.watch(setting.storeKey).map((v) => v ?? setting.defaultValue); } diff --git a/mobile/lib/domain/services/timeline.service.dart b/mobile/lib/domain/services/timeline.service.dart index 6bd088b74..5dc8ec3a8 100644 --- a/mobile/lib/domain/services/timeline.service.dart +++ b/mobile/lib/domain/services/timeline.service.dart @@ -194,15 +194,6 @@ class TimelineService { BaseAsset getRandomAsset() => _buffer.elementAt(math.Random().nextInt(_buffer.length)); - BaseAsset getAsset(int index) { - if (!hasRange(index, 1)) { - throw RangeError( - 'TimelineService::getAsset Index $index not in buffer range [$_bufferOffset, ${_bufferOffset + _buffer.length})', - ); - } - return _buffer.elementAt(index - _bufferOffset); - } - /// Gets an asset at the given index, automatically loading the buffer if needed. /// This is an async version that can handle out-of-range indices by loading the appropriate buffer. Future getAssetAsync(int index) async { diff --git a/mobile/lib/domain/utils/event_stream.dart b/mobile/lib/domain/utils/event_stream.dart index 0069c75f8..afbaa5bd9 100644 --- a/mobile/lib/domain/utils/event_stream.dart +++ b/mobile/lib/domain/utils/event_stream.dart @@ -30,9 +30,4 @@ class EventStream { }) { return where().listen(onData, onError: onError, onDone: onDone, cancelOnError: cancelOnError); } - - /// Closes the stream controller - Future dispose() { - return _controller.close(); - } } diff --git a/mobile/lib/extensions/codec_extensions.dart b/mobile/lib/extensions/codec_extensions.dart deleted file mode 100644 index 00c1158f0..000000000 --- a/mobile/lib/extensions/codec_extensions.dart +++ /dev/null @@ -1,10 +0,0 @@ -import 'dart:ui'; - -import 'package:flutter/painting.dart'; - -extension CodecImageInfoExtension on Codec { - Future getImageInfo({double scale = 1.0}) async { - final frame = await getNextFrame(); - return ImageInfo(image: frame.image, scale: scale); - } -} diff --git a/mobile/lib/extensions/collection_extensions.dart b/mobile/lib/extensions/collection_extensions.dart deleted file mode 100644 index 53e8e73fd..000000000 --- a/mobile/lib/extensions/collection_extensions.dart +++ /dev/null @@ -1,45 +0,0 @@ -import 'dart:typed_data'; - -import 'package:collection/collection.dart'; - -extension ListExtension on List { - List uniqueConsecutive({int Function(E a, E b)? compare, void Function(E a, E b)? onDuplicate}) { - compare ??= (E a, E b) => a == b ? 0 : 1; - int i = 1; - int j = 1; - for (; i < length; i++) { - if (compare(this[i - 1], this[i]) != 0) { - if (i != j) { - this[j] = this[i]; - } - j++; - } else if (onDuplicate != null) { - onDuplicate(this[i - 1], this[i]); - } - } - length = length == 0 ? 0 : j; - return this; - } - - ListSlice nestedSlice(int start, int end) { - if (this is ListSlice) { - final ListSlice self = this as ListSlice; - return ListSlice(self.source, self.start + start, self.start + end); - } - return ListSlice(this, start, end); - } -} - -extension IntListExtension on Iterable { - Int64List toInt64List() { - final list = Int64List(length); - list.setAll(0, this); - return list; - } -} - -extension SortedByProperty on Iterable { - Iterable sortedByField(Comparable Function(T e) key) { - return sorted((a, b) => key(a).compareTo(key(b))); - } -} diff --git a/mobile/lib/extensions/latlngbounds_extension.dart b/mobile/lib/extensions/latlngbounds_extension.dart deleted file mode 100644 index a8948728b..000000000 --- a/mobile/lib/extensions/latlngbounds_extension.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:maplibre_gl/maplibre_gl.dart'; - -extension WithinBounds on LatLngBounds { - /// Checks whether [point] is inside bounds - bool contains(LatLng point) { - final sw = point; - final ne = point; - return containsBounds(LatLngBounds(southwest: sw, northeast: ne)); - } - - /// Checks whether [bounds] is contained inside bounds - bool containsBounds(LatLngBounds bounds) { - final sw = bounds.southwest; - final ne = bounds.northeast; - return (sw.latitude >= southwest.latitude) && - (ne.latitude <= northeast.latitude) && - (sw.longitude >= southwest.longitude) && - (ne.longitude <= northeast.longitude); - } -} diff --git a/mobile/lib/extensions/maplibrecontroller_extensions.dart b/mobile/lib/extensions/maplibrecontroller_extensions.dart index d15f7c501..1528a9010 100644 --- a/mobile/lib/extensions/maplibrecontroller_extensions.dart +++ b/mobile/lib/extensions/maplibrecontroller_extensions.dart @@ -1,71 +1,9 @@ import 'dart:async'; -import 'dart:io'; -import 'dart:math'; import 'package:flutter/services.dart'; -import 'package:immich_mobile/models/map/map_marker.model.dart'; -import 'package:immich_mobile/utils/map_utils.dart'; import 'package:maplibre_gl/maplibre_gl.dart'; extension MapMarkers on MapLibreMapController { - static var _completer = Completer()..complete(); - - Future addGeoJSONSourceForMarkers(List markers) async { - return addSource( - MapUtils.defaultSourceId, - GeojsonSourceProperties(data: MapUtils.generateGeoJsonForMarkers(markers.toList())), - ); - } - - Future reloadAllLayersForMarkers(List markers) async { - // Wait for previous reload to complete - if (!_completer.isCompleted) { - return _completer.future; - } - _completer = Completer(); - - // !! Make sure to remove layers before sources else the native - // maplibre library would crash when removing the source saying that - // the source is still in use - final existingLayers = await getLayerIds(); - if (existingLayers.contains(MapUtils.defaultHeatMapLayerId)) { - await removeLayer(MapUtils.defaultHeatMapLayerId); - } - - final existingSources = await getSourceIds(); - if (existingSources.contains(MapUtils.defaultSourceId)) { - await removeSource(MapUtils.defaultSourceId); - } - - await addGeoJSONSourceForMarkers(markers); - - if (Platform.isAndroid) { - await addCircleLayer( - MapUtils.defaultSourceId, - MapUtils.defaultHeatMapLayerId, - const CircleLayerProperties( - circleRadius: 10, - circleColor: "rgba(150,86,34,0.7)", - circleBlur: 1.0, - circleOpacity: 0.7, - circleStrokeWidth: 0.1, - circleStrokeColor: "rgba(203,46,19,0.5)", - circleStrokeOpacity: 0.7, - ), - ); - } - - if (Platform.isIOS) { - await addHeatmapLayer( - MapUtils.defaultSourceId, - MapUtils.defaultHeatMapLayerId, - MapUtils.defaultHeatMapLayerProperties, - ); - } - - _completer.complete(); - } - Future addMarkerAtLatLng(LatLng centre) async { // no marker is displayed if asset-path is incorrect try { @@ -78,14 +16,4 @@ extension MapMarkers on MapLibreMapController { // no-op } } - - Future getBoundsFromPoint(Point point, double distance) async { - final southWestPx = Point(point.x - distance, point.y + distance); - final northEastPx = Point(point.x + distance, point.y - distance); - - final southWest = await toLatLng(southWestPx); - final northEast = await toLatLng(northEastPx); - - return LatLngBounds(southwest: southWest, northeast: northEast); - } } diff --git a/mobile/lib/extensions/response_extensions.dart b/mobile/lib/extensions/response_extensions.dart deleted file mode 100644 index 7fec41d07..000000000 --- a/mobile/lib/extensions/response_extensions.dart +++ /dev/null @@ -1,5 +0,0 @@ -import 'package:http/http.dart'; - -extension LoggerExtension on Response { - String toLoggerString() => "Status: $statusCode $reasonPhrase\n\n$body"; -} diff --git a/mobile/lib/extensions/string_extensions.dart b/mobile/lib/extensions/string_extensions.dart index a4308c4ec..3c318bd2e 100644 --- a/mobile/lib/extensions/string_extensions.dart +++ b/mobile/lib/extensions/string_extensions.dart @@ -3,10 +3,6 @@ import 'dart:convert'; import 'package:diacritic/diacritic.dart' as diacritic; extension StringExtension on String { - String capitalize() { - return split(" ").map((str) => str.isEmpty ? str : str[0].toUpperCase() + str.substring(1)).join(" "); - } - String? get nullIfEmpty => isEmpty ? null : this; String removeDiacritics() => diacritic.removeDiacritics(this); diff --git a/mobile/lib/infrastructure/repositories/local_asset.repository.dart b/mobile/lib/infrastructure/repositories/local_asset.repository.dart index 7dfd7106f..6d39b07e0 100644 --- a/mobile/lib/infrastructure/repositories/local_asset.repository.dart +++ b/mobile/lib/infrastructure/repositories/local_asset.repository.dart @@ -218,29 +218,4 @@ class LocalAssetRepository extends DatabaseAccessor with $LocalAssetRepos return RemovalCandidatesResult(assets: assets, totalBytes: totalBytes); } - - Future> getEmptyCloudIdAssets() { - final query = _db.localAssetEntity.select()..where((row) => row.iCloudId.isNull()); - return query.map((row) => row.toDto()).get(); - } - - Future reconcileHashesFromCloudId() async { - await _db.customUpdate( - ''' - UPDATE local_asset_entity - SET checksum = remote_asset_entity.checksum - FROM remote_asset_cloud_id_entity - INNER JOIN remote_asset_entity - ON remote_asset_cloud_id_entity.asset_id = remote_asset_entity.id - WHERE local_asset_entity.i_cloud_id = remote_asset_cloud_id_entity.cloud_id - AND local_asset_entity.checksum IS NULL - AND remote_asset_cloud_id_entity.adjustment_time IS local_asset_entity.adjustment_time - AND remote_asset_cloud_id_entity.latitude IS local_asset_entity.latitude - AND remote_asset_cloud_id_entity.longitude IS local_asset_entity.longitude - AND remote_asset_cloud_id_entity.created_at IS local_asset_entity.created_at - ''', - updates: {_db.localAssetEntity}, - updateKind: UpdateKind.update, - ); - } } diff --git a/mobile/lib/infrastructure/repositories/log.repository.dart b/mobile/lib/infrastructure/repositories/log.repository.dart index 29d59cb35..5e1592397 100644 --- a/mobile/lib/infrastructure/repositories/log.repository.dart +++ b/mobile/lib/infrastructure/repositories/log.repository.dart @@ -52,18 +52,6 @@ class LogRepository { return true; } - Future deleteByLogger(String logger) async { - await _db.logMessageEntity.deleteWhere((row) => row.logger.equals(logger)); - } - - Stream> watchMessages(String logger) { - final query = _db.logMessageEntity.select() - ..orderBy([(row) => OrderingTerm.desc(row.createdAt)]) - ..where((row) => row.logger.equals(logger)); - - return query.watch().map((rows) => rows.map((row) => row.toDto()).toList()); - } - Future truncate({int limit = kLogTruncateLimit}) async { final totalCount = await _db.managers.logMessageEntity.count(); if (totalCount > limit) { diff --git a/mobile/lib/infrastructure/repositories/remote_asset.repository.dart b/mobile/lib/infrastructure/repositories/remote_asset.repository.dart index 698ec2cb8..b3e29d24d 100644 --- a/mobile/lib/infrastructure/repositories/remote_asset.repository.dart +++ b/mobile/lib/infrastructure/repositories/remote_asset.repository.dart @@ -12,7 +12,6 @@ import 'package:immich_mobile/domain/models/exif.model.dart'; import 'package:immich_mobile/domain/models/stack.model.dart'; import 'package:immich_mobile/infrastructure/repositories/remote_asset.repository.drift.dart'; import 'package:immich_mobile/utils/option.dart'; -import 'package:maplibre_gl/maplibre_gl.dart'; @DriftAccessor() class RemoteAssetRepository extends DatabaseAccessor with $RemoteAssetRepositoryMixin { @@ -20,21 +19,6 @@ class RemoteAssetRepository extends DatabaseAccessor with $RemoteAssetRep Drift get _db => attachedDatabase; - /// For testing purposes - Future> getSome(String userId) { - final query = _db.remoteAssetEntity.select() - ..where( - (row) => - _db.remoteAssetEntity.ownerId.equals(userId) & - _db.remoteAssetEntity.deletedAt.isNull() & - _db.remoteAssetEntity.visibility.equalsValue(AssetVisibility.timeline), - ) - ..orderBy([(row) => OrderingTerm.desc(row.createdAt)]) - ..limit(10); - - return query.map((row) => row.toDto()).get(); - } - SingleOrNullSelectable _assetSelectable(String id) { final query = _db.remoteAssetEntity.select().addColumns([_db.localAssetEntity.id]).join([ @@ -119,18 +103,6 @@ class RemoteAssetRepository extends DatabaseAccessor with $RemoteAssetRep }).get(); } - Future updateVisibility(List ids, AssetVisibility visibility) { - return _db.batch((batch) async { - for (final id in ids) { - batch.update( - _db.remoteAssetEntity, - RemoteAssetEntityCompanion(visibility: Value(visibility)), - where: (e) => e.id.equals(id), - ); - } - }); - } - Future trash(List ids) { return _db.batch((batch) async { for (final id in ids) { @@ -267,37 +239,4 @@ class RemoteAssetRepository extends DatabaseAccessor with $RemoteAssetRep } }); } - - // TODO(shenlong): remove after action migration - Future updateLocation(List ids, LatLng location) { - return _db.batch((batch) async { - for (final id in ids) { - batch.update( - _db.remoteExifEntity, - RemoteExifEntityCompanion(latitude: Value(location.latitude), longitude: Value(location.longitude)), - where: (e) => e.assetId.equals(id), - ); - } - }); - } - - Future updateDateTime(List ids, DateTime dateTime, {String? timeZone}) { - return _db.batch((batch) async { - for (final id in ids) { - batch.update( - _db.remoteExifEntity, - RemoteExifEntityCompanion( - dateTimeOriginal: Value(dateTime), - timeZone: timeZone == null ? const Value.absent() : Value(timeZone), - ), - where: (e) => e.assetId.equals(id), - ); - batch.update( - _db.remoteAssetEntity, - RemoteAssetEntityCompanion(createdAt: Value(dateTime)), - where: (e) => e.id.equals(id), - ); - } - }); - } } diff --git a/mobile/lib/infrastructure/repositories/stack.repository.dart b/mobile/lib/infrastructure/repositories/stack.repository.dart deleted file mode 100644 index 2924c9472..000000000 --- a/mobile/lib/infrastructure/repositories/stack.repository.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:drift/drift.dart'; -import 'package:immich_mobile/data/db/main/database.dart'; -import 'package:immich_mobile/data/db/main/table/remote/stack.drift.dart'; -import 'package:immich_mobile/domain/models/stack.model.dart'; -import 'package:immich_mobile/infrastructure/repositories/stack.repository.drift.dart'; - -@DriftAccessor() -class StackRepository extends DatabaseAccessor with $StackRepositoryMixin { - StackRepository(super.attachedDatabase); - - Drift get _db => attachedDatabase; - - Future> getAll(String userId) { - final query = _db.stackEntity.select()..where((e) => e.ownerId.equals(userId)); - - return query.map((stack) { - return stack.toDto(); - }).get(); - } -} - -extension on StackEntityData { - Stack toDto() { - return Stack(id: id, createdAt: createdAt, updatedAt: updatedAt, ownerId: ownerId, primaryAssetId: primaryAssetId); - } -} diff --git a/mobile/lib/infrastructure/repositories/sync_stream.repository.dart b/mobile/lib/infrastructure/repositories/sync_stream.repository.dart index f3b3840a7..7c0e16c8e 100644 --- a/mobile/lib/infrastructure/repositories/sync_stream.repository.dart +++ b/mobile/lib/infrastructure/repositories/sync_stream.repository.dart @@ -900,40 +900,6 @@ class SyncStreamRepository extends DatabaseAccessor with $SyncStreamRepos rethrow; } } - - Future pruneAssets() async { - try { - await _db.transaction(() async { - final authQuery = _db.authUserEntity.selectOnly() - ..addColumns([_db.authUserEntity.id]) - ..limit(1); - final currentUserId = await authQuery.map((row) => row.read(_db.authUserEntity.id)).getSingleOrNull(); - if (currentUserId == null) { - _logger.warning('No authenticated user found during pruneAssets. Skipping asset pruning.'); - return; - } - - final partnerQuery = _db.partnerEntity.selectOnly() - ..addColumns([_db.partnerEntity.sharedById]) - ..where(_db.partnerEntity.sharedWithId.equals(currentUserId)); - final partnerIds = await partnerQuery.map((row) => row.read(_db.partnerEntity.sharedById)).get(); - - final validUsers = {currentUserId, ...partnerIds.nonNulls}; - - // Asset is not owned by the current user or any of their partners and is not part of any (shared) album - // Likely a stale asset that was previously shared but has been removed - await _db.remoteAssetEntity.deleteWhere((asset) { - return asset.ownerId.isNotIn(validUsers) & - asset.id.isNotInQuery( - _db.remoteAlbumAssetEntity.selectOnly()..addColumns([_db.remoteAlbumAssetEntity.assetId]), - ); - }); - }); - } catch (error, stack) { - _logger.severe('Error: pruneAssets', error, stack); - // We do not rethrow here as this is a client-only cleanup and should not affect the sync process - } - } } extension on AssetTypeEnum { diff --git a/mobile/lib/infrastructure/repositories/user_api.repository.dart b/mobile/lib/infrastructure/repositories/user_api.repository.dart index 800a23822..418d6b0ab 100644 --- a/mobile/lib/infrastructure/repositories/user_api.repository.dart +++ b/mobile/lib/infrastructure/repositories/user_api.repository.dart @@ -23,9 +23,4 @@ class UserApiRepository extends ApiRepository { final res = await checkNull(_api.createProfileImage(MultipartFile.fromBytes('file', data, filename: name))); return res.profileImagePath; } - - Future> getAll() async { - final dto = await checkNull(_api.searchUsers()); - return dto.map(UserConverter.fromSimpleUserDto).toList(); - } } diff --git a/mobile/lib/interfaces/database.interface.dart b/mobile/lib/interfaces/database.interface.dart deleted file mode 100644 index 5645d15c4..000000000 --- a/mobile/lib/interfaces/database.interface.dart +++ /dev/null @@ -1,3 +0,0 @@ -abstract interface class IDatabaseRepository { - Future transaction(Future Function() callback); -} diff --git a/mobile/lib/presentation/widgets/album/album_selector.widget.dart b/mobile/lib/presentation/widgets/album/album_selector.widget.dart index b66063f73..a3d4405b1 100644 --- a/mobile/lib/presentation/widgets/album/album_selector.widget.dart +++ b/mobile/lib/presentation/widgets/album/album_selector.widget.dart @@ -83,10 +83,6 @@ class _AlbumSelectorState extends ConsumerState { unawaited(filterAlbums()); } - Future onRefresh() async { - await ref.read(remoteAlbumProvider.notifier).refresh(); - } - void toggleViewMode() { setState(() { isGrid = !isGrid; diff --git a/mobile/lib/presentation/widgets/asset_viewer/asset_stack.provider.dart b/mobile/lib/presentation/widgets/asset_viewer/asset_stack.provider.dart index c4e06e5ad..dae6db568 100644 --- a/mobile/lib/presentation/widgets/asset_viewer/asset_stack.provider.dart +++ b/mobile/lib/presentation/widgets/asset_viewer/asset_stack.provider.dart @@ -11,10 +11,6 @@ class StackChildrenNotifier extends AutoDisposeFamilyAsyncNotifier stack) { - state = AsyncData(stack); - } } final stackChildrenNotifier = AsyncNotifierProvider.autoDispose diff --git a/mobile/lib/presentation/widgets/map/map.state.dart b/mobile/lib/presentation/widgets/map/map.state.dart index 3370fb736..39f629a9e 100644 --- a/mobile/lib/presentation/widgets/map/map.state.dart +++ b/mobile/lib/presentation/widgets/map/map.state.dart @@ -10,7 +10,6 @@ import 'package:immich_mobile/domain/utils/event_stream.dart'; import 'package:immich_mobile/providers/infrastructure/map.provider.dart'; import 'package:immich_mobile/providers/infrastructure/settings.provider.dart'; import 'package:immich_mobile/providers/map/map_state.provider.dart'; -import 'package:immich_mobile/utils/option.dart'; import 'package:maplibre_gl/maplibre_gl.dart'; part 'map.state.freezed.dart'; @@ -98,17 +97,6 @@ class MapStateNotifier extends Notifier { EventStream.shared.emit(const MapMarkerReloadEvent()); } - Option parseDateOption(String s) { - try { - if (s.trim().isEmpty) { - return const Option.none(); - } - return Option.some(DateTime.parse(s)); - } catch (_) { - return const Option.none(); - } - } - @override MapState build() { final mapConfig = ref.read(appConfigProvider.select((config) => config.map)); diff --git a/mobile/lib/providers/album/album_title.provider.dart b/mobile/lib/providers/album/album_title.provider.dart deleted file mode 100644 index b38c2929f..000000000 --- a/mobile/lib/providers/album/album_title.provider.dart +++ /dev/null @@ -1,15 +0,0 @@ -import 'package:hooks_riverpod/hooks_riverpod.dart'; - -class AlbumTitleNotifier extends StateNotifier { - AlbumTitleNotifier() : super(""); - - void setAlbumTitle(String title) { - state = title; - } - - void clearAlbumTitle() { - state = ""; - } -} - -final albumTitleProvider = StateNotifierProvider((ref) => AlbumTitleNotifier()); diff --git a/mobile/lib/providers/app_life_cycle.provider.dart b/mobile/lib/providers/app_life_cycle.provider.dart index c5702c4b5..1ea9f5692 100644 --- a/mobile/lib/providers/app_life_cycle.provider.dart +++ b/mobile/lib/providers/app_life_cycle.provider.dart @@ -31,10 +31,6 @@ class AppLifeCycleNotifier extends StateNotifier { AppLifeCycleNotifier(this._ref) : super(AppLifeCycleEnum.active); - AppLifeCycleEnum getAppState() { - return state; - } - Future handleAppResume() async { state = AppLifeCycleEnum.resumed; _log.info("App resumed"); diff --git a/mobile/lib/providers/asset_viewer/scroll_notifier.provider.dart b/mobile/lib/providers/asset_viewer/scroll_notifier.provider.dart deleted file mode 100644 index a5423554d..000000000 --- a/mobile/lib/providers/asset_viewer/scroll_notifier.provider.dart +++ /dev/null @@ -1,9 +0,0 @@ -import 'package:flutter/material.dart'; - -final scrollToTopNotifierProvider = ScrollNotifier(); - -class ScrollNotifier with ChangeNotifier { - void scrollToTop() { - notifyListeners(); - } -} diff --git a/mobile/lib/providers/asset_viewer/scroll_to_date_notifier.provider.dart b/mobile/lib/providers/asset_viewer/scroll_to_date_notifier.provider.dart deleted file mode 100644 index 69e598c43..000000000 --- a/mobile/lib/providers/asset_viewer/scroll_to_date_notifier.provider.dart +++ /dev/null @@ -1,14 +0,0 @@ -import 'package:flutter/material.dart'; - -final scrollToDateNotifierProvider = ScrollToDateNotifier(null); - -class ScrollToDateNotifier extends ValueNotifier { - ScrollToDateNotifier(super.value); - - void scrollToDate(DateTime date) { - value = date; - - // Manually notify listeners to trigger the scroll, even if the value hasn't changed - notifyListeners(); - } -} diff --git a/mobile/lib/providers/asset_viewer/show_controls.provider.dart b/mobile/lib/providers/asset_viewer/show_controls.provider.dart index f2d11b450..146894000 100644 --- a/mobile/lib/providers/asset_viewer/show_controls.provider.dart +++ b/mobile/lib/providers/asset_viewer/show_controls.provider.dart @@ -14,8 +14,4 @@ class ShowControls extends StateNotifier { set show(bool value) { state = value; } - - void toggle() { - state = !state; - } } diff --git a/mobile/lib/providers/cleanup.provider.dart b/mobile/lib/providers/cleanup.provider.dart index df51c36fd..361efd446 100644 --- a/mobile/lib/providers/cleanup.provider.dart +++ b/mobile/lib/providers/cleanup.provider.dart @@ -87,11 +87,6 @@ class CleanupNotifier extends StateNotifier { _persistExcludedAlbumIds(newKeepAlbumIds); } - void setExcludedAlbumIds(Set albumIds) { - state = state.copyWith(keepAlbumIds: albumIds, assetsToDelete: []); - _persistExcludedAlbumIds(albumIds); - } - void _persistExcludedAlbumIds(Set albumIds) { unawaited(_settingsRepository.write(.cleanupKeepAlbumIds, albumIds.toList())); } diff --git a/mobile/lib/providers/haptic_feedback.provider.dart b/mobile/lib/providers/haptic_feedback.provider.dart index 850935163..695bd5205 100644 --- a/mobile/lib/providers/haptic_feedback.provider.dart +++ b/mobile/lib/providers/haptic_feedback.provider.dart @@ -10,7 +10,6 @@ final hapticFeedbackProvider = StateNotifierProvider((ref) }); class HapticNotifier extends StateNotifier { - void build() {} final Ref _ref; HapticNotifier(this._ref) : super(null); @@ -21,12 +20,6 @@ class HapticNotifier extends StateNotifier { } } - void lightImpact() { - if (_ref.read(appSettingsServiceProvider).getSetting(AppSettingsEnum.enableHapticFeedback)) { - unawaited(HapticFeedback.lightImpact()); - } - } - void mediumImpact() { if (_ref.read(appSettingsServiceProvider).getSetting(AppSettingsEnum.enableHapticFeedback)) { unawaited(HapticFeedback.mediumImpact()); @@ -38,10 +31,4 @@ class HapticNotifier extends StateNotifier { unawaited(HapticFeedback.heavyImpact()); } } - - void vibrate() { - if (_ref.read(appSettingsServiceProvider).getSetting(AppSettingsEnum.enableHapticFeedback)) { - unawaited(HapticFeedback.vibrate()); - } - } } diff --git a/mobile/lib/providers/infrastructure/action.provider.dart b/mobile/lib/providers/infrastructure/action.provider.dart index 3fb9f8acb..2307d4e23 100644 --- a/mobile/lib/providers/infrastructure/action.provider.dart +++ b/mobile/lib/providers/infrastructure/action.provider.dart @@ -2,8 +2,6 @@ import 'dart:async'; -import 'package:auto_route/auto_route.dart'; -import 'package:flutter/material.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:immich_mobile/constants/enums.dart'; import 'package:immich_mobile/domain/models/album/album.model.dart'; @@ -13,7 +11,6 @@ import 'package:immich_mobile/providers/asset_viewer/asset_viewer.provider.dart' import 'package:immich_mobile/providers/backup/asset_upload_progress.provider.dart'; import 'package:immich_mobile/providers/infrastructure/album.provider.dart'; import 'package:immich_mobile/providers/timeline/multiselect.provider.dart'; -import 'package:immich_mobile/routing/router.dart'; import 'package:immich_mobile/services/action.service.dart'; import 'package:immich_mobile/services/foreground_upload.service.dart'; import 'package:logging/logging.dart'; @@ -67,16 +64,6 @@ class ActionNotifier extends Notifier { }; } - Future troubleshoot(ActionSource source, BuildContext context) async { - final assets = _getAssets(source); - if (assets.length > 1) { - return ActionResult(count: assets.length, success: false, error: 'Cannot troubleshoot multiple assets'); - } - unawaited(context.pushRoute(AssetTroubleshootRoute(asset: assets.first))); - - return ActionResult(count: assets.length, success: true); - } - Future emptyTrash(String userId) async { try { final count = await _service.emptyTrash(userId); diff --git a/mobile/lib/providers/infrastructure/setting.provider.dart b/mobile/lib/providers/infrastructure/setting.provider.dart index 9e33017ca..e334c6e67 100644 --- a/mobile/lib/providers/infrastructure/setting.provider.dart +++ b/mobile/lib/providers/infrastructure/setting.provider.dart @@ -10,13 +10,6 @@ class SettingsNotifier extends Notifier { SettingsService build() => SettingsService(storeService: ref.read(storeServiceProvider)); T get(Setting setting) => state.get(setting); - - Future set(Setting setting, T value) async { - await state.set(setting, value); - ref.invalidateSelf(); - } - - Stream watch(Setting setting) => state.watch(setting); } final settingsProvider = NotifierProvider(SettingsNotifier.new); diff --git a/mobile/lib/providers/infrastructure/tag.provider.dart b/mobile/lib/providers/infrastructure/tag.provider.dart index 152582aa9..83f0617b4 100644 --- a/mobile/lib/providers/infrastructure/tag.provider.dart +++ b/mobile/lib/providers/infrastructure/tag.provider.dart @@ -9,17 +9,6 @@ class TagNotifier extends AsyncNotifier> { Future> build() async { return ref.watch(tagServiceProvider).getAllTags(); } - - Future bulkTagAssets(List assetIds, List tagIds) async { - return ref.read(tagServiceProvider).bulkTagAssets(assetIds, tagIds); - } - - Future> upsertTags(List tags) async { - final upsertedTags = await ref.read(tagServiceProvider).upsertTags(tags); - - state = AsyncValue.data({...?state.valueOrNull, ...upsertedTags}); - return upsertedTags; - } } final tagProvider = AsyncNotifierProvider>(TagNotifier.new); diff --git a/mobile/lib/providers/map/map_state.provider.dart b/mobile/lib/providers/map/map_state.provider.dart index 12e9e59fa..fa4524ead 100644 --- a/mobile/lib/providers/map/map_state.provider.dart +++ b/mobile/lib/providers/map/map_state.provider.dart @@ -31,28 +31,4 @@ class MapStateNotifier extends Notifier { unawaited(ref.read(settingsProvider).write(.mapThemeMode, mode)); state = state.copyWith(themeMode: mode); } - - void switchFavoriteOnly(bool isFavoriteOnly) { - unawaited(ref.read(settingsProvider).write(.mapShowFavoriteOnly, isFavoriteOnly)); - state = state.copyWith(showFavoriteOnly: isFavoriteOnly, shouldRefetchMarkers: true); - } - - void setRefetchMarkers(bool shouldRefetch) { - state = state.copyWith(shouldRefetchMarkers: shouldRefetch); - } - - void switchIncludeArchived(bool isIncludeArchived) { - unawaited(ref.read(settingsProvider).write(.mapIncludeArchived, isIncludeArchived)); - state = state.copyWith(includeArchived: isIncludeArchived, shouldRefetchMarkers: true); - } - - void switchWithPartners(bool isWithPartners) { - unawaited(ref.read(settingsProvider).write(.mapWithPartners, isWithPartners)); - state = state.copyWith(withPartners: isWithPartners, shouldRefetchMarkers: true); - } - - void setRelativeTime(int relativeTime) { - unawaited(ref.read(settingsProvider).write(.mapRelativeDate, relativeTime)); - state = state.copyWith(relativeTime: relativeTime, shouldRefetchMarkers: true); - } } diff --git a/mobile/lib/providers/permission.provider.dart b/mobile/lib/providers/permission.provider.dart index bd4dc7b61..620a8d106 100644 --- a/mobile/lib/providers/permission.provider.dart +++ b/mobile/lib/providers/permission.provider.dart @@ -23,22 +23,11 @@ class NotificationPermissionNotifier extends StateNotifier { return permission; } - /// Whether the user has the permission or not - /// Note: In Android, this is always true - Future hasNotificationPermission() { - return Permission.notification.isGranted; - } - Future getNotificationPermission() async { final status = await Permission.notification.status; state = status; return status; } - - /// Either the permission was granted already or else ask for the permission - Future hasOrAskForNotificationPermission() { - return requestNotificationPermission().then((p) => p.isGranted); - } } final notificationPermissionProvider = StateNotifierProvider( diff --git a/mobile/lib/providers/sync_status.provider.dart b/mobile/lib/providers/sync_status.provider.dart index eb183fbb1..5f9d8c36a 100644 --- a/mobile/lib/providers/sync_status.provider.dart +++ b/mobile/lib/providers/sync_status.provider.dart @@ -1,26 +1,10 @@ import 'package:flutter/foundation.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/generated/translations.g.dart'; part 'sync_status.provider.freezed.dart'; -enum SyncStatus { - idle, - syncing, - success, - error; - - String localized() { - final t = StaticTranslations.instance; - return switch (this) { - SyncStatus.idle => t.idle, - SyncStatus.syncing => t.running, - SyncStatus.success => t.success, - SyncStatus.error => t.error, - }; - } -} +enum SyncStatus { idle, syncing, success, error } @freezed abstract class SyncStatusState with _$SyncStatusState { diff --git a/mobile/lib/providers/timeline/multiselect.provider.dart b/mobile/lib/providers/timeline/multiselect.provider.dart index f74201e98..b14f8527b 100644 --- a/mobile/lib/providers/timeline/multiselect.provider.dart +++ b/mobile/lib/providers/timeline/multiselect.provider.dart @@ -75,25 +75,6 @@ class MultiSelectNotifier extends Notifier { state = const MultiSelectState(selectedAssets: {}, lockedSelectionAssets: {}, forceEnable: false); } - /// Bucket bulk operations - Future selectBucket(int offset, int bucketCount) async { - final assets = await _timelineService.loadAssets(offset, bucketCount); - final selectedAssets = state.selectedAssets.toSet(); - - selectedAssets.addAll(assets); - - state = state.copyWith(selectedAssets: selectedAssets); - } - - Future deselectBucket(int offset, int bucketCount) async { - final assets = await _timelineService.loadAssets(offset, bucketCount); - final selectedAssets = state.selectedAssets.toSet(); - - selectedAssets.removeAll(assets); - - state = state.copyWith(selectedAssets: selectedAssets); - } - Future toggleBucketSelection(int offset, int bucketCount) async { final assets = await _timelineService.loadAssets(offset, bucketCount); toggleBucketSelectionByAssets(assets); @@ -119,10 +100,6 @@ class MultiSelectNotifier extends Notifier { state = state.copyWith(selectedAssets: selectedAssets); } - - void setLockedSelectionAssets(Set assets) { - state = state.copyWith(lockedSelectionAssets: assets); - } } final bucketSelectionProvider = Provider.family>((ref, bucketAssets) { diff --git a/mobile/lib/providers/view_intent/view_intent_file_path.provider.dart b/mobile/lib/providers/view_intent/view_intent_file_path.provider.dart index 75cd304a3..e776fb5b7 100644 --- a/mobile/lib/providers/view_intent/view_intent_file_path.provider.dart +++ b/mobile/lib/providers/view_intent/view_intent_file_path.provider.dart @@ -17,13 +17,6 @@ class ViewIntentFilePathNotifier extends Notifier { } state = null; } - - void clearIfMatch(String path) { - if (state != path) { - return; - } - state = null; - } } final viewIntentFilePathProvider = NotifierProvider( diff --git a/mobile/lib/repositories/activity_api.repository.dart b/mobile/lib/repositories/activity_api.repository.dart index 9ae83b0e7..5097a3934 100644 --- a/mobile/lib/repositories/activity_api.repository.dart +++ b/mobile/lib/repositories/activity_api.repository.dart @@ -34,11 +34,6 @@ class ActivityApiRepository extends ApiRepository { return checkNull(_api.deleteActivity(id)); } - Future getStats(String albumId, {String? assetId}) async { - final response = await checkNull(_api.getActivityStatistics(albumId, assetId: assetId)); - return ActivityStats(comments: response.comments); - } - static Activity _toActivity(ActivityResponseDto dto) => Activity( id: dto.id, createdAt: dto.createdAt, diff --git a/mobile/lib/repositories/asset_api.repository.dart b/mobile/lib/repositories/asset_api.repository.dart index 9b92b491b..50d8431de 100644 --- a/mobile/lib/repositories/asset_api.repository.dart +++ b/mobile/lib/repositories/asset_api.repository.dart @@ -1,5 +1,4 @@ import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:http/http.dart'; import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:immich_mobile/domain/models/asset_edit.model.dart' hide AssetEditAction; import 'package:immich_mobile/domain/models/stack.model.dart'; @@ -43,11 +42,6 @@ class AssetApiRepository extends ApiRepository { return response?.count ?? 0; } - // TODO(shenlong): remove after action migration - Future updateVisibility(List ids, AssetVisibility visibility) async { - return _api.updateAssets(AssetBulkUpdateDto(ids: ids, visibility: Optional.present(_mapVisibility(visibility)))); - } - Future stack(List ids) async { final responseDto = await checkNull(_stacksApi.createStack(StackCreateDto(assetIds: ids))); @@ -58,10 +52,6 @@ class AssetApiRepository extends ApiRepository { return _stacksApi.deleteStacks(BulkIdsDto(ids: ids)); } - Future downloadAsset(String id, {required bool edited}) { - return _api.downloadAssetWithHttpInfo(id, edited: edited); - } - api.AssetVisibility _mapVisibility(AssetVisibility visibility) => switch (visibility) { AssetVisibility.timeline => api.AssetVisibility.timeline, AssetVisibility.hidden => api.AssetVisibility.hidden, @@ -110,20 +100,6 @@ class AssetApiRepository extends ApiRepository { ), ); } - - Future updateLocation(List ids, LatLng location) async { - return _api.updateAssets( - AssetBulkUpdateDto( - ids: ids, - latitude: Optional.present(location.latitude), - longitude: Optional.present(location.longitude), - ), - ); - } - - Future updateDateTime(List ids, String dateTime) async { - return _api.updateAssets(AssetBulkUpdateDto(ids: ids, dateTimeOriginal: Optional.present(dateTime))); - } } extension on StackResponseDto { diff --git a/mobile/lib/repositories/asset_media.repository.dart b/mobile/lib/repositories/asset_media.repository.dart index f9a5de3a8..c95f48785 100644 --- a/mobile/lib/repositories/asset_media.repository.dart +++ b/mobile/lib/repositories/asset_media.repository.dart @@ -77,11 +77,6 @@ class AssetMediaRepository { return restoredIds; } - Future get(String id) async { - final entity = await AssetEntity.fromId(id); - return entity; - } - Future getOriginalFilename(String id) async { final entity = await AssetEntity.fromId(id); if (entity == null) { diff --git a/mobile/lib/repositories/download.repository.dart b/mobile/lib/repositories/download.repository.dart index 850448786..63b13a667 100644 --- a/mobile/lib/repositories/download.repository.dart +++ b/mobile/lib/repositories/download.repository.dart @@ -10,7 +10,6 @@ import 'package:immich_mobile/models/download/livephotos_medatada.model.dart'; import 'package:immich_mobile/services/api.service.dart'; import 'package:immich_mobile/utils/image_url_builder.dart'; -// ignore: dispose-provided-instances final downloadRepositoryProvider = Provider((ref) => DownloadRepository()); class DownloadRepository { @@ -60,18 +59,6 @@ class DownloadRepository { .listen((record) => onLivePhotoRecordComplete?.call(record)); } - Future> downloadAll(List tasks) { - return _downloader.enqueueAll(tasks); - } - - Future deleteAllTrackingRecords() { - return _downloader.database.deleteAllRecords(); - } - - Future cancel(String id) { - return _downloader.cancelTaskWithId(id); - } - Future> getLiveVideoTasks() { return _downloader.database.allRecordsWithStatus(TaskStatus.complete, group: kDownloadGroupLivePhoto); } diff --git a/mobile/lib/repositories/file_media.repository.dart b/mobile/lib/repositories/file_media.repository.dart index c54813a75..307bad90f 100644 --- a/mobile/lib/repositories/file_media.repository.dart +++ b/mobile/lib/repositories/file_media.repository.dart @@ -1,8 +1,6 @@ import 'dart:io'; -import 'package:flutter/foundation.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart'; -import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; import 'package:photo_manager/photo_manager.dart' hide AssetType; final fileMediaRepositoryProvider = Provider((ref) => const FileMediaRepository()); @@ -10,20 +8,6 @@ final fileMediaRepositoryProvider = Provider((ref) => const FileMediaRepository( class FileMediaRepository { const FileMediaRepository(); - Future saveLocalAsset(Uint8List data, {required String title, String? relativePath}) async { - final entity = await PhotoManager.editor.saveImage(data, filename: title, title: title, relativePath: relativePath); - - return LocalAsset( - id: entity.id, - name: title, - type: AssetType.image, - createdAt: entity.createDateTime, - updatedAt: entity.modifiedDateTime, - playbackStyle: AssetPlaybackStyle.image, - isEdited: false, - ); - } - Future saveImageWithFile(String filePath, {String? title, String? relativePath}) async { final entity = await PhotoManager.editor.saveImageWithPath(filePath, title: title, relativePath: relativePath); return entity; diff --git a/mobile/lib/repositories/network.repository.dart b/mobile/lib/repositories/network.repository.dart index 2f859e945..2b10ad90d 100644 --- a/mobile/lib/repositories/network.repository.dart +++ b/mobile/lib/repositories/network.repository.dart @@ -27,8 +27,4 @@ class NetworkRepository { } return _networkInfo.getWifiName(); } - - Future getWifiIp() { - return _networkInfo.getWifiIP(); - } } diff --git a/mobile/lib/repositories/partner_api.repository.dart b/mobile/lib/repositories/partner_api.repository.dart index eaca839bf..240b61f63 100644 --- a/mobile/lib/repositories/partner_api.repository.dart +++ b/mobile/lib/repositories/partner_api.repository.dart @@ -14,13 +14,6 @@ class PartnerApiRepository extends ApiRepository { PartnerApiRepository(this._api); - Future> getAll(Direction direction) async { - final response = await checkNull( - _api.getPartners(direction == Direction.sharedByMe ? PartnerDirection.sharedBy : PartnerDirection.sharedWith), - ); - return response.map(UserConverter.fromPartnerDto).toList(); - } - Future create(String sharedWithId) async { final dto = await checkNull(_api.createPartner(PartnerCreateDto(sharedWithId: sharedWithId))); return UserConverter.fromPartnerDto(dto); diff --git a/mobile/lib/repositories/upload.repository.dart b/mobile/lib/repositories/upload.repository.dart index 136684093..25960c6a5 100644 --- a/mobile/lib/repositories/upload.repository.dart +++ b/mobile/lib/repositories/upload.repository.dart @@ -9,7 +9,6 @@ import 'package:immich_mobile/constants/constants.dart'; import 'package:immich_mobile/domain/models/store.model.dart'; import 'package:immich_mobile/entities/store.entity.dart'; import 'package:immich_mobile/infrastructure/repositories/network.repository.dart'; -import 'package:immich_mobile/utils/debug_print.dart'; import 'package:logging/logging.dart'; final uploadRepositoryProvider = Provider((ref) => UploadRepository()); @@ -37,10 +36,6 @@ class UploadRepository { ); } - Future enqueueBackground(UploadTask task) { - return FileDownloader().enqueue(task); - } - Future> enqueueBackgroundAll(List tasks) { return FileDownloader().enqueueAll(tasks); } @@ -49,10 +44,6 @@ class UploadRepository { return FileDownloader().database.deleteAllRecords(group: group); } - Future cancelAll(String group) { - return FileDownloader().cancelAll(group: group); - } - Future reset(String group) { return FileDownloader().reset(group: group); } @@ -66,28 +57,6 @@ class UploadRepository { return FileDownloader().start(); } - Future getUploadInfo() async { - final [enqueuedTasks, runningTasks, canceledTasks, waitingTasks, pausedTasks] = await Future.wait([ - FileDownloader().database.allRecordsWithStatus(TaskStatus.enqueued, group: kBackupGroup), - FileDownloader().database.allRecordsWithStatus(TaskStatus.running, group: kBackupGroup), - FileDownloader().database.allRecordsWithStatus(TaskStatus.canceled, group: kBackupGroup), - FileDownloader().database.allRecordsWithStatus(TaskStatus.waitingToRetry, group: kBackupGroup), - FileDownloader().database.allRecordsWithStatus(TaskStatus.paused, group: kBackupGroup), - ]); - - dPrint( - () => - """ - Upload Info: - Enqueued: ${enqueuedTasks.length} - Running: ${runningTasks.length} - Canceled: ${canceledTasks.length} - Waiting: ${waitingTasks.length} - Paused: ${pausedTasks.length} - """, - ); - } - Future uploadFile({ required File file, required String originalFileName, diff --git a/mobile/lib/services/gcast.service.dart b/mobile/lib/services/gcast.service.dart index d9fc44a34..6d764edac 100644 --- a/mobile/lib/services/gcast.service.dart +++ b/mobile/lib/services/gcast.service.dart @@ -110,15 +110,6 @@ class GCastService { onReceiverName?.call(device.extras["fn"] ?? "Google Cast"); } - CastDestinationType getType() { - return CastDestinationType.googleCast; - } - - Future initialize() async { - // there is nothing blocking us from using Google Cast that we can check for - return true; - } - Future disconnect() async { onReceiverName?.call(""); currentAssetId = null; diff --git a/mobile/lib/services/toast.service.dart b/mobile/lib/services/toast.service.dart index 1cbb52635..400da452f 100644 --- a/mobile/lib/services/toast.service.dart +++ b/mobile/lib/services/toast.service.dart @@ -16,10 +16,6 @@ class ToastService { snackbar.success(message, duration: toast?.timeout, action: toast?.action); } - FutureOr info(String message, {ToastOption? toast}) { - snackbar.info(message, duration: toast?.timeout, action: toast?.action); - } - FutureOr error(String message, {ToastOption? toast}) { snackbar.error(message, duration: toast?.timeout, action: toast?.action); } diff --git a/mobile/lib/services/view_intent.service.dart b/mobile/lib/services/view_intent.service.dart index e822d1ebb..596443b7b 100644 --- a/mobile/lib/services/view_intent.service.dart +++ b/mobile/lib/services/view_intent.service.dart @@ -44,13 +44,6 @@ class ViewIntentService { } } - Future cleanupManagedTempFileIfCurrent(String path) async { - if (_managedTempFilePath == path) { - _managedTempFilePath = null; - } - await cleanupTempFile(path); - } - Future cleanupTempFile(String path) async { if (!_isManagedTempFile(path)) { return; @@ -90,19 +83,6 @@ class ViewIntentService { } } - void markUploadActive(String path) { - _activeUploadPaths.add(path); - } - - Future markUploadInactive(String path) async { - if (!_activeUploadPaths.remove(path)) { - return; - } - if (_managedTempFilePath != path) { - await cleanupTempFile(path); - } - } - bool _isManagedTempFile(String path) { return p.basename(path).startsWith('view_intent_') && p.basename(p.dirname(path)) == 'cache'; } diff --git a/mobile/lib/utils/action_button.utils.dart b/mobile/lib/utils/action_button.utils.dart index 4e0a5efff..4abd7f41a 100644 --- a/mobile/lib/utils/action_button.utils.dart +++ b/mobile/lib/utils/action_button.utils.dart @@ -260,10 +260,6 @@ class ActionButtonBuilder { ActionButtonType.restoreTrash, }; - static List build(ActionButtonContext context) { - return _actionTypes.where((type) => type.shouldShow(context)).map((type) => type.buildButton(context)).toList(); - } - static List buildViewerKebabMenu(ActionButtonContext context, BuildContext buildContext) { final visibleButtons = defaultViewerKebabMenuOrder .where((type) => !defaultViewerBottomBarButtons.contains(type) && type.shouldShow(context)) diff --git a/mobile/lib/utils/asset_filter.dart b/mobile/lib/utils/asset_filter.dart index a4de5d276..dbff9bd0d 100644 --- a/mobile/lib/utils/asset_filter.dart +++ b/mobile/lib/utils/asset_filter.dart @@ -2,9 +2,7 @@ import 'package:immich_mobile/domain/models/asset/base_asset.model.dart'; extension type const AssetFilter(Iterable assets) implements Iterable { AssetFilter where(bool Function(T asset) test) => AssetFilter(assets.where(test)); - AssetFilter whereNot(bool Function(T asset) test) => AssetFilter(assets.where((asset) => !test(asset))); - AssetFilter type(AssetType type) => where((asset) => asset.type == type); AssetFilter favorite({bool isFavorite = true}) => where((asset) => asset.isFavorite == isFavorite); AssetFilter remote() => AssetFilter(assets.whereType()); @@ -13,8 +11,6 @@ extension type const AssetFilter(Iterable assets) implem remote().where((asset) => asset.visibility == visibility); AssetFilter notVisibility(AssetVisibility visibility) => remote().where((asset) => asset.visibility != visibility); - AssetFilter archived({bool isArchived = true}) => - remote().where((asset) => asset.isArchived == isArchived); AssetFilter locked({bool isLocked = true}) => remote().where((asset) => asset.isLocked == isLocked); AssetFilter stacked({bool isStacked = true}) => remote().where((asset) => asset.isStacked == isStacked); AssetFilter trashed({bool isTrashed = true}) => remote().where((asset) => asset.isTrashed == isTrashed); diff --git a/mobile/lib/utils/debounce.dart b/mobile/lib/utils/debounce.dart index 4c8060142..0af3a3f2b 100644 --- a/mobile/lib/utils/debounce.dart +++ b/mobile/lib/utils/debounce.dart @@ -26,17 +26,6 @@ class Debouncer { _timer = Timer(interval, _callAndRest); } - Future? drain() { - final timer = _timer; - if (timer != null && timer.isActive) { - timer.cancel(); - if (_lastAction != null) { - _callAndRest(); - } - } - return _actionFuture; - } - @pragma('vm:prefer-inline') void _callAndRest() { _lastActionTime = DateTime.now(); diff --git a/mobile/lib/utils/map_utils.dart b/mobile/lib/utils/map_utils.dart index 2a89b6342..7685e78ef 100644 --- a/mobile/lib/utils/map_utils.dart +++ b/mobile/lib/utils/map_utils.dart @@ -3,7 +3,6 @@ import 'dart:async'; import 'package:flutter/material.dart'; import 'package:geolocator/geolocator.dart'; import 'package:immich_mobile/generated/translations.g.dart'; -import 'package:immich_mobile/models/map/map_marker.model.dart'; import 'package:immich_mobile/widgets/common/confirm_dialog.dart'; import 'package:logging/logging.dart'; import 'package:maplibre_gl/maplibre_gl.dart'; @@ -49,20 +48,6 @@ class MapUtils { heatmapOpacity: 0.7, ); - static Map _addFeature(MapMarker marker) => { - 'type': 'Feature', - 'id': marker.assetRemoteId, - 'geometry': { - 'type': 'Point', - 'coordinates': [marker.latLng.longitude, marker.latLng.latitude], - }, - }; - - static Map generateGeoJsonForMarkers(List markers) => { - 'type': 'FeatureCollection', - 'features': markers.map(_addFeature).toList(), - }; - static Future<(Position?, LocationPermission?)> checkPermAndGetLocation({ required BuildContext context, bool silent = false, diff --git a/mobile/lib/utils/migration.dart b/mobile/lib/utils/migration.dart index d7463d670..4dfd4e1c2 100644 --- a/mobile/lib/utils/migration.dart +++ b/mobile/lib/utils/migration.dart @@ -264,16 +264,6 @@ class _StoreMigrator { _migratedStoreIds.add(legacyKey.id); } - Future migrateString(StoreKey legacyKey, SettingsKey newKey) async { - final value = await readLegacyStoreString(legacyKey.id); - if (value == null) { - return; - } - - _cache[newKey] = value; - _migratedStoreIds.add(legacyKey.id); - } - void stage(StoreKey legacyKey, SettingsKey newKey, U value) { _cache[newKey] = value; _migratedStoreIds.add(legacyKey.id); diff --git a/mobile/lib/utils/semver.dart b/mobile/lib/utils/semver.dart index 8080af00b..b39757fa6 100644 --- a/mobile/lib/utils/semver.dart +++ b/mobile/lib/utils/semver.dart @@ -13,15 +13,6 @@ class SemVer { return '$major.$minor.$patch${prerelease == null ? '' : '-rc.$prerelease'}'; } - SemVer copyWith({int? major, int? minor, int? patch, int? prerelease}) { - return SemVer( - major: major ?? this.major, - minor: minor ?? this.minor, - patch: patch ?? this.patch, - prerelease: prerelease ?? this.prerelease, - ); - } - static final _pattern = RegExp(r'^v?(\d+)\.(\d+)\.(\d+)(?:-rc\.(\d+))?(?:[-+].*)?$', caseSensitive: false); factory SemVer.fromString(String version) { diff --git a/mobile/lib/utils/upload_speed_calculator.dart b/mobile/lib/utils/upload_speed_calculator.dart index a2153e6e3..cb681e9ce 100644 --- a/mobile/lib/utils/upload_speed_calculator.dart +++ b/mobile/lib/utils/upload_speed_calculator.dart @@ -24,14 +24,6 @@ class UploadSpeedCalculator { /// The total file size being uploaded. int _totalBytes = 0; - /// Resets the calculator for a new upload. - void reset() { - _speedSamples.clear(); - _lastUpdateTime = null; - _lastBytes = 0; - _totalBytes = 0; - } - /// Updates the calculator with the current progress. /// /// [currentBytes] is the number of bytes transferred so far. @@ -160,16 +152,6 @@ class UploadSpeedManager { return calculator.speedAsString; } - /// Gets the current speed string for a specific task. - String getSpeedAsString(String taskId) { - return _calculators[taskId]?.speedAsString ?? '-- MB/s'; - } - - /// Gets the time remaining string for a specific task. - String getTimeRemainingAsString(String taskId) { - return _calculators[taskId]?.timeRemainingAsString ?? '--:--'; - } - /// Removes a task from tracking. void removeTask(String taskId) { _calculators.remove(taskId); diff --git a/mobile/lib/widgets/photo_view/src/controller/photo_view_scalestate_controller.dart b/mobile/lib/widgets/photo_view/src/controller/photo_view_scalestate_controller.dart index c27ba9d8d..f2a49e1d5 100644 --- a/mobile/lib/widgets/photo_view/src/controller/photo_view_scalestate_controller.dart +++ b/mobile/lib/widgets/photo_view/src/controller/photo_view_scalestate_controller.dart @@ -62,12 +62,6 @@ class PhotoViewScaleStateController { /// Check if is `zoomedIn` & `zoomedOut` bool get isZooming => scaleState == PhotoViewScaleState.zoomedIn || scaleState == PhotoViewScaleState.zoomedOut; - /// Resets the state to the initial value; - void reset() { - prevScaleState = scaleState; - scaleState = PhotoViewScaleState.initial; - } - /// Closes streams and removes eventual listeners void dispose() { unawaited(_outputScaleStateCtrl.close()); diff --git a/mobile/lib/widgets/photo_view/src/core/photo_view_core.dart b/mobile/lib/widgets/photo_view/src/core/photo_view_core.dart index a8249b48f..171ece493 100644 --- a/mobile/lib/widgets/photo_view/src/core/photo_view_core.dart +++ b/mobile/lib/widgets/photo_view/src/core/photo_view_core.dart @@ -323,14 +323,6 @@ class PhotoViewCoreState extends State super.dispose(); } - void onTapUp(TapUpDetails details) { - widget.onTapUp?.call(context, details, controller.value); - } - - void onTapDown(TapDownDetails details) { - widget.onTapDown?.call(context, details, controller.value); - } - void _updateScaleBoundaries() { final prev = controller.scaleBoundaries; if (prev == widget.scaleBoundaries) { diff --git a/mobile/test/medium/repositories/local_asset_repository_test.dart b/mobile/test/medium/repositories/local_asset_repository_test.dart index bd048a13f..29a1ef084 100644 --- a/mobile/test/medium/repositories/local_asset_repository_test.dart +++ b/mobile/test/medium/repositories/local_asset_repository_test.dart @@ -443,195 +443,4 @@ void main() { expect(result.assets.first.id, videoAsset.id); }); }); - - group('reconcileHashesFromCloudId', () { - late String userId; - - setUp(() async { - final user = await ctx.newUser(); - userId = user.id; - }); - - test('updates local asset checksum when all metadata matches', () async { - final remoteAsset = await ctx.newRemoteAsset(ownerId: userId); - final remoteCloudAsset = await ctx.newRemoteAssetCloudId(id: remoteAsset.id); - final localAsset = await ctx.newLocalAsset( - checksumOption: const Option.none(), - iCloudId: remoteCloudAsset.cloudId, - createdAt: remoteCloudAsset.createdAt, - adjustmentTime: remoteCloudAsset.adjustmentTime, - latitude: remoteCloudAsset.latitude, - longitude: remoteCloudAsset.longitude, - ); - - await sut.reconcileHashesFromCloudId(); - final updated = await sut.getById(localAsset.id); - expect(updated?.checksum, remoteAsset.checksum); - }); - - test('does not update when local asset already has checksum', () async { - final remoteAsset = await ctx.newRemoteAsset(ownerId: userId); - final remoteCloudAsset = await ctx.newRemoteAssetCloudId(id: remoteAsset.id); - - final localAsset = await ctx.newLocalAsset( - checksum: 'existing', - iCloudId: remoteCloudAsset.cloudId, - createdAt: remoteCloudAsset.createdAt, - adjustmentTime: remoteCloudAsset.adjustmentTime, - latitude: remoteCloudAsset.latitude, - longitude: remoteCloudAsset.longitude, - ); - - await sut.reconcileHashesFromCloudId(); - final updated = await sut.getById(localAsset.id); - expect(updated?.checksum, 'existing'); - }); - - test('does not update when adjustment_time does not match', () async { - final remoteAsset = await ctx.newRemoteAsset(ownerId: userId); - final cloudIdAsset = await ctx.newRemoteAssetCloudId(id: remoteAsset.id, adjustmentTime: DateTime(2024, 1, 12)); - final localAsset = await ctx.newLocalAsset( - checksumOption: const Option.none(), - iCloudId: cloudIdAsset.cloudId, - createdAt: cloudIdAsset.createdAt, - adjustmentTime: DateTime(2026, 1, 12), - latitude: cloudIdAsset.latitude, - longitude: cloudIdAsset.longitude, - ); - - await sut.reconcileHashesFromCloudId(); - final updated = await sut.getById(localAsset.id); - expect(updated?.checksum, isNull); - }); - - test('does not update when latitude does not match', () async { - final remoteAsset = await ctx.newRemoteAsset(ownerId: userId); - final cloudIdAsset = await ctx.newRemoteAssetCloudId(id: remoteAsset.id, latitude: const Option.none()); - final localAsset = await ctx.newLocalAsset( - checksumOption: const Option.none(), - iCloudId: cloudIdAsset.cloudId, - createdAt: cloudIdAsset.createdAt, - adjustmentTime: cloudIdAsset.adjustmentTime, - latitude: 40.7128, - longitude: cloudIdAsset.longitude, - ); - - await sut.reconcileHashesFromCloudId(); - final updated = await sut.getById(localAsset.id); - expect(updated?.checksum, isNull); - }); - - test('does not update when longitude does not match', () async { - final remoteAsset = await ctx.newRemoteAsset(ownerId: userId); - final cloudIdAsset = await ctx.newRemoteAssetCloudId(id: remoteAsset.id, longitude: .fromNullable(-74.006)); - final localAsset = await ctx.newLocalAsset( - checksumOption: const Option.none(), - iCloudId: cloudIdAsset.cloudId, - createdAt: cloudIdAsset.createdAt, - adjustmentTime: cloudIdAsset.adjustmentTime, - latitude: cloudIdAsset.latitude, - longitude: 0.0, - ); - - await sut.reconcileHashesFromCloudId(); - final updated = await sut.getById(localAsset.id); - expect(updated?.checksum, isNull); - }); - - test('does not update when createdAt does not match', () async { - final remoteAsset = await ctx.newRemoteAsset(ownerId: userId); - final cloudIdAsset = await ctx.newRemoteAssetCloudId(id: remoteAsset.id, createdAt: DateTime(2024, 1, 5)); - final localAsset = await ctx.newLocalAsset( - checksumOption: const Option.none(), - iCloudId: cloudIdAsset.cloudId, - createdAt: DateTime(2024, 6, 1), - adjustmentTime: cloudIdAsset.adjustmentTime, - latitude: cloudIdAsset.latitude, - longitude: cloudIdAsset.longitude, - ); - - await sut.reconcileHashesFromCloudId(); - final updated = await sut.getById(localAsset.id); - expect(updated?.checksum, isNull); - }); - - test('does not update when iCloudId is null', () async { - final remoteAsset = await ctx.newRemoteAsset(ownerId: userId); - final cloudIdAsset = await ctx.newRemoteAssetCloudId(id: remoteAsset.id); - final localAsset = await ctx.newLocalAsset( - checksumOption: const Option.none(), - iCloudId: null, - createdAt: cloudIdAsset.createdAt, - adjustmentTime: cloudIdAsset.adjustmentTime, - latitude: cloudIdAsset.latitude, - longitude: cloudIdAsset.longitude, - ); - - await sut.reconcileHashesFromCloudId(); - final updated = await sut.getById(localAsset.id); - expect(updated?.checksum, isNull); - }); - - test('does not update when cloudId does not match iCloudId', () async { - final remoteAsset = await ctx.newRemoteAsset(ownerId: userId); - final cloudIdAsset = await ctx.newRemoteAssetCloudId(id: remoteAsset.id); - final localAsset = await ctx.newLocalAsset( - checksumOption: const Option.none(), - iCloudId: 'different-cloud-id', - createdAt: cloudIdAsset.createdAt, - adjustmentTime: cloudIdAsset.adjustmentTime, - latitude: cloudIdAsset.latitude, - longitude: cloudIdAsset.longitude, - ); - - await sut.reconcileHashesFromCloudId(); - final updated = await sut.getById(localAsset.id); - expect(updated?.checksum, isNull); - }); - - test('handles partial null metadata fields matching correctly', () async { - final remoteAsset = await ctx.newRemoteAsset(ownerId: userId); - final cloudIdAsset = await ctx.newRemoteAssetCloudId( - id: remoteAsset.id, - adjustmentTimeOption: const Option.none(), - ); - final localAsset = await ctx.newLocalAsset( - checksumOption: const Option.none(), - iCloudId: cloudIdAsset.cloudId, - createdAt: cloudIdAsset.createdAt, - adjustmentTimeOption: const Option.none(), - latitude: cloudIdAsset.latitude, - longitude: cloudIdAsset.longitude, - ); - - await sut.reconcileHashesFromCloudId(); - final updated = await sut.getById(localAsset.id); - expect(updated?.checksum, remoteAsset.checksum); - }); - - test('does not update when one has null and other has value', () async { - final remoteAsset = await ctx.newRemoteAsset(ownerId: userId); - final cloudIdAsset = await ctx.newRemoteAssetCloudId(id: remoteAsset.id); - final localAsset = await ctx.newLocalAsset( - checksumOption: const Option.none(), - iCloudId: cloudIdAsset.cloudId, - createdAt: cloudIdAsset.createdAt, - adjustmentTime: cloudIdAsset.adjustmentTime, - latitude: null, - longitude: cloudIdAsset.longitude, - ); - - await sut.reconcileHashesFromCloudId(); - final updated = await sut.getById(localAsset.id); - expect(updated?.checksum, isNull); - }); - - test('handles no matching assets gracefully', () async { - final localAsset = await ctx.newLocalAsset(checksumOption: const Option.none(), iCloudId: 'cloud-no-match'); - - await sut.reconcileHashesFromCloudId(); - final updated = await sut.getById(localAsset.id); - expect(updated?.checksum, isNull); - }); - }); } diff --git a/mobile/test/medium/service_context.dart b/mobile/test/medium/service_context.dart index 6f90b3e34..dd45e90ae 100644 --- a/mobile/test/medium/service_context.dart +++ b/mobile/test/medium/service_context.dart @@ -13,7 +13,6 @@ void _stubPartnerApi(MockPartnerApiRepository api) { final partner = UserDto(id: id, email: '$id@example.com', name: 'name $id', profileChangedAt: TestUtils.now()); registerFallbackValue(Direction.sharedByMe); - when(() => api.getAll(any())).thenAnswer((_) async => const []); when(() => api.create(any())).thenAnswer((_) async => partner); when(() => api.update(any(), inTimeline: any(named: 'inTimeline'))).thenAnswer((_) async => partner); when(() => api.delete(any())).thenAnswer((_) async {}); diff --git a/mobile/test/modules/extensions/builtin_extensions_test.dart b/mobile/test/modules/extensions/builtin_extensions_test.dart index 42538c17b..001a8becd 100644 --- a/mobile/test/modules/extensions/builtin_extensions_test.dart +++ b/mobile/test/modules/extensions/builtin_extensions_test.dart @@ -1,5 +1,4 @@ import 'package:flutter_test/flutter_test.dart'; -import 'package:immich_mobile/extensions/collection_extensions.dart'; import 'package:immich_mobile/extensions/string_extensions.dart'; void main() { @@ -61,45 +60,7 @@ void main() { test('diacritic removal is order-independent', () { const raw = 'Árvíztűrő'; - expect( - raw.toLowerCase().removeDiacritics(), - raw.removeDiacritics().toLowerCase(), - ); - }); - }); - - group('Test uniqueConsecutive', () { - test('empty', () { - final a = []; - expect(a.uniqueConsecutive(), []); - }); - - test('singleElement', () { - final a = [5]; - expect(a.uniqueConsecutive(), [5]); - }); - - test('noDuplicates', () { - final a = [1, 2, 3]; - expect(a.uniqueConsecutive(), orderedEquals([1, 2, 3])); - }); - - test('unsortedDuplicates', () { - final a = [1, 2, 1, 3]; - expect(a.uniqueConsecutive(), orderedEquals([1, 2, 1, 3])); - }); - - test('sortedDuplicates', () { - final a = [6, 6, 2, 3, 3, 3, 4, 5, 1, 1]; - expect(a.uniqueConsecutive(), orderedEquals([6, 2, 3, 4, 5, 1])); - }); - - test('withKey', () { - final a = ["a", "bb", "cc", "ddd"]; - expect( - a.uniqueConsecutive(compare: (s1, s2) => s1.length.compareTo(s2.length)), - orderedEquals(["a", "bb", "ddd"]), - ); + expect(raw.toLowerCase().removeDiacritics(), raw.removeDiacritics().toLowerCase()); }); }); } diff --git a/mobile/test/providers/app_life_cycle_provider_test.dart b/mobile/test/providers/app_life_cycle_provider_test.dart index bf05e5671..87766e94b 100644 --- a/mobile/test/providers/app_life_cycle_provider_test.dart +++ b/mobile/test/providers/app_life_cycle_provider_test.dart @@ -180,7 +180,7 @@ void main() { await lifeCycle.handleAppPause(); await releaseResume(); - expect(lifeCycle.getAppState(), AppLifeCycleEnum.paused); + expect(lifeCycle.state, AppLifeCycleEnum.paused); expect(serverVersionCount, 1); expect(websocket.disconnectCount, 2); expect(websocket.connectCount, 0); @@ -194,7 +194,7 @@ void main() { unawaited(lifeCycle.handleAppResume()); await websocket.connectCalled.future; - expect(lifeCycle.getAppState(), AppLifeCycleEnum.resumed); + expect(lifeCycle.state, AppLifeCycleEnum.resumed); expect(serverVersionCount, 2); expect(websocket.disconnectCount, 1); expect(websocket.connectCount, 1); @@ -211,7 +211,7 @@ void main() { unawaited(lifeCycle.handleAppResume()); await Future.delayed(Duration.zero); - expect(lifeCycle.getAppState(), AppLifeCycleEnum.resumed); + expect(lifeCycle.state, AppLifeCycleEnum.resumed); expect(serverVersionCount, 2); expect(websocket.disconnectCount, 2); expect(websocket.connectCount, 1); diff --git a/mobile/test/services/view_intent_service_test.dart b/mobile/test/services/view_intent_service_test.dart index fd8f5f725..578246c88 100644 --- a/mobile/test/services/view_intent_service_test.dart +++ b/mobile/test/services/view_intent_service_test.dart @@ -72,18 +72,6 @@ void main() { expect(await secondFile.exists(), isFalse); }); - test('cleanupTempFile defers deletion while an upload is active', () async { - final tempFile = File('${cacheDir.path}/view_intent_in_flight.jpg')..writeAsStringSync('bytes'); - - service.markUploadActive(tempFile.path); - await service.cleanupTempFile(tempFile.path); - - expect(await tempFile.exists(), isTrue, reason: 'active uploads block cleanup'); - - await service.markUploadInactive(tempFile.path); - expect(await tempFile.exists(), isFalse); - }); - test('cleanupTempFile ignores non-managed paths', () async { final nonManagedFile = File('${tempRoot.path}/plain_file.jpg')..writeAsStringSync('content'); @@ -103,15 +91,4 @@ void main() { expect(await secondFile.exists(), isFalse); expect(await unrelatedFile.exists(), isTrue); }); - - test('cleanupStaleTempFiles skips paths with active uploads', () async { - final stale = File('${cacheDir.path}/view_intent_stale.jpg')..writeAsStringSync('stale'); - final active = File('${cacheDir.path}/view_intent_active.jpg')..writeAsStringSync('active'); - service.markUploadActive(active.path); - - await service.cleanupStaleTempFiles(); - - expect(await stale.exists(), isFalse); - expect(await active.exists(), isTrue); - }); } diff --git a/mobile/test/unit/mocks.dart b/mobile/test/unit/mocks.dart index 55d7d3f5e..c27e29296 100644 --- a/mobile/test/unit/mocks.dart +++ b/mobile/test/unit/mocks.dart @@ -85,7 +85,6 @@ class RepositoryMocks { } void _stubLocalAssetRepository() { - when(localAsset.reconcileHashesFromCloudId).thenAnswer((_) async => {}); when(localAsset.updateHashes).thenAnswer((_) async => {}); when(localAsset.deleteAssets).thenAnswer((_) async => {}); } @@ -256,11 +255,7 @@ extension type const LocalAlbumRepositoryStub(MockLocalAlbumRepository repo) imp () => repo.getAssetsToHash(any()); } -extension type const LocalAssetRepositoryStub(MockLocalAssetRepository repo) - implements Stub { - Future Function() get reconcileHashesFromCloudId => - () => repo.reconcileHashesFromCloudId(); - +extension type const LocalAssetRepositoryStub(MockLocalAssetRepository repo) implements Stub { Future Function() get updateHashes => () => repo.updateHashes(any()); diff --git a/mobile/test/unit/utils/asset_filter_test.dart b/mobile/test/unit/utils/asset_filter_test.dart index 1db287b34..5462ac410 100644 --- a/mobile/test/unit/utils/asset_filter_test.dart +++ b/mobile/test/unit/utils/asset_filter_test.dart @@ -81,15 +81,6 @@ void main() { expect(favorites.toList(), [asset1]); }); - test('type keeps only assets of the given type', () { - final image = RemoteAssetFactory.create(); - final video = RemoteAssetFactory.create(ownerId: image.ownerId).copyWith(type: .video); - - final videos = AssetFilter([image, video]).type(.video); - - expect(videos.toList(), [video]); - }); - test('visibility keeps only assets with the given visibility', () { final locked = RemoteAssetFactory.create(visibility: AssetVisibility.locked); final onTimeline = RemoteAssetFactory.create(ownerId: locked.ownerId); @@ -99,15 +90,6 @@ void main() { expect(lockedPhotos.toList(), [locked]); }); - test('archived keeps only archived assets', () { - final archived = RemoteAssetFactory.create(visibility: AssetVisibility.archive); - final onTimeline = RemoteAssetFactory.create(ownerId: archived.ownerId); - - final archivedPhotos = AssetFilter([archived, onTimeline]).archived(); - - expect(archivedPhotos.toList(), [archived]); - }); - test('stacked keeps only assets belonging to a stack', () { final stacked = RemoteAssetFactory.create(stackId: 'stack'); final loose = RemoteAssetFactory.create(ownerId: stacked.ownerId); @@ -119,17 +101,6 @@ void main() { }); group('inversion', () { - test('notArchived keeps every non-archived visibility', () { - final archived = RemoteAssetFactory.create(visibility: AssetVisibility.archive); - final onTimeline = RemoteAssetFactory.create(ownerId: archived.ownerId, visibility: AssetVisibility.timeline); - final hidden = RemoteAssetFactory.create(ownerId: archived.ownerId, visibility: AssetVisibility.hidden); - final locked = RemoteAssetFactory.create(ownerId: archived.ownerId, visibility: AssetVisibility.locked); - - final visiblePhotos = AssetFilter([archived, onTimeline, hidden, locked]).archived(isArchived: false); - - expect(visiblePhotos.toSet(), {onTimeline, hidden, locked}); - }); - test('notVisibility keeps every asset not at the target visibility', () { final archived = RemoteAssetFactory.create(visibility: AssetVisibility.archive); final onTimeline = RemoteAssetFactory.create(ownerId: archived.ownerId, visibility: AssetVisibility.timeline); @@ -149,15 +120,6 @@ void main() { expect(loosePhotos.toList(), [loose]); }); - test('whereNot inverts an arbitrary predicate', () { - final favorite = RemoteAssetFactory.create(isFavorite: true); - final regular = RemoteAssetFactory.create(ownerId: favorite.ownerId); - - final nonFavorites = AssetFilter([favorite, regular]).whereNot((asset) => asset.isFavorite); - - expect(nonFavorites.toList(), [regular]); - }); - test('notFavorites keeps only non-favorite assets', () { final favorite = RemoteAssetFactory.create(isFavorite: true); final regular = RemoteAssetFactory.create(ownerId: favorite.ownerId); @@ -182,7 +144,7 @@ void main() { archived, stacked, localPhoto, - ]).owned(asset.ownerId).archived(isArchived: false).stacked(isStacked: false); + ]).owned(asset.ownerId).notVisibility(AssetVisibility.archive).stacked(isStacked: false); expect(result.toList(), [asset]); }); diff --git a/mobile/test/utils_legacy/action_button_utils_test.dart b/mobile/test/utils_legacy/action_button_utils_test.dart index 65e1cad7f..b2316e013 100644 --- a/mobile/test/utils_legacy/action_button_utils_test.dart +++ b/mobile/test/utils_legacy/action_button_utils_test.dart @@ -1034,100 +1034,4 @@ void main() { } }); }); - - group('ActionButtonBuilder', () { - test('should return buttons that should show', () { - final remoteAsset = createRemoteAsset(); - final context = ActionButtonContext( - asset: remoteAsset, - isOwner: true, - isArchived: false, - isTrashEnabled: true, - isInLockedView: false, - currentAlbum: null, - advancedTroubleshooting: false, - isStacked: false, - source: ActionSource.timeline, - ); - - final widgets = ActionButtonBuilder.build(context); - - expect(widgets, isNotEmpty); - expect(widgets.length, greaterThan(0)); - }); - - test('should include album-specific buttons when album is present', () { - final remoteAsset = createRemoteAsset(); - final album = createRemoteAlbum(isActivityEnabled: true, isShared: true); - final context = ActionButtonContext( - asset: remoteAsset, - isOwner: true, - isArchived: false, - isTrashEnabled: true, - isInLockedView: false, - currentAlbum: album, - advancedTroubleshooting: false, - isStacked: false, - source: ActionSource.timeline, - ); - - final widgets = ActionButtonBuilder.build(context); - - expect(widgets, isNotEmpty); - }); - - test('should only include local buttons for local assets', () { - final localAsset = createLocalAsset(); - final context = ActionButtonContext( - asset: localAsset, - isOwner: true, - isArchived: false, - isTrashEnabled: true, - isInLockedView: false, - currentAlbum: null, - advancedTroubleshooting: false, - isStacked: false, - source: ActionSource.timeline, - ); - - final widgets = ActionButtonBuilder.build(context); - - expect(widgets, isNotEmpty); - }); - - test('should respect archived state', () { - final remoteAsset = createRemoteAsset(); - - final archivedContext = ActionButtonContext( - asset: remoteAsset, - isOwner: true, - isArchived: true, - isTrashEnabled: true, - isInLockedView: false, - currentAlbum: null, - advancedTroubleshooting: false, - isStacked: false, - source: ActionSource.timeline, - ); - - final archivedWidgets = ActionButtonBuilder.build(archivedContext); - - final nonArchivedContext = ActionButtonContext( - asset: remoteAsset, - isOwner: true, - isArchived: false, - isTrashEnabled: true, - isInLockedView: false, - currentAlbum: null, - advancedTroubleshooting: false, - isStacked: false, - source: ActionSource.timeline, - ); - - final nonArchivedWidgets = ActionButtonBuilder.build(nonArchivedContext); - - expect(archivedWidgets, isNotEmpty); - expect(nonArchivedWidgets, isNotEmpty); - }); - }); }