db clear buttons, ios album lookup

This commit is contained in:
shenlong-tanwen 2025-05-10 02:06:27 +05:30
parent 9c2ac887b9
commit 95ba4e4d38
12 changed files with 106 additions and 5 deletions

View File

@ -44,6 +44,14 @@ class MediaManager(context: Context) {
}
}
fun clearSyncCheckpoint() {
ctx.getSharedPreferences(SHARED_PREF_NAME, Context.MODE_PRIVATE).edit().apply {
remove(SHARED_PREF_MEDIA_STORE_VERSION_KEY)
remove(SHARED_PREF_MEDIA_STORE_GEN_KEY)
apply()
}
}
@RequiresApi(Build.VERSION_CODES.Q)
fun getAssetIdsForAlbum(albumId: String): List<String> {
val uri = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL)

View File

@ -192,6 +192,7 @@ interface ImHostService {
fun shouldFullSync(): Boolean
fun getMediaChanges(): SyncDelta
fun checkpointSync()
fun clearSyncCheckpoint()
fun getAssetIdsForAlbum(albumId: String): List<String>
companion object {
@ -250,6 +251,22 @@ interface ImHostService {
channel.setMessageHandler(null)
}
}
run {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.immich_mobile.ImHostService.clearSyncCheckpoint$separatedMessageChannelSuffix", codec)
if (api != null) {
channel.setMessageHandler { _, reply ->
val wrapped: List<Any?> = try {
api.clearSyncCheckpoint()
listOf(null)
} catch (exception: Throwable) {
MessagesPigeonUtils.wrapError(exception)
}
reply.reply(wrapped)
}
} else {
channel.setMessageHandler(null)
}
}
run {
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.immich_mobile.ImHostService.getAssetIdsForAlbum$separatedMessageChannelSuffix", codec, taskQueue)
if (api != null) {

View File

@ -37,6 +37,10 @@ class MessagesImpl(context: Context) : ImHostService {
mediaManager.checkpointSync()
}
override fun clearSyncCheckpoint() {
mediaManager.clearSyncCheckpoint()
}
override fun getAssetIdsForAlbum(albumId: String): List<String> {
if (!isMediaChangesSupported()) {
throw unsupportedFeatureException()

View File

@ -50,6 +50,11 @@ class MediaManager {
}
}
func clearSyncCheckpoint() -> Void {
defaults.removeObject(forKey: changeTokenKey)
print("MediaManager::removeChangeToken: Change token removed from UserDefaults")
}
@available(iOS 16, *)
func checkpointSync() {
saveChangeToken(token: PHPhotoLibrary.shared().currentChangeToken)
@ -150,9 +155,15 @@ class MediaManager {
let albumTypes: [PHAssetCollectionType] = [.album, .smartAlbum]
albumTypes.forEach { type in
let collections = PHAssetCollection.fetchAssetCollectionsContaining(forAsset, with: type, options: nil)
let collections = PHAssetCollection.fetchAssetCollections(with: type, subtype: .any, options: nil)
collections.enumerateObjects { (album, _, _) in
albumIds.append(album.localIdentifier)
var options = PHFetchOptions()
options.fetchLimit = 1
options.predicate = NSPredicate(format: "localIdentifier == %@", forAsset.localIdentifier)
let result = PHAsset.fetchAssets(in: album, options: options)
if(result.count == 1) {
albumIds.append(album.localIdentifier)
}
}
}
return albumIds

View File

@ -256,6 +256,7 @@ protocol ImHostService {
func shouldFullSync() throws -> Bool
func getMediaChanges() throws -> SyncDelta
func checkpointSync() throws
func clearSyncCheckpoint() throws
func getAssetIdsForAlbum(albumId: String) throws -> [String]
}
@ -311,6 +312,19 @@ class ImHostServiceSetup {
} else {
checkpointSyncChannel.setMessageHandler(nil)
}
let clearSyncCheckpointChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.immich_mobile.ImHostService.clearSyncCheckpoint\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
if let api = api {
clearSyncCheckpointChannel.setMessageHandler { _, reply in
do {
try api.clearSyncCheckpoint()
reply(wrapResult(nil))
} catch {
reply(wrapError(error))
}
}
} else {
clearSyncCheckpointChannel.setMessageHandler(nil)
}
let getAssetIdsForAlbumChannel = taskQueue == nil
? FlutterBasicMessageChannel(name: "dev.flutter.pigeon.immich_mobile.ImHostService.getAssetIdsForAlbum\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
: FlutterBasicMessageChannel(name: "dev.flutter.pigeon.immich_mobile.ImHostService.getAssetIdsForAlbum\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec, taskQueue: taskQueue)

View File

@ -1,6 +1,7 @@
import Photos
class ImHostServiceImpl: ImHostService {
private let mediaManager: MediaManager
init() {
@ -29,6 +30,10 @@ class ImHostServiceImpl: ImHostService {
}
}
func clearSyncCheckpoint() {
mediaManager.clearSyncCheckpoint()
}
func getAssetIdsForAlbum(albumId: String) throws -> [String] {
// Android specific, empty list is safe no-op
return []

View File

@ -24,7 +24,7 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository
final assetCount = _db.localAlbumAssetEntity.assetId.count();
final query = _db.localAlbumEntity.select().join([
innerJoin(
leftOuterJoin(
_db.localAlbumAssetEntity,
_db.localAlbumAssetEntity.albumId.equalsExp(_db.localAlbumEntity.id),
useColumns: false,

View File

@ -53,6 +53,8 @@ abstract class ImHostService {
void checkpointSync();
void clearSyncCheckpoint();
@TaskQueue(type: TaskQueueType.serialBackgroundThread)
List<String> getAssetIdsForAlbum(String albumId);
}

View File

@ -275,6 +275,29 @@ class ImHostService {
}
}
Future<void> clearSyncCheckpoint() async {
final String pigeonVar_channelName = 'dev.flutter.pigeon.immich_mobile.ImHostService.clearSyncCheckpoint$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
pigeonVar_channelName,
pigeonChannelCodec,
binaryMessenger: pigeonVar_binaryMessenger,
);
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
final List<Object?>? pigeonVar_replyList =
await pigeonVar_sendFuture as List<Object?>?;
if (pigeonVar_replyList == null) {
throw _createConnectionError(pigeonVar_channelName);
} else if (pigeonVar_replyList.length > 1) {
throw PlatformException(
code: pigeonVar_replyList[0]! as String,
message: pigeonVar_replyList[1] as String?,
details: pigeonVar_replyList[2],
);
} else {
return;
}
}
Future<List<String>> getAssetIdsForAlbum(String albumId) async {
final String pigeonVar_channelName = 'dev.flutter.pigeon.immich_mobile.ImHostService.getAssetIdsForAlbum$pigeonVar_messageChannelSuffix';
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(

View File

@ -1,10 +1,12 @@
import 'dart:async';
import 'package:auto_route/auto_route.dart';
import 'package:drift/drift.dart';
import 'package:flutter/material.dart';
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/providers/background_sync.provider.dart';
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
import 'package:immich_mobile/providers/infrastructure/platform.provider.dart';
import 'package:immich_mobile/routing/router.dart';
final _features = [
@ -25,6 +27,21 @@ final _features = [
.read(driftProvider)
.customStatement("pragma wal_checkpoint(truncate)"),
),
_Feature(
name: 'Clear Delta Checkpoint',
icon: Icons.delete_rounded,
onTap: (_, ref) => ref.read(hostServiceProvider).clearSyncCheckpoint(),
),
_Feature(
name: 'Clear Local Data',
icon: Icons.delete_forever_rounded,
onTap: (_, ref) async {
final db = ref.read(driftProvider);
await db.localAssetEntity.deleteAll();
await db.localAlbumEntity.deleteAll();
await db.localAlbumAssetEntity.deleteAll();
},
),
_Feature(
name: 'Local Media Summary',
icon: Icons.table_chart_rounded,

View File

@ -1,4 +1,4 @@
import 'package:hooks_riverpod/hooks_riverpod.dart';
import 'package:immich_mobile/platform/messages.g.dart';
final platformMessagesImpl = Provider<ImHostService>((_) => ImHostService());
final hostServiceProvider = Provider<ImHostService>((_) => ImHostService());

View File

@ -13,7 +13,7 @@ final deviceSyncServiceProvider = Provider(
(ref) => DeviceSyncService(
albumMediaRepository: ref.watch(albumMediaRepositoryProvider),
localAlbumRepository: ref.watch(localAlbumRepository),
hostService: ref.watch(platformMessagesImpl),
hostService: ref.watch(hostServiceProvider),
),
);