chore: cleanup unused store keys (#28415)

cleanup unused store keys

Co-authored-by: shenlong-tanwen <139912620+shalong-tanwen@users.noreply.github.com>
This commit is contained in:
shenlong
2026-05-14 04:33:57 +05:30
committed by GitHub
parent b031548791
commit aeaf846482
7 changed files with 21 additions and 97 deletions
-11
View File
@@ -4,25 +4,15 @@ import 'package:immich_mobile/domain/models/user.model.dart';
/// Defines the data type for each value /// Defines the data type for each value
enum StoreKey<T> { enum StoreKey<T> {
version<int>._(0), version<int>._(0),
assetETag<String>._(1),
currentUser<UserDto>._(2), currentUser<UserDto>._(2),
deviceIdHash<int>._(3),
deviceId<String>._(4), deviceId<String>._(4),
backupFailedSince<DateTime>._(5),
backupRequireWifi<bool>._(6),
backupRequireCharging<bool>._(7), backupRequireCharging<bool>._(7),
backupTriggerDelay<int>._(8), backupTriggerDelay<int>._(8),
serverUrl<String>._(10), serverUrl<String>._(10),
accessToken<String>._(11), accessToken<String>._(11),
serverEndpoint<String>._(12), serverEndpoint<String>._(12),
autoBackup<bool>._(13),
backgroundBackup<bool>._(14),
sslClientCertData<String>._(15),
sslClientPasswd<String>._(16),
uploadErrorNotificationGracePeriod<int>._(106),
selectedAlbumSortOrder<int>._(113), selectedAlbumSortOrder<int>._(113),
advancedTroubleshooting<bool>._(114), advancedTroubleshooting<bool>._(114),
selfSignedCert<bool>._(120),
selectedAlbumSortReverse<bool>._(123), selectedAlbumSortReverse<bool>._(123),
enableHapticFeedback<bool>._(126), enableHapticFeedback<bool>._(126),
customHeaders<String>._(127), customHeaders<String>._(127),
@@ -38,7 +28,6 @@ enum StoreKey<T> {
// Read-only Mode settings // Read-only Mode settings
readonlyModeEnabled<bool>._(138), readonlyModeEnabled<bool>._(138),
albumGridView<bool>._(140), albumGridView<bool>._(140),
loadOriginal<bool>._(101),
// Experimental stuff // Experimental stuff
enableBackup<bool>._(1003), enableBackup<bool>._(1003),
+1 -3
View File
@@ -11,12 +11,11 @@ import 'package:immich_mobile/providers/api.provider.dart';
import 'package:immich_mobile/providers/infrastructure/user.provider.dart'; import 'package:immich_mobile/providers/infrastructure/user.provider.dart';
import 'package:immich_mobile/services/api.service.dart'; import 'package:immich_mobile/services/api.service.dart';
import 'package:immich_mobile/services/auth.service.dart'; import 'package:immich_mobile/services/auth.service.dart';
import 'package:immich_mobile/services/background_upload.service.dart';
import 'package:immich_mobile/services/foreground_upload.service.dart'; import 'package:immich_mobile/services/foreground_upload.service.dart';
import 'package:immich_mobile/services/secure_storage.service.dart'; import 'package:immich_mobile/services/secure_storage.service.dart';
import 'package:immich_mobile/services/background_upload.service.dart';
import 'package:immich_mobile/services/widget.service.dart'; import 'package:immich_mobile/services/widget.service.dart';
import 'package:immich_mobile/utils/debug_print.dart'; import 'package:immich_mobile/utils/debug_print.dart';
import 'package:immich_mobile/utils/hash.dart';
import 'package:logging/logging.dart'; import 'package:logging/logging.dart';
import 'package:openapi/api.dart'; import 'package:openapi/api.dart';
@@ -144,7 +143,6 @@ class AuthNotifier extends StateNotifier<AuthState> {
// Due to the flow of the code, this will always happen on first login // Due to the flow of the code, this will always happen on first login
user = serverUser; user = serverUser;
await Store.put(StoreKey.deviceId, deviceId); await Store.put(StoreKey.deviceId, deviceId);
await Store.put(StoreKey.deviceIdHash, fastHash(deviceId));
} }
} on ApiException catch (error, stackTrace) { } on ApiException catch (error, stackTrace) {
if (error.code == 401) { if (error.code == 401) {
@@ -2,15 +2,9 @@ import 'package:immich_mobile/domain/models/store.model.dart';
import 'package:immich_mobile/entities/store.entity.dart'; import 'package:immich_mobile/entities/store.entity.dart';
enum AppSettingsEnum<T> { enum AppSettingsEnum<T> {
uploadErrorNotificationGracePeriod<int>(
StoreKey.uploadErrorNotificationGracePeriod,
"uploadErrorNotificationGracePeriod",
2,
),
selectedAlbumSortOrder<int>(StoreKey.selectedAlbumSortOrder, "selectedAlbumSortOrder", 2), selectedAlbumSortOrder<int>(StoreKey.selectedAlbumSortOrder, "selectedAlbumSortOrder", 2),
advancedTroubleshooting<bool>(StoreKey.advancedTroubleshooting, null, false), advancedTroubleshooting<bool>(StoreKey.advancedTroubleshooting, null, false),
manageLocalMediaAndroid<bool>(StoreKey.manageLocalMediaAndroid, null, false), manageLocalMediaAndroid<bool>(StoreKey.manageLocalMediaAndroid, null, false),
allowSelfSignedSSLCert<bool>(StoreKey.selfSignedCert, null, false),
selectedAlbumSortReverse<bool>(StoreKey.selectedAlbumSortReverse, null, true), selectedAlbumSortReverse<bool>(StoreKey.selectedAlbumSortReverse, null, true),
enableHapticFeedback<bool>(StoreKey.enableHapticFeedback, null, true), enableHapticFeedback<bool>(StoreKey.enableHapticFeedback, null, true),
syncAlbums<bool>(StoreKey.syncAlbums, null, false), syncAlbums<bool>(StoreKey.syncAlbums, null, false),
-1
View File
@@ -123,7 +123,6 @@ class AuthService {
_authRepository.clearLocalData(), _authRepository.clearLocalData(),
Store.delete(StoreKey.currentUser), Store.delete(StoreKey.currentUser),
Store.delete(StoreKey.accessToken), Store.delete(StoreKey.accessToken),
Store.delete(StoreKey.assetETag),
Store.delete(StoreKey.autoEndpointSwitching), Store.delete(StoreKey.autoEndpointSwitching),
Store.delete(StoreKey.preferredWifiName), Store.delete(StoreKey.preferredWifiName),
Store.delete(StoreKey.localEndpoint), Store.delete(StoreKey.localEndpoint),
@@ -3,10 +3,7 @@ import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart'; import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/extensions/build_context_extensions.dart'; import 'package:immich_mobile/extensions/build_context_extensions.dart';
import 'package:immich_mobile/providers/notification_permission.provider.dart'; import 'package:immich_mobile/providers/notification_permission.provider.dart';
import 'package:immich_mobile/services/app_settings.service.dart';
import 'package:immich_mobile/utils/hooks/app_settings_update_hook.dart';
import 'package:immich_mobile/widgets/settings/settings_button_list_tile.dart'; import 'package:immich_mobile/widgets/settings/settings_button_list_tile.dart';
import 'package:immich_mobile/widgets/settings/settings_slider_list_tile.dart';
import 'package:immich_mobile/widgets/settings/settings_sub_page_scaffold.dart'; import 'package:immich_mobile/widgets/settings/settings_sub_page_scaffold.dart';
import 'package:permission_handler/permission_handler.dart'; import 'package:permission_handler/permission_handler.dart';
@@ -16,9 +13,6 @@ class NotificationSetting extends HookConsumerWidget {
@override @override
Widget build(BuildContext context, WidgetRef ref) { Widget build(BuildContext context, WidgetRef ref) {
final permissionService = ref.watch(notificationPermissionProvider); final permissionService = ref.watch(notificationPermissionProvider);
final sliderValue = useAppSettingsState(AppSettingsEnum.uploadErrorNotificationGracePeriod);
final hasPermission = permissionService == PermissionStatus.granted; final hasPermission = permissionService == PermissionStatus.granted;
openAppNotificationSettings(BuildContext ctx) { openAppNotificationSettings(BuildContext ctx) {
@@ -41,8 +35,6 @@ class NotificationSetting extends HookConsumerWidget {
); );
} }
final String formattedValue = _formatSliderValue(sliderValue.value.toDouble());
final notificationSettings = [ final notificationSettings = [
if (!hasPermission) if (!hasPermission)
SettingsButtonListTile( SettingsButtonListTile(
@@ -57,32 +49,8 @@ class NotificationSetting extends HookConsumerWidget {
} }
}), }),
), ),
SettingsSliderListTile(
enabled: hasPermission,
valueNotifier: sliderValue,
text: 'setting_notifications_notify_failures_grace_period'.tr(namedArgs: {'duration': formattedValue}),
maxValue: 5.0,
noDivisons: 5,
label: formattedValue,
),
]; ];
return SettingsSubPageScaffold(settings: notificationSettings); return SettingsSubPageScaffold(settings: notificationSettings);
} }
} }
String _formatSliderValue(double v) {
if (v == 0.0) {
return 'setting_notifications_notify_immediately'.tr();
} else if (v == 1.0) {
return 'setting_notifications_notify_minutes'.tr(namedArgs: {'count': '30'});
} else if (v == 2.0) {
return 'setting_notifications_notify_hours'.tr(namedArgs: {'count': '2'});
} else if (v == 3.0) {
return 'setting_notifications_notify_hours'.tr(namedArgs: {'count': '8'});
} else if (v == 4.0) {
return 'setting_notifications_notify_hours'.tr(namedArgs: {'count': '24'});
} else {
return 'setting_notifications_notify_never'.tr();
}
}
@@ -9,9 +9,8 @@ import 'package:mocktail/mocktail.dart';
import '../../infrastructure/repository.mock.dart'; import '../../infrastructure/repository.mock.dart';
const _kAccessToken = '#ThisIsAToken'; const _kAccessToken = '#ThisIsAToken';
const _kBackgroundBackup = false; const _kEnableBackup = false;
const _kVersion = 2; const _kVersion = 2;
final _kBackupFailedSince = DateTime.utc(2023);
void main() { void main() {
late StoreService sut; late StoreService sut;
@@ -24,15 +23,13 @@ void main() {
// For generics, we need to provide fallback to each concrete type to avoid runtime errors // For generics, we need to provide fallback to each concrete type to avoid runtime errors
registerFallbackValue(StoreKey.accessToken); registerFallbackValue(StoreKey.accessToken);
registerFallbackValue(StoreKey.backupTriggerDelay); registerFallbackValue(StoreKey.backupTriggerDelay);
registerFallbackValue(StoreKey.backgroundBackup); registerFallbackValue(StoreKey.enableBackup);
registerFallbackValue(StoreKey.backupFailedSince);
when(() => mockDriftStoreRepo.getAll()).thenAnswer( when(() => mockDriftStoreRepo.getAll()).thenAnswer(
(_) async => [ (_) async => [
const StoreDto(StoreKey.accessToken, _kAccessToken), const StoreDto(StoreKey.accessToken, _kAccessToken),
const StoreDto(StoreKey.backgroundBackup, _kBackgroundBackup), const StoreDto(StoreKey.enableBackup, _kEnableBackup),
const StoreDto(StoreKey.version, _kVersion), const StoreDto(StoreKey.version, _kVersion),
StoreDto(StoreKey.backupFailedSince, _kBackupFailedSince),
], ],
); );
when(() => mockDriftStoreRepo.watchAll()).thenAnswer((_) => controller.stream); when(() => mockDriftStoreRepo.watchAll()).thenAnswer((_) => controller.stream);
@@ -49,9 +46,8 @@ void main() {
test('Populates the internal cache on init', () { test('Populates the internal cache on init', () {
verify(() => mockDriftStoreRepo.getAll()).called(1); verify(() => mockDriftStoreRepo.getAll()).called(1);
expect(sut.tryGet(StoreKey.accessToken), _kAccessToken); expect(sut.tryGet(StoreKey.accessToken), _kAccessToken);
expect(sut.tryGet(StoreKey.backgroundBackup), _kBackgroundBackup); expect(sut.tryGet(StoreKey.enableBackup), _kEnableBackup);
expect(sut.tryGet(StoreKey.version), _kVersion); expect(sut.tryGet(StoreKey.version), _kVersion);
expect(sut.tryGet(StoreKey.backupFailedSince), _kBackupFailedSince);
// Other keys should be null // Other keys should be null
expect(sut.tryGet(StoreKey.currentUser), isNull); expect(sut.tryGet(StoreKey.currentUser), isNull);
}); });
@@ -151,9 +147,8 @@ void main() {
await sut.clear(); await sut.clear();
verify(() => mockDriftStoreRepo.deleteAll()).called(1); verify(() => mockDriftStoreRepo.deleteAll()).called(1);
expect(sut.tryGet(StoreKey.accessToken), isNull); expect(sut.tryGet(StoreKey.accessToken), isNull);
expect(sut.tryGet(StoreKey.backgroundBackup), isNull); expect(sut.tryGet(StoreKey.enableBackup), isNull);
expect(sut.tryGet(StoreKey.version), isNull); expect(sut.tryGet(StoreKey.version), isNull);
expect(sut.tryGet(StoreKey.backupFailedSince), isNull);
}); });
}); });
} }
@@ -12,9 +12,8 @@ import 'package:immich_mobile/infrastructure/repositories/store.repository.dart'
import '../../fixtures/user.stub.dart'; import '../../fixtures/user.stub.dart';
const _kTestAccessToken = "#TestToken"; const _kTestAccessToken = "#TestToken";
final _kTestBackupFailed = DateTime(2025, 2, 20, 11, 45);
const _kTestVersion = 10; const _kTestVersion = 10;
const _kTestBackupRequireWifi = false; const _kTestBackupRequireCharging = false;
final _kTestUser = UserStub.admin; final _kTestUser = UserStub.admin;
Future<void> _populateStore(Drift db) async { Future<void> _populateStore(Drift db) async {
@@ -22,16 +21,8 @@ Future<void> _populateStore(Drift db) async {
batch.insert( batch.insert(
db.storeEntity, db.storeEntity,
StoreEntityCompanion( StoreEntityCompanion(
id: Value(StoreKey.backupRequireWifi.id), id: Value(StoreKey.backupRequireCharging.id),
intValue: const Value(_kTestBackupRequireWifi ? 1 : 0), intValue: const Value(_kTestBackupRequireCharging ? 1 : 0),
stringValue: const Value(null),
),
);
batch.insert(
db.storeEntity,
StoreEntityCompanion(
id: Value(StoreKey.backupFailedSince.id),
intValue: Value(_kTestBackupFailed.millisecondsSinceEpoch),
stringValue: const Value(null), stringValue: const Value(null),
), ),
); );
@@ -84,20 +75,12 @@ void main() {
expect(accessToken, _kTestAccessToken); expect(accessToken, _kTestAccessToken);
}); });
test('converts datetime', () async {
DateTime? backupFailedSince = await sut.tryGet(StoreKey.backupFailedSince);
expect(backupFailedSince, isNull);
await sut.upsert(StoreKey.backupFailedSince, _kTestBackupFailed);
backupFailedSince = await sut.tryGet(StoreKey.backupFailedSince);
expect(backupFailedSince, _kTestBackupFailed);
});
test('converts bool', () async { test('converts bool', () async {
bool? backupRequireWifi = await sut.tryGet(StoreKey.backupRequireWifi); bool? backupRequireCharging = await sut.tryGet(StoreKey.backupRequireCharging);
expect(backupRequireWifi, isNull); expect(backupRequireCharging, isNull);
await sut.upsert(StoreKey.backupRequireWifi, _kTestBackupRequireWifi); await sut.upsert(StoreKey.backupRequireCharging, _kTestBackupRequireCharging);
backupRequireWifi = await sut.tryGet(StoreKey.backupRequireWifi); backupRequireCharging = await sut.tryGet(StoreKey.backupRequireCharging);
expect(backupRequireWifi, _kTestBackupRequireWifi); expect(backupRequireCharging, _kTestBackupRequireCharging);
}); });
test('converts user', () async { test('converts user', () async {
@@ -115,11 +98,11 @@ void main() {
}); });
test('delete()', () async { test('delete()', () async {
bool? backupRequireWifi = await sut.tryGet(StoreKey.backupRequireWifi); bool? backupRequireCharging = await sut.tryGet(StoreKey.backupRequireCharging);
expect(backupRequireWifi, isFalse); expect(backupRequireCharging, isFalse);
await sut.delete(StoreKey.backupRequireWifi); await sut.delete(StoreKey.backupRequireCharging);
backupRequireWifi = await sut.tryGet(StoreKey.backupRequireWifi); backupRequireCharging = await sut.tryGet(StoreKey.backupRequireCharging);
expect(backupRequireWifi, isNull); expect(backupRequireCharging, isNull);
}); });
test('deleteAll()', () async { test('deleteAll()', () async {
@@ -164,14 +147,12 @@ void main() {
emitsInOrder([ emitsInOrder([
[ [
const StoreDto<Object>(StoreKey.version, _kTestVersion), const StoreDto<Object>(StoreKey.version, _kTestVersion),
StoreDto<Object>(StoreKey.backupFailedSince, _kTestBackupFailed), const StoreDto<Object>(StoreKey.backupRequireCharging, _kTestBackupRequireCharging),
const StoreDto<Object>(StoreKey.backupRequireWifi, _kTestBackupRequireWifi),
const StoreDto<Object>(StoreKey.accessToken, _kTestAccessToken), const StoreDto<Object>(StoreKey.accessToken, _kTestAccessToken),
], ],
[ [
const StoreDto<Object>(StoreKey.version, _kTestVersion + 10), const StoreDto<Object>(StoreKey.version, _kTestVersion + 10),
StoreDto<Object>(StoreKey.backupFailedSince, _kTestBackupFailed), const StoreDto<Object>(StoreKey.backupRequireCharging, _kTestBackupRequireCharging),
const StoreDto<Object>(StoreKey.backupRequireWifi, _kTestBackupRequireWifi),
const StoreDto<Object>(StoreKey.accessToken, _kTestAccessToken), const StoreDto<Object>(StoreKey.accessToken, _kTestAccessToken),
], ],
]), ]),