mirror of
https://github.com/immich-app/immich.git
synced 2025-10-22 22:39:01 -04:00
more fixes
This commit is contained in:
parent
254ca4a13d
commit
9cf5d83707
@ -1,5 +1,3 @@
|
|||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
enum RemoteAssetMetadataKey {
|
enum RemoteAssetMetadataKey {
|
||||||
mobileApp("mobile-app");
|
mobileApp("mobile-app");
|
||||||
|
|
||||||
@ -8,25 +6,30 @@ enum RemoteAssetMetadataKey {
|
|||||||
const RemoteAssetMetadataKey(this.key);
|
const RemoteAssetMetadataKey(this.key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
abstract class RemoteAssetMetadataValue {
|
||||||
|
const RemoteAssetMetadataValue();
|
||||||
|
|
||||||
|
Map<String, dynamic> toJson();
|
||||||
|
}
|
||||||
|
|
||||||
class RemoteAssetMetadataItem {
|
class RemoteAssetMetadataItem {
|
||||||
final RemoteAssetMetadataKey key;
|
final RemoteAssetMetadataKey key;
|
||||||
final Object value;
|
final RemoteAssetMetadataValue value;
|
||||||
|
|
||||||
const RemoteAssetMetadataItem({required this.key, required this.value});
|
const RemoteAssetMetadataItem({required this.key, required this.value});
|
||||||
|
|
||||||
Map<String, Object?> toMap() {
|
Map<String, Object?> toJson() {
|
||||||
return {'key': key.key, 'value': value};
|
return {'key': key.key, 'value': value};
|
||||||
}
|
}
|
||||||
|
|
||||||
String toJson() => json.encode(toMap());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class RemoteAssetMobileAppMetadata {
|
class RemoteAssetMobileAppMetadata extends RemoteAssetMetadataValue {
|
||||||
final String? cloudId;
|
final String? cloudId;
|
||||||
|
|
||||||
const RemoteAssetMobileAppMetadata({this.cloudId});
|
const RemoteAssetMobileAppMetadata({this.cloudId});
|
||||||
|
|
||||||
Map<String, Object?> toMap() {
|
@override
|
||||||
|
Map<String, dynamic> toJson() {
|
||||||
final map = <String, Object?>{};
|
final map = <String, Object?>{};
|
||||||
if (cloudId != null) {
|
if (cloudId != null) {
|
||||||
map["iCloudId"] = cloudId;
|
map["iCloudId"] = cloudId;
|
||||||
@ -34,6 +37,4 @@ class RemoteAssetMobileAppMetadata {
|
|||||||
|
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
String toJson() => json.encode(toMap());
|
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,8 @@ import 'package:immich_mobile/platform/native_sync_api.g.dart';
|
|||||||
import 'package:immich_mobile/providers/api.provider.dart';
|
import 'package:immich_mobile/providers/api.provider.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/db.provider.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/sync.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/sync.provider.dart';
|
||||||
|
import 'package:immich_mobile/providers/user.provider.dart';
|
||||||
|
import 'package:logging/logging.dart';
|
||||||
// ignore: import_rule_openapi
|
// ignore: import_rule_openapi
|
||||||
import 'package:openapi/api.dart';
|
import 'package:openapi/api.dart';
|
||||||
|
|
||||||
@ -19,14 +21,24 @@ Future<void> migrateCloudIds(ProviderContainer ref) async {
|
|||||||
await ref.read(syncStreamServiceProvider).sync();
|
await ref.read(syncStreamServiceProvider).sync();
|
||||||
|
|
||||||
// Fetch the mapping for backed up assets that have a cloud ID locally but do not have a cloud ID on the server
|
// Fetch the mapping for backed up assets that have a cloud ID locally but do not have a cloud ID on the server
|
||||||
final mappingsToUpdate = await _fetchCloudIdMappings(db);
|
final currentUser = ref.read(currentUserProvider);
|
||||||
|
if (currentUser == null) {
|
||||||
|
Logger('migrateCloudIds').warning('Current user is null. Aborting cloudId migration.');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
final mappingsToUpdate = await _fetchCloudIdMappings(db, currentUser.id);
|
||||||
final assetApi = ref.read(apiServiceProvider).assetsApi;
|
final assetApi = ref.read(apiServiceProvider).assetsApi;
|
||||||
for (final mapping in mappingsToUpdate) {
|
for (final mapping in mappingsToUpdate) {
|
||||||
final mobileMeta = AssetMetadataUpsertItemDto(
|
final mobileMeta = AssetMetadataUpsertItemDto(
|
||||||
key: AssetMetadataKey.mobileApp,
|
key: AssetMetadataKey.mobileApp,
|
||||||
value: RemoteAssetMobileAppMetadata(cloudId: mapping.cloudId).toMap(),
|
value: RemoteAssetMobileAppMetadata(cloudId: mapping.cloudId),
|
||||||
);
|
);
|
||||||
await assetApi.updateAssetMetadata(mapping.assetId, AssetMetadataUpsertDto(items: [mobileMeta]));
|
try {
|
||||||
|
await assetApi.updateAssetMetadata(mapping.assetId, AssetMetadataUpsertDto(items: [mobileMeta]));
|
||||||
|
} catch (error, stack) {
|
||||||
|
Logger('migrateCloudIds').warning('Failed to update metadata for asset ${mapping.assetId}', error, stack);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,7 +53,7 @@ Future<void> _populateCloudIds(Drift drift) async {
|
|||||||
|
|
||||||
typedef _CloudIdMapping = ({String assetId, String cloudId});
|
typedef _CloudIdMapping = ({String assetId, String cloudId});
|
||||||
|
|
||||||
Future<List<_CloudIdMapping>> _fetchCloudIdMappings(Drift drift) async {
|
Future<List<_CloudIdMapping>> _fetchCloudIdMappings(Drift drift, String userId) async {
|
||||||
final query =
|
final query =
|
||||||
drift.remoteAssetEntity.selectOnly().join([
|
drift.remoteAssetEntity.selectOnly().join([
|
||||||
leftOuterJoin(
|
leftOuterJoin(
|
||||||
@ -58,7 +70,8 @@ Future<List<_CloudIdMapping>> _fetchCloudIdMappings(Drift drift) async {
|
|||||||
])
|
])
|
||||||
..addColumns([drift.remoteAssetEntity.id, drift.localAssetEntity.cloudId])
|
..addColumns([drift.remoteAssetEntity.id, drift.localAssetEntity.cloudId])
|
||||||
..where(
|
..where(
|
||||||
drift.localAssetEntity.id.isNotNull() &
|
drift.remoteAssetEntity.ownerId.equals(userId) &
|
||||||
|
drift.localAssetEntity.id.isNotNull() &
|
||||||
drift.localAssetEntity.cloudId.isNotNull() &
|
drift.localAssetEntity.cloudId.isNotNull() &
|
||||||
drift.remoteAssetMetadataEntity.cloudId.isNull(),
|
drift.remoteAssetMetadataEntity.cloudId.isNull(),
|
||||||
);
|
);
|
||||||
|
@ -37,5 +37,6 @@ extension LocalAssetEntityDataDomainExtension on LocalAssetEntityData {
|
|||||||
width: width,
|
width: width,
|
||||||
remoteId: null,
|
remoteId: null,
|
||||||
orientation: orientation,
|
orientation: orientation,
|
||||||
|
cloudId: cloudId,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,3 @@
|
|||||||
import 'dart:convert';
|
|
||||||
|
|
||||||
import 'package:drift/drift.dart';
|
import 'package:drift/drift.dart';
|
||||||
import 'package:drift/extensions/json1.dart';
|
import 'package:drift/extensions/json1.dart';
|
||||||
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.dart';
|
import 'package:immich_mobile/infrastructure/entities/remote_asset.entity.dart';
|
||||||
@ -17,7 +15,7 @@ class RemoteAssetMetadataEntity extends Table with DriftDefaultsMixin {
|
|||||||
|
|
||||||
BlobColumn get value => blob().map(assetMetadataConverter)();
|
BlobColumn get value => blob().map(assetMetadataConverter)();
|
||||||
|
|
||||||
TextColumn get cloudId => text().generatedAs(key.jsonExtract(r'$.iCloudId'), stored: true)();
|
TextColumn get cloudId => text().generatedAs(value.jsonExtract(r'$.iCloudId'), stored: true).nullable()();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Set<Column> get primaryKey => {assetId, key};
|
Set<Column> get primaryKey => {assetId, key};
|
||||||
@ -25,5 +23,4 @@ class RemoteAssetMetadataEntity extends Table with DriftDefaultsMixin {
|
|||||||
|
|
||||||
final JsonTypeConverter2<Map<String, Object?>, Uint8List, Object?> assetMetadataConverter = TypeConverter.jsonb(
|
final JsonTypeConverter2<Map<String, Object?>, Uint8List, Object?> assetMetadataConverter = TypeConverter.jsonb(
|
||||||
fromJson: (json) => json as Map<String, Object?>,
|
fromJson: (json) => json as Map<String, Object?>,
|
||||||
toJson: (value) => jsonEncode(value),
|
|
||||||
);
|
);
|
||||||
|
@ -425,9 +425,9 @@ class $RemoteAssetMetadataEntityTable extends i3.RemoteAssetMetadataEntity
|
|||||||
late final i0.GeneratedColumn<String> cloudId = i0.GeneratedColumn<String>(
|
late final i0.GeneratedColumn<String> cloudId = i0.GeneratedColumn<String>(
|
||||||
'cloud_id',
|
'cloud_id',
|
||||||
aliasedName,
|
aliasedName,
|
||||||
false,
|
true,
|
||||||
generatedAs: i0.GeneratedAs(
|
generatedAs: i0.GeneratedAs(
|
||||||
i4.JsonExtensions(key).jsonExtract(r'$.iCloudId'),
|
i4.JsonbExtensions(value).jsonExtract(r'$.iCloudId'),
|
||||||
true,
|
true,
|
||||||
),
|
),
|
||||||
type: i0.DriftSqlType.string,
|
type: i0.DriftSqlType.string,
|
||||||
@ -498,7 +498,7 @@ class $RemoteAssetMetadataEntityTable extends i3.RemoteAssetMetadataEntity
|
|||||||
cloudId: attachedDatabase.typeMapping.read(
|
cloudId: attachedDatabase.typeMapping.read(
|
||||||
i0.DriftSqlType.string,
|
i0.DriftSqlType.string,
|
||||||
data['${effectivePrefix}cloud_id'],
|
data['${effectivePrefix}cloud_id'],
|
||||||
)!,
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -520,12 +520,12 @@ class RemoteAssetMetadataEntityData extends i0.DataClass
|
|||||||
final String assetId;
|
final String assetId;
|
||||||
final String key;
|
final String key;
|
||||||
final Map<String, Object?> value;
|
final Map<String, Object?> value;
|
||||||
final String cloudId;
|
final String? cloudId;
|
||||||
const RemoteAssetMetadataEntityData({
|
const RemoteAssetMetadataEntityData({
|
||||||
required this.assetId,
|
required this.assetId,
|
||||||
required this.key,
|
required this.key,
|
||||||
required this.value,
|
required this.value,
|
||||||
required this.cloudId,
|
this.cloudId,
|
||||||
});
|
});
|
||||||
@override
|
@override
|
||||||
Map<String, i0.Expression> toColumns(bool nullToAbsent) {
|
Map<String, i0.Expression> toColumns(bool nullToAbsent) {
|
||||||
@ -551,7 +551,7 @@ class RemoteAssetMetadataEntityData extends i0.DataClass
|
|||||||
value: i1.$RemoteAssetMetadataEntityTable.$convertervalue.fromJson(
|
value: i1.$RemoteAssetMetadataEntityTable.$convertervalue.fromJson(
|
||||||
serializer.fromJson<Object?>(json['value']),
|
serializer.fromJson<Object?>(json['value']),
|
||||||
),
|
),
|
||||||
cloudId: serializer.fromJson<String>(json['cloudId']),
|
cloudId: serializer.fromJson<String?>(json['cloudId']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@override
|
@override
|
||||||
@ -563,7 +563,7 @@ class RemoteAssetMetadataEntityData extends i0.DataClass
|
|||||||
'value': serializer.toJson<Object?>(
|
'value': serializer.toJson<Object?>(
|
||||||
i1.$RemoteAssetMetadataEntityTable.$convertervalue.toJson(value),
|
i1.$RemoteAssetMetadataEntityTable.$convertervalue.toJson(value),
|
||||||
),
|
),
|
||||||
'cloudId': serializer.toJson<String>(cloudId),
|
'cloudId': serializer.toJson<String?>(cloudId),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -571,12 +571,12 @@ class RemoteAssetMetadataEntityData extends i0.DataClass
|
|||||||
String? assetId,
|
String? assetId,
|
||||||
String? key,
|
String? key,
|
||||||
Map<String, Object?>? value,
|
Map<String, Object?>? value,
|
||||||
String? cloudId,
|
i0.Value<String?> cloudId = const i0.Value.absent(),
|
||||||
}) => i1.RemoteAssetMetadataEntityData(
|
}) => i1.RemoteAssetMetadataEntityData(
|
||||||
assetId: assetId ?? this.assetId,
|
assetId: assetId ?? this.assetId,
|
||||||
key: key ?? this.key,
|
key: key ?? this.key,
|
||||||
value: value ?? this.value,
|
value: value ?? this.value,
|
||||||
cloudId: cloudId ?? this.cloudId,
|
cloudId: cloudId.present ? cloudId.value : this.cloudId,
|
||||||
);
|
);
|
||||||
@override
|
@override
|
||||||
String toString() {
|
String toString() {
|
||||||
|
@ -368,7 +368,7 @@ class UploadService {
|
|||||||
'metadata': jsonEncode([
|
'metadata': jsonEncode([
|
||||||
RemoteAssetMetadataItem(
|
RemoteAssetMetadataItem(
|
||||||
key: RemoteAssetMetadataKey.mobileApp,
|
key: RemoteAssetMetadataKey.mobileApp,
|
||||||
value: RemoteAssetMobileAppMetadata(cloudId: cloudId).toMap(),
|
value: RemoteAssetMobileAppMetadata(cloudId: cloudId),
|
||||||
),
|
),
|
||||||
]),
|
]),
|
||||||
if (fields != null) ...fields,
|
if (fields != null) ...fields,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user