mirror of
https://github.com/immich-app/immich.git
synced 2026-05-18 03:10:24 +03:00
review changes
This commit is contained in:
@@ -2,8 +2,8 @@ import 'package:flutter/material.dart';
|
|||||||
import 'package:immich_mobile/domain/models/log.model.dart';
|
import 'package:immich_mobile/domain/models/log.model.dart';
|
||||||
|
|
||||||
enum MetadataDomain {
|
enum MetadataDomain {
|
||||||
appConfig('app-config'),
|
appConfig('config.app'),
|
||||||
systemConfig('system-config');
|
systemConfig('config.system');
|
||||||
|
|
||||||
final String prefix;
|
final String prefix;
|
||||||
const MetadataDomain(this.prefix);
|
const MetadataDomain(this.prefix);
|
||||||
@@ -22,10 +22,5 @@ enum MetadataKey<T extends Object> {
|
|||||||
|
|
||||||
String get key => '${domain.prefix}.$name';
|
String get key => '${domain.prefix}.$name';
|
||||||
|
|
||||||
static MetadataKey<Object>? fromKey(String key) {
|
static Map<String, MetadataKey<Object>> asKeyMap() => {for (var value in MetadataKey.values) value.key: value};
|
||||||
for (final m in MetadataKey.values) {
|
|
||||||
if (m.key == key) return m;
|
|
||||||
}
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ enum StoreKey<T> {
|
|||||||
// user settings from [AppSettingsEnum] below:
|
// user settings from [AppSettingsEnum] below:
|
||||||
loadPreview<bool>._(100),
|
loadPreview<bool>._(100),
|
||||||
loadOriginal<bool>._(101),
|
loadOriginal<bool>._(101),
|
||||||
// id 102 (themeMode) moved to user_config.theme-mode
|
|
||||||
tilesPerRow<int>._(103),
|
tilesPerRow<int>._(103),
|
||||||
dynamicLayout<bool>._(104),
|
dynamicLayout<bool>._(104),
|
||||||
groupAssetsBy<int>._(105),
|
groupAssetsBy<int>._(105),
|
||||||
@@ -35,7 +34,6 @@ enum StoreKey<T> {
|
|||||||
albumThumbnailCacheSize<int>._(112),
|
albumThumbnailCacheSize<int>._(112),
|
||||||
selectedAlbumSortOrder<int>._(113),
|
selectedAlbumSortOrder<int>._(113),
|
||||||
advancedTroubleshooting<bool>._(114),
|
advancedTroubleshooting<bool>._(114),
|
||||||
// id 115 (logLevel) moved to app_metadata.log-level
|
|
||||||
preferRemoteImage<bool>._(116),
|
preferRemoteImage<bool>._(116),
|
||||||
loopVideo<bool>._(117),
|
loopVideo<bool>._(117),
|
||||||
// map related settings
|
// map related settings
|
||||||
@@ -94,7 +92,11 @@ enum StoreKey<T> {
|
|||||||
cleanupCutoffDaysAgo<int>._(1011),
|
cleanupCutoffDaysAgo<int>._(1011),
|
||||||
cleanupDefaultsInitialized<bool>._(1012),
|
cleanupDefaultsInitialized<bool>._(1012),
|
||||||
|
|
||||||
syncMigrationStatus<String>._(1013);
|
syncMigrationStatus<String>._(1013),
|
||||||
|
|
||||||
|
// Legacy keys that have been migrated to the new metadata store
|
||||||
|
legacyThemeMode<String>._(102),
|
||||||
|
legacyLogLevel<int>._(115);
|
||||||
|
|
||||||
const StoreKey._(this.id);
|
const StoreKey._(this.id);
|
||||||
final int id;
|
final int id;
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ import 'package:drift/drift.dart';
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:immich_mobile/domain/models/config/app_config.dart';
|
import 'package:immich_mobile/domain/models/config/app_config.dart';
|
||||||
import 'package:immich_mobile/domain/models/config/system_config.dart';
|
import 'package:immich_mobile/domain/models/config/system_config.dart';
|
||||||
import 'package:immich_mobile/domain/models/config/theme_config.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/metadata_key.dart';
|
import 'package:immich_mobile/domain/models/metadata_key.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/metadata.entity.drift.dart';
|
import 'package:immich_mobile/infrastructure/entities/metadata.entity.drift.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||||
@@ -24,6 +23,12 @@ class MetadataRepository extends DriftDatabaseRepository {
|
|||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
AppConfig _appConfig = const .new();
|
||||||
|
AppConfig get appConfig => _appConfig;
|
||||||
|
|
||||||
|
SystemConfig _systemConfig = const .new();
|
||||||
|
SystemConfig get systemConfig => _systemConfig;
|
||||||
|
|
||||||
static Future<MetadataRepository> ensureInitialized(Drift db) async {
|
static Future<MetadataRepository> ensureInitialized(Drift db) async {
|
||||||
if (_instance == null) {
|
if (_instance == null) {
|
||||||
final instance = MetadataRepository._(db);
|
final instance = MetadataRepository._(db);
|
||||||
@@ -35,16 +40,12 @@ class MetadataRepository extends DriftDatabaseRepository {
|
|||||||
|
|
||||||
static Future<void> refresh() async {
|
static Future<void> refresh() async {
|
||||||
instance._cache.clear();
|
instance._cache.clear();
|
||||||
|
instance._appConfig = const .new();
|
||||||
|
instance._systemConfig = const .new();
|
||||||
await instance._hydrate();
|
await instance._hydrate();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _hydrate() async {
|
Future<void> _hydrate() async => _hydrateCache(await _db.select(_db.metadataEntity).get());
|
||||||
final rows = await _db.select(_db.metadataEntity).get();
|
|
||||||
for (final row in rows) {
|
|
||||||
final key = MetadataKey.fromKey(row.key);
|
|
||||||
if (key != null) _cache[key] = decode(key, row.value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
T _read<T extends Object>(MetadataKey<T> key) => (_cache[key] as T?) ?? key.defaultValue;
|
T _read<T extends Object>(MetadataKey<T> key) => (_cache[key] as T?) ?? key.defaultValue;
|
||||||
|
|
||||||
@@ -56,7 +57,7 @@ class MetadataRepository extends DriftDatabaseRepository {
|
|||||||
.insertOnConflictUpdate(
|
.insertOnConflictUpdate(
|
||||||
MetadataEntityCompanion.insert(key: key.key, value: encode(value), updatedAt: Value(DateTime.now())),
|
MetadataEntityCompanion.insert(key: key.key, value: encode(value), updatedAt: Value(DateTime.now())),
|
||||||
);
|
);
|
||||||
_cache[key] = value;
|
_updateCache(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@visibleForTesting
|
@visibleForTesting
|
||||||
@@ -79,27 +80,36 @@ class MetadataRepository extends DriftDatabaseRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> delete<T extends Object>(MetadataKey<T> key) async {
|
Future<void> delete<T extends Object>(MetadataKey<T> key) async {
|
||||||
_cache[key] = key.defaultValue;
|
|
||||||
await (_db.delete(_db.metadataEntity)..where((t) => t.key.equals(key.key))).go();
|
await (_db.delete(_db.metadataEntity)..where((t) => t.key.equals(key.key))).go();
|
||||||
|
_updateCache(key, key.defaultValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
AppConfig get appConfig => AppConfig(theme: ThemeConfig(mode: _read(MetadataKey.themeMode)));
|
Stream<AppConfig> watchAppConfig() => _watchDomain(.appConfig).map((_) => appConfig).distinct();
|
||||||
|
|
||||||
SystemConfig get systemConfig => SystemConfig(logLevel: _read(MetadataKey.logLevel));
|
Stream<SystemConfig> watchSystemConfig() => _watchDomain(.systemConfig).map((_) => systemConfig).distinct();
|
||||||
|
|
||||||
Stream<AppConfig> watchAppConfig() => _watchDomain(MetadataDomain.appConfig).map((_) => appConfig).distinct();
|
|
||||||
|
|
||||||
Stream<SystemConfig> watchSystemConfig() =>
|
|
||||||
_watchDomain(MetadataDomain.systemConfig).map((_) => systemConfig).distinct();
|
|
||||||
|
|
||||||
Stream<void> _watchDomain(MetadataDomain domain) {
|
Stream<void> _watchDomain(MetadataDomain domain) {
|
||||||
final query = _db.select(_db.metadataEntity)..where((t) => t.key.like('${domain.prefix}.%'));
|
final query = _db.select(_db.metadataEntity)..where((t) => t.key.like('${domain.prefix}.%'));
|
||||||
return query.watch().map((rows) => rows.forEach(_updateCacheForRow));
|
return query.watch().map(_hydrateCache);
|
||||||
}
|
}
|
||||||
|
|
||||||
void _updateCacheForRow(MetadataEntityData row) {
|
void _hydrateCache(List<MetadataEntityData> rows) {
|
||||||
final key = MetadataKey.fromKey(row.key);
|
final keyMap = MetadataKey.asKeyMap();
|
||||||
if (key == null) return;
|
for (final row in rows) {
|
||||||
_cache[key] = decode(key, row.value);
|
final key = keyMap[row.key];
|
||||||
|
if (key == null) continue;
|
||||||
|
_updateCache(key, decode(key, row.value));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void _updateCache<T extends Object>(MetadataKey<T> key, T value) {
|
||||||
|
if (_cache[key] == value) return;
|
||||||
|
_cache[key] = value;
|
||||||
|
switch (key.domain) {
|
||||||
|
case .appConfig:
|
||||||
|
_appConfig = .new(theme: .new(mode: _read(.themeMode)));
|
||||||
|
case .systemConfig:
|
||||||
|
_systemConfig = .new(logLevel: _read(.logLevel));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -40,24 +40,21 @@ Future<void> _migrateTo25() async {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _migrateTo26(Drift drift) async {
|
Future<void> _migrateTo26(Drift drift) async {
|
||||||
const int themeModeKey = 102;
|
|
||||||
const int logLevelKey = 115;
|
|
||||||
|
|
||||||
final repo = MetadataRepository.instance;
|
final repo = MetadataRepository.instance;
|
||||||
final migrated = <int>[];
|
final migrated = <int>[];
|
||||||
|
|
||||||
final themeMode = await _readLegacyStoreString(drift, themeModeKey);
|
final themeMode = await _readLegacyStoreString(drift, StoreKey.legacyThemeMode.id);
|
||||||
if (themeMode != null) {
|
if (themeMode != null) {
|
||||||
final mode = ThemeMode.values.firstWhere((m) => m.name == themeMode, orElse: () => ThemeMode.system);
|
final mode = ThemeMode.values.firstWhere((m) => m.name == themeMode, orElse: () => ThemeMode.system);
|
||||||
await repo.write(MetadataKey.themeMode, mode);
|
await repo.write(MetadataKey.themeMode, mode);
|
||||||
migrated.add(themeModeKey);
|
migrated.add(StoreKey.legacyThemeMode.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
final logLevelIndex = await _readLegacyStoreInt(drift, logLevelKey);
|
final logLevelIndex = await _readLegacyStoreInt(drift, StoreKey.legacyLogLevel.id);
|
||||||
if (logLevelIndex != null) {
|
if (logLevelIndex != null) {
|
||||||
final logLevel = LogLevel.values.elementAtOrNull(logLevelIndex) ?? LogLevel.info;
|
final logLevel = LogLevel.values.elementAtOrNull(logLevelIndex) ?? LogLevel.info;
|
||||||
await LogService.I.setLogLevel(logLevel);
|
await LogService.I.setLogLevel(logLevel);
|
||||||
migrated.add(logLevelKey);
|
migrated.add(StoreKey.legacyLogLevel.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
await _deleteLegacyStoreRows(drift, migrated);
|
await _deleteLegacyStoreRows(drift, migrated);
|
||||||
|
|||||||
Reference in New Issue
Block a user