mirror of
https://github.com/immich-app/immich
synced 2025-11-07 17:27:20 +00:00
trashed_local_asset table mirror of local_asset table structure
trashed_local_asset<->local_asset transfer data on move to trash or restore refactor code
This commit is contained in:
parent
b15056deb9
commit
bec1b30554
19 changed files with 1191 additions and 620 deletions
|
|
@ -90,8 +90,8 @@ data class PlatformAsset (
|
||||||
val durationInSeconds: Long,
|
val durationInSeconds: Long,
|
||||||
val orientation: Long,
|
val orientation: Long,
|
||||||
val isFavorite: Boolean,
|
val isFavorite: Boolean,
|
||||||
val isTrashed: Boolean,
|
val isTrashed: Boolean? = null,
|
||||||
val size: Long? = null
|
val volume: String? = null
|
||||||
)
|
)
|
||||||
{
|
{
|
||||||
companion object {
|
companion object {
|
||||||
|
|
@ -106,9 +106,9 @@ data class PlatformAsset (
|
||||||
val durationInSeconds = pigeonVar_list[7] as Long
|
val durationInSeconds = pigeonVar_list[7] as Long
|
||||||
val orientation = pigeonVar_list[8] as Long
|
val orientation = pigeonVar_list[8] as Long
|
||||||
val isFavorite = pigeonVar_list[9] as Boolean
|
val isFavorite = pigeonVar_list[9] as Boolean
|
||||||
val isTrashed = pigeonVar_list[10] as Boolean
|
val isTrashed = pigeonVar_list[10] as Boolean?
|
||||||
val size = pigeonVar_list[11] as Long?
|
val volume = pigeonVar_list[11] as String?
|
||||||
return PlatformAsset(id, name, type, createdAt, updatedAt, width, height, durationInSeconds, orientation, isFavorite, isTrashed, size)
|
return PlatformAsset(id, name, type, createdAt, updatedAt, width, height, durationInSeconds, orientation, isFavorite, isTrashed, volume)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fun toList(): List<Any?> {
|
fun toList(): List<Any?> {
|
||||||
|
|
@ -124,7 +124,7 @@ data class PlatformAsset (
|
||||||
orientation,
|
orientation,
|
||||||
isFavorite,
|
isFavorite,
|
||||||
isTrashed,
|
isTrashed,
|
||||||
size,
|
volume,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
override fun equals(other: Any?): Boolean {
|
override fun equals(other: Any?): Boolean {
|
||||||
|
|
@ -345,7 +345,7 @@ private open class MessagesPigeonCodec : StandardMessageCodec() {
|
||||||
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
|
/** Generated interface from Pigeon that represents a handler of messages from Flutter. */
|
||||||
interface NativeSyncApi {
|
interface NativeSyncApi {
|
||||||
fun shouldFullSync(): Boolean
|
fun shouldFullSync(): Boolean
|
||||||
fun getMediaChanges(): SyncDelta
|
fun getMediaChanges(isTrashed: Boolean): SyncDelta
|
||||||
fun checkpointSync()
|
fun checkpointSync()
|
||||||
fun clearSyncCheckpoint()
|
fun clearSyncCheckpoint()
|
||||||
fun getAssetIdsForAlbum(albumId: String): List<String>
|
fun getAssetIdsForAlbum(albumId: String): List<String>
|
||||||
|
|
@ -354,7 +354,7 @@ interface NativeSyncApi {
|
||||||
fun getAssetsForAlbum(albumId: String, updatedTimeCond: Long?): List<PlatformAsset>
|
fun getAssetsForAlbum(albumId: String, updatedTimeCond: Long?): List<PlatformAsset>
|
||||||
fun hashAssets(assetIds: List<String>, allowNetworkAccess: Boolean, callback: (Result<List<HashResult>>) -> Unit)
|
fun hashAssets(assetIds: List<String>, allowNetworkAccess: Boolean, callback: (Result<List<HashResult>>) -> Unit)
|
||||||
fun cancelHashing()
|
fun cancelHashing()
|
||||||
fun getTrashedAssetsForAlbum(albumId: String, updatedTimeCond: Long?): List<PlatformAsset>
|
fun getTrashedAssetsForAlbum(albumId: String): List<PlatformAsset>
|
||||||
fun hashTrashedAssets(trashedAssets: List<TrashedAssetParams>, callback: (Result<List<HashResult>>) -> Unit)
|
fun hashTrashedAssets(trashedAssets: List<TrashedAssetParams>, callback: (Result<List<HashResult>>) -> Unit)
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
@ -385,9 +385,11 @@ interface NativeSyncApi {
|
||||||
run {
|
run {
|
||||||
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.immich_mobile.NativeSyncApi.getMediaChanges$separatedMessageChannelSuffix", codec, taskQueue)
|
val channel = BasicMessageChannel<Any?>(binaryMessenger, "dev.flutter.pigeon.immich_mobile.NativeSyncApi.getMediaChanges$separatedMessageChannelSuffix", codec, taskQueue)
|
||||||
if (api != null) {
|
if (api != null) {
|
||||||
channel.setMessageHandler { _, reply ->
|
channel.setMessageHandler { message, reply ->
|
||||||
|
val args = message as List<Any?>
|
||||||
|
val isTrashedArg = args[0] as Boolean
|
||||||
val wrapped: List<Any?> = try {
|
val wrapped: List<Any?> = try {
|
||||||
listOf(api.getMediaChanges())
|
listOf(api.getMediaChanges(isTrashedArg))
|
||||||
} catch (exception: Throwable) {
|
} catch (exception: Throwable) {
|
||||||
MessagesPigeonUtils.wrapError(exception)
|
MessagesPigeonUtils.wrapError(exception)
|
||||||
}
|
}
|
||||||
|
|
@ -540,9 +542,8 @@ interface NativeSyncApi {
|
||||||
channel.setMessageHandler { message, reply ->
|
channel.setMessageHandler { message, reply ->
|
||||||
val args = message as List<Any?>
|
val args = message as List<Any?>
|
||||||
val albumIdArg = args[0] as String
|
val albumIdArg = args[0] as String
|
||||||
val updatedTimeCondArg = args[1] as Long?
|
|
||||||
val wrapped: List<Any?> = try {
|
val wrapped: List<Any?> = try {
|
||||||
listOf(api.getTrashedAssetsForAlbum(albumIdArg, updatedTimeCondArg))
|
listOf(api.getTrashedAssetsForAlbum(albumIdArg))
|
||||||
} catch (exception: Throwable) {
|
} catch (exception: Throwable) {
|
||||||
MessagesPigeonUtils.wrapError(exception)
|
MessagesPigeonUtils.wrapError(exception)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,13 +18,12 @@ class NativeSyncApiImpl26(context: Context) : NativeSyncApiImplBase(context), Na
|
||||||
// No-op for Android 10 and below
|
// No-op for Android 10 and below
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMediaChanges(): SyncDelta {
|
override fun getMediaChanges(isTrashed: Boolean): SyncDelta {
|
||||||
throw IllegalStateException("Method not supported on this Android version.")
|
throw IllegalStateException("Method not supported on this Android version.")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getTrashedAssetsForAlbum(
|
override fun getTrashedAssetsForAlbum(
|
||||||
albumId: String,
|
albumId: String,
|
||||||
updatedTimeCond: Long?
|
|
||||||
): List<PlatformAsset> {
|
): List<PlatformAsset> {
|
||||||
throw IllegalStateException("Method not supported on this Android version.")
|
throw IllegalStateException("Method not supported on this Android version.")
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,21 +45,90 @@ class NativeSyncApiImpl30(context: Context) : NativeSyncApiImplBase(context), Na
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun shouldFullSync(): Boolean =
|
||||||
|
MediaStore.getVersion(ctx) != prefs.getString(SHARED_PREF_MEDIA_STORE_VERSION_KEY, null)
|
||||||
|
|
||||||
|
override fun checkpointSync() {
|
||||||
|
val genMap = MediaStore.getExternalVolumeNames(ctx)
|
||||||
|
.associateWith { MediaStore.getGeneration(ctx, it) }
|
||||||
|
|
||||||
|
prefs.edit().apply {
|
||||||
|
putString(SHARED_PREF_MEDIA_STORE_VERSION_KEY, MediaStore.getVersion(ctx))
|
||||||
|
putString(SHARED_PREF_MEDIA_STORE_GEN_KEY, Json.encodeToString(genMap))
|
||||||
|
apply()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getMediaChanges(isTrashed: Boolean): SyncDelta {
|
||||||
|
val genMap = getSavedGenerationMap()
|
||||||
|
val currentVolumes = MediaStore.getExternalVolumeNames(ctx)
|
||||||
|
val changed = mutableListOf<PlatformAsset>()
|
||||||
|
val deleted = mutableListOf<String>()
|
||||||
|
val assetAlbums = mutableMapOf<String, List<String>>()
|
||||||
|
var hasChanges = genMap.keys != currentVolumes
|
||||||
|
|
||||||
|
for (volume in currentVolumes) {
|
||||||
|
val currentGen = MediaStore.getGeneration(ctx, volume)
|
||||||
|
val storedGen = genMap[volume] ?: 0
|
||||||
|
if (currentGen <= storedGen) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
|
hasChanges = true
|
||||||
|
|
||||||
|
val selection =
|
||||||
|
"$MEDIA_SELECTION AND (${MediaStore.MediaColumns.GENERATION_MODIFIED} > ? OR ${MediaStore.MediaColumns.GENERATION_ADDED} > ?)"
|
||||||
|
val selectionArgs = arrayOf(
|
||||||
|
*MEDIA_SELECTION_ARGS,
|
||||||
|
storedGen.toString(),
|
||||||
|
storedGen.toString()
|
||||||
|
)
|
||||||
|
if (isTrashed) {
|
||||||
|
val uri = MediaStore.Files.getContentUri(volume)
|
||||||
|
val queryArgs = Bundle().apply {
|
||||||
|
putString(ContentResolver.QUERY_ARG_SQL_SELECTION, selection)
|
||||||
|
putStringArray(ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS, selectionArgs)
|
||||||
|
putInt(MediaStore.QUERY_ARG_MATCH_TRASHED, MediaStore.MATCH_ONLY)
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx.contentResolver.query(uri, ASSET_PROJECTION, queryArgs, null).use { cursor ->
|
||||||
|
getAssets(cursor).forEach {
|
||||||
|
when (it) {
|
||||||
|
is AssetResult.ValidAsset -> {
|
||||||
|
changed.add(it.asset)
|
||||||
|
assetAlbums[it.asset.id] = listOf(it.albumId)
|
||||||
|
}
|
||||||
|
|
||||||
|
is AssetResult.InvalidAsset -> deleted.add(it.assetId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
getAssets(getCursor(volume, selection, selectionArgs)).forEach {
|
||||||
|
when (it) {
|
||||||
|
is AssetResult.ValidAsset -> {
|
||||||
|
changed.add(it.asset)
|
||||||
|
assetAlbums[it.asset.id] = listOf(it.albumId)
|
||||||
|
}
|
||||||
|
|
||||||
|
is AssetResult.InvalidAsset -> deleted.add(it.assetId)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Unmounted volumes are handled in dart when the album is removed
|
||||||
|
return SyncDelta(hasChanges, changed, deleted, assetAlbums)
|
||||||
|
}
|
||||||
|
|
||||||
override fun getTrashedAssetsForAlbum(
|
override fun getTrashedAssetsForAlbum(
|
||||||
albumId: String,
|
albumId: String
|
||||||
updatedTimeCond: Long?
|
|
||||||
): List<PlatformAsset> {
|
): List<PlatformAsset> {
|
||||||
val trashed = mutableListOf<PlatformAsset>()
|
val trashed = mutableListOf<PlatformAsset>()
|
||||||
val volumes = MediaStore.getExternalVolumeNames(ctx)
|
val volumes = MediaStore.getExternalVolumeNames(ctx)
|
||||||
|
|
||||||
var selection = "$BUCKET_SELECTION AND $MEDIA_SELECTION"
|
val selection = "$BUCKET_SELECTION AND $MEDIA_SELECTION"
|
||||||
val selectionArgs = mutableListOf(albumId, *MEDIA_SELECTION_ARGS)
|
val selectionArgs = mutableListOf(albumId, *MEDIA_SELECTION_ARGS)
|
||||||
|
|
||||||
if (updatedTimeCond != null) {
|
|
||||||
selection += " AND (${MediaStore.Files.FileColumns.DATE_MODIFIED} > ? OR ${MediaStore.Files.FileColumns.DATE_ADDED} > ?)"
|
|
||||||
selectionArgs.addAll(listOf(updatedTimeCond.toString(), updatedTimeCond.toString()))
|
|
||||||
}
|
|
||||||
|
|
||||||
for (volume in volumes) {
|
for (volume in volumes) {
|
||||||
val uri = MediaStore.Files.getContentUri(volume)
|
val uri = MediaStore.Files.getContentUri(volume)
|
||||||
val queryArgs = Bundle().apply {
|
val queryArgs = Bundle().apply {
|
||||||
|
|
@ -114,68 +183,6 @@ class NativeSyncApiImpl30(context: Context) : NativeSyncApiImplBase(context), Na
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun shouldFullSync(): Boolean =
|
|
||||||
MediaStore.getVersion(ctx) != prefs.getString(SHARED_PREF_MEDIA_STORE_VERSION_KEY, null)
|
|
||||||
|
|
||||||
override fun checkpointSync() {
|
|
||||||
val genMap = MediaStore.getExternalVolumeNames(ctx)
|
|
||||||
.associateWith { MediaStore.getGeneration(ctx, it) }
|
|
||||||
|
|
||||||
prefs.edit().apply {
|
|
||||||
putString(SHARED_PREF_MEDIA_STORE_VERSION_KEY, MediaStore.getVersion(ctx))
|
|
||||||
putString(SHARED_PREF_MEDIA_STORE_GEN_KEY, Json.encodeToString(genMap))
|
|
||||||
apply()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun getMediaChanges(): SyncDelta {
|
|
||||||
val genMap = getSavedGenerationMap()
|
|
||||||
val currentVolumes = MediaStore.getExternalVolumeNames(ctx)
|
|
||||||
val changed = mutableListOf<PlatformAsset>()
|
|
||||||
val deleted = mutableListOf<String>()
|
|
||||||
val assetAlbums = mutableMapOf<String, List<String>>()
|
|
||||||
var hasChanges = genMap.keys != currentVolumes
|
|
||||||
|
|
||||||
for (volume in currentVolumes) {
|
|
||||||
val currentGen = MediaStore.getGeneration(ctx, volume)
|
|
||||||
val storedGen = genMap[volume] ?: 0
|
|
||||||
if (currentGen <= storedGen) {
|
|
||||||
continue
|
|
||||||
}
|
|
||||||
|
|
||||||
hasChanges = true
|
|
||||||
|
|
||||||
val selection =
|
|
||||||
"$MEDIA_SELECTION AND (${MediaStore.MediaColumns.GENERATION_MODIFIED} > ? OR ${MediaStore.MediaColumns.GENERATION_ADDED} > ?)"
|
|
||||||
val selectionArgs = arrayOf(
|
|
||||||
*MEDIA_SELECTION_ARGS,
|
|
||||||
storedGen.toString(),
|
|
||||||
storedGen.toString()
|
|
||||||
)
|
|
||||||
|
|
||||||
val uri = MediaStore.Files.getContentUri(volume)
|
|
||||||
val queryArgs = Bundle().apply {
|
|
||||||
putString(ContentResolver.QUERY_ARG_SQL_SELECTION, selection)
|
|
||||||
putStringArray(ContentResolver.QUERY_ARG_SQL_SELECTION_ARGS, selectionArgs)
|
|
||||||
putInt(MediaStore.QUERY_ARG_MATCH_TRASHED, MediaStore.MATCH_INCLUDE)
|
|
||||||
}
|
|
||||||
|
|
||||||
ctx.contentResolver.query(uri, ASSET_PROJECTION, queryArgs, null).use { cursor ->
|
|
||||||
getAssets(cursor).forEach {
|
|
||||||
when (it) {
|
|
||||||
is AssetResult.ValidAsset -> {
|
|
||||||
changed.add(it.asset)
|
|
||||||
assetAlbums[it.asset.id] = listOf(it.albumId)
|
|
||||||
}
|
|
||||||
is AssetResult.InvalidAsset -> deleted.add(it.assetId)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// Unmounted volumes are handled in dart when the album is removed
|
|
||||||
return SyncDelta(hasChanges, changed, deleted, assetAlbums)
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun hashTrashedAsset(assetParams: TrashedAssetParams): HashResult {
|
suspend fun hashTrashedAsset(assetParams: TrashedAssetParams): HashResult {
|
||||||
val id = assetParams.id.toLong()
|
val id = assetParams.id.toLong()
|
||||||
val mediaType = assetParams.type.toInt()
|
val mediaType = assetParams.type.toInt()
|
||||||
|
|
|
||||||
|
|
@ -58,13 +58,12 @@ open class NativeSyncApiImplBase(context: Context) {
|
||||||
add(MediaStore.MediaColumns.HEIGHT)
|
add(MediaStore.MediaColumns.HEIGHT)
|
||||||
add(MediaStore.MediaColumns.DURATION)
|
add(MediaStore.MediaColumns.DURATION)
|
||||||
add(MediaStore.MediaColumns.ORIENTATION)
|
add(MediaStore.MediaColumns.ORIENTATION)
|
||||||
// IS_FAVORITE is only available on Android 11 and above
|
// only available on Android 11 and above
|
||||||
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
|
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.R) {
|
||||||
add(MediaStore.MediaColumns.IS_FAVORITE)
|
add(MediaStore.MediaColumns.IS_FAVORITE)
|
||||||
// IS_TRASHED available on Android 11+
|
|
||||||
add(MediaStore.MediaColumns.IS_TRASHED)
|
add(MediaStore.MediaColumns.IS_TRASHED)
|
||||||
|
add(MediaStore.MediaColumns.VOLUME_NAME)
|
||||||
}
|
}
|
||||||
add(MediaStore.MediaColumns.SIZE)
|
|
||||||
}.toTypedArray()
|
}.toTypedArray()
|
||||||
|
|
||||||
const val HASH_BUFFER_SIZE = 2 * 1024 * 1024
|
const val HASH_BUFFER_SIZE = 2 * 1024 * 1024
|
||||||
|
|
@ -102,7 +101,7 @@ open class NativeSyncApiImplBase(context: Context) {
|
||||||
c.getColumnIndexOrThrow(MediaStore.MediaColumns.ORIENTATION)
|
c.getColumnIndexOrThrow(MediaStore.MediaColumns.ORIENTATION)
|
||||||
val favoriteColumn = c.getColumnIndex(MediaStore.MediaColumns.IS_FAVORITE)
|
val favoriteColumn = c.getColumnIndex(MediaStore.MediaColumns.IS_FAVORITE)
|
||||||
val trashedColumn = c.getColumnIndex(MediaStore.MediaColumns.IS_TRASHED)
|
val trashedColumn = c.getColumnIndex(MediaStore.MediaColumns.IS_TRASHED)
|
||||||
val sizeColumn = c.getColumnIndex(MediaStore.MediaColumns.SIZE)
|
val volumeColumn = c.getColumnIndex(MediaStore.MediaColumns.VOLUME_NAME)
|
||||||
|
|
||||||
while (c.moveToNext()) {
|
while (c.moveToNext()) {
|
||||||
val id = c.getLong(idColumn).toString()
|
val id = c.getLong(idColumn).toString()
|
||||||
|
|
@ -132,8 +131,8 @@ open class NativeSyncApiImplBase(context: Context) {
|
||||||
val bucketId = c.getString(bucketIdColumn)
|
val bucketId = c.getString(bucketIdColumn)
|
||||||
val orientation = c.getInt(orientationColumn)
|
val orientation = c.getInt(orientationColumn)
|
||||||
val isFavorite = if (favoriteColumn == -1) false else c.getInt(favoriteColumn) != 0
|
val isFavorite = if (favoriteColumn == -1) false else c.getInt(favoriteColumn) != 0
|
||||||
val isTrashed = if (trashedColumn == -1) false else c.getInt(trashedColumn) != 0
|
val isTrashed = if (trashedColumn == -1) null else c.getInt(trashedColumn) != 0
|
||||||
val size = c.getLong(sizeColumn)
|
val volume = if (volumeColumn == -1) null else c.getString(volumeColumn)
|
||||||
val asset = PlatformAsset(
|
val asset = PlatformAsset(
|
||||||
id,
|
id,
|
||||||
name,
|
name,
|
||||||
|
|
@ -146,7 +145,7 @@ open class NativeSyncApiImplBase(context: Context) {
|
||||||
orientation.toLong(),
|
orientation.toLong(),
|
||||||
isFavorite,
|
isFavorite,
|
||||||
isTrashed,
|
isTrashed,
|
||||||
size
|
volume,
|
||||||
)
|
)
|
||||||
yield(AssetResult.ValidAsset(asset, bucketId))
|
yield(AssetResult.ValidAsset(asset, bucketId))
|
||||||
}
|
}
|
||||||
|
|
|
||||||
2
mobile/drift_schemas/main/drift_schema_v12.json
generated
2
mobile/drift_schemas/main/drift_schema_v12.json
generated
File diff suppressed because one or more lines are too long
|
|
@ -140,8 +140,8 @@ struct PlatformAsset: Hashable {
|
||||||
var durationInSeconds: Int64
|
var durationInSeconds: Int64
|
||||||
var orientation: Int64
|
var orientation: Int64
|
||||||
var isFavorite: Bool
|
var isFavorite: Bool
|
||||||
var isTrashed: Bool
|
var isTrashed: Bool? = nil
|
||||||
var size: Int64? = nil
|
var volume: String? = nil
|
||||||
|
|
||||||
|
|
||||||
// swift-format-ignore: AlwaysUseLowerCamelCase
|
// swift-format-ignore: AlwaysUseLowerCamelCase
|
||||||
|
|
@ -156,8 +156,8 @@ struct PlatformAsset: Hashable {
|
||||||
let durationInSeconds = pigeonVar_list[7] as! Int64
|
let durationInSeconds = pigeonVar_list[7] as! Int64
|
||||||
let orientation = pigeonVar_list[8] as! Int64
|
let orientation = pigeonVar_list[8] as! Int64
|
||||||
let isFavorite = pigeonVar_list[9] as! Bool
|
let isFavorite = pigeonVar_list[9] as! Bool
|
||||||
let isTrashed = pigeonVar_list[10] as! Bool
|
let isTrashed: Bool? = nilOrValue(pigeonVar_list[10])
|
||||||
let size: Int64? = nilOrValue(pigeonVar_list[11])
|
let volume: String? = nilOrValue(pigeonVar_list[11])
|
||||||
|
|
||||||
return PlatformAsset(
|
return PlatformAsset(
|
||||||
id: id,
|
id: id,
|
||||||
|
|
@ -171,7 +171,7 @@ struct PlatformAsset: Hashable {
|
||||||
orientation: orientation,
|
orientation: orientation,
|
||||||
isFavorite: isFavorite,
|
isFavorite: isFavorite,
|
||||||
isTrashed: isTrashed,
|
isTrashed: isTrashed,
|
||||||
size: size
|
volume: volume
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
func toList() -> [Any?] {
|
func toList() -> [Any?] {
|
||||||
|
|
@ -187,7 +187,7 @@ struct PlatformAsset: Hashable {
|
||||||
orientation,
|
orientation,
|
||||||
isFavorite,
|
isFavorite,
|
||||||
isTrashed,
|
isTrashed,
|
||||||
size,
|
volume,
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
static func == (lhs: PlatformAsset, rhs: PlatformAsset) -> Bool {
|
static func == (lhs: PlatformAsset, rhs: PlatformAsset) -> Bool {
|
||||||
|
|
@ -401,7 +401,7 @@ class MessagesPigeonCodec: FlutterStandardMessageCodec, @unchecked Sendable {
|
||||||
/// Generated protocol from Pigeon that represents a handler of messages from Flutter.
|
/// Generated protocol from Pigeon that represents a handler of messages from Flutter.
|
||||||
protocol NativeSyncApi {
|
protocol NativeSyncApi {
|
||||||
func shouldFullSync() throws -> Bool
|
func shouldFullSync() throws -> Bool
|
||||||
func getMediaChanges() throws -> SyncDelta
|
func getMediaChanges(isTrashed: Bool) throws -> SyncDelta
|
||||||
func checkpointSync() throws
|
func checkpointSync() throws
|
||||||
func clearSyncCheckpoint() throws
|
func clearSyncCheckpoint() throws
|
||||||
func getAssetIdsForAlbum(albumId: String) throws -> [String]
|
func getAssetIdsForAlbum(albumId: String) throws -> [String]
|
||||||
|
|
@ -410,7 +410,7 @@ protocol NativeSyncApi {
|
||||||
func getAssetsForAlbum(albumId: String, updatedTimeCond: Int64?) throws -> [PlatformAsset]
|
func getAssetsForAlbum(albumId: String, updatedTimeCond: Int64?) throws -> [PlatformAsset]
|
||||||
func hashAssets(assetIds: [String], allowNetworkAccess: Bool, completion: @escaping (Result<[HashResult], Error>) -> Void)
|
func hashAssets(assetIds: [String], allowNetworkAccess: Bool, completion: @escaping (Result<[HashResult], Error>) -> Void)
|
||||||
func cancelHashing() throws
|
func cancelHashing() throws
|
||||||
func getTrashedAssetsForAlbum(albumId: String, updatedTimeCond: Int64?) throws -> [PlatformAsset]
|
func getTrashedAssetsForAlbum(albumId: String) throws -> [PlatformAsset]
|
||||||
func hashTrashedAssets(trashedAssets: [TrashedAssetParams], completion: @escaping (Result<[HashResult], Error>) -> Void)
|
func hashTrashedAssets(trashedAssets: [TrashedAssetParams], completion: @escaping (Result<[HashResult], Error>) -> Void)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -442,9 +442,11 @@ class NativeSyncApiSetup {
|
||||||
? FlutterBasicMessageChannel(name: "dev.flutter.pigeon.immich_mobile.NativeSyncApi.getMediaChanges\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
|
? FlutterBasicMessageChannel(name: "dev.flutter.pigeon.immich_mobile.NativeSyncApi.getMediaChanges\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec)
|
||||||
: FlutterBasicMessageChannel(name: "dev.flutter.pigeon.immich_mobile.NativeSyncApi.getMediaChanges\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec, taskQueue: taskQueue)
|
: FlutterBasicMessageChannel(name: "dev.flutter.pigeon.immich_mobile.NativeSyncApi.getMediaChanges\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec, taskQueue: taskQueue)
|
||||||
if let api = api {
|
if let api = api {
|
||||||
getMediaChangesChannel.setMessageHandler { _, reply in
|
getMediaChangesChannel.setMessageHandler { message, reply in
|
||||||
|
let args = message as! [Any?]
|
||||||
|
let isTrashedArg = args[0] as! Bool
|
||||||
do {
|
do {
|
||||||
let result = try api.getMediaChanges()
|
let result = try api.getMediaChanges(isTrashed: isTrashedArg)
|
||||||
reply(wrapResult(result))
|
reply(wrapResult(result))
|
||||||
} catch {
|
} catch {
|
||||||
reply(wrapError(error))
|
reply(wrapError(error))
|
||||||
|
|
@ -587,9 +589,8 @@ class NativeSyncApiSetup {
|
||||||
getTrashedAssetsForAlbumChannel.setMessageHandler { message, reply in
|
getTrashedAssetsForAlbumChannel.setMessageHandler { message, reply in
|
||||||
let args = message as! [Any?]
|
let args = message as! [Any?]
|
||||||
let albumIdArg = args[0] as! String
|
let albumIdArg = args[0] as! String
|
||||||
let updatedTimeCondArg: Int64? = nilOrValue(args[1])
|
|
||||||
do {
|
do {
|
||||||
let result = try api.getTrashedAssetsForAlbum(albumId: albumIdArg, updatedTimeCond: updatedTimeCondArg)
|
let result = try api.getTrashedAssetsForAlbum(albumId: albumIdArg)
|
||||||
reply(wrapResult(result))
|
reply(wrapResult(result))
|
||||||
} catch {
|
} catch {
|
||||||
reply(wrapError(error))
|
reply(wrapError(error))
|
||||||
|
|
|
||||||
|
|
@ -3,43 +3,43 @@ import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||||
class TrashedAsset {
|
class TrashedAsset {
|
||||||
final String id;
|
final String id;
|
||||||
final String name;
|
final String name;
|
||||||
|
final String? volume;
|
||||||
final String albumId;
|
final String albumId;
|
||||||
final String? checksum;
|
final String? checksum;
|
||||||
final AssetType type;
|
final AssetType type;
|
||||||
final DateTime createdAt;
|
final DateTime createdAt;
|
||||||
final DateTime updatedAt;
|
final DateTime updatedAt;
|
||||||
final int? size;
|
|
||||||
|
|
||||||
const TrashedAsset({
|
const TrashedAsset({
|
||||||
required this.id,
|
required this.id,
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.checksum,
|
|
||||||
required this.albumId,
|
required this.albumId,
|
||||||
required this.type,
|
required this.type,
|
||||||
required this.createdAt,
|
required this.createdAt,
|
||||||
required this.updatedAt,
|
required this.updatedAt,
|
||||||
this.size,
|
this.volume,
|
||||||
|
this.checksum,
|
||||||
});
|
});
|
||||||
|
|
||||||
TrashedAsset copyWith({
|
TrashedAsset copyWith({
|
||||||
String? id,
|
String? id,
|
||||||
String? name,
|
String? name,
|
||||||
|
String? volume,
|
||||||
String? albumId,
|
String? albumId,
|
||||||
String? checksum,
|
String? checksum,
|
||||||
AssetType? type,
|
AssetType? type,
|
||||||
DateTime? createdAt,
|
DateTime? createdAt,
|
||||||
DateTime? updatedAt,
|
DateTime? updatedAt,
|
||||||
int? size,
|
|
||||||
}) {
|
}) {
|
||||||
return TrashedAsset(
|
return TrashedAsset(
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
name: name ?? this.name,
|
name: name ?? this.name,
|
||||||
|
volume: volume ?? this.volume,
|
||||||
albumId: albumId ?? this.albumId,
|
albumId: albumId ?? this.albumId,
|
||||||
checksum: checksum ?? this.checksum,
|
checksum: checksum ?? this.checksum,
|
||||||
type: type ?? this.type,
|
type: type ?? this.type,
|
||||||
createdAt: createdAt ?? this.createdAt,
|
createdAt: createdAt ?? this.createdAt,
|
||||||
updatedAt: updatedAt ?? this.updatedAt,
|
updatedAt: updatedAt ?? this.updatedAt,
|
||||||
size: size ?? this.size,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -48,29 +48,29 @@ class TrashedAsset {
|
||||||
return 'TrashedAsset('
|
return 'TrashedAsset('
|
||||||
'id: $id, '
|
'id: $id, '
|
||||||
'name: $name, '
|
'name: $name, '
|
||||||
|
'volume: $volume, '
|
||||||
'albumId: $albumId, '
|
'albumId: $albumId, '
|
||||||
'checksum: $checksum, '
|
'checksum: $checksum, '
|
||||||
'type: $type, '
|
'type: $type, '
|
||||||
'createdAt: $createdAt, '
|
'createdAt: $createdAt, '
|
||||||
'updatedAt: $updatedAt, '
|
'updatedAt: $updatedAt, '
|
||||||
'size: ${size ?? "<NA>"}'
|
|
||||||
')';
|
')';
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
identical(this, other) ||
|
identical(this, other) ||
|
||||||
other is TrashedAsset &&
|
other is TrashedAsset &&
|
||||||
runtimeType == other.runtimeType &&
|
runtimeType == other.runtimeType &&
|
||||||
id == other.id &&
|
id == other.id &&
|
||||||
name == other.name &&
|
name == other.name &&
|
||||||
albumId == other.albumId &&
|
volume == other.volume &&
|
||||||
checksum == other.checksum &&
|
albumId == other.albumId &&
|
||||||
type == other.type &&
|
checksum == other.checksum &&
|
||||||
createdAt == other.createdAt &&
|
type == other.type &&
|
||||||
updatedAt == other.updatedAt &&
|
createdAt == other.createdAt &&
|
||||||
size == other.size;
|
updatedAt == other.updatedAt;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(id, name, albumId, checksum, type, createdAt, updatedAt, size);
|
int get hashCode => Object.hash(id, name, volume, albumId, checksum, type, createdAt, updatedAt);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -152,13 +152,6 @@ class HashService {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (asset.size == null) {
|
|
||||||
_log.warning(
|
|
||||||
"Cannot get size for asset ${asset.id}, name: ${asset.name}, created on: ${asset.createdAt} from album: ${album.name}",
|
|
||||||
);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
toHash.add(asset);
|
toHash.add(asset);
|
||||||
|
|
||||||
if (toHash.length == _batchSize) {
|
if (toHash.length == _batchSize) {
|
||||||
|
|
|
||||||
|
|
@ -40,14 +40,13 @@ class LocalSyncService {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
final updates = delta.updates.where((e) => !e.isTrashed);
|
_log.fine("Delta updated: ${delta.updates.length}");
|
||||||
_log.fine("Delta updated assets: ${updates.length}");
|
|
||||||
_log.fine("Delta deleted: ${delta.deletes.length}");
|
_log.fine("Delta deleted: ${delta.deletes.length}");
|
||||||
|
|
||||||
final deviceAlbums = await _nativeSyncApi.getAlbums();
|
final deviceAlbums = await _nativeSyncApi.getAlbums();
|
||||||
await _localAlbumRepository.updateAll(deviceAlbums.toLocalAlbums());
|
await _localAlbumRepository.updateAll(deviceAlbums.toLocalAlbums());
|
||||||
await _localAlbumRepository.processDelta(
|
await _localAlbumRepository.processDelta(
|
||||||
updates: updates.toLocalAssets(),
|
updates: delta.updates.toLocalAssets(),
|
||||||
deletes: delta.deletes,
|
deletes: delta.deletes,
|
||||||
assetAlbums: delta.assetAlbums,
|
assetAlbums: delta.assetAlbums,
|
||||||
);
|
);
|
||||||
|
|
@ -77,7 +76,8 @@ class LocalSyncService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (_trashSyncService.isAutoSyncMode) {
|
if (_trashSyncService.isAutoSyncMode) {
|
||||||
_log.fine("Delta updated trashed: ${delta.updates.length - updates.length}");
|
final delta = await _nativeSyncApi.getMediaChanges(isTrashed: true);
|
||||||
|
_log.fine("Delta updated in trash: ${delta.updates.length - delta.updates.length}");
|
||||||
await _trashSyncService.applyTrashDelta(delta);
|
await _trashSyncService.applyTrashDelta(delta);
|
||||||
}
|
}
|
||||||
await _nativeSyncApi.checkpointSync();
|
await _nativeSyncApi.checkpointSync();
|
||||||
|
|
|
||||||
|
|
@ -88,7 +88,7 @@ class SyncStreamService {
|
||||||
case SyncEntityType.assetV1:
|
case SyncEntityType.assetV1:
|
||||||
final remoteSyncAssets = data.cast<SyncAssetV1>();
|
final remoteSyncAssets = data.cast<SyncAssetV1>();
|
||||||
if (_trashSyncService.isAutoSyncMode) {
|
if (_trashSyncService.isAutoSyncMode) {
|
||||||
await _trashSyncService.handleRemoteChanges(
|
await _trashSyncService.handleRemoteTrashed(
|
||||||
remoteSyncAssets.where((e) => e.deletedAt != null).map((e) => e.checksum),
|
remoteSyncAssets.where((e) => e.deletedAt != null).map((e) => e.checksum),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -56,15 +56,15 @@ class TrashSyncService {
|
||||||
}
|
}
|
||||||
for (final album in backupAlbums) {
|
for (final album in backupAlbums) {
|
||||||
_logger.info("deviceTrashedAssets prepare, album: ${album.id}/${album.name}");
|
_logger.info("deviceTrashedAssets prepare, album: ${album.id}/${album.name}");
|
||||||
final deviceTrashedAssets = await _nativeSyncApi.getTrashedAssetsForAlbum(album.id);
|
final trashedPlatformAssets = await _nativeSyncApi.getTrashedAssetsForAlbum(album.id);
|
||||||
await _trashedLocalAssetRepository.applyTrashSnapshot(deviceTrashedAssets.toTrashedAssets(album.id), album.id);
|
final trashedAssets = trashedPlatformAssets.toTrashedAssets(album.id);
|
||||||
|
await _trashedLocalAssetRepository.applyTrashSnapshot(trashedAssets, album.id);
|
||||||
}
|
}
|
||||||
// todo find for more suitable place
|
|
||||||
await applyRemoteRestoreToLocal();
|
await applyRemoteRestoreToLocal();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> applyTrashDelta(SyncDelta delta) async {
|
Future<void> applyTrashDelta(SyncDelta delta) async {
|
||||||
final trashUpdates = delta.updates.where((e) => e.isTrashed);
|
final trashUpdates = delta.updates;
|
||||||
if (trashUpdates.isEmpty) {
|
if (trashUpdates.isEmpty) {
|
||||||
return Future.value();
|
return Future.value();
|
||||||
}
|
}
|
||||||
|
|
@ -77,11 +77,10 @@ class TrashSyncService {
|
||||||
}
|
}
|
||||||
_logger.info("updateLocalTrashChanges trashedAssets: ${trashedAssets.map((e) => e.id)}");
|
_logger.info("updateLocalTrashChanges trashedAssets: ${trashedAssets.map((e) => e.id)}");
|
||||||
await _trashedLocalAssetRepository.insertTrashDelta(trashedAssets);
|
await _trashedLocalAssetRepository.insertTrashDelta(trashedAssets);
|
||||||
// todo find for more suitable place
|
|
||||||
await applyRemoteRestoreToLocal();
|
await applyRemoteRestoreToLocal();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> handleRemoteChanges(Iterable<String> checksums) async {
|
Future<void> handleRemoteTrashed(Iterable<String> checksums) async {
|
||||||
if (checksums.isEmpty) {
|
if (checksums.isEmpty) {
|
||||||
return Future.value();
|
return Future.value();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -95,7 +94,7 @@ class TrashSyncService {
|
||||||
_logger.info("Moving to trash ${mediaUrls.join(", ")} assets");
|
_logger.info("Moving to trash ${mediaUrls.join(", ")} assets");
|
||||||
final result = await _localFilesManager.moveToTrash(mediaUrls.nonNulls.toList());
|
final result = await _localFilesManager.moveToTrash(mediaUrls.nonNulls.toList());
|
||||||
if (result) {
|
if (result) {
|
||||||
await _localAssetRepository.trash(localAssetsToTrash);
|
await _trashedLocalAssetRepository.trashLocalAsset(localAssetsToTrash);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
_logger.info("No assets found in backup-enabled albums for assets: $checksums");
|
_logger.info("No assets found in backup-enabled albums for assets: $checksums");
|
||||||
|
|
@ -111,12 +110,7 @@ class TrashSyncService {
|
||||||
_logger.info("Restoring from trash, localId: ${asset.id}, remoteId: ${asset.checksum}");
|
_logger.info("Restoring from trash, localId: ${asset.id}, remoteId: ${asset.checksum}");
|
||||||
await _localFilesManager.restoreFromTrashById(asset.id, asset.type.index);
|
await _localFilesManager.restoreFromTrashById(asset.id, asset.type.index);
|
||||||
}
|
}
|
||||||
// todo 19/09/2025
|
await _trashedLocalAssetRepository.restoreLocalAssets(remoteAssetsToRestore.map((e) => e.id));
|
||||||
// 1. keeping full mirror of local asset table struct + size into trashedLocalAssetEntity could help to restore assets here
|
|
||||||
// 2. now when hash calculating doing without taking into account size of files, size field may be redundant
|
|
||||||
|
|
||||||
// todo It`s necessary? could cause race with deletion in applyTrashSnapshot? 18/09/2025
|
|
||||||
await _trashedLocalAssetRepository.delete(remoteAssetsToRestore.map((e) => e.id));
|
|
||||||
} else {
|
} else {
|
||||||
_logger.info("No remote assets found for restoration");
|
_logger.info("No remote assets found for restoration");
|
||||||
}
|
}
|
||||||
|
|
@ -131,7 +125,7 @@ extension on PlatformAsset {
|
||||||
type: AssetType.values.elementAtOrNull(type) ?? AssetType.other,
|
type: AssetType.values.elementAtOrNull(type) ?? AssetType.other,
|
||||||
createdAt: tryFromSecondsSinceEpoch(createdAt) ?? DateTime.now(),
|
createdAt: tryFromSecondsSinceEpoch(createdAt) ?? DateTime.now(),
|
||||||
updatedAt: tryFromSecondsSinceEpoch(updatedAt) ?? DateTime.now(),
|
updatedAt: tryFromSecondsSinceEpoch(updatedAt) ?? DateTime.now(),
|
||||||
size: size,
|
volume: volume,
|
||||||
albumId: albumId,
|
albumId: albumId,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,42 +1,39 @@
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
|
||||||
import 'package:immich_mobile/domain/models/asset/trashed_asset.model.dart';
|
import 'package:immich_mobile/domain/models/asset/trashed_asset.model.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/trashed_local_asset.entity.drift.dart';
|
import 'package:immich_mobile/infrastructure/entities/trashed_local_asset.entity.drift.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/utils/asset.mixin.dart';
|
||||||
import 'package:immich_mobile/infrastructure/utils/drift_default.mixin.dart';
|
import 'package:immich_mobile/infrastructure/utils/drift_default.mixin.dart';
|
||||||
|
|
||||||
@TableIndex.sql('CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_checksum ON trashed_local_asset_entity (checksum)')
|
@TableIndex.sql('CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_checksum ON trashed_local_asset_entity (checksum)')
|
||||||
class TrashedLocalAssetEntity extends Table with DriftDefaultsMixin {
|
class TrashedLocalAssetEntity extends Table with DriftDefaultsMixin, AssetEntityMixin {
|
||||||
const TrashedLocalAssetEntity();
|
const TrashedLocalAssetEntity();
|
||||||
|
|
||||||
TextColumn get id => text()();
|
TextColumn get id => text()();
|
||||||
|
|
||||||
TextColumn get albumId => text()();
|
TextColumn get albumId => text()();
|
||||||
|
|
||||||
|
TextColumn get volume => text().nullable()();
|
||||||
|
|
||||||
TextColumn get checksum => text().nullable()();
|
TextColumn get checksum => text().nullable()();
|
||||||
|
|
||||||
TextColumn get name => text()();
|
BoolColumn get isFavorite => boolean().withDefault(const Constant(false))();
|
||||||
|
|
||||||
IntColumn get type => intEnum<AssetType>()();
|
IntColumn get orientation => integer().withDefault(const Constant(0))();
|
||||||
|
|
||||||
DateTimeColumn get createdAt => dateTime().withDefault(currentDateAndTime)();
|
|
||||||
|
|
||||||
DateTimeColumn get updatedAt => dateTime().withDefault(currentDateAndTime)();
|
|
||||||
|
|
||||||
IntColumn get size => integer().nullable()();
|
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Set<Column> get primaryKey => {id};
|
Set<Column> get primaryKey => {id, albumId};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
extension TrashedLocalAssetEntityDataDomainExtension on TrashedLocalAssetEntityData {
|
extension TrashedLocalAssetEntityDataDomainExtension on TrashedLocalAssetEntityData {
|
||||||
TrashedAsset toDto(String albumId) => TrashedAsset(
|
TrashedAsset toDto() => TrashedAsset(
|
||||||
id: id,
|
id: id,
|
||||||
name: name,
|
name: name,
|
||||||
|
volume: volume,
|
||||||
albumId: albumId,
|
albumId: albumId,
|
||||||
checksum: checksum,
|
checksum: checksum,
|
||||||
type: type,
|
type: type,
|
||||||
createdAt: createdAt,
|
createdAt: createdAt,
|
||||||
updatedAt: updatedAt,
|
updatedAt: updatedAt,
|
||||||
size: size,
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -5038,16 +5038,21 @@ final class Schema12 extends i0.VersionedSchema {
|
||||||
entityName: 'trashed_local_asset_entity',
|
entityName: 'trashed_local_asset_entity',
|
||||||
withoutRowId: true,
|
withoutRowId: true,
|
||||||
isStrict: true,
|
isStrict: true,
|
||||||
tableConstraints: ['PRIMARY KEY(id)'],
|
tableConstraints: ['PRIMARY KEY(id, album_id)'],
|
||||||
columns: [
|
columns: [
|
||||||
_column_0,
|
|
||||||
_column_95,
|
|
||||||
_column_22,
|
|
||||||
_column_1,
|
_column_1,
|
||||||
_column_8,
|
_column_8,
|
||||||
_column_9,
|
_column_9,
|
||||||
_column_5,
|
_column_5,
|
||||||
|
_column_10,
|
||||||
|
_column_11,
|
||||||
|
_column_12,
|
||||||
|
_column_0,
|
||||||
|
_column_95,
|
||||||
_column_96,
|
_column_96,
|
||||||
|
_column_22,
|
||||||
|
_column_14,
|
||||||
|
_column_23,
|
||||||
],
|
],
|
||||||
attachedDatabase: database,
|
attachedDatabase: database,
|
||||||
),
|
),
|
||||||
|
|
@ -5065,12 +5070,6 @@ final class Schema12 extends i0.VersionedSchema {
|
||||||
|
|
||||||
class Shape23 extends i0.VersionedTable {
|
class Shape23 extends i0.VersionedTable {
|
||||||
Shape23({required super.source, required super.alias}) : super.aliased();
|
Shape23({required super.source, required super.alias}) : super.aliased();
|
||||||
i1.GeneratedColumn<String> get id =>
|
|
||||||
columnsByName['id']! as i1.GeneratedColumn<String>;
|
|
||||||
i1.GeneratedColumn<String> get albumId =>
|
|
||||||
columnsByName['album_id']! as i1.GeneratedColumn<String>;
|
|
||||||
i1.GeneratedColumn<String> get checksum =>
|
|
||||||
columnsByName['checksum']! as i1.GeneratedColumn<String>;
|
|
||||||
i1.GeneratedColumn<String> get name =>
|
i1.GeneratedColumn<String> get name =>
|
||||||
columnsByName['name']! as i1.GeneratedColumn<String>;
|
columnsByName['name']! as i1.GeneratedColumn<String>;
|
||||||
i1.GeneratedColumn<int> get type =>
|
i1.GeneratedColumn<int> get type =>
|
||||||
|
|
@ -5079,8 +5078,24 @@ class Shape23 extends i0.VersionedTable {
|
||||||
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
|
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
|
||||||
i1.GeneratedColumn<DateTime> get updatedAt =>
|
i1.GeneratedColumn<DateTime> get updatedAt =>
|
||||||
columnsByName['updated_at']! as i1.GeneratedColumn<DateTime>;
|
columnsByName['updated_at']! as i1.GeneratedColumn<DateTime>;
|
||||||
i1.GeneratedColumn<int> get size =>
|
i1.GeneratedColumn<int> get width =>
|
||||||
columnsByName['size']! as i1.GeneratedColumn<int>;
|
columnsByName['width']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get height =>
|
||||||
|
columnsByName['height']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<int> get durationInSeconds =>
|
||||||
|
columnsByName['duration_in_seconds']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<String> get id =>
|
||||||
|
columnsByName['id']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<String> get albumId =>
|
||||||
|
columnsByName['album_id']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<String> get volume =>
|
||||||
|
columnsByName['volume']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<String> get checksum =>
|
||||||
|
columnsByName['checksum']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<bool> get isFavorite =>
|
||||||
|
columnsByName['is_favorite']! as i1.GeneratedColumn<bool>;
|
||||||
|
i1.GeneratedColumn<int> get orientation =>
|
||||||
|
columnsByName['orientation']! as i1.GeneratedColumn<int>;
|
||||||
}
|
}
|
||||||
|
|
||||||
i1.GeneratedColumn<String> _column_95(String aliasedName) =>
|
i1.GeneratedColumn<String> _column_95(String aliasedName) =>
|
||||||
|
|
@ -5090,12 +5105,12 @@ i1.GeneratedColumn<String> _column_95(String aliasedName) =>
|
||||||
false,
|
false,
|
||||||
type: i1.DriftSqlType.string,
|
type: i1.DriftSqlType.string,
|
||||||
);
|
);
|
||||||
i1.GeneratedColumn<int> _column_96(String aliasedName) =>
|
i1.GeneratedColumn<String> _column_96(String aliasedName) =>
|
||||||
i1.GeneratedColumn<int>(
|
i1.GeneratedColumn<String>(
|
||||||
'size',
|
'volume',
|
||||||
aliasedName,
|
aliasedName,
|
||||||
true,
|
true,
|
||||||
type: i1.DriftSqlType.int,
|
type: i1.DriftSqlType.string,
|
||||||
);
|
);
|
||||||
i0.MigrationStepWithVersion migrationSteps({
|
i0.MigrationStepWithVersion migrationSteps({
|
||||||
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
|
required Future<void> Function(i1.Migrator m, Schema2 schema) from1To2,
|
||||||
|
|
|
||||||
|
|
@ -5,10 +5,9 @@ import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/local_album.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/local_album.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.drift.dart';
|
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.drift.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/trashed_local_asset.entity.drift.dart';
|
|
||||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||||
|
|
||||||
typedef AssetsByAlbums = Map<String, List<LocalAsset>>;
|
typedef AlbumId = String;
|
||||||
|
|
||||||
class DriftLocalAssetRepository extends DriftDatabaseRepository {
|
class DriftLocalAssetRepository extends DriftDatabaseRepository {
|
||||||
final Drift _db;
|
final Drift _db;
|
||||||
|
|
@ -68,41 +67,6 @@ class DriftLocalAssetRepository extends DriftDatabaseRepository {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> trash(AssetsByAlbums assetsByAlbums) async {
|
|
||||||
if (assetsByAlbums.isEmpty) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
final companions = <TrashedLocalAssetEntityCompanion>[];
|
|
||||||
final idToDelete = <String>{};
|
|
||||||
|
|
||||||
assetsByAlbums.forEach((albumId, assets) {
|
|
||||||
for (final asset in assets) {
|
|
||||||
idToDelete.add(asset.id);
|
|
||||||
companions.add(
|
|
||||||
TrashedLocalAssetEntityCompanion(
|
|
||||||
id: Value(asset.id),
|
|
||||||
name: Value(asset.name),
|
|
||||||
albumId: Value(albumId),
|
|
||||||
checksum: asset.checksum == null ? const Value.absent() : Value(asset.checksum),
|
|
||||||
type: Value(asset.type),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
await _db.transaction(() async {
|
|
||||||
for (final slice in companions.slices(200)) {
|
|
||||||
await _db.batch((batch) {
|
|
||||||
batch.insertAllOnConflictUpdate(_db.trashedLocalAssetEntity, slice);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
for (final slice in idToDelete.slices(800)) {
|
|
||||||
await (_db.delete(_db.localAssetEntity)..where((e) => e.id.isIn(slice))).go();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<LocalAsset?> getById(String id) {
|
Future<LocalAsset?> getById(String id) {
|
||||||
final query = _db.localAssetEntity.select()..where((lae) => lae.id.equals(id));
|
final query = _db.localAssetEntity.select()..where((lae) => lae.id.equals(id));
|
||||||
|
|
||||||
|
|
@ -136,7 +100,7 @@ class DriftLocalAssetRepository extends DriftDatabaseRepository {
|
||||||
return query.map((localAlbum) => localAlbum.toDto()).get();
|
return query.map((localAlbum) => localAlbum.toDto()).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<AssetsByAlbums> getBackupSelectedAssetsByAlbum(Iterable<String> checksums) async {
|
Future<Map<AlbumId, List<LocalAsset>>> getBackupSelectedAssetsByAlbum(Iterable<String> checksums) async {
|
||||||
if (checksums.isEmpty) {
|
if (checksums.isEmpty) {
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,10 +1,13 @@
|
||||||
import 'package:collection/collection.dart';
|
import 'package:collection/collection.dart';
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:immich_mobile/domain/models/album/local_album.model.dart';
|
import 'package:immich_mobile/domain/models/album/local_album.model.dart';
|
||||||
|
import 'package:immich_mobile/domain/models/asset/base_asset.model.dart';
|
||||||
import 'package:immich_mobile/domain/models/asset/trashed_asset.model.dart';
|
import 'package:immich_mobile/domain/models/asset/trashed_asset.model.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/entities/local_asset.entity.drift.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/trashed_local_asset.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/trashed_local_asset.entity.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/trashed_local_asset.entity.drift.dart';
|
import 'package:immich_mobile/infrastructure/entities/trashed_local_asset.entity.drift.dart';
|
||||||
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
import 'package:immich_mobile/infrastructure/repositories/db.repository.dart';
|
||||||
|
import 'package:immich_mobile/infrastructure/repositories/local_asset.repository.dart';
|
||||||
|
|
||||||
class DriftTrashedLocalAssetRepository extends DriftDatabaseRepository {
|
class DriftTrashedLocalAssetRepository extends DriftDatabaseRepository {
|
||||||
final Drift _db;
|
final Drift _db;
|
||||||
|
|
@ -29,10 +32,10 @@ class DriftTrashedLocalAssetRepository extends DriftDatabaseRepository {
|
||||||
|
|
||||||
Future<Iterable<TrashedAsset>> getToHash(String albumId) {
|
Future<Iterable<TrashedAsset>> getToHash(String albumId) {
|
||||||
final query = _db.trashedLocalAssetEntity.select()..where((r) => r.albumId.equals(albumId) & r.checksum.isNull());
|
final query = _db.trashedLocalAssetEntity.select()..where((r) => r.albumId.equals(albumId) & r.checksum.isNull());
|
||||||
return query.map((row) => row.toDto(albumId)).get();
|
return query.map((row) => row.toDto()).get();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<TrashedAsset>> getToRestore() async {
|
Future<Iterable<TrashedAsset>> getToRestore() async {
|
||||||
final trashed = _db.trashedLocalAssetEntity;
|
final trashed = _db.trashedLocalAssetEntity;
|
||||||
final remote = _db.remoteAssetEntity;
|
final remote = _db.remoteAssetEntity;
|
||||||
final album = _db.localAlbumEntity;
|
final album = _db.localAlbumEntity;
|
||||||
|
|
@ -45,10 +48,7 @@ class DriftTrashedLocalAssetRepository extends DriftDatabaseRepository {
|
||||||
innerJoin(remote, remote.checksum.equalsExp(trashed.checksum)),
|
innerJoin(remote, remote.checksum.equalsExp(trashed.checksum)),
|
||||||
])..where(trashed.albumId.isInQuery(selectedAlbumIds) & remote.deletedAt.isNull())).get();
|
])..where(trashed.albumId.isInQuery(selectedAlbumIds) & remote.deletedAt.isNull())).get();
|
||||||
|
|
||||||
return rows.map((result) {
|
return rows.map((result) => result.readTable(trashed).toDto());
|
||||||
final assetData = result.readTable(trashed);
|
|
||||||
return assetData.toDto(assetData.albumId);
|
|
||||||
}).toList();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Applies resulted snapshot of trashed assets:
|
/// Applies resulted snapshot of trashed assets:
|
||||||
|
|
@ -67,12 +67,12 @@ class DriftTrashedLocalAssetRepository extends DriftDatabaseRepository {
|
||||||
(a) => TrashedLocalAssetEntityCompanion.insert(
|
(a) => TrashedLocalAssetEntityCompanion.insert(
|
||||||
id: a.id,
|
id: a.id,
|
||||||
albumId: albumId,
|
albumId: albumId,
|
||||||
|
volume: a.volume == null ? const Value.absent() : Value(a.volume),
|
||||||
checksum: a.checksum == null ? const Value.absent() : Value(a.checksum),
|
checksum: a.checksum == null ? const Value.absent() : Value(a.checksum),
|
||||||
name: a.name,
|
name: a.name,
|
||||||
type: a.type,
|
type: a.type,
|
||||||
createdAt: Value(a.createdAt),
|
createdAt: Value(a.createdAt),
|
||||||
updatedAt: Value(a.updatedAt),
|
updatedAt: Value(a.updatedAt),
|
||||||
size: a.size == null ? const Value.absent() : Value(a.size),
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
@ -102,11 +102,11 @@ class DriftTrashedLocalAssetRepository extends DriftDatabaseRepository {
|
||||||
final companions = trashUpdates.map(
|
final companions = trashUpdates.map(
|
||||||
(a) => TrashedLocalAssetEntityCompanion.insert(
|
(a) => TrashedLocalAssetEntityCompanion.insert(
|
||||||
id: a.id,
|
id: a.id,
|
||||||
|
volume: a.volume == null ? const Value.absent() : Value(a.volume),
|
||||||
albumId: a.albumId,
|
albumId: a.albumId,
|
||||||
name: a.name,
|
name: a.name,
|
||||||
type: a.type,
|
type: a.type,
|
||||||
checksum: a.checksum == null ? const Value.absent() : Value(a.checksum),
|
checksum: a.checksum == null ? const Value.absent() : Value(a.checksum),
|
||||||
size: a.size == null ? const Value.absent() : Value(a.size),
|
|
||||||
createdAt: Value(a.createdAt),
|
createdAt: Value(a.createdAt),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
@ -132,14 +132,80 @@ class DriftTrashedLocalAssetRepository extends DriftDatabaseRepository {
|
||||||
.map((row) => row.read<int>(t.id.count()) ?? 0);
|
.map((row) => row.read<int>(t.id.count()) ?? 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> delete(Iterable<String> ids) {
|
Future<void> trashLocalAsset(Map<AlbumId, List<LocalAsset>> assetsByAlbums) async {
|
||||||
if (ids.isEmpty) {
|
if (assetsByAlbums.isEmpty) {
|
||||||
return Future.value();
|
return;
|
||||||
}
|
}
|
||||||
return _db.batch((batch) {
|
|
||||||
for (final slice in ids.slices(32000)) {
|
final companions = <TrashedLocalAssetEntityCompanion>[];
|
||||||
batch.deleteWhere(_db.trashedLocalAssetEntity, (e) => e.id.isIn(slice));
|
final idToDelete = <String>{};
|
||||||
|
|
||||||
|
assetsByAlbums.forEach((albumId, assets) {
|
||||||
|
for (final asset in assets) {
|
||||||
|
idToDelete.add(asset.id);
|
||||||
|
companions.add(
|
||||||
|
TrashedLocalAssetEntityCompanion(
|
||||||
|
id: Value(asset.id),
|
||||||
|
name: Value(asset.name),
|
||||||
|
albumId: Value(albumId),
|
||||||
|
checksum: asset.checksum == null ? const Value.absent() : Value(asset.checksum),
|
||||||
|
type: Value(asset.type),
|
||||||
|
width: Value(asset.width),
|
||||||
|
height: Value(asset.height),
|
||||||
|
durationInSeconds: Value(asset.durationInSeconds),
|
||||||
|
isFavorite: Value(asset.isFavorite),
|
||||||
|
orientation: Value(asset.orientation),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
await _db.transaction(() async {
|
||||||
|
for (final slice in companions.slices(200)) {
|
||||||
|
await _db.batch((batch) {
|
||||||
|
batch.insertAllOnConflictUpdate(_db.trashedLocalAssetEntity, slice);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
for (final slice in idToDelete.slices(800)) {
|
||||||
|
await (_db.delete(_db.localAssetEntity)..where((e) => e.id.isIn(slice))).go();
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> restoreLocalAssets(Iterable<String> ids) async {
|
||||||
|
if (ids.isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final trashedAssets = await (_db.select(_db.trashedLocalAssetEntity)..where((tbl) => tbl.id.isIn(ids))).get();
|
||||||
|
|
||||||
|
if (trashedAssets.isEmpty) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final localAssets = trashedAssets.map((e) {
|
||||||
|
return LocalAssetEntityCompanion.insert(
|
||||||
|
id: e.id,
|
||||||
|
name: e.name,
|
||||||
|
type: e.type,
|
||||||
|
createdAt: Value(e.createdAt),
|
||||||
|
updatedAt: Value(e.updatedAt),
|
||||||
|
width: Value(e.width),
|
||||||
|
height: Value(e.height),
|
||||||
|
durationInSeconds: Value(e.durationInSeconds),
|
||||||
|
checksum: Value(e.checksum),
|
||||||
|
isFavorite: Value(e.isFavorite),
|
||||||
|
orientation: Value(e.orientation),
|
||||||
|
);
|
||||||
|
}).toList();
|
||||||
|
|
||||||
|
await _db.transaction(() async {
|
||||||
|
await _db.batch((batch) {
|
||||||
|
batch.insertAllOnConflictUpdate(_db.localAssetEntity, localAssets);
|
||||||
|
for (final slice in ids.slices(32000)) {
|
||||||
|
batch.deleteWhere(_db.trashedLocalAssetEntity, (tbl) => tbl.id.isIn(slice));
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
22
mobile/lib/platform/native_sync_api.g.dart
generated
22
mobile/lib/platform/native_sync_api.g.dart
generated
|
|
@ -41,8 +41,8 @@ class PlatformAsset {
|
||||||
required this.durationInSeconds,
|
required this.durationInSeconds,
|
||||||
required this.orientation,
|
required this.orientation,
|
||||||
required this.isFavorite,
|
required this.isFavorite,
|
||||||
required this.isTrashed,
|
this.isTrashed,
|
||||||
this.size,
|
this.volume,
|
||||||
});
|
});
|
||||||
|
|
||||||
String id;
|
String id;
|
||||||
|
|
@ -65,9 +65,9 @@ class PlatformAsset {
|
||||||
|
|
||||||
bool isFavorite;
|
bool isFavorite;
|
||||||
|
|
||||||
bool isTrashed;
|
bool? isTrashed;
|
||||||
|
|
||||||
int? size;
|
String? volume;
|
||||||
|
|
||||||
List<Object?> _toList() {
|
List<Object?> _toList() {
|
||||||
return <Object?>[
|
return <Object?>[
|
||||||
|
|
@ -82,7 +82,7 @@ class PlatformAsset {
|
||||||
orientation,
|
orientation,
|
||||||
isFavorite,
|
isFavorite,
|
||||||
isTrashed,
|
isTrashed,
|
||||||
size,
|
volume,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -103,8 +103,8 @@ class PlatformAsset {
|
||||||
durationInSeconds: result[7]! as int,
|
durationInSeconds: result[7]! as int,
|
||||||
orientation: result[8]! as int,
|
orientation: result[8]! as int,
|
||||||
isFavorite: result[9]! as bool,
|
isFavorite: result[9]! as bool,
|
||||||
isTrashed: result[10]! as bool,
|
isTrashed: result[10] as bool?,
|
||||||
size: result[11] as int?,
|
volume: result[11] as String?,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -391,7 +391,7 @@ class NativeSyncApi {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<SyncDelta> getMediaChanges() async {
|
Future<SyncDelta> getMediaChanges({bool isTrashed = false}) async {
|
||||||
final String pigeonVar_channelName =
|
final String pigeonVar_channelName =
|
||||||
'dev.flutter.pigeon.immich_mobile.NativeSyncApi.getMediaChanges$pigeonVar_messageChannelSuffix';
|
'dev.flutter.pigeon.immich_mobile.NativeSyncApi.getMediaChanges$pigeonVar_messageChannelSuffix';
|
||||||
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
|
|
@ -399,7 +399,7 @@ class NativeSyncApi {
|
||||||
pigeonChannelCodec,
|
pigeonChannelCodec,
|
||||||
binaryMessenger: pigeonVar_binaryMessenger,
|
binaryMessenger: pigeonVar_binaryMessenger,
|
||||||
);
|
);
|
||||||
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(null);
|
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[isTrashed]);
|
||||||
final List<Object?>? pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
final List<Object?>? pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
||||||
if (pigeonVar_replyList == null) {
|
if (pigeonVar_replyList == null) {
|
||||||
throw _createConnectionError(pigeonVar_channelName);
|
throw _createConnectionError(pigeonVar_channelName);
|
||||||
|
|
@ -628,7 +628,7 @@ class NativeSyncApi {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<List<PlatformAsset>> getTrashedAssetsForAlbum(String albumId, {int? updatedTimeCond}) async {
|
Future<List<PlatformAsset>> getTrashedAssetsForAlbum(String albumId) async {
|
||||||
final String pigeonVar_channelName =
|
final String pigeonVar_channelName =
|
||||||
'dev.flutter.pigeon.immich_mobile.NativeSyncApi.getTrashedAssetsForAlbum$pigeonVar_messageChannelSuffix';
|
'dev.flutter.pigeon.immich_mobile.NativeSyncApi.getTrashedAssetsForAlbum$pigeonVar_messageChannelSuffix';
|
||||||
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
final BasicMessageChannel<Object?> pigeonVar_channel = BasicMessageChannel<Object?>(
|
||||||
|
|
@ -636,7 +636,7 @@ class NativeSyncApi {
|
||||||
pigeonChannelCodec,
|
pigeonChannelCodec,
|
||||||
binaryMessenger: pigeonVar_binaryMessenger,
|
binaryMessenger: pigeonVar_binaryMessenger,
|
||||||
);
|
);
|
||||||
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[albumId, updatedTimeCond]);
|
final Future<Object?> pigeonVar_sendFuture = pigeonVar_channel.send(<Object?>[albumId]);
|
||||||
final List<Object?>? pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
final List<Object?>? pigeonVar_replyList = await pigeonVar_sendFuture as List<Object?>?;
|
||||||
if (pigeonVar_replyList == null) {
|
if (pigeonVar_replyList == null) {
|
||||||
throw _createConnectionError(pigeonVar_channelName);
|
throw _createConnectionError(pigeonVar_channelName);
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,8 @@ class PlatformAsset {
|
||||||
final int durationInSeconds;
|
final int durationInSeconds;
|
||||||
final int orientation;
|
final int orientation;
|
||||||
final bool isFavorite;
|
final bool isFavorite;
|
||||||
final bool isTrashed;
|
final bool? isTrashed;
|
||||||
final int? size;
|
final String? volume;
|
||||||
|
|
||||||
const PlatformAsset({
|
const PlatformAsset({
|
||||||
required this.id,
|
required this.id,
|
||||||
|
|
@ -38,8 +38,8 @@ class PlatformAsset {
|
||||||
this.durationInSeconds = 0,
|
this.durationInSeconds = 0,
|
||||||
this.orientation = 0,
|
this.orientation = 0,
|
||||||
this.isFavorite = false,
|
this.isFavorite = false,
|
||||||
this.isTrashed = false,
|
this.isTrashed,
|
||||||
this.size,
|
this.volume,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -100,7 +100,7 @@ abstract class NativeSyncApi {
|
||||||
bool shouldFullSync();
|
bool shouldFullSync();
|
||||||
|
|
||||||
@TaskQueue(type: TaskQueueType.serialBackgroundThread)
|
@TaskQueue(type: TaskQueueType.serialBackgroundThread)
|
||||||
SyncDelta getMediaChanges();
|
SyncDelta getMediaChanges({bool isTrashed = false});
|
||||||
|
|
||||||
void checkpointSync();
|
void checkpointSync();
|
||||||
|
|
||||||
|
|
@ -125,7 +125,7 @@ abstract class NativeSyncApi {
|
||||||
void cancelHashing();
|
void cancelHashing();
|
||||||
|
|
||||||
@TaskQueue(type: TaskQueueType.serialBackgroundThread)
|
@TaskQueue(type: TaskQueueType.serialBackgroundThread)
|
||||||
List<PlatformAsset> getTrashedAssetsForAlbum(String albumId, {int? updatedTimeCond});
|
List<PlatformAsset> getTrashedAssetsForAlbum(String albumId);
|
||||||
|
|
||||||
@async
|
@async
|
||||||
@TaskQueue(type: TaskQueueType.serialBackgroundThread)
|
@TaskQueue(type: TaskQueueType.serialBackgroundThread)
|
||||||
|
|
|
||||||
461
mobile/test/drift/main/generated/schema_v12.dart
generated
461
mobile/test/drift/main/generated/schema_v12.dart
generated
|
|
@ -7119,27 +7119,6 @@ class TrashedLocalAssetEntity extends Table
|
||||||
final GeneratedDatabase attachedDatabase;
|
final GeneratedDatabase attachedDatabase;
|
||||||
final String? _alias;
|
final String? _alias;
|
||||||
TrashedLocalAssetEntity(this.attachedDatabase, [this._alias]);
|
TrashedLocalAssetEntity(this.attachedDatabase, [this._alias]);
|
||||||
late final GeneratedColumn<String> id = GeneratedColumn<String>(
|
|
||||||
'id',
|
|
||||||
aliasedName,
|
|
||||||
false,
|
|
||||||
type: DriftSqlType.string,
|
|
||||||
requiredDuringInsert: true,
|
|
||||||
);
|
|
||||||
late final GeneratedColumn<String> albumId = GeneratedColumn<String>(
|
|
||||||
'album_id',
|
|
||||||
aliasedName,
|
|
||||||
false,
|
|
||||||
type: DriftSqlType.string,
|
|
||||||
requiredDuringInsert: true,
|
|
||||||
);
|
|
||||||
late final GeneratedColumn<String> checksum = GeneratedColumn<String>(
|
|
||||||
'checksum',
|
|
||||||
aliasedName,
|
|
||||||
true,
|
|
||||||
type: DriftSqlType.string,
|
|
||||||
requiredDuringInsert: false,
|
|
||||||
);
|
|
||||||
late final GeneratedColumn<String> name = GeneratedColumn<String>(
|
late final GeneratedColumn<String> name = GeneratedColumn<String>(
|
||||||
'name',
|
'name',
|
||||||
aliasedName,
|
aliasedName,
|
||||||
|
|
@ -7170,23 +7149,89 @@ class TrashedLocalAssetEntity extends Table
|
||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
defaultValue: const CustomExpression('CURRENT_TIMESTAMP'),
|
defaultValue: const CustomExpression('CURRENT_TIMESTAMP'),
|
||||||
);
|
);
|
||||||
late final GeneratedColumn<int> size = GeneratedColumn<int>(
|
late final GeneratedColumn<int> width = GeneratedColumn<int>(
|
||||||
'size',
|
'width',
|
||||||
aliasedName,
|
aliasedName,
|
||||||
true,
|
true,
|
||||||
type: DriftSqlType.int,
|
type: DriftSqlType.int,
|
||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
);
|
);
|
||||||
|
late final GeneratedColumn<int> height = GeneratedColumn<int>(
|
||||||
|
'height',
|
||||||
|
aliasedName,
|
||||||
|
true,
|
||||||
|
type: DriftSqlType.int,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
);
|
||||||
|
late final GeneratedColumn<int> durationInSeconds = GeneratedColumn<int>(
|
||||||
|
'duration_in_seconds',
|
||||||
|
aliasedName,
|
||||||
|
true,
|
||||||
|
type: DriftSqlType.int,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
);
|
||||||
|
late final GeneratedColumn<String> id = GeneratedColumn<String>(
|
||||||
|
'id',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: DriftSqlType.string,
|
||||||
|
requiredDuringInsert: true,
|
||||||
|
);
|
||||||
|
late final GeneratedColumn<String> albumId = GeneratedColumn<String>(
|
||||||
|
'album_id',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: DriftSqlType.string,
|
||||||
|
requiredDuringInsert: true,
|
||||||
|
);
|
||||||
|
late final GeneratedColumn<String> volume = GeneratedColumn<String>(
|
||||||
|
'volume',
|
||||||
|
aliasedName,
|
||||||
|
true,
|
||||||
|
type: DriftSqlType.string,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
);
|
||||||
|
late final GeneratedColumn<String> checksum = GeneratedColumn<String>(
|
||||||
|
'checksum',
|
||||||
|
aliasedName,
|
||||||
|
true,
|
||||||
|
type: DriftSqlType.string,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
);
|
||||||
|
late final GeneratedColumn<bool> isFavorite = GeneratedColumn<bool>(
|
||||||
|
'is_favorite',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: DriftSqlType.bool,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
defaultConstraints: GeneratedColumn.constraintIsAlways(
|
||||||
|
'CHECK ("is_favorite" IN (0, 1))',
|
||||||
|
),
|
||||||
|
defaultValue: const CustomExpression('0'),
|
||||||
|
);
|
||||||
|
late final GeneratedColumn<int> orientation = GeneratedColumn<int>(
|
||||||
|
'orientation',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: DriftSqlType.int,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
defaultValue: const CustomExpression('0'),
|
||||||
|
);
|
||||||
@override
|
@override
|
||||||
List<GeneratedColumn> get $columns => [
|
List<GeneratedColumn> get $columns => [
|
||||||
id,
|
|
||||||
albumId,
|
|
||||||
checksum,
|
|
||||||
name,
|
name,
|
||||||
type,
|
type,
|
||||||
createdAt,
|
createdAt,
|
||||||
updatedAt,
|
updatedAt,
|
||||||
size,
|
width,
|
||||||
|
height,
|
||||||
|
durationInSeconds,
|
||||||
|
id,
|
||||||
|
albumId,
|
||||||
|
volume,
|
||||||
|
checksum,
|
||||||
|
isFavorite,
|
||||||
|
orientation,
|
||||||
];
|
];
|
||||||
@override
|
@override
|
||||||
String get aliasedName => _alias ?? actualTableName;
|
String get aliasedName => _alias ?? actualTableName;
|
||||||
|
|
@ -7194,7 +7239,7 @@ class TrashedLocalAssetEntity extends Table
|
||||||
String get actualTableName => $name;
|
String get actualTableName => $name;
|
||||||
static const String $name = 'trashed_local_asset_entity';
|
static const String $name = 'trashed_local_asset_entity';
|
||||||
@override
|
@override
|
||||||
Set<GeneratedColumn> get $primaryKey => {id};
|
Set<GeneratedColumn> get $primaryKey => {id, albumId};
|
||||||
@override
|
@override
|
||||||
TrashedLocalAssetEntityData map(
|
TrashedLocalAssetEntityData map(
|
||||||
Map<String, dynamic> data, {
|
Map<String, dynamic> data, {
|
||||||
|
|
@ -7202,18 +7247,6 @@ class TrashedLocalAssetEntity extends Table
|
||||||
}) {
|
}) {
|
||||||
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
|
final effectivePrefix = tablePrefix != null ? '$tablePrefix.' : '';
|
||||||
return TrashedLocalAssetEntityData(
|
return TrashedLocalAssetEntityData(
|
||||||
id: attachedDatabase.typeMapping.read(
|
|
||||||
DriftSqlType.string,
|
|
||||||
data['${effectivePrefix}id'],
|
|
||||||
)!,
|
|
||||||
albumId: attachedDatabase.typeMapping.read(
|
|
||||||
DriftSqlType.string,
|
|
||||||
data['${effectivePrefix}album_id'],
|
|
||||||
)!,
|
|
||||||
checksum: attachedDatabase.typeMapping.read(
|
|
||||||
DriftSqlType.string,
|
|
||||||
data['${effectivePrefix}checksum'],
|
|
||||||
),
|
|
||||||
name: attachedDatabase.typeMapping.read(
|
name: attachedDatabase.typeMapping.read(
|
||||||
DriftSqlType.string,
|
DriftSqlType.string,
|
||||||
data['${effectivePrefix}name'],
|
data['${effectivePrefix}name'],
|
||||||
|
|
@ -7230,10 +7263,42 @@ class TrashedLocalAssetEntity extends Table
|
||||||
DriftSqlType.dateTime,
|
DriftSqlType.dateTime,
|
||||||
data['${effectivePrefix}updated_at'],
|
data['${effectivePrefix}updated_at'],
|
||||||
)!,
|
)!,
|
||||||
size: attachedDatabase.typeMapping.read(
|
width: attachedDatabase.typeMapping.read(
|
||||||
DriftSqlType.int,
|
DriftSqlType.int,
|
||||||
data['${effectivePrefix}size'],
|
data['${effectivePrefix}width'],
|
||||||
),
|
),
|
||||||
|
height: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.int,
|
||||||
|
data['${effectivePrefix}height'],
|
||||||
|
),
|
||||||
|
durationInSeconds: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.int,
|
||||||
|
data['${effectivePrefix}duration_in_seconds'],
|
||||||
|
),
|
||||||
|
id: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}id'],
|
||||||
|
)!,
|
||||||
|
albumId: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}album_id'],
|
||||||
|
)!,
|
||||||
|
volume: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}volume'],
|
||||||
|
),
|
||||||
|
checksum: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.string,
|
||||||
|
data['${effectivePrefix}checksum'],
|
||||||
|
),
|
||||||
|
isFavorite: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.bool,
|
||||||
|
data['${effectivePrefix}is_favorite'],
|
||||||
|
)!,
|
||||||
|
orientation: attachedDatabase.typeMapping.read(
|
||||||
|
DriftSqlType.int,
|
||||||
|
data['${effectivePrefix}orientation'],
|
||||||
|
)!,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -7250,39 +7315,60 @@ class TrashedLocalAssetEntity extends Table
|
||||||
|
|
||||||
class TrashedLocalAssetEntityData extends DataClass
|
class TrashedLocalAssetEntityData extends DataClass
|
||||||
implements Insertable<TrashedLocalAssetEntityData> {
|
implements Insertable<TrashedLocalAssetEntityData> {
|
||||||
final String id;
|
|
||||||
final String albumId;
|
|
||||||
final String? checksum;
|
|
||||||
final String name;
|
final String name;
|
||||||
final int type;
|
final int type;
|
||||||
final DateTime createdAt;
|
final DateTime createdAt;
|
||||||
final DateTime updatedAt;
|
final DateTime updatedAt;
|
||||||
final int? size;
|
final int? width;
|
||||||
|
final int? height;
|
||||||
|
final int? durationInSeconds;
|
||||||
|
final String id;
|
||||||
|
final String albumId;
|
||||||
|
final String? volume;
|
||||||
|
final String? checksum;
|
||||||
|
final bool isFavorite;
|
||||||
|
final int orientation;
|
||||||
const TrashedLocalAssetEntityData({
|
const TrashedLocalAssetEntityData({
|
||||||
required this.id,
|
|
||||||
required this.albumId,
|
|
||||||
this.checksum,
|
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.type,
|
required this.type,
|
||||||
required this.createdAt,
|
required this.createdAt,
|
||||||
required this.updatedAt,
|
required this.updatedAt,
|
||||||
this.size,
|
this.width,
|
||||||
|
this.height,
|
||||||
|
this.durationInSeconds,
|
||||||
|
required this.id,
|
||||||
|
required this.albumId,
|
||||||
|
this.volume,
|
||||||
|
this.checksum,
|
||||||
|
required this.isFavorite,
|
||||||
|
required this.orientation,
|
||||||
});
|
});
|
||||||
@override
|
@override
|
||||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||||
final map = <String, Expression>{};
|
final map = <String, Expression>{};
|
||||||
map['id'] = Variable<String>(id);
|
|
||||||
map['album_id'] = Variable<String>(albumId);
|
|
||||||
if (!nullToAbsent || checksum != null) {
|
|
||||||
map['checksum'] = Variable<String>(checksum);
|
|
||||||
}
|
|
||||||
map['name'] = Variable<String>(name);
|
map['name'] = Variable<String>(name);
|
||||||
map['type'] = Variable<int>(type);
|
map['type'] = Variable<int>(type);
|
||||||
map['created_at'] = Variable<DateTime>(createdAt);
|
map['created_at'] = Variable<DateTime>(createdAt);
|
||||||
map['updated_at'] = Variable<DateTime>(updatedAt);
|
map['updated_at'] = Variable<DateTime>(updatedAt);
|
||||||
if (!nullToAbsent || size != null) {
|
if (!nullToAbsent || width != null) {
|
||||||
map['size'] = Variable<int>(size);
|
map['width'] = Variable<int>(width);
|
||||||
}
|
}
|
||||||
|
if (!nullToAbsent || height != null) {
|
||||||
|
map['height'] = Variable<int>(height);
|
||||||
|
}
|
||||||
|
if (!nullToAbsent || durationInSeconds != null) {
|
||||||
|
map['duration_in_seconds'] = Variable<int>(durationInSeconds);
|
||||||
|
}
|
||||||
|
map['id'] = Variable<String>(id);
|
||||||
|
map['album_id'] = Variable<String>(albumId);
|
||||||
|
if (!nullToAbsent || volume != null) {
|
||||||
|
map['volume'] = Variable<String>(volume);
|
||||||
|
}
|
||||||
|
if (!nullToAbsent || checksum != null) {
|
||||||
|
map['checksum'] = Variable<String>(checksum);
|
||||||
|
}
|
||||||
|
map['is_favorite'] = Variable<bool>(isFavorite);
|
||||||
|
map['orientation'] = Variable<int>(orientation);
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -7292,194 +7378,268 @@ class TrashedLocalAssetEntityData extends DataClass
|
||||||
}) {
|
}) {
|
||||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||||
return TrashedLocalAssetEntityData(
|
return TrashedLocalAssetEntityData(
|
||||||
id: serializer.fromJson<String>(json['id']),
|
|
||||||
albumId: serializer.fromJson<String>(json['albumId']),
|
|
||||||
checksum: serializer.fromJson<String?>(json['checksum']),
|
|
||||||
name: serializer.fromJson<String>(json['name']),
|
name: serializer.fromJson<String>(json['name']),
|
||||||
type: serializer.fromJson<int>(json['type']),
|
type: serializer.fromJson<int>(json['type']),
|
||||||
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
|
createdAt: serializer.fromJson<DateTime>(json['createdAt']),
|
||||||
updatedAt: serializer.fromJson<DateTime>(json['updatedAt']),
|
updatedAt: serializer.fromJson<DateTime>(json['updatedAt']),
|
||||||
size: serializer.fromJson<int?>(json['size']),
|
width: serializer.fromJson<int?>(json['width']),
|
||||||
|
height: serializer.fromJson<int?>(json['height']),
|
||||||
|
durationInSeconds: serializer.fromJson<int?>(json['durationInSeconds']),
|
||||||
|
id: serializer.fromJson<String>(json['id']),
|
||||||
|
albumId: serializer.fromJson<String>(json['albumId']),
|
||||||
|
volume: serializer.fromJson<String?>(json['volume']),
|
||||||
|
checksum: serializer.fromJson<String?>(json['checksum']),
|
||||||
|
isFavorite: serializer.fromJson<bool>(json['isFavorite']),
|
||||||
|
orientation: serializer.fromJson<int>(json['orientation']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@override
|
@override
|
||||||
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
|
Map<String, dynamic> toJson({ValueSerializer? serializer}) {
|
||||||
serializer ??= driftRuntimeOptions.defaultSerializer;
|
serializer ??= driftRuntimeOptions.defaultSerializer;
|
||||||
return <String, dynamic>{
|
return <String, dynamic>{
|
||||||
'id': serializer.toJson<String>(id),
|
|
||||||
'albumId': serializer.toJson<String>(albumId),
|
|
||||||
'checksum': serializer.toJson<String?>(checksum),
|
|
||||||
'name': serializer.toJson<String>(name),
|
'name': serializer.toJson<String>(name),
|
||||||
'type': serializer.toJson<int>(type),
|
'type': serializer.toJson<int>(type),
|
||||||
'createdAt': serializer.toJson<DateTime>(createdAt),
|
'createdAt': serializer.toJson<DateTime>(createdAt),
|
||||||
'updatedAt': serializer.toJson<DateTime>(updatedAt),
|
'updatedAt': serializer.toJson<DateTime>(updatedAt),
|
||||||
'size': serializer.toJson<int?>(size),
|
'width': serializer.toJson<int?>(width),
|
||||||
|
'height': serializer.toJson<int?>(height),
|
||||||
|
'durationInSeconds': serializer.toJson<int?>(durationInSeconds),
|
||||||
|
'id': serializer.toJson<String>(id),
|
||||||
|
'albumId': serializer.toJson<String>(albumId),
|
||||||
|
'volume': serializer.toJson<String?>(volume),
|
||||||
|
'checksum': serializer.toJson<String?>(checksum),
|
||||||
|
'isFavorite': serializer.toJson<bool>(isFavorite),
|
||||||
|
'orientation': serializer.toJson<int>(orientation),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
TrashedLocalAssetEntityData copyWith({
|
TrashedLocalAssetEntityData copyWith({
|
||||||
String? id,
|
|
||||||
String? albumId,
|
|
||||||
Value<String?> checksum = const Value.absent(),
|
|
||||||
String? name,
|
String? name,
|
||||||
int? type,
|
int? type,
|
||||||
DateTime? createdAt,
|
DateTime? createdAt,
|
||||||
DateTime? updatedAt,
|
DateTime? updatedAt,
|
||||||
Value<int?> size = const Value.absent(),
|
Value<int?> width = const Value.absent(),
|
||||||
|
Value<int?> height = const Value.absent(),
|
||||||
|
Value<int?> durationInSeconds = const Value.absent(),
|
||||||
|
String? id,
|
||||||
|
String? albumId,
|
||||||
|
Value<String?> volume = const Value.absent(),
|
||||||
|
Value<String?> checksum = const Value.absent(),
|
||||||
|
bool? isFavorite,
|
||||||
|
int? orientation,
|
||||||
}) => TrashedLocalAssetEntityData(
|
}) => TrashedLocalAssetEntityData(
|
||||||
id: id ?? this.id,
|
|
||||||
albumId: albumId ?? this.albumId,
|
|
||||||
checksum: checksum.present ? checksum.value : this.checksum,
|
|
||||||
name: name ?? this.name,
|
name: name ?? this.name,
|
||||||
type: type ?? this.type,
|
type: type ?? this.type,
|
||||||
createdAt: createdAt ?? this.createdAt,
|
createdAt: createdAt ?? this.createdAt,
|
||||||
updatedAt: updatedAt ?? this.updatedAt,
|
updatedAt: updatedAt ?? this.updatedAt,
|
||||||
size: size.present ? size.value : this.size,
|
width: width.present ? width.value : this.width,
|
||||||
|
height: height.present ? height.value : this.height,
|
||||||
|
durationInSeconds: durationInSeconds.present
|
||||||
|
? durationInSeconds.value
|
||||||
|
: this.durationInSeconds,
|
||||||
|
id: id ?? this.id,
|
||||||
|
albumId: albumId ?? this.albumId,
|
||||||
|
volume: volume.present ? volume.value : this.volume,
|
||||||
|
checksum: checksum.present ? checksum.value : this.checksum,
|
||||||
|
isFavorite: isFavorite ?? this.isFavorite,
|
||||||
|
orientation: orientation ?? this.orientation,
|
||||||
);
|
);
|
||||||
TrashedLocalAssetEntityData copyWithCompanion(
|
TrashedLocalAssetEntityData copyWithCompanion(
|
||||||
TrashedLocalAssetEntityCompanion data,
|
TrashedLocalAssetEntityCompanion data,
|
||||||
) {
|
) {
|
||||||
return TrashedLocalAssetEntityData(
|
return TrashedLocalAssetEntityData(
|
||||||
id: data.id.present ? data.id.value : this.id,
|
|
||||||
albumId: data.albumId.present ? data.albumId.value : this.albumId,
|
|
||||||
checksum: data.checksum.present ? data.checksum.value : this.checksum,
|
|
||||||
name: data.name.present ? data.name.value : this.name,
|
name: data.name.present ? data.name.value : this.name,
|
||||||
type: data.type.present ? data.type.value : this.type,
|
type: data.type.present ? data.type.value : this.type,
|
||||||
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
|
createdAt: data.createdAt.present ? data.createdAt.value : this.createdAt,
|
||||||
updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt,
|
updatedAt: data.updatedAt.present ? data.updatedAt.value : this.updatedAt,
|
||||||
size: data.size.present ? data.size.value : this.size,
|
width: data.width.present ? data.width.value : this.width,
|
||||||
|
height: data.height.present ? data.height.value : this.height,
|
||||||
|
durationInSeconds: data.durationInSeconds.present
|
||||||
|
? data.durationInSeconds.value
|
||||||
|
: this.durationInSeconds,
|
||||||
|
id: data.id.present ? data.id.value : this.id,
|
||||||
|
albumId: data.albumId.present ? data.albumId.value : this.albumId,
|
||||||
|
volume: data.volume.present ? data.volume.value : this.volume,
|
||||||
|
checksum: data.checksum.present ? data.checksum.value : this.checksum,
|
||||||
|
isFavorite: data.isFavorite.present
|
||||||
|
? data.isFavorite.value
|
||||||
|
: this.isFavorite,
|
||||||
|
orientation: data.orientation.present
|
||||||
|
? data.orientation.value
|
||||||
|
: this.orientation,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return (StringBuffer('TrashedLocalAssetEntityData(')
|
return (StringBuffer('TrashedLocalAssetEntityData(')
|
||||||
..write('id: $id, ')
|
|
||||||
..write('albumId: $albumId, ')
|
|
||||||
..write('checksum: $checksum, ')
|
|
||||||
..write('name: $name, ')
|
..write('name: $name, ')
|
||||||
..write('type: $type, ')
|
..write('type: $type, ')
|
||||||
..write('createdAt: $createdAt, ')
|
..write('createdAt: $createdAt, ')
|
||||||
..write('updatedAt: $updatedAt, ')
|
..write('updatedAt: $updatedAt, ')
|
||||||
..write('size: $size')
|
..write('width: $width, ')
|
||||||
|
..write('height: $height, ')
|
||||||
|
..write('durationInSeconds: $durationInSeconds, ')
|
||||||
|
..write('id: $id, ')
|
||||||
|
..write('albumId: $albumId, ')
|
||||||
|
..write('volume: $volume, ')
|
||||||
|
..write('checksum: $checksum, ')
|
||||||
|
..write('isFavorite: $isFavorite, ')
|
||||||
|
..write('orientation: $orientation')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => Object.hash(
|
int get hashCode => Object.hash(
|
||||||
id,
|
|
||||||
albumId,
|
|
||||||
checksum,
|
|
||||||
name,
|
name,
|
||||||
type,
|
type,
|
||||||
createdAt,
|
createdAt,
|
||||||
updatedAt,
|
updatedAt,
|
||||||
size,
|
width,
|
||||||
|
height,
|
||||||
|
durationInSeconds,
|
||||||
|
id,
|
||||||
|
albumId,
|
||||||
|
volume,
|
||||||
|
checksum,
|
||||||
|
isFavorite,
|
||||||
|
orientation,
|
||||||
);
|
);
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
identical(this, other) ||
|
identical(this, other) ||
|
||||||
(other is TrashedLocalAssetEntityData &&
|
(other is TrashedLocalAssetEntityData &&
|
||||||
other.id == this.id &&
|
|
||||||
other.albumId == this.albumId &&
|
|
||||||
other.checksum == this.checksum &&
|
|
||||||
other.name == this.name &&
|
other.name == this.name &&
|
||||||
other.type == this.type &&
|
other.type == this.type &&
|
||||||
other.createdAt == this.createdAt &&
|
other.createdAt == this.createdAt &&
|
||||||
other.updatedAt == this.updatedAt &&
|
other.updatedAt == this.updatedAt &&
|
||||||
other.size == this.size);
|
other.width == this.width &&
|
||||||
|
other.height == this.height &&
|
||||||
|
other.durationInSeconds == this.durationInSeconds &&
|
||||||
|
other.id == this.id &&
|
||||||
|
other.albumId == this.albumId &&
|
||||||
|
other.volume == this.volume &&
|
||||||
|
other.checksum == this.checksum &&
|
||||||
|
other.isFavorite == this.isFavorite &&
|
||||||
|
other.orientation == this.orientation);
|
||||||
}
|
}
|
||||||
|
|
||||||
class TrashedLocalAssetEntityCompanion
|
class TrashedLocalAssetEntityCompanion
|
||||||
extends UpdateCompanion<TrashedLocalAssetEntityData> {
|
extends UpdateCompanion<TrashedLocalAssetEntityData> {
|
||||||
final Value<String> id;
|
|
||||||
final Value<String> albumId;
|
|
||||||
final Value<String?> checksum;
|
|
||||||
final Value<String> name;
|
final Value<String> name;
|
||||||
final Value<int> type;
|
final Value<int> type;
|
||||||
final Value<DateTime> createdAt;
|
final Value<DateTime> createdAt;
|
||||||
final Value<DateTime> updatedAt;
|
final Value<DateTime> updatedAt;
|
||||||
final Value<int?> size;
|
final Value<int?> width;
|
||||||
|
final Value<int?> height;
|
||||||
|
final Value<int?> durationInSeconds;
|
||||||
|
final Value<String> id;
|
||||||
|
final Value<String> albumId;
|
||||||
|
final Value<String?> volume;
|
||||||
|
final Value<String?> checksum;
|
||||||
|
final Value<bool> isFavorite;
|
||||||
|
final Value<int> orientation;
|
||||||
const TrashedLocalAssetEntityCompanion({
|
const TrashedLocalAssetEntityCompanion({
|
||||||
this.id = const Value.absent(),
|
|
||||||
this.albumId = const Value.absent(),
|
|
||||||
this.checksum = const Value.absent(),
|
|
||||||
this.name = const Value.absent(),
|
this.name = const Value.absent(),
|
||||||
this.type = const Value.absent(),
|
this.type = const Value.absent(),
|
||||||
this.createdAt = const Value.absent(),
|
this.createdAt = const Value.absent(),
|
||||||
this.updatedAt = const Value.absent(),
|
this.updatedAt = const Value.absent(),
|
||||||
this.size = const Value.absent(),
|
this.width = const Value.absent(),
|
||||||
|
this.height = const Value.absent(),
|
||||||
|
this.durationInSeconds = const Value.absent(),
|
||||||
|
this.id = const Value.absent(),
|
||||||
|
this.albumId = const Value.absent(),
|
||||||
|
this.volume = const Value.absent(),
|
||||||
|
this.checksum = const Value.absent(),
|
||||||
|
this.isFavorite = const Value.absent(),
|
||||||
|
this.orientation = const Value.absent(),
|
||||||
});
|
});
|
||||||
TrashedLocalAssetEntityCompanion.insert({
|
TrashedLocalAssetEntityCompanion.insert({
|
||||||
required String id,
|
|
||||||
required String albumId,
|
|
||||||
this.checksum = const Value.absent(),
|
|
||||||
required String name,
|
required String name,
|
||||||
required int type,
|
required int type,
|
||||||
this.createdAt = const Value.absent(),
|
this.createdAt = const Value.absent(),
|
||||||
this.updatedAt = const Value.absent(),
|
this.updatedAt = const Value.absent(),
|
||||||
this.size = const Value.absent(),
|
this.width = const Value.absent(),
|
||||||
}) : id = Value(id),
|
this.height = const Value.absent(),
|
||||||
albumId = Value(albumId),
|
this.durationInSeconds = const Value.absent(),
|
||||||
name = Value(name),
|
required String id,
|
||||||
type = Value(type);
|
required String albumId,
|
||||||
|
this.volume = const Value.absent(),
|
||||||
|
this.checksum = const Value.absent(),
|
||||||
|
this.isFavorite = const Value.absent(),
|
||||||
|
this.orientation = const Value.absent(),
|
||||||
|
}) : name = Value(name),
|
||||||
|
type = Value(type),
|
||||||
|
id = Value(id),
|
||||||
|
albumId = Value(albumId);
|
||||||
static Insertable<TrashedLocalAssetEntityData> custom({
|
static Insertable<TrashedLocalAssetEntityData> custom({
|
||||||
Expression<String>? id,
|
|
||||||
Expression<String>? albumId,
|
|
||||||
Expression<String>? checksum,
|
|
||||||
Expression<String>? name,
|
Expression<String>? name,
|
||||||
Expression<int>? type,
|
Expression<int>? type,
|
||||||
Expression<DateTime>? createdAt,
|
Expression<DateTime>? createdAt,
|
||||||
Expression<DateTime>? updatedAt,
|
Expression<DateTime>? updatedAt,
|
||||||
Expression<int>? size,
|
Expression<int>? width,
|
||||||
|
Expression<int>? height,
|
||||||
|
Expression<int>? durationInSeconds,
|
||||||
|
Expression<String>? id,
|
||||||
|
Expression<String>? albumId,
|
||||||
|
Expression<String>? volume,
|
||||||
|
Expression<String>? checksum,
|
||||||
|
Expression<bool>? isFavorite,
|
||||||
|
Expression<int>? orientation,
|
||||||
}) {
|
}) {
|
||||||
return RawValuesInsertable({
|
return RawValuesInsertable({
|
||||||
if (id != null) 'id': id,
|
|
||||||
if (albumId != null) 'album_id': albumId,
|
|
||||||
if (checksum != null) 'checksum': checksum,
|
|
||||||
if (name != null) 'name': name,
|
if (name != null) 'name': name,
|
||||||
if (type != null) 'type': type,
|
if (type != null) 'type': type,
|
||||||
if (createdAt != null) 'created_at': createdAt,
|
if (createdAt != null) 'created_at': createdAt,
|
||||||
if (updatedAt != null) 'updated_at': updatedAt,
|
if (updatedAt != null) 'updated_at': updatedAt,
|
||||||
if (size != null) 'size': size,
|
if (width != null) 'width': width,
|
||||||
|
if (height != null) 'height': height,
|
||||||
|
if (durationInSeconds != null) 'duration_in_seconds': durationInSeconds,
|
||||||
|
if (id != null) 'id': id,
|
||||||
|
if (albumId != null) 'album_id': albumId,
|
||||||
|
if (volume != null) 'volume': volume,
|
||||||
|
if (checksum != null) 'checksum': checksum,
|
||||||
|
if (isFavorite != null) 'is_favorite': isFavorite,
|
||||||
|
if (orientation != null) 'orientation': orientation,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
TrashedLocalAssetEntityCompanion copyWith({
|
TrashedLocalAssetEntityCompanion copyWith({
|
||||||
Value<String>? id,
|
|
||||||
Value<String>? albumId,
|
|
||||||
Value<String?>? checksum,
|
|
||||||
Value<String>? name,
|
Value<String>? name,
|
||||||
Value<int>? type,
|
Value<int>? type,
|
||||||
Value<DateTime>? createdAt,
|
Value<DateTime>? createdAt,
|
||||||
Value<DateTime>? updatedAt,
|
Value<DateTime>? updatedAt,
|
||||||
Value<int?>? size,
|
Value<int?>? width,
|
||||||
|
Value<int?>? height,
|
||||||
|
Value<int?>? durationInSeconds,
|
||||||
|
Value<String>? id,
|
||||||
|
Value<String>? albumId,
|
||||||
|
Value<String?>? volume,
|
||||||
|
Value<String?>? checksum,
|
||||||
|
Value<bool>? isFavorite,
|
||||||
|
Value<int>? orientation,
|
||||||
}) {
|
}) {
|
||||||
return TrashedLocalAssetEntityCompanion(
|
return TrashedLocalAssetEntityCompanion(
|
||||||
id: id ?? this.id,
|
|
||||||
albumId: albumId ?? this.albumId,
|
|
||||||
checksum: checksum ?? this.checksum,
|
|
||||||
name: name ?? this.name,
|
name: name ?? this.name,
|
||||||
type: type ?? this.type,
|
type: type ?? this.type,
|
||||||
createdAt: createdAt ?? this.createdAt,
|
createdAt: createdAt ?? this.createdAt,
|
||||||
updatedAt: updatedAt ?? this.updatedAt,
|
updatedAt: updatedAt ?? this.updatedAt,
|
||||||
size: size ?? this.size,
|
width: width ?? this.width,
|
||||||
|
height: height ?? this.height,
|
||||||
|
durationInSeconds: durationInSeconds ?? this.durationInSeconds,
|
||||||
|
id: id ?? this.id,
|
||||||
|
albumId: albumId ?? this.albumId,
|
||||||
|
volume: volume ?? this.volume,
|
||||||
|
checksum: checksum ?? this.checksum,
|
||||||
|
isFavorite: isFavorite ?? this.isFavorite,
|
||||||
|
orientation: orientation ?? this.orientation,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Map<String, Expression> toColumns(bool nullToAbsent) {
|
Map<String, Expression> toColumns(bool nullToAbsent) {
|
||||||
final map = <String, Expression>{};
|
final map = <String, Expression>{};
|
||||||
if (id.present) {
|
|
||||||
map['id'] = Variable<String>(id.value);
|
|
||||||
}
|
|
||||||
if (albumId.present) {
|
|
||||||
map['album_id'] = Variable<String>(albumId.value);
|
|
||||||
}
|
|
||||||
if (checksum.present) {
|
|
||||||
map['checksum'] = Variable<String>(checksum.value);
|
|
||||||
}
|
|
||||||
if (name.present) {
|
if (name.present) {
|
||||||
map['name'] = Variable<String>(name.value);
|
map['name'] = Variable<String>(name.value);
|
||||||
}
|
}
|
||||||
|
|
@ -7492,8 +7652,32 @@ class TrashedLocalAssetEntityCompanion
|
||||||
if (updatedAt.present) {
|
if (updatedAt.present) {
|
||||||
map['updated_at'] = Variable<DateTime>(updatedAt.value);
|
map['updated_at'] = Variable<DateTime>(updatedAt.value);
|
||||||
}
|
}
|
||||||
if (size.present) {
|
if (width.present) {
|
||||||
map['size'] = Variable<int>(size.value);
|
map['width'] = Variable<int>(width.value);
|
||||||
|
}
|
||||||
|
if (height.present) {
|
||||||
|
map['height'] = Variable<int>(height.value);
|
||||||
|
}
|
||||||
|
if (durationInSeconds.present) {
|
||||||
|
map['duration_in_seconds'] = Variable<int>(durationInSeconds.value);
|
||||||
|
}
|
||||||
|
if (id.present) {
|
||||||
|
map['id'] = Variable<String>(id.value);
|
||||||
|
}
|
||||||
|
if (albumId.present) {
|
||||||
|
map['album_id'] = Variable<String>(albumId.value);
|
||||||
|
}
|
||||||
|
if (volume.present) {
|
||||||
|
map['volume'] = Variable<String>(volume.value);
|
||||||
|
}
|
||||||
|
if (checksum.present) {
|
||||||
|
map['checksum'] = Variable<String>(checksum.value);
|
||||||
|
}
|
||||||
|
if (isFavorite.present) {
|
||||||
|
map['is_favorite'] = Variable<bool>(isFavorite.value);
|
||||||
|
}
|
||||||
|
if (orientation.present) {
|
||||||
|
map['orientation'] = Variable<int>(orientation.value);
|
||||||
}
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
@ -7501,14 +7685,19 @@ class TrashedLocalAssetEntityCompanion
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
return (StringBuffer('TrashedLocalAssetEntityCompanion(')
|
return (StringBuffer('TrashedLocalAssetEntityCompanion(')
|
||||||
..write('id: $id, ')
|
|
||||||
..write('albumId: $albumId, ')
|
|
||||||
..write('checksum: $checksum, ')
|
|
||||||
..write('name: $name, ')
|
..write('name: $name, ')
|
||||||
..write('type: $type, ')
|
..write('type: $type, ')
|
||||||
..write('createdAt: $createdAt, ')
|
..write('createdAt: $createdAt, ')
|
||||||
..write('updatedAt: $updatedAt, ')
|
..write('updatedAt: $updatedAt, ')
|
||||||
..write('size: $size')
|
..write('width: $width, ')
|
||||||
|
..write('height: $height, ')
|
||||||
|
..write('durationInSeconds: $durationInSeconds, ')
|
||||||
|
..write('id: $id, ')
|
||||||
|
..write('albumId: $albumId, ')
|
||||||
|
..write('volume: $volume, ')
|
||||||
|
..write('checksum: $checksum, ')
|
||||||
|
..write('isFavorite: $isFavorite, ')
|
||||||
|
..write('orientation: $orientation')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue