fix(mobile): refresh the memory lane after resume (#31260)

fix(mobile): refresh the memory lane after resume (#31239)

(cherry picked from commit b1a93688d3)

Co-authored-by: Santo Shakil <santoshakil@users.noreply.github.com>
This commit is contained in:
immich-push-o-matic[bot]
2026-09-04 15:31:24 -04:00
committed by GitHub
co-authored by Santo Shakil
parent bf75aaa81e
commit 7c91747a9d
2 changed files with 54 additions and 1 deletions
@@ -130,6 +130,7 @@ class AppLifeCycleNotifier extends StateNotifier<AppLifeCycleEnum> {
syncSuccess = await backgroundManager.syncRemote();
}, "syncRemote"),
]);
_ref.invalidate(memoryLaneProvider);
_ref.invalidate(allMemoriesProvider);
if (syncSuccess) {
await Future.wait([
@@ -2,21 +2,30 @@ import 'dart:async';
import 'package:flutter_test/flutter_test.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/constants/enums.dart';
import 'package:immich_mobile/domain/models/config/app_config.dart';
import 'package:immich_mobile/domain/models/log.model.dart';
import 'package:immich_mobile/domain/services/device_permission.service.dart';
import 'package:immich_mobile/domain/services/log.service.dart';
import 'package:immich_mobile/models/auth/auth_state.model.dart';
import 'package:immich_mobile/models/server_info/server_version.model.dart';
import 'package:immich_mobile/providers/app_life_cycle.provider.dart';
import 'package:immich_mobile/providers/auth.provider.dart';
import 'package:immich_mobile/providers/background_sync.provider.dart';
import 'package:immich_mobile/providers/backup/backup.provider.dart';
import 'package:immich_mobile/providers/gallery_permission.provider.dart';
import 'package:immich_mobile/providers/infrastructure/memory.provider.dart';
import 'package:immich_mobile/providers/infrastructure/platform.provider.dart';
import 'package:immich_mobile/providers/infrastructure/settings.provider.dart';
import 'package:immich_mobile/providers/permission.provider.dart';
import 'package:immich_mobile/providers/server_info.provider.dart';
import 'package:immich_mobile/providers/websocket.provider.dart';
import 'package:immich_mobile/utils/upload_speed_calculator.dart';
import 'package:mocktail/mocktail.dart';
import 'package:permission_handler/permission_handler.dart';
import '../infrastructure/repository.mock.dart';
import '../repository.mocks.dart';
import '../service.mocks.dart';
class FakeLogMessage extends Fake implements LogMessage {}
@@ -51,6 +60,7 @@ class TestWebsocketNotifier extends WebsocketNotifier {
int connectCount = 0;
int disconnectCount = 0;
bool throwOnConnect = true;
final connectCalled = Completer<void>();
@override
@@ -59,7 +69,9 @@ class TestWebsocketNotifier extends WebsocketNotifier {
if (!connectCalled.isCompleted) {
connectCalled.complete();
}
throw StateError('unexpected websocket connection');
if (throwOnConnect) {
throw StateError('unexpected websocket connection');
}
}
@override
@@ -70,6 +82,18 @@ class TestDriftBackupNotifier extends BackupNotifier {
TestDriftBackupNotifier() : super(MockForegroundUploadService(), MockBackgroundUploadService(), UploadSpeedManager());
}
class TestNotificationPermissionNotifier extends NotificationPermissionNotifier {
@override
Future<PermissionStatus> getNotificationPermission() async => state;
}
class TestGalleryPermissionNotifier extends GalleryPermissionNotifier {
TestGalleryPermissionNotifier() : super(DevicePermissionService(MockPermissionRepository()));
@override
Future<DevicePermissionStatus> getGalleryPermissionStatus() async => state;
}
void main() {
late LogService logService;
late Completer<ServerVersion?> serverVersion;
@@ -79,6 +103,7 @@ void main() {
late TestWebsocketNotifier websocket;
late AppLifeCycleNotifier lifeCycle;
late int serverVersionCount;
late int memoryLaneBuilds;
setUpAll(() async {
final logRepository = MockLogRepository();
@@ -100,7 +125,9 @@ void main() {
serverVersion = Completer<ServerVersion?>();
serverInfoService = MockServerInfoService();
lockService = MockBackgroundWorkerLockService();
final backgroundSync = MockBackgroundSyncManager();
serverVersionCount = 0;
memoryLaneBuilds = 0;
when(() => serverInfoService.getServerVersion()).thenAnswer((_) {
serverVersionCount++;
@@ -108,6 +135,10 @@ void main() {
});
when(() => lockService.lock()).thenAnswer((_) async {});
when(() => lockService.unlock()).thenAnswer((_) async {});
when(() => backgroundSync.cancelResumeSyncs()).thenAnswer((_) async {});
when(() => backgroundSync.syncLocal(full: any(named: 'full'))).thenAnswer((_) async {});
when(() => backgroundSync.syncRemote()).thenAnswer((_) async => true);
when(() => backgroundSync.hashAssets()).thenAnswer((_) async {});
container = ProviderContainer(
overrides: [
@@ -118,6 +149,14 @@ void main() {
}),
backupProvider.overrideWith((_) => TestDriftBackupNotifier()),
backgroundWorkerLockServiceProvider.overrideWithValue(lockService),
backgroundSyncProvider.overrideWithValue(backgroundSync),
appConfigProvider.overrideWithValue(defaultConfig),
notificationPermissionProvider.overrideWith((_) => TestNotificationPermissionNotifier()),
galleryPermissionNotifier.overrideWith((_) => TestGalleryPermissionNotifier()),
memoryLaneProvider.overrideWith((_) {
memoryLaneBuilds++;
return const [];
}),
],
);
lifeCycle = container.read(appStateProvider.notifier);
@@ -177,4 +216,17 @@ void main() {
expect(websocket.disconnectCount, 2);
expect(websocket.connectCount, 1);
});
test('resume re-queries the memory lane', () async {
container.listen(memoryLaneProvider, (_, _) {});
expect(memoryLaneBuilds, 1);
await lifeCycle.handleAppPause();
websocket.throwOnConnect = false;
serverVersion.complete();
await lifeCycle.handleAppResume();
await Future<void>.delayed(Duration.zero);
expect(memoryLaneBuilds, 2);
});
}