mirror of
https://github.com/immich-app/immich.git
synced 2025-05-31 04:05:39 -04:00
db clear buttons, ios album lookup
This commit is contained in:
parent
9c2ac887b9
commit
95ba4e4d38
@ -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)
|
@RequiresApi(Build.VERSION_CODES.Q)
|
||||||
fun getAssetIdsForAlbum(albumId: String): List<String> {
|
fun getAssetIdsForAlbum(albumId: String): List<String> {
|
||||||
val uri = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL)
|
val uri = MediaStore.Files.getContentUri(MediaStore.VOLUME_EXTERNAL)
|
||||||
|
@ -192,6 +192,7 @@ interface ImHostService {
|
|||||||
fun shouldFullSync(): Boolean
|
fun shouldFullSync(): Boolean
|
||||||
fun getMediaChanges(): SyncDelta
|
fun getMediaChanges(): SyncDelta
|
||||||
fun checkpointSync()
|
fun checkpointSync()
|
||||||
|
fun clearSyncCheckpoint()
|
||||||
fun getAssetIdsForAlbum(albumId: String): List<String>
|
fun getAssetIdsForAlbum(albumId: String): List<String>
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -250,6 +251,22 @@ interface ImHostService {
|
|||||||
channel.setMessageHandler(null)
|
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 {
|
run {
|
||||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.immich_mobile.ImHostService.getAssetIdsForAlbum$separatedMessageChannelSuffix", codec, taskQueue)
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.immich_mobile.ImHostService.getAssetIdsForAlbum$separatedMessageChannelSuffix", codec, taskQueue)
|
||||||
if (api != null) {
|
if (api != null) {
|
||||||
|
@ -37,6 +37,10 @@ class MessagesImpl(context: Context) : ImHostService {
|
|||||||
mediaManager.checkpointSync()
|
mediaManager.checkpointSync()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun clearSyncCheckpoint() {
|
||||||
|
mediaManager.clearSyncCheckpoint()
|
||||||
|
}
|
||||||
|
|
||||||
override fun getAssetIdsForAlbum(albumId: String): List<String> {
|
override fun getAssetIdsForAlbum(albumId: String): List<String> {
|
||||||
if (!isMediaChangesSupported()) {
|
if (!isMediaChangesSupported()) {
|
||||||
throw unsupportedFeatureException()
|
throw unsupportedFeatureException()
|
||||||
|
@ -50,6 +50,11 @@ class MediaManager {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func clearSyncCheckpoint() -> Void {
|
||||||
|
defaults.removeObject(forKey: changeTokenKey)
|
||||||
|
print("MediaManager::removeChangeToken: Change token removed from UserDefaults")
|
||||||
|
}
|
||||||
|
|
||||||
@available(iOS 16, *)
|
@available(iOS 16, *)
|
||||||
func checkpointSync() {
|
func checkpointSync() {
|
||||||
saveChangeToken(token: PHPhotoLibrary.shared().currentChangeToken)
|
saveChangeToken(token: PHPhotoLibrary.shared().currentChangeToken)
|
||||||
@ -150,9 +155,15 @@ class MediaManager {
|
|||||||
let albumTypes: [PHAssetCollectionType] = [.album, .smartAlbum]
|
let albumTypes: [PHAssetCollectionType] = [.album, .smartAlbum]
|
||||||
|
|
||||||
albumTypes.forEach { type in
|
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
|
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
|
return albumIds
|
||||||
|
@ -256,6 +256,7 @@ protocol ImHostService {
|
|||||||
func shouldFullSync() throws -> Bool
|
func shouldFullSync() throws -> Bool
|
||||||
func getMediaChanges() throws -> SyncDelta
|
func getMediaChanges() throws -> SyncDelta
|
||||||
func checkpointSync() throws
|
func checkpointSync() throws
|
||||||
|
func clearSyncCheckpoint() throws
|
||||||
func getAssetIdsForAlbum(albumId: String) throws -> [String]
|
func getAssetIdsForAlbum(albumId: String) throws -> [String]
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -311,6 +312,19 @@ class ImHostServiceSetup {
|
|||||||
} else {
|
} else {
|
||||||
checkpointSyncChannel.setMessageHandler(nil)
|
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
|
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)
|
||||||
: FlutterBasicMessageChannel(name: "dev.flutter.pigeon.immich_mobile.ImHostService.getAssetIdsForAlbum\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec, taskQueue: taskQueue)
|
: FlutterBasicMessageChannel(name: "dev.flutter.pigeon.immich_mobile.ImHostService.getAssetIdsForAlbum\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec, taskQueue: taskQueue)
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import Photos
|
import Photos
|
||||||
|
|
||||||
class ImHostServiceImpl: ImHostService {
|
class ImHostServiceImpl: ImHostService {
|
||||||
|
|
||||||
private let mediaManager: MediaManager
|
private let mediaManager: MediaManager
|
||||||
|
|
||||||
init() {
|
init() {
|
||||||
@ -29,6 +30,10 @@ class ImHostServiceImpl: ImHostService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func clearSyncCheckpoint() {
|
||||||
|
mediaManager.clearSyncCheckpoint()
|
||||||
|
}
|
||||||
|
|
||||||
func getAssetIdsForAlbum(albumId: String) throws -> [String] {
|
func getAssetIdsForAlbum(albumId: String) throws -> [String] {
|
||||||
// Android specific, empty list is safe no-op
|
// Android specific, empty list is safe no-op
|
||||||
return []
|
return []
|
||||||
|
@ -24,7 +24,7 @@ class DriftLocalAlbumRepository extends DriftDatabaseRepository
|
|||||||
final assetCount = _db.localAlbumAssetEntity.assetId.count();
|
final assetCount = _db.localAlbumAssetEntity.assetId.count();
|
||||||
|
|
||||||
final query = _db.localAlbumEntity.select().join([
|
final query = _db.localAlbumEntity.select().join([
|
||||||
innerJoin(
|
leftOuterJoin(
|
||||||
_db.localAlbumAssetEntity,
|
_db.localAlbumAssetEntity,
|
||||||
_db.localAlbumAssetEntity.albumId.equalsExp(_db.localAlbumEntity.id),
|
_db.localAlbumAssetEntity.albumId.equalsExp(_db.localAlbumEntity.id),
|
||||||
useColumns: false,
|
useColumns: false,
|
||||||
|
@ -53,6 +53,8 @@ abstract class ImHostService {
|
|||||||
|
|
||||||
void checkpointSync();
|
void checkpointSync();
|
||||||
|
|
||||||
|
void clearSyncCheckpoint();
|
||||||
|
|
||||||
@TaskQueue(type: TaskQueueType.serialBackgroundThread)
|
@TaskQueue(type: TaskQueueType.serialBackgroundThread)
|
||||||
List<String> getAssetIdsForAlbum(String albumId);
|
List<String> getAssetIdsForAlbum(String albumId);
|
||||||
}
|
}
|
||||||
|
23
mobile/lib/platform/messages.g.dart
generated
23
mobile/lib/platform/messages.g.dart
generated
@ -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 {
|
Future<List<String>> getAssetIdsForAlbum(String albumId) async {
|
||||||
final String pigeonVar_channelName = 'dev.flutter.pigeon.immich_mobile.ImHostService.getAssetIdsForAlbum$pigeonVar_messageChannelSuffix';
|
final String pigeonVar_channelName = 'dev.flutter.pigeon.immich_mobile.ImHostService.getAssetIdsForAlbum$pigeonVar_messageChannelSuffix';
|
||||||
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
|
|
||||||
import 'package:auto_route/auto_route.dart';
|
import 'package:auto_route/auto_route.dart';
|
||||||
|
import 'package:drift/drift.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/providers/background_sync.provider.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/db.provider.dart';
|
||||||
|
import 'package:immich_mobile/providers/infrastructure/platform.provider.dart';
|
||||||
import 'package:immich_mobile/routing/router.dart';
|
import 'package:immich_mobile/routing/router.dart';
|
||||||
|
|
||||||
final _features = [
|
final _features = [
|
||||||
@ -25,6 +27,21 @@ final _features = [
|
|||||||
.read(driftProvider)
|
.read(driftProvider)
|
||||||
.customStatement("pragma wal_checkpoint(truncate)"),
|
.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(
|
_Feature(
|
||||||
name: 'Local Media Summary',
|
name: 'Local Media Summary',
|
||||||
icon: Icons.table_chart_rounded,
|
icon: Icons.table_chart_rounded,
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/platform/messages.g.dart';
|
import 'package:immich_mobile/platform/messages.g.dart';
|
||||||
|
|
||||||
final platformMessagesImpl = Provider<ImHostService>((_) => ImHostService());
|
final hostServiceProvider = Provider<ImHostService>((_) => ImHostService());
|
||||||
|
@ -13,7 +13,7 @@ final deviceSyncServiceProvider = Provider(
|
|||||||
(ref) => DeviceSyncService(
|
(ref) => DeviceSyncService(
|
||||||
albumMediaRepository: ref.watch(albumMediaRepositoryProvider),
|
albumMediaRepository: ref.watch(albumMediaRepositoryProvider),
|
||||||
localAlbumRepository: ref.watch(localAlbumRepository),
|
localAlbumRepository: ref.watch(localAlbumRepository),
|
||||||
hostService: ref.watch(platformMessagesImpl),
|
hostService: ref.watch(hostServiceProvider),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user