mirror of
https://github.com/immich-app/immich.git
synced 2026-05-18 03:10:24 +03:00
fix: mobile edit handling (#25315)
Co-authored-by: mertalev <101130780+mertalev@users.noreply.github.com>
This commit is contained in:
+1
File diff suppressed because one or more lines are too long
@@ -22,6 +22,7 @@ sealed class BaseAsset {
|
|||||||
final int? durationInSeconds;
|
final int? durationInSeconds;
|
||||||
final bool isFavorite;
|
final bool isFavorite;
|
||||||
final String? livePhotoVideoId;
|
final String? livePhotoVideoId;
|
||||||
|
final bool isEdited;
|
||||||
|
|
||||||
const BaseAsset({
|
const BaseAsset({
|
||||||
required this.name,
|
required this.name,
|
||||||
@@ -34,6 +35,7 @@ sealed class BaseAsset {
|
|||||||
this.durationInSeconds,
|
this.durationInSeconds,
|
||||||
this.isFavorite = false,
|
this.isFavorite = false,
|
||||||
this.livePhotoVideoId,
|
this.livePhotoVideoId,
|
||||||
|
required this.isEdited,
|
||||||
});
|
});
|
||||||
|
|
||||||
bool get isImage => type == AssetType.image;
|
bool get isImage => type == AssetType.image;
|
||||||
@@ -71,6 +73,7 @@ sealed class BaseAsset {
|
|||||||
height: ${height ?? "<NA>"},
|
height: ${height ?? "<NA>"},
|
||||||
durationInSeconds: ${durationInSeconds ?? "<NA>"},
|
durationInSeconds: ${durationInSeconds ?? "<NA>"},
|
||||||
isFavorite: $isFavorite,
|
isFavorite: $isFavorite,
|
||||||
|
isEdited: $isEdited,
|
||||||
}''';
|
}''';
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -85,7 +88,8 @@ sealed class BaseAsset {
|
|||||||
width == other.width &&
|
width == other.width &&
|
||||||
height == other.height &&
|
height == other.height &&
|
||||||
durationInSeconds == other.durationInSeconds &&
|
durationInSeconds == other.durationInSeconds &&
|
||||||
isFavorite == other.isFavorite;
|
isFavorite == other.isFavorite &&
|
||||||
|
isEdited == other.isEdited;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -99,6 +103,7 @@ sealed class BaseAsset {
|
|||||||
width.hashCode ^
|
width.hashCode ^
|
||||||
height.hashCode ^
|
height.hashCode ^
|
||||||
durationInSeconds.hashCode ^
|
durationInSeconds.hashCode ^
|
||||||
isFavorite.hashCode;
|
isFavorite.hashCode ^
|
||||||
|
isEdited.hashCode;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ class LocalAsset extends BaseAsset {
|
|||||||
this.adjustmentTime,
|
this.adjustmentTime,
|
||||||
this.latitude,
|
this.latitude,
|
||||||
this.longitude,
|
this.longitude,
|
||||||
|
required super.isEdited,
|
||||||
}) : remoteAssetId = remoteId;
|
}) : remoteAssetId = remoteId;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -107,6 +108,7 @@ class LocalAsset extends BaseAsset {
|
|||||||
DateTime? adjustmentTime,
|
DateTime? adjustmentTime,
|
||||||
double? latitude,
|
double? latitude,
|
||||||
double? longitude,
|
double? longitude,
|
||||||
|
bool? isEdited,
|
||||||
}) {
|
}) {
|
||||||
return LocalAsset(
|
return LocalAsset(
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
@@ -125,6 +127,7 @@ class LocalAsset extends BaseAsset {
|
|||||||
adjustmentTime: adjustmentTime ?? this.adjustmentTime,
|
adjustmentTime: adjustmentTime ?? this.adjustmentTime,
|
||||||
latitude: latitude ?? this.latitude,
|
latitude: latitude ?? this.latitude,
|
||||||
longitude: longitude ?? this.longitude,
|
longitude: longitude ?? this.longitude,
|
||||||
|
isEdited: isEdited ?? this.isEdited,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ class RemoteAsset extends BaseAsset {
|
|||||||
this.visibility = AssetVisibility.timeline,
|
this.visibility = AssetVisibility.timeline,
|
||||||
super.livePhotoVideoId,
|
super.livePhotoVideoId,
|
||||||
this.stackId,
|
this.stackId,
|
||||||
|
required super.isEdited,
|
||||||
}) : localAssetId = localId;
|
}) : localAssetId = localId;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
@@ -104,6 +105,7 @@ class RemoteAsset extends BaseAsset {
|
|||||||
AssetVisibility? visibility,
|
AssetVisibility? visibility,
|
||||||
String? livePhotoVideoId,
|
String? livePhotoVideoId,
|
||||||
String? stackId,
|
String? stackId,
|
||||||
|
bool? isEdited,
|
||||||
}) {
|
}) {
|
||||||
return RemoteAsset(
|
return RemoteAsset(
|
||||||
id: id ?? this.id,
|
id: id ?? this.id,
|
||||||
@@ -122,6 +124,7 @@ class RemoteAsset extends BaseAsset {
|
|||||||
visibility: visibility ?? this.visibility,
|
visibility: visibility ?? this.visibility,
|
||||||
livePhotoVideoId: livePhotoVideoId ?? this.livePhotoVideoId,
|
livePhotoVideoId: livePhotoVideoId ?? this.livePhotoVideoId,
|
||||||
stackId: stackId ?? this.stackId,
|
stackId: stackId ?? this.stackId,
|
||||||
|
isEdited: isEdited ?? this.isEdited,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -436,5 +436,6 @@ extension PlatformToLocalAsset on PlatformAsset {
|
|||||||
adjustmentTime: tryFromSecondsSinceEpoch(adjustmentTime, isUtc: true),
|
adjustmentTime: tryFromSecondsSinceEpoch(adjustmentTime, isUtc: true),
|
||||||
latitude: latitude,
|
latitude: latitude,
|
||||||
longitude: longitude,
|
longitude: longitude,
|
||||||
|
isEdited: false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -77,6 +77,7 @@ extension on AssetResponseDto {
|
|||||||
thumbHash: thumbhash,
|
thumbHash: thumbhash,
|
||||||
localId: null,
|
localId: null,
|
||||||
type: type.toAssetType(),
|
type: type.toAssetType(),
|
||||||
|
isEdited: isEdited,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -247,6 +247,42 @@ class SyncStreamService {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> handleWsAssetEditReadyV1Batch(List<dynamic> batchData) async {
|
||||||
|
if (batchData.isEmpty) return;
|
||||||
|
|
||||||
|
_logger.info('Processing batch of ${batchData.length} AssetEditReadyV1 events');
|
||||||
|
|
||||||
|
final List<SyncAssetV1> assets = [];
|
||||||
|
|
||||||
|
try {
|
||||||
|
for (final data in batchData) {
|
||||||
|
if (data is! Map<String, dynamic>) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final payload = data;
|
||||||
|
final assetData = payload['asset'];
|
||||||
|
|
||||||
|
if (assetData == null) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
final asset = SyncAssetV1.fromJson(assetData);
|
||||||
|
|
||||||
|
if (asset != null) {
|
||||||
|
assets.add(asset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (assets.isNotEmpty) {
|
||||||
|
await _syncStreamRepository.updateAssetsV1(assets, debugLabel: 'websocket-edit');
|
||||||
|
_logger.info('Successfully processed ${assets.length} edited assets');
|
||||||
|
}
|
||||||
|
} catch (error, stackTrace) {
|
||||||
|
_logger.severe("Error processing AssetEditReadyV1 websocket batch events", error, stackTrace);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _handleRemoteTrashed(Iterable<String> checksums) async {
|
Future<void> _handleRemoteTrashed(Iterable<String> checksums) async {
|
||||||
if (checksums.isEmpty) {
|
if (checksums.isEmpty) {
|
||||||
return Future.value();
|
return Future.value();
|
||||||
|
|||||||
@@ -196,6 +196,16 @@ class BackgroundSyncManager {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> syncWebsocketEditBatch(List<dynamic> batchData) {
|
||||||
|
if (_syncWebsocketTask != null) {
|
||||||
|
return _syncWebsocketTask!.future;
|
||||||
|
}
|
||||||
|
_syncWebsocketTask = _handleWsAssetEditReadyV1Batch(batchData);
|
||||||
|
return _syncWebsocketTask!.whenComplete(() {
|
||||||
|
_syncWebsocketTask = null;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> syncLinkedAlbum() {
|
Future<void> syncLinkedAlbum() {
|
||||||
if (_linkedAlbumSyncTask != null) {
|
if (_linkedAlbumSyncTask != null) {
|
||||||
return _linkedAlbumSyncTask!.future;
|
return _linkedAlbumSyncTask!.future;
|
||||||
@@ -231,3 +241,8 @@ Cancelable<void> _handleWsAssetUploadReadyV1Batch(List<dynamic> batchData) => ru
|
|||||||
computation: (ref) => ref.read(syncStreamServiceProvider).handleWsAssetUploadReadyV1Batch(batchData),
|
computation: (ref) => ref.read(syncStreamServiceProvider).handleWsAssetUploadReadyV1Batch(batchData),
|
||||||
debugLabel: 'websocket-batch',
|
debugLabel: 'websocket-batch',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Cancelable<void> _handleWsAssetEditReadyV1Batch(List<dynamic> batchData) => runInIsolateGentle(
|
||||||
|
computation: (ref) => ref.read(syncStreamServiceProvider).handleWsAssetEditReadyV1Batch(batchData),
|
||||||
|
debugLabel: 'websocket-edit',
|
||||||
|
);
|
||||||
|
|||||||
@@ -47,5 +47,6 @@ extension LocalAssetEntityDataDomainExtension on LocalAssetEntityData {
|
|||||||
latitude: latitude,
|
latitude: latitude,
|
||||||
longitude: longitude,
|
longitude: longitude,
|
||||||
cloudId: iCloudId,
|
cloudId: iCloudId,
|
||||||
|
isEdited: false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,8 @@ SELECT
|
|||||||
NULL as i_cloud_id,
|
NULL as i_cloud_id,
|
||||||
NULL as latitude,
|
NULL as latitude,
|
||||||
NULL as longitude,
|
NULL as longitude,
|
||||||
NULL as adjustmentTime
|
NULL as adjustmentTime,
|
||||||
|
rae.is_edited
|
||||||
FROM
|
FROM
|
||||||
remote_asset_entity rae
|
remote_asset_entity rae
|
||||||
LEFT JOIN
|
LEFT JOIN
|
||||||
@@ -61,7 +62,8 @@ SELECT
|
|||||||
lae.i_cloud_id,
|
lae.i_cloud_id,
|
||||||
lae.latitude,
|
lae.latitude,
|
||||||
lae.longitude,
|
lae.longitude,
|
||||||
lae.adjustment_time
|
lae.adjustment_time,
|
||||||
|
0 as is_edited
|
||||||
FROM
|
FROM
|
||||||
local_asset_entity lae
|
local_asset_entity lae
|
||||||
WHERE NOT EXISTS (
|
WHERE NOT EXISTS (
|
||||||
|
|||||||
+4
-1
@@ -29,7 +29,7 @@ class MergedAssetDrift extends i1.ModularAccessor {
|
|||||||
);
|
);
|
||||||
$arrayStartIndex += generatedlimit.amountOfVariables;
|
$arrayStartIndex += generatedlimit.amountOfVariables;
|
||||||
return customSelect(
|
return customSelect(
|
||||||
'SELECT rae.id AS remote_id, (SELECT lae.id FROM local_asset_entity AS lae WHERE lae.checksum = rae.checksum LIMIT 1) AS local_id, rae.name, rae.type, rae.created_at AS created_at, rae.updated_at, rae.width, rae.height, rae.duration_in_seconds, rae.is_favorite, rae.thumb_hash, rae.checksum, rae.owner_id, rae.live_photo_video_id, 0 AS orientation, rae.stack_id, NULL AS i_cloud_id, NULL AS latitude, NULL AS longitude, NULL AS adjustmentTime FROM remote_asset_entity AS rae LEFT JOIN stack_entity AS se ON rae.stack_id = se.id WHERE rae.deleted_at IS NULL AND rae.visibility = 0 AND rae.owner_id IN ($expandeduserIds) AND(rae.stack_id IS NULL OR rae.id = se.primary_asset_id)UNION ALL SELECT NULL AS remote_id, lae.id AS local_id, lae.name, lae.type, lae.created_at AS created_at, lae.updated_at, lae.width, lae.height, lae.duration_in_seconds, lae.is_favorite, NULL AS thumb_hash, lae.checksum, NULL AS owner_id, NULL AS live_photo_video_id, lae.orientation, NULL AS stack_id, lae.i_cloud_id, lae.latitude, lae.longitude, lae.adjustment_time FROM local_asset_entity AS lae WHERE NOT EXISTS (SELECT 1 FROM remote_asset_entity AS rae WHERE rae.checksum = lae.checksum AND rae.owner_id IN ($expandeduserIds)) AND EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 0) AND NOT EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 2) ORDER BY created_at DESC ${generatedlimit.sql}',
|
'SELECT rae.id AS remote_id, (SELECT lae.id FROM local_asset_entity AS lae WHERE lae.checksum = rae.checksum LIMIT 1) AS local_id, rae.name, rae.type, rae.created_at AS created_at, rae.updated_at, rae.width, rae.height, rae.duration_in_seconds, rae.is_favorite, rae.thumb_hash, rae.checksum, rae.owner_id, rae.live_photo_video_id, 0 AS orientation, rae.stack_id, NULL AS i_cloud_id, NULL AS latitude, NULL AS longitude, NULL AS adjustmentTime, rae.is_edited FROM remote_asset_entity AS rae LEFT JOIN stack_entity AS se ON rae.stack_id = se.id WHERE rae.deleted_at IS NULL AND rae.visibility = 0 AND rae.owner_id IN ($expandeduserIds) AND(rae.stack_id IS NULL OR rae.id = se.primary_asset_id)UNION ALL SELECT NULL AS remote_id, lae.id AS local_id, lae.name, lae.type, lae.created_at AS created_at, lae.updated_at, lae.width, lae.height, lae.duration_in_seconds, lae.is_favorite, NULL AS thumb_hash, lae.checksum, NULL AS owner_id, NULL AS live_photo_video_id, lae.orientation, NULL AS stack_id, lae.i_cloud_id, lae.latitude, lae.longitude, lae.adjustment_time, 0 AS is_edited FROM local_asset_entity AS lae WHERE NOT EXISTS (SELECT 1 FROM remote_asset_entity AS rae WHERE rae.checksum = lae.checksum AND rae.owner_id IN ($expandeduserIds)) AND EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 0) AND NOT EXISTS (SELECT 1 FROM local_album_asset_entity AS laa INNER JOIN local_album_entity AS la ON laa.album_id = la.id WHERE laa.asset_id = lae.id AND la.backup_selection = 2) ORDER BY created_at DESC ${generatedlimit.sql}',
|
||||||
variables: [
|
variables: [
|
||||||
for (var $ in userIds) i0.Variable<String>($),
|
for (var $ in userIds) i0.Variable<String>($),
|
||||||
...generatedlimit.introducedVariables,
|
...generatedlimit.introducedVariables,
|
||||||
@@ -66,6 +66,7 @@ class MergedAssetDrift extends i1.ModularAccessor {
|
|||||||
latitude: row.readNullable<double>('latitude'),
|
latitude: row.readNullable<double>('latitude'),
|
||||||
longitude: row.readNullable<double>('longitude'),
|
longitude: row.readNullable<double>('longitude'),
|
||||||
adjustmentTime: row.readNullable<DateTime>('adjustmentTime'),
|
adjustmentTime: row.readNullable<DateTime>('adjustmentTime'),
|
||||||
|
isEdited: row.read<bool>('is_edited'),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@@ -137,6 +138,7 @@ class MergedAssetResult {
|
|||||||
final double? latitude;
|
final double? latitude;
|
||||||
final double? longitude;
|
final double? longitude;
|
||||||
final DateTime? adjustmentTime;
|
final DateTime? adjustmentTime;
|
||||||
|
final bool isEdited;
|
||||||
MergedAssetResult({
|
MergedAssetResult({
|
||||||
this.remoteId,
|
this.remoteId,
|
||||||
this.localId,
|
this.localId,
|
||||||
@@ -158,6 +160,7 @@ class MergedAssetResult {
|
|||||||
this.latitude,
|
this.latitude,
|
||||||
this.longitude,
|
this.longitude,
|
||||||
this.adjustmentTime,
|
this.adjustmentTime,
|
||||||
|
required this.isEdited,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -44,6 +44,8 @@ class RemoteAssetEntity extends Table with DriftDefaultsMixin, AssetEntityMixin
|
|||||||
|
|
||||||
TextColumn get libraryId => text().nullable()();
|
TextColumn get libraryId => text().nullable()();
|
||||||
|
|
||||||
|
BoolColumn get isEdited => boolean().withDefault(const Constant(false))();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Set<Column> get primaryKey => {id};
|
Set<Column> get primaryKey => {id};
|
||||||
}
|
}
|
||||||
@@ -66,5 +68,6 @@ extension RemoteAssetEntityDataDomainEx on RemoteAssetEntityData {
|
|||||||
livePhotoVideoId: livePhotoVideoId,
|
livePhotoVideoId: livePhotoVideoId,
|
||||||
localId: localId,
|
localId: localId,
|
||||||
stackId: stackId,
|
stackId: stackId,
|
||||||
|
isEdited: isEdited,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ typedef $$RemoteAssetEntityTableCreateCompanionBuilder =
|
|||||||
required i2.AssetVisibility visibility,
|
required i2.AssetVisibility visibility,
|
||||||
i0.Value<String?> stackId,
|
i0.Value<String?> stackId,
|
||||||
i0.Value<String?> libraryId,
|
i0.Value<String?> libraryId,
|
||||||
|
i0.Value<bool> isEdited,
|
||||||
});
|
});
|
||||||
typedef $$RemoteAssetEntityTableUpdateCompanionBuilder =
|
typedef $$RemoteAssetEntityTableUpdateCompanionBuilder =
|
||||||
i1.RemoteAssetEntityCompanion Function({
|
i1.RemoteAssetEntityCompanion Function({
|
||||||
@@ -52,6 +53,7 @@ typedef $$RemoteAssetEntityTableUpdateCompanionBuilder =
|
|||||||
i0.Value<i2.AssetVisibility> visibility,
|
i0.Value<i2.AssetVisibility> visibility,
|
||||||
i0.Value<String?> stackId,
|
i0.Value<String?> stackId,
|
||||||
i0.Value<String?> libraryId,
|
i0.Value<String?> libraryId,
|
||||||
|
i0.Value<bool> isEdited,
|
||||||
});
|
});
|
||||||
|
|
||||||
final class $$RemoteAssetEntityTableReferences
|
final class $$RemoteAssetEntityTableReferences
|
||||||
@@ -196,6 +198,11 @@ class $$RemoteAssetEntityTableFilterComposer
|
|||||||
builder: (column) => i0.ColumnFilters(column),
|
builder: (column) => i0.ColumnFilters(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
i0.ColumnFilters<bool> get isEdited => $composableBuilder(
|
||||||
|
column: $table.isEdited,
|
||||||
|
builder: (column) => i0.ColumnFilters(column),
|
||||||
|
);
|
||||||
|
|
||||||
i5.$$UserEntityTableFilterComposer get ownerId {
|
i5.$$UserEntityTableFilterComposer get ownerId {
|
||||||
final i5.$$UserEntityTableFilterComposer composer = $composerBuilder(
|
final i5.$$UserEntityTableFilterComposer composer = $composerBuilder(
|
||||||
composer: this,
|
composer: this,
|
||||||
@@ -318,6 +325,11 @@ class $$RemoteAssetEntityTableOrderingComposer
|
|||||||
builder: (column) => i0.ColumnOrderings(column),
|
builder: (column) => i0.ColumnOrderings(column),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
i0.ColumnOrderings<bool> get isEdited => $composableBuilder(
|
||||||
|
column: $table.isEdited,
|
||||||
|
builder: (column) => i0.ColumnOrderings(column),
|
||||||
|
);
|
||||||
|
|
||||||
i5.$$UserEntityTableOrderingComposer get ownerId {
|
i5.$$UserEntityTableOrderingComposer get ownerId {
|
||||||
final i5.$$UserEntityTableOrderingComposer composer = $composerBuilder(
|
final i5.$$UserEntityTableOrderingComposer composer = $composerBuilder(
|
||||||
composer: this,
|
composer: this,
|
||||||
@@ -417,6 +429,9 @@ class $$RemoteAssetEntityTableAnnotationComposer
|
|||||||
i0.GeneratedColumn<String> get libraryId =>
|
i0.GeneratedColumn<String> get libraryId =>
|
||||||
$composableBuilder(column: $table.libraryId, builder: (column) => column);
|
$composableBuilder(column: $table.libraryId, builder: (column) => column);
|
||||||
|
|
||||||
|
i0.GeneratedColumn<bool> get isEdited =>
|
||||||
|
$composableBuilder(column: $table.isEdited, builder: (column) => column);
|
||||||
|
|
||||||
i5.$$UserEntityTableAnnotationComposer get ownerId {
|
i5.$$UserEntityTableAnnotationComposer get ownerId {
|
||||||
final i5.$$UserEntityTableAnnotationComposer composer = $composerBuilder(
|
final i5.$$UserEntityTableAnnotationComposer composer = $composerBuilder(
|
||||||
composer: this,
|
composer: this,
|
||||||
@@ -497,6 +512,7 @@ class $$RemoteAssetEntityTableTableManager
|
|||||||
const i0.Value.absent(),
|
const i0.Value.absent(),
|
||||||
i0.Value<String?> stackId = const i0.Value.absent(),
|
i0.Value<String?> stackId = const i0.Value.absent(),
|
||||||
i0.Value<String?> libraryId = const i0.Value.absent(),
|
i0.Value<String?> libraryId = const i0.Value.absent(),
|
||||||
|
i0.Value<bool> isEdited = const i0.Value.absent(),
|
||||||
}) => i1.RemoteAssetEntityCompanion(
|
}) => i1.RemoteAssetEntityCompanion(
|
||||||
name: name,
|
name: name,
|
||||||
type: type,
|
type: type,
|
||||||
@@ -516,6 +532,7 @@ class $$RemoteAssetEntityTableTableManager
|
|||||||
visibility: visibility,
|
visibility: visibility,
|
||||||
stackId: stackId,
|
stackId: stackId,
|
||||||
libraryId: libraryId,
|
libraryId: libraryId,
|
||||||
|
isEdited: isEdited,
|
||||||
),
|
),
|
||||||
createCompanionCallback:
|
createCompanionCallback:
|
||||||
({
|
({
|
||||||
@@ -537,6 +554,7 @@ class $$RemoteAssetEntityTableTableManager
|
|||||||
required i2.AssetVisibility visibility,
|
required i2.AssetVisibility visibility,
|
||||||
i0.Value<String?> stackId = const i0.Value.absent(),
|
i0.Value<String?> stackId = const i0.Value.absent(),
|
||||||
i0.Value<String?> libraryId = const i0.Value.absent(),
|
i0.Value<String?> libraryId = const i0.Value.absent(),
|
||||||
|
i0.Value<bool> isEdited = const i0.Value.absent(),
|
||||||
}) => i1.RemoteAssetEntityCompanion.insert(
|
}) => i1.RemoteAssetEntityCompanion.insert(
|
||||||
name: name,
|
name: name,
|
||||||
type: type,
|
type: type,
|
||||||
@@ -556,6 +574,7 @@ class $$RemoteAssetEntityTableTableManager
|
|||||||
visibility: visibility,
|
visibility: visibility,
|
||||||
stackId: stackId,
|
stackId: stackId,
|
||||||
libraryId: libraryId,
|
libraryId: libraryId,
|
||||||
|
isEdited: isEdited,
|
||||||
),
|
),
|
||||||
withReferenceMapper: (p0) => p0
|
withReferenceMapper: (p0) => p0
|
||||||
.map(
|
.map(
|
||||||
@@ -844,6 +863,21 @@ class $RemoteAssetEntityTable extends i3.RemoteAssetEntity
|
|||||||
type: i0.DriftSqlType.string,
|
type: i0.DriftSqlType.string,
|
||||||
requiredDuringInsert: false,
|
requiredDuringInsert: false,
|
||||||
);
|
);
|
||||||
|
static const i0.VerificationMeta _isEditedMeta = const i0.VerificationMeta(
|
||||||
|
'isEdited',
|
||||||
|
);
|
||||||
|
@override
|
||||||
|
late final i0.GeneratedColumn<bool> isEdited = i0.GeneratedColumn<bool>(
|
||||||
|
'is_edited',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: i0.DriftSqlType.bool,
|
||||||
|
requiredDuringInsert: false,
|
||||||
|
defaultConstraints: i0.GeneratedColumn.constraintIsAlways(
|
||||||
|
'CHECK ("is_edited" IN (0, 1))',
|
||||||
|
),
|
||||||
|
defaultValue: const i4.Constant(false),
|
||||||
|
);
|
||||||
@override
|
@override
|
||||||
List<i0.GeneratedColumn> get $columns => [
|
List<i0.GeneratedColumn> get $columns => [
|
||||||
name,
|
name,
|
||||||
@@ -864,6 +898,7 @@ class $RemoteAssetEntityTable extends i3.RemoteAssetEntity
|
|||||||
visibility,
|
visibility,
|
||||||
stackId,
|
stackId,
|
||||||
libraryId,
|
libraryId,
|
||||||
|
isEdited,
|
||||||
];
|
];
|
||||||
@override
|
@override
|
||||||
String get aliasedName => _alias ?? actualTableName;
|
String get aliasedName => _alias ?? actualTableName;
|
||||||
@@ -987,6 +1022,12 @@ class $RemoteAssetEntityTable extends i3.RemoteAssetEntity
|
|||||||
libraryId.isAcceptableOrUnknown(data['library_id']!, _libraryIdMeta),
|
libraryId.isAcceptableOrUnknown(data['library_id']!, _libraryIdMeta),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
if (data.containsKey('is_edited')) {
|
||||||
|
context.handle(
|
||||||
|
_isEditedMeta,
|
||||||
|
isEdited.isAcceptableOrUnknown(data['is_edited']!, _isEditedMeta),
|
||||||
|
);
|
||||||
|
}
|
||||||
return context;
|
return context;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1075,6 +1116,10 @@ class $RemoteAssetEntityTable extends i3.RemoteAssetEntity
|
|||||||
i0.DriftSqlType.string,
|
i0.DriftSqlType.string,
|
||||||
data['${effectivePrefix}library_id'],
|
data['${effectivePrefix}library_id'],
|
||||||
),
|
),
|
||||||
|
isEdited: attachedDatabase.typeMapping.read(
|
||||||
|
i0.DriftSqlType.bool,
|
||||||
|
data['${effectivePrefix}is_edited'],
|
||||||
|
)!,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1115,6 +1160,7 @@ class RemoteAssetEntityData extends i0.DataClass
|
|||||||
final i2.AssetVisibility visibility;
|
final i2.AssetVisibility visibility;
|
||||||
final String? stackId;
|
final String? stackId;
|
||||||
final String? libraryId;
|
final String? libraryId;
|
||||||
|
final bool isEdited;
|
||||||
const RemoteAssetEntityData({
|
const RemoteAssetEntityData({
|
||||||
required this.name,
|
required this.name,
|
||||||
required this.type,
|
required this.type,
|
||||||
@@ -1134,6 +1180,7 @@ class RemoteAssetEntityData extends i0.DataClass
|
|||||||
required this.visibility,
|
required this.visibility,
|
||||||
this.stackId,
|
this.stackId,
|
||||||
this.libraryId,
|
this.libraryId,
|
||||||
|
required this.isEdited,
|
||||||
});
|
});
|
||||||
@override
|
@override
|
||||||
Map<String, i0.Expression> toColumns(bool nullToAbsent) {
|
Map<String, i0.Expression> toColumns(bool nullToAbsent) {
|
||||||
@@ -1182,6 +1229,7 @@ class RemoteAssetEntityData extends i0.DataClass
|
|||||||
if (!nullToAbsent || libraryId != null) {
|
if (!nullToAbsent || libraryId != null) {
|
||||||
map['library_id'] = i0.Variable<String>(libraryId);
|
map['library_id'] = i0.Variable<String>(libraryId);
|
||||||
}
|
}
|
||||||
|
map['is_edited'] = i0.Variable<bool>(isEdited);
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1213,6 +1261,7 @@ class RemoteAssetEntityData extends i0.DataClass
|
|||||||
),
|
),
|
||||||
stackId: serializer.fromJson<String?>(json['stackId']),
|
stackId: serializer.fromJson<String?>(json['stackId']),
|
||||||
libraryId: serializer.fromJson<String?>(json['libraryId']),
|
libraryId: serializer.fromJson<String?>(json['libraryId']),
|
||||||
|
isEdited: serializer.fromJson<bool>(json['isEdited']),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@override
|
@override
|
||||||
@@ -1241,6 +1290,7 @@ class RemoteAssetEntityData extends i0.DataClass
|
|||||||
),
|
),
|
||||||
'stackId': serializer.toJson<String?>(stackId),
|
'stackId': serializer.toJson<String?>(stackId),
|
||||||
'libraryId': serializer.toJson<String?>(libraryId),
|
'libraryId': serializer.toJson<String?>(libraryId),
|
||||||
|
'isEdited': serializer.toJson<bool>(isEdited),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1263,6 +1313,7 @@ class RemoteAssetEntityData extends i0.DataClass
|
|||||||
i2.AssetVisibility? visibility,
|
i2.AssetVisibility? visibility,
|
||||||
i0.Value<String?> stackId = const i0.Value.absent(),
|
i0.Value<String?> stackId = const i0.Value.absent(),
|
||||||
i0.Value<String?> libraryId = const i0.Value.absent(),
|
i0.Value<String?> libraryId = const i0.Value.absent(),
|
||||||
|
bool? isEdited,
|
||||||
}) => i1.RemoteAssetEntityData(
|
}) => i1.RemoteAssetEntityData(
|
||||||
name: name ?? this.name,
|
name: name ?? this.name,
|
||||||
type: type ?? this.type,
|
type: type ?? this.type,
|
||||||
@@ -1288,6 +1339,7 @@ class RemoteAssetEntityData extends i0.DataClass
|
|||||||
visibility: visibility ?? this.visibility,
|
visibility: visibility ?? this.visibility,
|
||||||
stackId: stackId.present ? stackId.value : this.stackId,
|
stackId: stackId.present ? stackId.value : this.stackId,
|
||||||
libraryId: libraryId.present ? libraryId.value : this.libraryId,
|
libraryId: libraryId.present ? libraryId.value : this.libraryId,
|
||||||
|
isEdited: isEdited ?? this.isEdited,
|
||||||
);
|
);
|
||||||
RemoteAssetEntityData copyWithCompanion(i1.RemoteAssetEntityCompanion data) {
|
RemoteAssetEntityData copyWithCompanion(i1.RemoteAssetEntityCompanion data) {
|
||||||
return RemoteAssetEntityData(
|
return RemoteAssetEntityData(
|
||||||
@@ -1319,6 +1371,7 @@ class RemoteAssetEntityData extends i0.DataClass
|
|||||||
: this.visibility,
|
: this.visibility,
|
||||||
stackId: data.stackId.present ? data.stackId.value : this.stackId,
|
stackId: data.stackId.present ? data.stackId.value : this.stackId,
|
||||||
libraryId: data.libraryId.present ? data.libraryId.value : this.libraryId,
|
libraryId: data.libraryId.present ? data.libraryId.value : this.libraryId,
|
||||||
|
isEdited: data.isEdited.present ? data.isEdited.value : this.isEdited,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1342,7 +1395,8 @@ class RemoteAssetEntityData extends i0.DataClass
|
|||||||
..write('livePhotoVideoId: $livePhotoVideoId, ')
|
..write('livePhotoVideoId: $livePhotoVideoId, ')
|
||||||
..write('visibility: $visibility, ')
|
..write('visibility: $visibility, ')
|
||||||
..write('stackId: $stackId, ')
|
..write('stackId: $stackId, ')
|
||||||
..write('libraryId: $libraryId')
|
..write('libraryId: $libraryId, ')
|
||||||
|
..write('isEdited: $isEdited')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
@@ -1367,6 +1421,7 @@ class RemoteAssetEntityData extends i0.DataClass
|
|||||||
visibility,
|
visibility,
|
||||||
stackId,
|
stackId,
|
||||||
libraryId,
|
libraryId,
|
||||||
|
isEdited,
|
||||||
);
|
);
|
||||||
@override
|
@override
|
||||||
bool operator ==(Object other) =>
|
bool operator ==(Object other) =>
|
||||||
@@ -1389,7 +1444,8 @@ class RemoteAssetEntityData extends i0.DataClass
|
|||||||
other.livePhotoVideoId == this.livePhotoVideoId &&
|
other.livePhotoVideoId == this.livePhotoVideoId &&
|
||||||
other.visibility == this.visibility &&
|
other.visibility == this.visibility &&
|
||||||
other.stackId == this.stackId &&
|
other.stackId == this.stackId &&
|
||||||
other.libraryId == this.libraryId);
|
other.libraryId == this.libraryId &&
|
||||||
|
other.isEdited == this.isEdited);
|
||||||
}
|
}
|
||||||
|
|
||||||
class RemoteAssetEntityCompanion
|
class RemoteAssetEntityCompanion
|
||||||
@@ -1412,6 +1468,7 @@ class RemoteAssetEntityCompanion
|
|||||||
final i0.Value<i2.AssetVisibility> visibility;
|
final i0.Value<i2.AssetVisibility> visibility;
|
||||||
final i0.Value<String?> stackId;
|
final i0.Value<String?> stackId;
|
||||||
final i0.Value<String?> libraryId;
|
final i0.Value<String?> libraryId;
|
||||||
|
final i0.Value<bool> isEdited;
|
||||||
const RemoteAssetEntityCompanion({
|
const RemoteAssetEntityCompanion({
|
||||||
this.name = const i0.Value.absent(),
|
this.name = const i0.Value.absent(),
|
||||||
this.type = const i0.Value.absent(),
|
this.type = const i0.Value.absent(),
|
||||||
@@ -1431,6 +1488,7 @@ class RemoteAssetEntityCompanion
|
|||||||
this.visibility = const i0.Value.absent(),
|
this.visibility = const i0.Value.absent(),
|
||||||
this.stackId = const i0.Value.absent(),
|
this.stackId = const i0.Value.absent(),
|
||||||
this.libraryId = const i0.Value.absent(),
|
this.libraryId = const i0.Value.absent(),
|
||||||
|
this.isEdited = const i0.Value.absent(),
|
||||||
});
|
});
|
||||||
RemoteAssetEntityCompanion.insert({
|
RemoteAssetEntityCompanion.insert({
|
||||||
required String name,
|
required String name,
|
||||||
@@ -1451,6 +1509,7 @@ class RemoteAssetEntityCompanion
|
|||||||
required i2.AssetVisibility visibility,
|
required i2.AssetVisibility visibility,
|
||||||
this.stackId = const i0.Value.absent(),
|
this.stackId = const i0.Value.absent(),
|
||||||
this.libraryId = const i0.Value.absent(),
|
this.libraryId = const i0.Value.absent(),
|
||||||
|
this.isEdited = const i0.Value.absent(),
|
||||||
}) : name = i0.Value(name),
|
}) : name = i0.Value(name),
|
||||||
type = i0.Value(type),
|
type = i0.Value(type),
|
||||||
id = i0.Value(id),
|
id = i0.Value(id),
|
||||||
@@ -1476,6 +1535,7 @@ class RemoteAssetEntityCompanion
|
|||||||
i0.Expression<int>? visibility,
|
i0.Expression<int>? visibility,
|
||||||
i0.Expression<String>? stackId,
|
i0.Expression<String>? stackId,
|
||||||
i0.Expression<String>? libraryId,
|
i0.Expression<String>? libraryId,
|
||||||
|
i0.Expression<bool>? isEdited,
|
||||||
}) {
|
}) {
|
||||||
return i0.RawValuesInsertable({
|
return i0.RawValuesInsertable({
|
||||||
if (name != null) 'name': name,
|
if (name != null) 'name': name,
|
||||||
@@ -1496,6 +1556,7 @@ class RemoteAssetEntityCompanion
|
|||||||
if (visibility != null) 'visibility': visibility,
|
if (visibility != null) 'visibility': visibility,
|
||||||
if (stackId != null) 'stack_id': stackId,
|
if (stackId != null) 'stack_id': stackId,
|
||||||
if (libraryId != null) 'library_id': libraryId,
|
if (libraryId != null) 'library_id': libraryId,
|
||||||
|
if (isEdited != null) 'is_edited': isEdited,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1518,6 +1579,7 @@ class RemoteAssetEntityCompanion
|
|||||||
i0.Value<i2.AssetVisibility>? visibility,
|
i0.Value<i2.AssetVisibility>? visibility,
|
||||||
i0.Value<String?>? stackId,
|
i0.Value<String?>? stackId,
|
||||||
i0.Value<String?>? libraryId,
|
i0.Value<String?>? libraryId,
|
||||||
|
i0.Value<bool>? isEdited,
|
||||||
}) {
|
}) {
|
||||||
return i1.RemoteAssetEntityCompanion(
|
return i1.RemoteAssetEntityCompanion(
|
||||||
name: name ?? this.name,
|
name: name ?? this.name,
|
||||||
@@ -1538,6 +1600,7 @@ class RemoteAssetEntityCompanion
|
|||||||
visibility: visibility ?? this.visibility,
|
visibility: visibility ?? this.visibility,
|
||||||
stackId: stackId ?? this.stackId,
|
stackId: stackId ?? this.stackId,
|
||||||
libraryId: libraryId ?? this.libraryId,
|
libraryId: libraryId ?? this.libraryId,
|
||||||
|
isEdited: isEdited ?? this.isEdited,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1602,6 +1665,9 @@ class RemoteAssetEntityCompanion
|
|||||||
if (libraryId.present) {
|
if (libraryId.present) {
|
||||||
map['library_id'] = i0.Variable<String>(libraryId.value);
|
map['library_id'] = i0.Variable<String>(libraryId.value);
|
||||||
}
|
}
|
||||||
|
if (isEdited.present) {
|
||||||
|
map['is_edited'] = i0.Variable<bool>(isEdited.value);
|
||||||
|
}
|
||||||
return map;
|
return map;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1625,7 +1691,8 @@ class RemoteAssetEntityCompanion
|
|||||||
..write('livePhotoVideoId: $livePhotoVideoId, ')
|
..write('livePhotoVideoId: $livePhotoVideoId, ')
|
||||||
..write('visibility: $visibility, ')
|
..write('visibility: $visibility, ')
|
||||||
..write('stackId: $stackId, ')
|
..write('stackId: $stackId, ')
|
||||||
..write('libraryId: $libraryId')
|
..write('libraryId: $libraryId, ')
|
||||||
|
..write('isEdited: $isEdited')
|
||||||
..write(')'))
|
..write(')'))
|
||||||
.toString();
|
.toString();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -45,5 +45,6 @@ extension TrashedLocalAssetEntityDataDomainExtension on TrashedLocalAssetEntityD
|
|||||||
height: height,
|
height: height,
|
||||||
width: width,
|
width: width,
|
||||||
orientation: orientation,
|
orientation: orientation,
|
||||||
|
isEdited: false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -97,7 +97,7 @@ class Drift extends $Drift implements IDatabaseRepository {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get schemaVersion => 16;
|
int get schemaVersion => 17;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
MigrationStrategy get migration => MigrationStrategy(
|
MigrationStrategy get migration => MigrationStrategy(
|
||||||
@@ -201,6 +201,9 @@ class Drift extends $Drift implements IDatabaseRepository {
|
|||||||
await m.createIndex(v16.idxLocalAssetCloudId);
|
await m.createIndex(v16.idxLocalAssetCloudId);
|
||||||
await m.createTable(v16.remoteAssetCloudIdEntity);
|
await m.createTable(v16.remoteAssetCloudIdEntity);
|
||||||
},
|
},
|
||||||
|
from16To17: (m, v17) async {
|
||||||
|
await m.addColumn(v17.remoteAssetEntity, v17.remoteAssetEntity.isEdited);
|
||||||
|
},
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -6911,6 +6911,503 @@ i1.GeneratedColumn<DateTime> _column_100(String aliasedName) =>
|
|||||||
true,
|
true,
|
||||||
type: i1.DriftSqlType.dateTime,
|
type: i1.DriftSqlType.dateTime,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final class Schema17 extends i0.VersionedSchema {
|
||||||
|
Schema17({required super.database}) : super(version: 17);
|
||||||
|
@override
|
||||||
|
late final List<i1.DatabaseSchemaEntity> entities = [
|
||||||
|
userEntity,
|
||||||
|
remoteAssetEntity,
|
||||||
|
stackEntity,
|
||||||
|
localAssetEntity,
|
||||||
|
remoteAlbumEntity,
|
||||||
|
localAlbumEntity,
|
||||||
|
localAlbumAssetEntity,
|
||||||
|
idxLocalAssetChecksum,
|
||||||
|
idxLocalAssetCloudId,
|
||||||
|
idxRemoteAssetOwnerChecksum,
|
||||||
|
uQRemoteAssetsOwnerChecksum,
|
||||||
|
uQRemoteAssetsOwnerLibraryChecksum,
|
||||||
|
idxRemoteAssetChecksum,
|
||||||
|
authUserEntity,
|
||||||
|
userMetadataEntity,
|
||||||
|
partnerEntity,
|
||||||
|
remoteExifEntity,
|
||||||
|
remoteAlbumAssetEntity,
|
||||||
|
remoteAlbumUserEntity,
|
||||||
|
remoteAssetCloudIdEntity,
|
||||||
|
memoryEntity,
|
||||||
|
memoryAssetEntity,
|
||||||
|
personEntity,
|
||||||
|
assetFaceEntity,
|
||||||
|
storeEntity,
|
||||||
|
trashedLocalAssetEntity,
|
||||||
|
idxLatLng,
|
||||||
|
idxTrashedLocalAssetChecksum,
|
||||||
|
idxTrashedLocalAssetAlbum,
|
||||||
|
];
|
||||||
|
late final Shape20 userEntity = Shape20(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'user_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(id)'],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_1,
|
||||||
|
_column_3,
|
||||||
|
_column_84,
|
||||||
|
_column_85,
|
||||||
|
_column_91,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape28 remoteAssetEntity = Shape28(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'remote_asset_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(id)'],
|
||||||
|
columns: [
|
||||||
|
_column_1,
|
||||||
|
_column_8,
|
||||||
|
_column_9,
|
||||||
|
_column_5,
|
||||||
|
_column_10,
|
||||||
|
_column_11,
|
||||||
|
_column_12,
|
||||||
|
_column_0,
|
||||||
|
_column_13,
|
||||||
|
_column_14,
|
||||||
|
_column_15,
|
||||||
|
_column_16,
|
||||||
|
_column_17,
|
||||||
|
_column_18,
|
||||||
|
_column_19,
|
||||||
|
_column_20,
|
||||||
|
_column_21,
|
||||||
|
_column_86,
|
||||||
|
_column_101,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape3 stackEntity = Shape3(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'stack_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(id)'],
|
||||||
|
columns: [_column_0, _column_9, _column_5, _column_15, _column_75],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape26 localAssetEntity = Shape26(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'local_asset_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(id)'],
|
||||||
|
columns: [
|
||||||
|
_column_1,
|
||||||
|
_column_8,
|
||||||
|
_column_9,
|
||||||
|
_column_5,
|
||||||
|
_column_10,
|
||||||
|
_column_11,
|
||||||
|
_column_12,
|
||||||
|
_column_0,
|
||||||
|
_column_22,
|
||||||
|
_column_14,
|
||||||
|
_column_23,
|
||||||
|
_column_98,
|
||||||
|
_column_96,
|
||||||
|
_column_46,
|
||||||
|
_column_47,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape9 remoteAlbumEntity = Shape9(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'remote_album_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(id)'],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_1,
|
||||||
|
_column_56,
|
||||||
|
_column_9,
|
||||||
|
_column_5,
|
||||||
|
_column_15,
|
||||||
|
_column_57,
|
||||||
|
_column_58,
|
||||||
|
_column_59,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape19 localAlbumEntity = Shape19(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'local_album_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(id)'],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_1,
|
||||||
|
_column_5,
|
||||||
|
_column_31,
|
||||||
|
_column_32,
|
||||||
|
_column_90,
|
||||||
|
_column_33,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape22 localAlbumAssetEntity = Shape22(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'local_album_asset_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(asset_id, album_id)'],
|
||||||
|
columns: [_column_34, _column_35, _column_33],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
final i1.Index idxLocalAssetChecksum = i1.Index(
|
||||||
|
'idx_local_asset_checksum',
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_local_asset_checksum ON local_asset_entity (checksum)',
|
||||||
|
);
|
||||||
|
final i1.Index idxLocalAssetCloudId = i1.Index(
|
||||||
|
'idx_local_asset_cloud_id',
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_local_asset_cloud_id ON local_asset_entity (i_cloud_id)',
|
||||||
|
);
|
||||||
|
final i1.Index idxRemoteAssetOwnerChecksum = i1.Index(
|
||||||
|
'idx_remote_asset_owner_checksum',
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_remote_asset_owner_checksum ON remote_asset_entity (owner_id, checksum)',
|
||||||
|
);
|
||||||
|
final i1.Index uQRemoteAssetsOwnerChecksum = i1.Index(
|
||||||
|
'UQ_remote_assets_owner_checksum',
|
||||||
|
'CREATE UNIQUE INDEX IF NOT EXISTS UQ_remote_assets_owner_checksum ON remote_asset_entity (owner_id, checksum) WHERE(library_id IS NULL)',
|
||||||
|
);
|
||||||
|
final i1.Index uQRemoteAssetsOwnerLibraryChecksum = i1.Index(
|
||||||
|
'UQ_remote_assets_owner_library_checksum',
|
||||||
|
'CREATE UNIQUE INDEX IF NOT EXISTS UQ_remote_assets_owner_library_checksum ON remote_asset_entity (owner_id, library_id, checksum) WHERE(library_id IS NOT NULL)',
|
||||||
|
);
|
||||||
|
final i1.Index idxRemoteAssetChecksum = i1.Index(
|
||||||
|
'idx_remote_asset_checksum',
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_remote_asset_checksum ON remote_asset_entity (checksum)',
|
||||||
|
);
|
||||||
|
late final Shape21 authUserEntity = Shape21(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'auth_user_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(id)'],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_1,
|
||||||
|
_column_3,
|
||||||
|
_column_2,
|
||||||
|
_column_84,
|
||||||
|
_column_85,
|
||||||
|
_column_92,
|
||||||
|
_column_93,
|
||||||
|
_column_7,
|
||||||
|
_column_94,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape4 userMetadataEntity = Shape4(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'user_metadata_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(user_id, "key")'],
|
||||||
|
columns: [_column_25, _column_26, _column_27],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape5 partnerEntity = Shape5(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'partner_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(shared_by_id, shared_with_id)'],
|
||||||
|
columns: [_column_28, _column_29, _column_30],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape8 remoteExifEntity = Shape8(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'remote_exif_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(asset_id)'],
|
||||||
|
columns: [
|
||||||
|
_column_36,
|
||||||
|
_column_37,
|
||||||
|
_column_38,
|
||||||
|
_column_39,
|
||||||
|
_column_40,
|
||||||
|
_column_41,
|
||||||
|
_column_11,
|
||||||
|
_column_10,
|
||||||
|
_column_42,
|
||||||
|
_column_43,
|
||||||
|
_column_44,
|
||||||
|
_column_45,
|
||||||
|
_column_46,
|
||||||
|
_column_47,
|
||||||
|
_column_48,
|
||||||
|
_column_49,
|
||||||
|
_column_50,
|
||||||
|
_column_51,
|
||||||
|
_column_52,
|
||||||
|
_column_53,
|
||||||
|
_column_54,
|
||||||
|
_column_55,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape7 remoteAlbumAssetEntity = Shape7(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'remote_album_asset_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(asset_id, album_id)'],
|
||||||
|
columns: [_column_36, _column_60],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape10 remoteAlbumUserEntity = Shape10(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'remote_album_user_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(album_id, user_id)'],
|
||||||
|
columns: [_column_60, _column_25, _column_61],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape27 remoteAssetCloudIdEntity = Shape27(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'remote_asset_cloud_id_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(asset_id)'],
|
||||||
|
columns: [
|
||||||
|
_column_36,
|
||||||
|
_column_99,
|
||||||
|
_column_100,
|
||||||
|
_column_96,
|
||||||
|
_column_46,
|
||||||
|
_column_47,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape11 memoryEntity = Shape11(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'memory_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(id)'],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_9,
|
||||||
|
_column_5,
|
||||||
|
_column_18,
|
||||||
|
_column_15,
|
||||||
|
_column_8,
|
||||||
|
_column_62,
|
||||||
|
_column_63,
|
||||||
|
_column_64,
|
||||||
|
_column_65,
|
||||||
|
_column_66,
|
||||||
|
_column_67,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape12 memoryAssetEntity = Shape12(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'memory_asset_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(asset_id, memory_id)'],
|
||||||
|
columns: [_column_36, _column_68],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape14 personEntity = Shape14(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'person_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(id)'],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_9,
|
||||||
|
_column_5,
|
||||||
|
_column_15,
|
||||||
|
_column_1,
|
||||||
|
_column_69,
|
||||||
|
_column_71,
|
||||||
|
_column_72,
|
||||||
|
_column_73,
|
||||||
|
_column_74,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape15 assetFaceEntity = Shape15(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'asset_face_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(id)'],
|
||||||
|
columns: [
|
||||||
|
_column_0,
|
||||||
|
_column_36,
|
||||||
|
_column_76,
|
||||||
|
_column_77,
|
||||||
|
_column_78,
|
||||||
|
_column_79,
|
||||||
|
_column_80,
|
||||||
|
_column_81,
|
||||||
|
_column_82,
|
||||||
|
_column_83,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape18 storeEntity = Shape18(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'store_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(id)'],
|
||||||
|
columns: [_column_87, _column_88, _column_89],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
late final Shape25 trashedLocalAssetEntity = Shape25(
|
||||||
|
source: i0.VersionedTable(
|
||||||
|
entityName: 'trashed_local_asset_entity',
|
||||||
|
withoutRowId: true,
|
||||||
|
isStrict: true,
|
||||||
|
tableConstraints: ['PRIMARY KEY(id, album_id)'],
|
||||||
|
columns: [
|
||||||
|
_column_1,
|
||||||
|
_column_8,
|
||||||
|
_column_9,
|
||||||
|
_column_5,
|
||||||
|
_column_10,
|
||||||
|
_column_11,
|
||||||
|
_column_12,
|
||||||
|
_column_0,
|
||||||
|
_column_95,
|
||||||
|
_column_22,
|
||||||
|
_column_14,
|
||||||
|
_column_23,
|
||||||
|
_column_97,
|
||||||
|
],
|
||||||
|
attachedDatabase: database,
|
||||||
|
),
|
||||||
|
alias: null,
|
||||||
|
);
|
||||||
|
final i1.Index idxLatLng = i1.Index(
|
||||||
|
'idx_lat_lng',
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_lat_lng ON remote_exif_entity (latitude, longitude)',
|
||||||
|
);
|
||||||
|
final i1.Index idxTrashedLocalAssetChecksum = i1.Index(
|
||||||
|
'idx_trashed_local_asset_checksum',
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_checksum ON trashed_local_asset_entity (checksum)',
|
||||||
|
);
|
||||||
|
final i1.Index idxTrashedLocalAssetAlbum = i1.Index(
|
||||||
|
'idx_trashed_local_asset_album',
|
||||||
|
'CREATE INDEX IF NOT EXISTS idx_trashed_local_asset_album ON trashed_local_asset_entity (album_id)',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
class Shape28 extends i0.VersionedTable {
|
||||||
|
Shape28({required super.source, required super.alias}) : super.aliased();
|
||||||
|
i1.GeneratedColumn<String> get name =>
|
||||||
|
columnsByName['name']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<int> get type =>
|
||||||
|
columnsByName['type']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<DateTime> get createdAt =>
|
||||||
|
columnsByName['created_at']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
i1.GeneratedColumn<DateTime> get updatedAt =>
|
||||||
|
columnsByName['updated_at']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
i1.GeneratedColumn<int> get width =>
|
||||||
|
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 checksum =>
|
||||||
|
columnsByName['checksum']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<bool> get isFavorite =>
|
||||||
|
columnsByName['is_favorite']! as i1.GeneratedColumn<bool>;
|
||||||
|
i1.GeneratedColumn<String> get ownerId =>
|
||||||
|
columnsByName['owner_id']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<DateTime> get localDateTime =>
|
||||||
|
columnsByName['local_date_time']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
i1.GeneratedColumn<String> get thumbHash =>
|
||||||
|
columnsByName['thumb_hash']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<DateTime> get deletedAt =>
|
||||||
|
columnsByName['deleted_at']! as i1.GeneratedColumn<DateTime>;
|
||||||
|
i1.GeneratedColumn<String> get livePhotoVideoId =>
|
||||||
|
columnsByName['live_photo_video_id']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<int> get visibility =>
|
||||||
|
columnsByName['visibility']! as i1.GeneratedColumn<int>;
|
||||||
|
i1.GeneratedColumn<String> get stackId =>
|
||||||
|
columnsByName['stack_id']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<String> get libraryId =>
|
||||||
|
columnsByName['library_id']! as i1.GeneratedColumn<String>;
|
||||||
|
i1.GeneratedColumn<bool> get isEdited =>
|
||||||
|
columnsByName['is_edited']! as i1.GeneratedColumn<bool>;
|
||||||
|
}
|
||||||
|
|
||||||
|
i1.GeneratedColumn<bool> _column_101(String aliasedName) =>
|
||||||
|
i1.GeneratedColumn<bool>(
|
||||||
|
'is_edited',
|
||||||
|
aliasedName,
|
||||||
|
false,
|
||||||
|
type: i1.DriftSqlType.bool,
|
||||||
|
defaultConstraints: i1.GeneratedColumn.constraintIsAlways(
|
||||||
|
'CHECK ("is_edited" IN (0, 1))',
|
||||||
|
),
|
||||||
|
defaultValue: const CustomExpression('0'),
|
||||||
|
);
|
||||||
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,
|
||||||
required Future<void> Function(i1.Migrator m, Schema3 schema) from2To3,
|
required Future<void> Function(i1.Migrator m, Schema3 schema) from2To3,
|
||||||
@@ -6927,6 +7424,7 @@ i0.MigrationStepWithVersion migrationSteps({
|
|||||||
required Future<void> Function(i1.Migrator m, Schema14 schema) from13To14,
|
required Future<void> Function(i1.Migrator m, Schema14 schema) from13To14,
|
||||||
required Future<void> Function(i1.Migrator m, Schema15 schema) from14To15,
|
required Future<void> Function(i1.Migrator m, Schema15 schema) from14To15,
|
||||||
required Future<void> Function(i1.Migrator m, Schema16 schema) from15To16,
|
required Future<void> Function(i1.Migrator m, Schema16 schema) from15To16,
|
||||||
|
required Future<void> Function(i1.Migrator m, Schema17 schema) from16To17,
|
||||||
}) {
|
}) {
|
||||||
return (currentVersion, database) async {
|
return (currentVersion, database) async {
|
||||||
switch (currentVersion) {
|
switch (currentVersion) {
|
||||||
@@ -7005,6 +7503,11 @@ i0.MigrationStepWithVersion migrationSteps({
|
|||||||
final migrator = i1.Migrator(database, schema);
|
final migrator = i1.Migrator(database, schema);
|
||||||
await from15To16(migrator, schema);
|
await from15To16(migrator, schema);
|
||||||
return 16;
|
return 16;
|
||||||
|
case 16:
|
||||||
|
final schema = Schema17(database: database);
|
||||||
|
final migrator = i1.Migrator(database, schema);
|
||||||
|
await from16To17(migrator, schema);
|
||||||
|
return 17;
|
||||||
default:
|
default:
|
||||||
throw ArgumentError.value('Unknown migration from $currentVersion');
|
throw ArgumentError.value('Unknown migration from $currentVersion');
|
||||||
}
|
}
|
||||||
@@ -7027,6 +7530,7 @@ i1.OnUpgrade stepByStep({
|
|||||||
required Future<void> Function(i1.Migrator m, Schema14 schema) from13To14,
|
required Future<void> Function(i1.Migrator m, Schema14 schema) from13To14,
|
||||||
required Future<void> Function(i1.Migrator m, Schema15 schema) from14To15,
|
required Future<void> Function(i1.Migrator m, Schema15 schema) from14To15,
|
||||||
required Future<void> Function(i1.Migrator m, Schema16 schema) from15To16,
|
required Future<void> Function(i1.Migrator m, Schema16 schema) from15To16,
|
||||||
|
required Future<void> Function(i1.Migrator m, Schema17 schema) from16To17,
|
||||||
}) => i0.VersionedSchema.stepByStepHelper(
|
}) => i0.VersionedSchema.stepByStepHelper(
|
||||||
step: migrationSteps(
|
step: migrationSteps(
|
||||||
from1To2: from1To2,
|
from1To2: from1To2,
|
||||||
@@ -7044,5 +7548,6 @@ i1.OnUpgrade stepByStep({
|
|||||||
from13To14: from13To14,
|
from13To14: from13To14,
|
||||||
from14To15: from14To15,
|
from14To15: from14To15,
|
||||||
from15To16: from15To16,
|
from15To16: from15To16,
|
||||||
|
from16To17: from16To17,
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -200,6 +200,7 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
|||||||
libraryId: Value(asset.libraryId),
|
libraryId: Value(asset.libraryId),
|
||||||
width: Value(asset.width),
|
width: Value(asset.width),
|
||||||
height: Value(asset.height),
|
height: Value(asset.height),
|
||||||
|
isEdited: Value(asset.isEdited),
|
||||||
);
|
);
|
||||||
|
|
||||||
batch.insert(
|
batch.insert(
|
||||||
|
|||||||
@@ -70,6 +70,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
|
|||||||
durationInSeconds: row.durationInSeconds,
|
durationInSeconds: row.durationInSeconds,
|
||||||
livePhotoVideoId: row.livePhotoVideoId,
|
livePhotoVideoId: row.livePhotoVideoId,
|
||||||
stackId: row.stackId,
|
stackId: row.stackId,
|
||||||
|
isEdited: row.isEdited,
|
||||||
)
|
)
|
||||||
: LocalAsset(
|
: LocalAsset(
|
||||||
id: row.localId!,
|
id: row.localId!,
|
||||||
@@ -88,6 +89,7 @@ class DriftTimelineRepository extends DriftDatabaseRepository {
|
|||||||
latitude: row.latitude,
|
latitude: row.latitude,
|
||||||
longitude: row.longitude,
|
longitude: row.longitude,
|
||||||
adjustmentTime: row.adjustmentTime,
|
adjustmentTime: row.adjustmentTime,
|
||||||
|
isEdited: row.isEdited,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
.get();
|
.get();
|
||||||
|
|||||||
@@ -118,6 +118,7 @@ class _AssetPropertiesSectionState extends ConsumerState<_AssetPropertiesSection
|
|||||||
),
|
),
|
||||||
_PropertyItem(label: 'Is Favorite', value: asset.isFavorite.toString()),
|
_PropertyItem(label: 'Is Favorite', value: asset.isFavorite.toString()),
|
||||||
_PropertyItem(label: 'Live Photo Video ID', value: asset.livePhotoVideoId),
|
_PropertyItem(label: 'Live Photo Video ID', value: asset.livePhotoVideoId),
|
||||||
|
_PropertyItem(label: 'Is Edited', value: asset.isEdited.toString()),
|
||||||
]);
|
]);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ class _PlaceTile extends StatelessWidget {
|
|||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: 80,
|
width: 80,
|
||||||
height: 80,
|
height: 80,
|
||||||
child: Thumbnail.remote(remoteId: place.$2, fit: BoxFit.cover),
|
child: Thumbnail.remote(remoteId: place.$2, fit: BoxFit.cover, thumbhash: ""),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -14,14 +14,15 @@ import 'package:immich_mobile/models/albums/album_search.model.dart';
|
|||||||
import 'package:immich_mobile/presentation/widgets/album/album_tile.dart';
|
import 'package:immich_mobile/presentation/widgets/album/album_tile.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/album/new_album_name_modal.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/album/new_album_name_modal.widget.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/images/thumbnail.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/images/thumbnail.widget.dart';
|
||||||
|
import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart';
|
||||||
|
import 'package:immich_mobile/providers/app_settings.provider.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/album.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/album.provider.dart';
|
||||||
|
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
||||||
import 'package:immich_mobile/providers/infrastructure/asset_viewer/current_asset.provider.dart';
|
import 'package:immich_mobile/providers/infrastructure/asset_viewer/current_asset.provider.dart';
|
||||||
import 'package:immich_mobile/providers/timeline/multiselect.provider.dart';
|
import 'package:immich_mobile/providers/timeline/multiselect.provider.dart';
|
||||||
import 'package:immich_mobile/providers/user.provider.dart';
|
import 'package:immich_mobile/providers/user.provider.dart';
|
||||||
import 'package:immich_mobile/providers/album/album_sort_by_options.provider.dart';
|
|
||||||
import 'package:immich_mobile/providers/app_settings.provider.dart';
|
|
||||||
import 'package:immich_mobile/services/app_settings.service.dart';
|
|
||||||
import 'package:immich_mobile/routing/router.dart';
|
import 'package:immich_mobile/routing/router.dart';
|
||||||
|
import 'package:immich_mobile/services/app_settings.service.dart';
|
||||||
import 'package:immich_mobile/utils/album_filter.utils.dart';
|
import 'package:immich_mobile/utils/album_filter.utils.dart';
|
||||||
import 'package:immich_mobile/widgets/common/confirm_dialog.dart';
|
import 'package:immich_mobile/widgets/common/confirm_dialog.dart';
|
||||||
import 'package:immich_mobile/widgets/common/immich_toast.dart';
|
import 'package:immich_mobile/widgets/common/immich_toast.dart';
|
||||||
@@ -666,6 +667,8 @@ class _GridAlbumCard extends ConsumerWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context, WidgetRef ref) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final albumThumbnailAsset = ref.read(assetServiceProvider).getRemoteAsset(album.thumbnailAssetId ?? "");
|
||||||
|
|
||||||
return GestureDetector(
|
return GestureDetector(
|
||||||
onTap: () => onAlbumSelected(album),
|
onTap: () => onAlbumSelected(album),
|
||||||
child: Card(
|
child: Card(
|
||||||
@@ -684,12 +687,22 @@ class _GridAlbumCard extends ConsumerWidget {
|
|||||||
borderRadius: const BorderRadius.vertical(top: Radius.circular(15)),
|
borderRadius: const BorderRadius.vertical(top: Radius.circular(15)),
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: double.infinity,
|
width: double.infinity,
|
||||||
child: album.thumbnailAssetId != null
|
child: FutureBuilder(
|
||||||
? Thumbnail.remote(remoteId: album.thumbnailAssetId!)
|
future: albumThumbnailAsset,
|
||||||
: Container(
|
builder: (context, snapshot) {
|
||||||
color: context.colorScheme.surfaceContainerHighest,
|
if (snapshot.hasData && snapshot.data != null) {
|
||||||
child: const Icon(Icons.photo_album_rounded, size: 40, color: Colors.grey),
|
return Thumbnail.remote(
|
||||||
),
|
remoteId: album.thumbnailAssetId!,
|
||||||
|
thumbhash: snapshot.data!.thumbHash ?? "",
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return Container(
|
||||||
|
color: context.colorScheme.surfaceContainerHighest,
|
||||||
|
child: const Icon(Icons.photo_album_rounded, size: 40, color: Colors.grey),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,12 +1,14 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
import 'package:immich_mobile/domain/models/album/album.model.dart';
|
import 'package:immich_mobile/domain/models/album/album.model.dart';
|
||||||
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
import 'package:immich_mobile/extensions/build_context_extensions.dart';
|
||||||
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
import 'package:immich_mobile/extensions/theme_extensions.dart';
|
||||||
import 'package:immich_mobile/extensions/translate_extensions.dart';
|
import 'package:immich_mobile/extensions/translate_extensions.dart';
|
||||||
import 'package:immich_mobile/pages/common/large_leading_tile.dart';
|
import 'package:immich_mobile/pages/common/large_leading_tile.dart';
|
||||||
import 'package:immich_mobile/presentation/widgets/images/thumbnail.widget.dart';
|
import 'package:immich_mobile/presentation/widgets/images/thumbnail.widget.dart';
|
||||||
|
import 'package:immich_mobile/providers/infrastructure/asset.provider.dart';
|
||||||
|
|
||||||
class AlbumTile extends StatelessWidget {
|
class AlbumTile extends ConsumerWidget {
|
||||||
const AlbumTile({super.key, required this.album, required this.isOwner, this.onAlbumSelected});
|
const AlbumTile({super.key, required this.album, required this.isOwner, this.onAlbumSelected});
|
||||||
|
|
||||||
final RemoteAlbum album;
|
final RemoteAlbum album;
|
||||||
@@ -14,7 +16,9 @@ class AlbumTile extends StatelessWidget {
|
|||||||
final Function(RemoteAlbum)? onAlbumSelected;
|
final Function(RemoteAlbum)? onAlbumSelected;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final albumThumbnailAsset = ref.read(assetServiceProvider).getRemoteAsset(album.thumbnailAssetId ?? "");
|
||||||
|
|
||||||
return LargeLeadingTile(
|
return LargeLeadingTile(
|
||||||
title: Text(
|
title: Text(
|
||||||
album.name,
|
album.name,
|
||||||
@@ -29,23 +33,35 @@ class AlbumTile extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
onTap: () => onAlbumSelected?.call(album),
|
onTap: () => onAlbumSelected?.call(album),
|
||||||
leadingPadding: const EdgeInsets.only(right: 16),
|
leadingPadding: const EdgeInsets.only(right: 16),
|
||||||
leading: album.thumbnailAssetId != null
|
leading: FutureBuilder(
|
||||||
? ClipRRect(
|
future: albumThumbnailAsset,
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(15)),
|
builder: (context, snapshot) {
|
||||||
child: SizedBox(width: 80, height: 80, child: Thumbnail.remote(remoteId: album.thumbnailAssetId!)),
|
return snapshot.hasData && snapshot.data != null
|
||||||
)
|
? ClipRRect(
|
||||||
: SizedBox(
|
borderRadius: const BorderRadius.all(Radius.circular(15)),
|
||||||
width: 80,
|
child: SizedBox(
|
||||||
height: 80,
|
width: 80,
|
||||||
child: Container(
|
height: 80,
|
||||||
decoration: BoxDecoration(
|
child: Thumbnail.remote(
|
||||||
color: context.colorScheme.surfaceContainer,
|
remoteId: album.thumbnailAssetId!,
|
||||||
borderRadius: const BorderRadius.all(Radius.circular(16)),
|
thumbhash: snapshot.data!.thumbHash ?? "",
|
||||||
border: Border.all(color: context.colorScheme.outline.withAlpha(50), width: 1),
|
),
|
||||||
),
|
),
|
||||||
child: const Icon(Icons.photo_album_rounded, size: 24, color: Colors.grey),
|
)
|
||||||
),
|
: SizedBox(
|
||||||
),
|
width: 80,
|
||||||
|
height: 80,
|
||||||
|
child: Container(
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: context.colorScheme.surfaceContainer,
|
||||||
|
borderRadius: const BorderRadius.all(Radius.circular(16)),
|
||||||
|
border: Border.all(color: context.colorScheme.outline.withAlpha(50), width: 1),
|
||||||
|
),
|
||||||
|
child: const Icon(Icons.photo_album_rounded, size: 24, color: Colors.grey),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
},
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -112,14 +112,17 @@ ImageProvider getFullImageProvider(BaseAsset asset, {Size size = const Size(1080
|
|||||||
provider = LocalFullImageProvider(id: id, size: size, assetType: asset.type);
|
provider = LocalFullImageProvider(id: id, size: size, assetType: asset.type);
|
||||||
} else {
|
} else {
|
||||||
final String assetId;
|
final String assetId;
|
||||||
|
final String thumbhash;
|
||||||
if (asset is LocalAsset && asset.hasRemote) {
|
if (asset is LocalAsset && asset.hasRemote) {
|
||||||
assetId = asset.remoteId!;
|
assetId = asset.remoteId!;
|
||||||
|
thumbhash = "";
|
||||||
} else if (asset is RemoteAsset) {
|
} else if (asset is RemoteAsset) {
|
||||||
assetId = asset.id;
|
assetId = asset.id;
|
||||||
|
thumbhash = asset.thumbHash ?? "";
|
||||||
} else {
|
} else {
|
||||||
throw ArgumentError("Unsupported asset type: ${asset.runtimeType}");
|
throw ArgumentError("Unsupported asset type: ${asset.runtimeType}");
|
||||||
}
|
}
|
||||||
provider = RemoteFullImageProvider(assetId: assetId);
|
provider = RemoteFullImageProvider(assetId: assetId, thumbhash: thumbhash);
|
||||||
}
|
}
|
||||||
|
|
||||||
return provider;
|
return provider;
|
||||||
@@ -132,8 +135,9 @@ ImageProvider? getThumbnailImageProvider(BaseAsset asset, {Size size = kThumbnai
|
|||||||
}
|
}
|
||||||
|
|
||||||
final assetId = asset is RemoteAsset ? asset.id : (asset as LocalAsset).remoteId;
|
final assetId = asset is RemoteAsset ? asset.id : (asset as LocalAsset).remoteId;
|
||||||
return assetId != null ? RemoteThumbProvider(assetId: assetId) : null;
|
final thumbhash = asset is RemoteAsset ? asset.thumbHash ?? "" : "";
|
||||||
|
return assetId != null ? RemoteThumbProvider(assetId: assetId, thumbhash: thumbhash) : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool _shouldUseLocalAsset(BaseAsset asset) =>
|
bool _shouldUseLocalAsset(BaseAsset asset) =>
|
||||||
asset.hasLocal && (!asset.hasRemote || !AppSetting.get(Setting.preferRemoteImage));
|
asset.hasLocal && (!asset.hasRemote || !AppSetting.get(Setting.preferRemoteImage)) && !asset.isEdited;
|
||||||
|
|||||||
@@ -16,8 +16,9 @@ class RemoteThumbProvider extends CancellableImageProvider<RemoteThumbProvider>
|
|||||||
with CancellableImageProviderMixin<RemoteThumbProvider> {
|
with CancellableImageProviderMixin<RemoteThumbProvider> {
|
||||||
static final cacheManager = RemoteThumbnailCacheManager();
|
static final cacheManager = RemoteThumbnailCacheManager();
|
||||||
final String assetId;
|
final String assetId;
|
||||||
|
final String thumbhash;
|
||||||
|
|
||||||
RemoteThumbProvider({required this.assetId});
|
RemoteThumbProvider({required this.assetId, required this.thumbhash});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<RemoteThumbProvider> obtainKey(ImageConfiguration configuration) {
|
Future<RemoteThumbProvider> obtainKey(ImageConfiguration configuration) {
|
||||||
@@ -38,7 +39,7 @@ class RemoteThumbProvider extends CancellableImageProvider<RemoteThumbProvider>
|
|||||||
|
|
||||||
Stream<ImageInfo> _codec(RemoteThumbProvider key, ImageDecoderCallback decode) {
|
Stream<ImageInfo> _codec(RemoteThumbProvider key, ImageDecoderCallback decode) {
|
||||||
final request = this.request = RemoteImageRequest(
|
final request = this.request = RemoteImageRequest(
|
||||||
uri: getThumbnailUrlForRemoteId(key.assetId),
|
uri: getThumbnailUrlForRemoteId(key.assetId, thumbhash: key.thumbhash),
|
||||||
headers: ApiService.getRequestHeaders(),
|
headers: ApiService.getRequestHeaders(),
|
||||||
cacheManager: cacheManager,
|
cacheManager: cacheManager,
|
||||||
);
|
);
|
||||||
@@ -49,22 +50,23 @@ class RemoteThumbProvider extends CancellableImageProvider<RemoteThumbProvider>
|
|||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
if (identical(this, other)) return true;
|
if (identical(this, other)) return true;
|
||||||
if (other is RemoteThumbProvider) {
|
if (other is RemoteThumbProvider) {
|
||||||
return assetId == other.assetId;
|
return assetId == other.assetId && thumbhash == other.thumbhash;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => assetId.hashCode;
|
int get hashCode => assetId.hashCode ^ thumbhash.hashCode;
|
||||||
}
|
}
|
||||||
|
|
||||||
class RemoteFullImageProvider extends CancellableImageProvider<RemoteFullImageProvider>
|
class RemoteFullImageProvider extends CancellableImageProvider<RemoteFullImageProvider>
|
||||||
with CancellableImageProviderMixin<RemoteFullImageProvider> {
|
with CancellableImageProviderMixin<RemoteFullImageProvider> {
|
||||||
static final cacheManager = RemoteThumbnailCacheManager();
|
static final cacheManager = RemoteThumbnailCacheManager();
|
||||||
final String assetId;
|
final String assetId;
|
||||||
|
final String thumbhash;
|
||||||
|
|
||||||
RemoteFullImageProvider({required this.assetId});
|
RemoteFullImageProvider({required this.assetId, required this.thumbhash});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<RemoteFullImageProvider> obtainKey(ImageConfiguration configuration) {
|
Future<RemoteFullImageProvider> obtainKey(ImageConfiguration configuration) {
|
||||||
@@ -75,7 +77,7 @@ class RemoteFullImageProvider extends CancellableImageProvider<RemoteFullImagePr
|
|||||||
ImageStreamCompleter loadImage(RemoteFullImageProvider key, ImageDecoderCallback decode) {
|
ImageStreamCompleter loadImage(RemoteFullImageProvider key, ImageDecoderCallback decode) {
|
||||||
return OneFramePlaceholderImageStreamCompleter(
|
return OneFramePlaceholderImageStreamCompleter(
|
||||||
_codec(key, decode),
|
_codec(key, decode),
|
||||||
initialImage: getInitialImage(RemoteThumbProvider(assetId: key.assetId)),
|
initialImage: getInitialImage(RemoteThumbProvider(assetId: key.assetId, thumbhash: key.thumbhash)),
|
||||||
informationCollector: () => <DiagnosticsNode>[
|
informationCollector: () => <DiagnosticsNode>[
|
||||||
DiagnosticsProperty<ImageProvider>('Image provider', this),
|
DiagnosticsProperty<ImageProvider>('Image provider', this),
|
||||||
DiagnosticsProperty<String>('Asset Id', key.assetId),
|
DiagnosticsProperty<String>('Asset Id', key.assetId),
|
||||||
@@ -94,7 +96,7 @@ class RemoteFullImageProvider extends CancellableImageProvider<RemoteFullImagePr
|
|||||||
|
|
||||||
final headers = ApiService.getRequestHeaders();
|
final headers = ApiService.getRequestHeaders();
|
||||||
final request = this.request = RemoteImageRequest(
|
final request = this.request = RemoteImageRequest(
|
||||||
uri: getThumbnailUrlForRemoteId(key.assetId, type: AssetMediaSize.preview),
|
uri: getThumbnailUrlForRemoteId(key.assetId, type: AssetMediaSize.preview, thumbhash: key.thumbhash),
|
||||||
headers: headers,
|
headers: headers,
|
||||||
cacheManager: cacheManager,
|
cacheManager: cacheManager,
|
||||||
);
|
);
|
||||||
@@ -115,12 +117,12 @@ class RemoteFullImageProvider extends CancellableImageProvider<RemoteFullImagePr
|
|||||||
bool operator ==(Object other) {
|
bool operator ==(Object other) {
|
||||||
if (identical(this, other)) return true;
|
if (identical(this, other)) return true;
|
||||||
if (other is RemoteFullImageProvider) {
|
if (other is RemoteFullImageProvider) {
|
||||||
return assetId == other.assetId;
|
return assetId == other.assetId && thumbhash == other.thumbhash;
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
int get hashCode => assetId.hashCode;
|
int get hashCode => assetId.hashCode ^ thumbhash.hashCode;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,9 +21,14 @@ class Thumbnail extends StatefulWidget {
|
|||||||
|
|
||||||
const Thumbnail({this.imageProvider, this.fit = BoxFit.cover, this.thumbhashProvider, super.key});
|
const Thumbnail({this.imageProvider, this.fit = BoxFit.cover, this.thumbhashProvider, super.key});
|
||||||
|
|
||||||
Thumbnail.remote({required String remoteId, this.fit = BoxFit.cover, Size size = kThumbnailResolution, super.key})
|
Thumbnail.remote({
|
||||||
: imageProvider = RemoteThumbProvider(assetId: remoteId),
|
required String remoteId,
|
||||||
thumbhashProvider = null;
|
required String thumbhash,
|
||||||
|
this.fit = BoxFit.cover,
|
||||||
|
Size size = kThumbnailResolution,
|
||||||
|
super.key,
|
||||||
|
}) : imageProvider = RemoteThumbProvider(assetId: remoteId, thumbhash: thumbhash),
|
||||||
|
thumbhashProvider = null;
|
||||||
|
|
||||||
Thumbnail.fromAsset({
|
Thumbnail.fromAsset({
|
||||||
required BaseAsset? asset,
|
required BaseAsset? asset,
|
||||||
|
|||||||
@@ -60,7 +60,11 @@ class DriftMemoryCard extends ConsumerWidget {
|
|||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: 205,
|
width: 205,
|
||||||
height: 200,
|
height: 200,
|
||||||
child: Thumbnail.remote(remoteId: memory.assets[0].id, fit: BoxFit.cover),
|
child: Thumbnail.remote(
|
||||||
|
remoteId: memory.assets[0].id,
|
||||||
|
thumbhash: memory.assets[0].thumbHash ?? "",
|
||||||
|
fit: BoxFit.cover,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Positioned(
|
Positioned(
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ class CastNotifier extends StateNotifier<CastManagerState> {
|
|||||||
: AssetType.other,
|
: AssetType.other,
|
||||||
createdAt: asset.fileCreatedAt,
|
createdAt: asset.fileCreatedAt,
|
||||||
updatedAt: asset.updatedAt,
|
updatedAt: asset.updatedAt,
|
||||||
|
isEdited: false,
|
||||||
);
|
);
|
||||||
|
|
||||||
_gCastService.loadMedia(remoteAsset, reload);
|
_gCastService.loadMedia(remoteAsset, reload);
|
||||||
|
|||||||
@@ -144,6 +144,7 @@ class WebsocketNotifier extends StateNotifier<WebsocketState> {
|
|||||||
socket.on('on_asset_hidden', _handleOnAssetHidden);
|
socket.on('on_asset_hidden', _handleOnAssetHidden);
|
||||||
} else {
|
} else {
|
||||||
socket.on('AssetUploadReadyV1', _handleSyncAssetUploadReady);
|
socket.on('AssetUploadReadyV1', _handleSyncAssetUploadReady);
|
||||||
|
socket.on('AssetEditReadyV1', _handleSyncAssetEditReady);
|
||||||
}
|
}
|
||||||
|
|
||||||
socket.on('on_config_update', _handleOnConfigUpdate);
|
socket.on('on_config_update', _handleOnConfigUpdate);
|
||||||
@@ -192,10 +193,12 @@ class WebsocketNotifier extends StateNotifier<WebsocketState> {
|
|||||||
|
|
||||||
void stopListeningToBetaEvents() {
|
void stopListeningToBetaEvents() {
|
||||||
state.socket?.off('AssetUploadReadyV1');
|
state.socket?.off('AssetUploadReadyV1');
|
||||||
|
state.socket?.off('AssetEditReadyV1');
|
||||||
}
|
}
|
||||||
|
|
||||||
void startListeningToBetaEvents() {
|
void startListeningToBetaEvents() {
|
||||||
state.socket?.on('AssetUploadReadyV1', _handleSyncAssetUploadReady);
|
state.socket?.on('AssetUploadReadyV1', _handleSyncAssetUploadReady);
|
||||||
|
state.socket?.on('AssetEditReadyV1', _handleSyncAssetEditReady);
|
||||||
}
|
}
|
||||||
|
|
||||||
void listenUploadEvent() {
|
void listenUploadEvent() {
|
||||||
@@ -315,6 +318,10 @@ class WebsocketNotifier extends StateNotifier<WebsocketState> {
|
|||||||
_batchDebouncer.run(_processBatchedAssetUploadReady);
|
_batchDebouncer.run(_processBatchedAssetUploadReady);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _handleSyncAssetEditReady(dynamic data) {
|
||||||
|
unawaited(_ref.read(backgroundSyncProvider).syncWebsocketEditBatch([data]));
|
||||||
|
}
|
||||||
|
|
||||||
void _processBatchedAssetUploadReady() {
|
void _processBatchedAssetUploadReady() {
|
||||||
if (_batchedAssetUploadReady.isEmpty) {
|
if (_batchedAssetUploadReady.isEmpty) {
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ class FileMediaRepository {
|
|||||||
type: AssetType.image,
|
type: AssetType.image,
|
||||||
createdAt: entity.createDateTime,
|
createdAt: entity.createDateTime,
|
||||||
updatedAt: entity.modifiedDateTime,
|
updatedAt: entity.modifiedDateTime,
|
||||||
|
isEdited: false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -50,8 +50,10 @@ String getThumbnailUrlForRemoteId(
|
|||||||
final String id, {
|
final String id, {
|
||||||
AssetMediaSize type = AssetMediaSize.thumbnail,
|
AssetMediaSize type = AssetMediaSize.thumbnail,
|
||||||
bool edited = true,
|
bool edited = true,
|
||||||
|
String? thumbhash,
|
||||||
}) {
|
}) {
|
||||||
return '${Store.get(StoreKey.serverEndpoint)}/assets/$id/thumbnail?size=${type.value}&edited=$edited';
|
final url = '${Store.get(StoreKey.serverEndpoint)}/assets/$id/thumbnail?size=${type.value}&edited=$edited';
|
||||||
|
return thumbhash != null ? '$url&c=${Uri.encodeComponent(thumbhash)}' : url;
|
||||||
}
|
}
|
||||||
|
|
||||||
String getPlaybackUrlForRemoteId(final String id) {
|
String getPlaybackUrlForRemoteId(final String id) {
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ dynamic upgradeDto(dynamic value, String targetType) {
|
|||||||
}
|
}
|
||||||
case 'SyncAssetV1':
|
case 'SyncAssetV1':
|
||||||
if (value is Map) {
|
if (value is Map) {
|
||||||
addDefault(value, 'editCount', 0);
|
addDefault(value, 'isEdited', false);
|
||||||
}
|
}
|
||||||
case 'ServerFeaturesDto':
|
case 'ServerFeaturesDto':
|
||||||
if (value is Map) {
|
if (value is Map) {
|
||||||
|
|||||||
+9
-9
@@ -16,11 +16,11 @@ class SyncAssetV1 {
|
|||||||
required this.checksum,
|
required this.checksum,
|
||||||
required this.deletedAt,
|
required this.deletedAt,
|
||||||
required this.duration,
|
required this.duration,
|
||||||
required this.editCount,
|
|
||||||
required this.fileCreatedAt,
|
required this.fileCreatedAt,
|
||||||
required this.fileModifiedAt,
|
required this.fileModifiedAt,
|
||||||
required this.height,
|
required this.height,
|
||||||
required this.id,
|
required this.id,
|
||||||
|
required this.isEdited,
|
||||||
required this.isFavorite,
|
required this.isFavorite,
|
||||||
required this.libraryId,
|
required this.libraryId,
|
||||||
required this.livePhotoVideoId,
|
required this.livePhotoVideoId,
|
||||||
@@ -40,8 +40,6 @@ class SyncAssetV1 {
|
|||||||
|
|
||||||
String? duration;
|
String? duration;
|
||||||
|
|
||||||
int editCount;
|
|
||||||
|
|
||||||
DateTime? fileCreatedAt;
|
DateTime? fileCreatedAt;
|
||||||
|
|
||||||
DateTime? fileModifiedAt;
|
DateTime? fileModifiedAt;
|
||||||
@@ -50,6 +48,8 @@ class SyncAssetV1 {
|
|||||||
|
|
||||||
String id;
|
String id;
|
||||||
|
|
||||||
|
bool isEdited;
|
||||||
|
|
||||||
bool isFavorite;
|
bool isFavorite;
|
||||||
|
|
||||||
String? libraryId;
|
String? libraryId;
|
||||||
@@ -77,11 +77,11 @@ class SyncAssetV1 {
|
|||||||
other.checksum == checksum &&
|
other.checksum == checksum &&
|
||||||
other.deletedAt == deletedAt &&
|
other.deletedAt == deletedAt &&
|
||||||
other.duration == duration &&
|
other.duration == duration &&
|
||||||
other.editCount == editCount &&
|
|
||||||
other.fileCreatedAt == fileCreatedAt &&
|
other.fileCreatedAt == fileCreatedAt &&
|
||||||
other.fileModifiedAt == fileModifiedAt &&
|
other.fileModifiedAt == fileModifiedAt &&
|
||||||
other.height == height &&
|
other.height == height &&
|
||||||
other.id == id &&
|
other.id == id &&
|
||||||
|
other.isEdited == isEdited &&
|
||||||
other.isFavorite == isFavorite &&
|
other.isFavorite == isFavorite &&
|
||||||
other.libraryId == libraryId &&
|
other.libraryId == libraryId &&
|
||||||
other.livePhotoVideoId == livePhotoVideoId &&
|
other.livePhotoVideoId == livePhotoVideoId &&
|
||||||
@@ -100,11 +100,11 @@ class SyncAssetV1 {
|
|||||||
(checksum.hashCode) +
|
(checksum.hashCode) +
|
||||||
(deletedAt == null ? 0 : deletedAt!.hashCode) +
|
(deletedAt == null ? 0 : deletedAt!.hashCode) +
|
||||||
(duration == null ? 0 : duration!.hashCode) +
|
(duration == null ? 0 : duration!.hashCode) +
|
||||||
(editCount.hashCode) +
|
|
||||||
(fileCreatedAt == null ? 0 : fileCreatedAt!.hashCode) +
|
(fileCreatedAt == null ? 0 : fileCreatedAt!.hashCode) +
|
||||||
(fileModifiedAt == null ? 0 : fileModifiedAt!.hashCode) +
|
(fileModifiedAt == null ? 0 : fileModifiedAt!.hashCode) +
|
||||||
(height == null ? 0 : height!.hashCode) +
|
(height == null ? 0 : height!.hashCode) +
|
||||||
(id.hashCode) +
|
(id.hashCode) +
|
||||||
|
(isEdited.hashCode) +
|
||||||
(isFavorite.hashCode) +
|
(isFavorite.hashCode) +
|
||||||
(libraryId == null ? 0 : libraryId!.hashCode) +
|
(libraryId == null ? 0 : libraryId!.hashCode) +
|
||||||
(livePhotoVideoId == null ? 0 : livePhotoVideoId!.hashCode) +
|
(livePhotoVideoId == null ? 0 : livePhotoVideoId!.hashCode) +
|
||||||
@@ -118,7 +118,7 @@ class SyncAssetV1 {
|
|||||||
(width == null ? 0 : width!.hashCode);
|
(width == null ? 0 : width!.hashCode);
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() => 'SyncAssetV1[checksum=$checksum, deletedAt=$deletedAt, duration=$duration, editCount=$editCount, fileCreatedAt=$fileCreatedAt, fileModifiedAt=$fileModifiedAt, height=$height, id=$id, isFavorite=$isFavorite, libraryId=$libraryId, livePhotoVideoId=$livePhotoVideoId, localDateTime=$localDateTime, originalFileName=$originalFileName, ownerId=$ownerId, stackId=$stackId, thumbhash=$thumbhash, type=$type, visibility=$visibility, width=$width]';
|
String toString() => 'SyncAssetV1[checksum=$checksum, deletedAt=$deletedAt, duration=$duration, fileCreatedAt=$fileCreatedAt, fileModifiedAt=$fileModifiedAt, height=$height, id=$id, isEdited=$isEdited, isFavorite=$isFavorite, libraryId=$libraryId, livePhotoVideoId=$livePhotoVideoId, localDateTime=$localDateTime, originalFileName=$originalFileName, ownerId=$ownerId, stackId=$stackId, thumbhash=$thumbhash, type=$type, visibility=$visibility, width=$width]';
|
||||||
|
|
||||||
Map<String, dynamic> toJson() {
|
Map<String, dynamic> toJson() {
|
||||||
final json = <String, dynamic>{};
|
final json = <String, dynamic>{};
|
||||||
@@ -133,7 +133,6 @@ class SyncAssetV1 {
|
|||||||
} else {
|
} else {
|
||||||
// json[r'duration'] = null;
|
// json[r'duration'] = null;
|
||||||
}
|
}
|
||||||
json[r'editCount'] = this.editCount;
|
|
||||||
if (this.fileCreatedAt != null) {
|
if (this.fileCreatedAt != null) {
|
||||||
json[r'fileCreatedAt'] = this.fileCreatedAt!.toUtc().toIso8601String();
|
json[r'fileCreatedAt'] = this.fileCreatedAt!.toUtc().toIso8601String();
|
||||||
} else {
|
} else {
|
||||||
@@ -150,6 +149,7 @@ class SyncAssetV1 {
|
|||||||
// json[r'height'] = null;
|
// json[r'height'] = null;
|
||||||
}
|
}
|
||||||
json[r'id'] = this.id;
|
json[r'id'] = this.id;
|
||||||
|
json[r'isEdited'] = this.isEdited;
|
||||||
json[r'isFavorite'] = this.isFavorite;
|
json[r'isFavorite'] = this.isFavorite;
|
||||||
if (this.libraryId != null) {
|
if (this.libraryId != null) {
|
||||||
json[r'libraryId'] = this.libraryId;
|
json[r'libraryId'] = this.libraryId;
|
||||||
@@ -200,11 +200,11 @@ class SyncAssetV1 {
|
|||||||
checksum: mapValueOfType<String>(json, r'checksum')!,
|
checksum: mapValueOfType<String>(json, r'checksum')!,
|
||||||
deletedAt: mapDateTime(json, r'deletedAt', r''),
|
deletedAt: mapDateTime(json, r'deletedAt', r''),
|
||||||
duration: mapValueOfType<String>(json, r'duration'),
|
duration: mapValueOfType<String>(json, r'duration'),
|
||||||
editCount: mapValueOfType<int>(json, r'editCount')!,
|
|
||||||
fileCreatedAt: mapDateTime(json, r'fileCreatedAt', r''),
|
fileCreatedAt: mapDateTime(json, r'fileCreatedAt', r''),
|
||||||
fileModifiedAt: mapDateTime(json, r'fileModifiedAt', r''),
|
fileModifiedAt: mapDateTime(json, r'fileModifiedAt', r''),
|
||||||
height: mapValueOfType<int>(json, r'height'),
|
height: mapValueOfType<int>(json, r'height'),
|
||||||
id: mapValueOfType<String>(json, r'id')!,
|
id: mapValueOfType<String>(json, r'id')!,
|
||||||
|
isEdited: mapValueOfType<bool>(json, r'isEdited')!,
|
||||||
isFavorite: mapValueOfType<bool>(json, r'isFavorite')!,
|
isFavorite: mapValueOfType<bool>(json, r'isFavorite')!,
|
||||||
libraryId: mapValueOfType<String>(json, r'libraryId'),
|
libraryId: mapValueOfType<String>(json, r'libraryId'),
|
||||||
livePhotoVideoId: mapValueOfType<String>(json, r'livePhotoVideoId'),
|
livePhotoVideoId: mapValueOfType<String>(json, r'livePhotoVideoId'),
|
||||||
@@ -266,11 +266,11 @@ class SyncAssetV1 {
|
|||||||
'checksum',
|
'checksum',
|
||||||
'deletedAt',
|
'deletedAt',
|
||||||
'duration',
|
'duration',
|
||||||
'editCount',
|
|
||||||
'fileCreatedAt',
|
'fileCreatedAt',
|
||||||
'fileModifiedAt',
|
'fileModifiedAt',
|
||||||
'height',
|
'height',
|
||||||
'id',
|
'id',
|
||||||
|
'isEdited',
|
||||||
'isFavorite',
|
'isFavorite',
|
||||||
'libraryId',
|
'libraryId',
|
||||||
'livePhotoVideoId',
|
'livePhotoVideoId',
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ SyncAssetV1 _createAsset({
|
|||||||
livePhotoVideoId: null,
|
livePhotoVideoId: null,
|
||||||
stackId: null,
|
stackId: null,
|
||||||
thumbhash: null,
|
thumbhash: null,
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+4
@@ -19,6 +19,7 @@ import 'schema_v13.dart' as v13;
|
|||||||
import 'schema_v14.dart' as v14;
|
import 'schema_v14.dart' as v14;
|
||||||
import 'schema_v15.dart' as v15;
|
import 'schema_v15.dart' as v15;
|
||||||
import 'schema_v16.dart' as v16;
|
import 'schema_v16.dart' as v16;
|
||||||
|
import 'schema_v17.dart' as v17;
|
||||||
|
|
||||||
class GeneratedHelper implements SchemaInstantiationHelper {
|
class GeneratedHelper implements SchemaInstantiationHelper {
|
||||||
@override
|
@override
|
||||||
@@ -56,6 +57,8 @@ class GeneratedHelper implements SchemaInstantiationHelper {
|
|||||||
return v15.DatabaseAtV15(db);
|
return v15.DatabaseAtV15(db);
|
||||||
case 16:
|
case 16:
|
||||||
return v16.DatabaseAtV16(db);
|
return v16.DatabaseAtV16(db);
|
||||||
|
case 17:
|
||||||
|
return v17.DatabaseAtV17(db);
|
||||||
default:
|
default:
|
||||||
throw MissingSchemaException(version, versions);
|
throw MissingSchemaException(version, versions);
|
||||||
}
|
}
|
||||||
@@ -78,5 +81,6 @@ class GeneratedHelper implements SchemaInstantiationHelper {
|
|||||||
14,
|
14,
|
||||||
15,
|
15,
|
||||||
16,
|
16,
|
||||||
|
17,
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
+8337
File diff suppressed because it is too large
Load Diff
Vendored
+2
@@ -64,6 +64,7 @@ abstract final class LocalAssetStub {
|
|||||||
type: AssetType.image,
|
type: AssetType.image,
|
||||||
createdAt: DateTime(2025),
|
createdAt: DateTime(2025),
|
||||||
updatedAt: DateTime(2025, 2),
|
updatedAt: DateTime(2025, 2),
|
||||||
|
isEdited: false,
|
||||||
);
|
);
|
||||||
|
|
||||||
static final image2 = LocalAsset(
|
static final image2 = LocalAsset(
|
||||||
@@ -72,5 +73,6 @@ abstract final class LocalAssetStub {
|
|||||||
type: AssetType.image,
|
type: AssetType.image,
|
||||||
createdAt: DateTime(2000),
|
createdAt: DateTime(2000),
|
||||||
updatedAt: DateTime(20021),
|
updatedAt: DateTime(20021),
|
||||||
|
isEdited: false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -128,7 +128,7 @@ abstract final class SyncStreamStub {
|
|||||||
visibility: AssetVisibility.timeline,
|
visibility: AssetVisibility.timeline,
|
||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
),
|
),
|
||||||
ack: ack,
|
ack: ack,
|
||||||
);
|
);
|
||||||
|
|||||||
@@ -194,6 +194,7 @@ void main() {
|
|||||||
latitude: 37.7749,
|
latitude: 37.7749,
|
||||||
longitude: -122.4194,
|
longitude: -122.4194,
|
||||||
adjustmentTime: DateTime(2026, 1, 2),
|
adjustmentTime: DateTime(2026, 1, 2),
|
||||||
|
isEdited: false,
|
||||||
);
|
);
|
||||||
|
|
||||||
final mockEntity = MockAssetEntity();
|
final mockEntity = MockAssetEntity();
|
||||||
@@ -242,6 +243,7 @@ void main() {
|
|||||||
cloudId: 'cloud-id-123',
|
cloudId: 'cloud-id-123',
|
||||||
latitude: 37.7749,
|
latitude: 37.7749,
|
||||||
longitude: -122.4194,
|
longitude: -122.4194,
|
||||||
|
isEdited: false,
|
||||||
);
|
);
|
||||||
|
|
||||||
final mockEntity = MockAssetEntity();
|
final mockEntity = MockAssetEntity();
|
||||||
@@ -279,6 +281,7 @@ void main() {
|
|||||||
createdAt: DateTime(2025, 1, 1),
|
createdAt: DateTime(2025, 1, 1),
|
||||||
updatedAt: DateTime(2025, 1, 2),
|
updatedAt: DateTime(2025, 1, 2),
|
||||||
cloudId: null, // No cloudId
|
cloudId: null, // No cloudId
|
||||||
|
isEdited: false,
|
||||||
);
|
);
|
||||||
|
|
||||||
final mockEntity = MockAssetEntity();
|
final mockEntity = MockAssetEntity();
|
||||||
@@ -320,6 +323,7 @@ void main() {
|
|||||||
cloudId: 'cloud-id-livephoto',
|
cloudId: 'cloud-id-livephoto',
|
||||||
latitude: 37.7749,
|
latitude: 37.7749,
|
||||||
longitude: -122.4194,
|
longitude: -122.4194,
|
||||||
|
isEdited: false,
|
||||||
);
|
);
|
||||||
|
|
||||||
final mockEntity = MockAssetEntity();
|
final mockEntity = MockAssetEntity();
|
||||||
|
|||||||
@@ -131,6 +131,7 @@ abstract final class TestUtils {
|
|||||||
isFavorite: false,
|
isFavorite: false,
|
||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
|
isEdited: false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -154,6 +155,7 @@ abstract final class TestUtils {
|
|||||||
width: width,
|
width: width,
|
||||||
height: height,
|
height: height,
|
||||||
orientation: orientation,
|
orientation: orientation,
|
||||||
|
isEdited: false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,6 +27,7 @@ class MediumFactory {
|
|||||||
type: type ?? AssetType.image,
|
type: type ?? AssetType.image,
|
||||||
createdAt: createdAt ?? DateTime.fromMillisecondsSinceEpoch(random.nextInt(1000000000)),
|
createdAt: createdAt ?? DateTime.fromMillisecondsSinceEpoch(random.nextInt(1000000000)),
|
||||||
updatedAt: updatedAt ?? DateTime.fromMillisecondsSinceEpoch(random.nextInt(1000000000)),
|
updatedAt: updatedAt ?? DateTime.fromMillisecondsSinceEpoch(random.nextInt(1000000000)),
|
||||||
|
isEdited: false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ LocalAsset createLocalAsset({
|
|||||||
createdAt: createdAt ?? DateTime.now(),
|
createdAt: createdAt ?? DateTime.now(),
|
||||||
updatedAt: updatedAt ?? DateTime.now(),
|
updatedAt: updatedAt ?? DateTime.now(),
|
||||||
isFavorite: isFavorite,
|
isFavorite: isFavorite,
|
||||||
|
isEdited: false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,6 +46,7 @@ RemoteAsset createRemoteAsset({
|
|||||||
createdAt: createdAt ?? DateTime.now(),
|
createdAt: createdAt ?? DateTime.now(),
|
||||||
updatedAt: updatedAt ?? DateTime.now(),
|
updatedAt: updatedAt ?? DateTime.now(),
|
||||||
isFavorite: isFavorite,
|
isFavorite: isFavorite,
|
||||||
|
isEdited: false,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -21291,9 +21291,6 @@
|
|||||||
"nullable": true,
|
"nullable": true,
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
"editCount": {
|
|
||||||
"type": "integer"
|
|
||||||
},
|
|
||||||
"fileCreatedAt": {
|
"fileCreatedAt": {
|
||||||
"format": "date-time",
|
"format": "date-time",
|
||||||
"nullable": true,
|
"nullable": true,
|
||||||
@@ -21311,6 +21308,9 @@
|
|||||||
"id": {
|
"id": {
|
||||||
"type": "string"
|
"type": "string"
|
||||||
},
|
},
|
||||||
|
"isEdited": {
|
||||||
|
"type": "boolean"
|
||||||
|
},
|
||||||
"isFavorite": {
|
"isFavorite": {
|
||||||
"type": "boolean"
|
"type": "boolean"
|
||||||
},
|
},
|
||||||
@@ -21364,11 +21364,11 @@
|
|||||||
"checksum",
|
"checksum",
|
||||||
"deletedAt",
|
"deletedAt",
|
||||||
"duration",
|
"duration",
|
||||||
"editCount",
|
|
||||||
"fileCreatedAt",
|
"fileCreatedAt",
|
||||||
"fileModifiedAt",
|
"fileModifiedAt",
|
||||||
"height",
|
"height",
|
||||||
"id",
|
"id",
|
||||||
|
"isEdited",
|
||||||
"isFavorite",
|
"isFavorite",
|
||||||
"libraryId",
|
"libraryId",
|
||||||
"livePhotoVideoId",
|
"livePhotoVideoId",
|
||||||
|
|||||||
@@ -395,7 +395,7 @@ export const columns = {
|
|||||||
'asset.libraryId',
|
'asset.libraryId',
|
||||||
'asset.width',
|
'asset.width',
|
||||||
'asset.height',
|
'asset.height',
|
||||||
'asset.editCount',
|
'asset.isEdited',
|
||||||
],
|
],
|
||||||
syncAlbumUser: ['album_user.albumId as albumId', 'album_user.userId as userId', 'album_user.role'],
|
syncAlbumUser: ['album_user.albumId as albumId', 'album_user.userId as userId', 'album_user.role'],
|
||||||
syncStack: ['stack.id', 'stack.createdAt', 'stack.updatedAt', 'stack.primaryAssetId', 'stack.ownerId'],
|
syncStack: ['stack.id', 'stack.createdAt', 'stack.updatedAt', 'stack.primaryAssetId', 'stack.ownerId'],
|
||||||
|
|||||||
@@ -139,7 +139,7 @@ export type MapAsset = {
|
|||||||
type: AssetType;
|
type: AssetType;
|
||||||
width: number | null;
|
width: number | null;
|
||||||
height: number | null;
|
height: number | null;
|
||||||
editCount: number;
|
isEdited: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
export class AssetStackResponseDto {
|
export class AssetStackResponseDto {
|
||||||
@@ -248,6 +248,6 @@ export function mapAsset(entity: MapAsset, options: AssetMapOptions = {}): Asset
|
|||||||
resized: true,
|
resized: true,
|
||||||
width: entity.width,
|
width: entity.width,
|
||||||
height: entity.height,
|
height: entity.height,
|
||||||
isEdited: entity.editCount > 0,
|
isEdited: entity.isEdited,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -121,8 +121,8 @@ export class SyncAssetV1 {
|
|||||||
width!: number | null;
|
width!: number | null;
|
||||||
@ApiProperty({ type: 'integer' })
|
@ApiProperty({ type: 'integer' })
|
||||||
height!: number | null;
|
height!: number | null;
|
||||||
@ApiProperty({ type: 'integer' })
|
@ApiProperty({ type: 'boolean' })
|
||||||
editCount!: number;
|
isEdited!: boolean;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ExtraModel()
|
@ExtraModel()
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ select
|
|||||||
"asset"."libraryId",
|
"asset"."libraryId",
|
||||||
"asset"."width",
|
"asset"."width",
|
||||||
"asset"."height",
|
"asset"."height",
|
||||||
"asset"."editCount",
|
"asset"."isEdited",
|
||||||
"album_asset"."updateId"
|
"album_asset"."updateId"
|
||||||
from
|
from
|
||||||
"album_asset" as "album_asset"
|
"album_asset" as "album_asset"
|
||||||
@@ -104,7 +104,7 @@ select
|
|||||||
"asset"."libraryId",
|
"asset"."libraryId",
|
||||||
"asset"."width",
|
"asset"."width",
|
||||||
"asset"."height",
|
"asset"."height",
|
||||||
"asset"."editCount",
|
"asset"."isEdited",
|
||||||
"asset"."updateId"
|
"asset"."updateId"
|
||||||
from
|
from
|
||||||
"asset" as "asset"
|
"asset" as "asset"
|
||||||
@@ -143,7 +143,7 @@ select
|
|||||||
"asset"."libraryId",
|
"asset"."libraryId",
|
||||||
"asset"."width",
|
"asset"."width",
|
||||||
"asset"."height",
|
"asset"."height",
|
||||||
"asset"."editCount"
|
"asset"."isEdited"
|
||||||
from
|
from
|
||||||
"album_asset" as "album_asset"
|
"album_asset" as "album_asset"
|
||||||
inner join "asset" on "asset"."id" = "album_asset"."assetId"
|
inner join "asset" on "asset"."id" = "album_asset"."assetId"
|
||||||
@@ -459,7 +459,7 @@ select
|
|||||||
"asset"."libraryId",
|
"asset"."libraryId",
|
||||||
"asset"."width",
|
"asset"."width",
|
||||||
"asset"."height",
|
"asset"."height",
|
||||||
"asset"."editCount",
|
"asset"."isEdited",
|
||||||
"asset"."updateId"
|
"asset"."updateId"
|
||||||
from
|
from
|
||||||
"asset" as "asset"
|
"asset" as "asset"
|
||||||
@@ -755,7 +755,7 @@ select
|
|||||||
"asset"."libraryId",
|
"asset"."libraryId",
|
||||||
"asset"."width",
|
"asset"."width",
|
||||||
"asset"."height",
|
"asset"."height",
|
||||||
"asset"."editCount",
|
"asset"."isEdited",
|
||||||
"asset"."updateId"
|
"asset"."updateId"
|
||||||
from
|
from
|
||||||
"asset" as "asset"
|
"asset" as "asset"
|
||||||
@@ -807,7 +807,7 @@ select
|
|||||||
"asset"."libraryId",
|
"asset"."libraryId",
|
||||||
"asset"."width",
|
"asset"."width",
|
||||||
"asset"."height",
|
"asset"."height",
|
||||||
"asset"."editCount",
|
"asset"."isEdited",
|
||||||
"asset"."updateId"
|
"asset"."updateId"
|
||||||
from
|
from
|
||||||
"asset" as "asset"
|
"asset" as "asset"
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ export interface ClientEventMap {
|
|||||||
|
|
||||||
AssetUploadReadyV1: [{ asset: SyncAssetV1; exif: SyncAssetExifV1 }];
|
AssetUploadReadyV1: [{ asset: SyncAssetV1; exif: SyncAssetExifV1 }];
|
||||||
AppRestartV1: [AppRestartEvent];
|
AppRestartV1: [AppRestartEvent];
|
||||||
AssetEditReadyV1: [{ assetId: string }];
|
AssetEditReadyV1: [{ asset: SyncAssetV1 }];
|
||||||
}
|
}
|
||||||
|
|
||||||
export type AuthFn = (client: Socket) => Promise<AuthDto>;
|
export type AuthFn = (client: Socket) => Promise<AuthDto>;
|
||||||
|
|||||||
@@ -263,8 +263,9 @@ export const asset_edit_insert = registerFunction({
|
|||||||
body: `
|
body: `
|
||||||
BEGIN
|
BEGIN
|
||||||
UPDATE asset
|
UPDATE asset
|
||||||
SET "editCount" = "editCount" + 1
|
SET "isEdited" = true
|
||||||
WHERE "id" = NEW."assetId";
|
FROM inserted_edit
|
||||||
|
WHERE asset.id = inserted_edit."assetId" AND NOT asset."isEdited";
|
||||||
RETURN NULL;
|
RETURN NULL;
|
||||||
END
|
END
|
||||||
`,
|
`,
|
||||||
@@ -277,8 +278,10 @@ export const asset_edit_delete = registerFunction({
|
|||||||
body: `
|
body: `
|
||||||
BEGIN
|
BEGIN
|
||||||
UPDATE asset
|
UPDATE asset
|
||||||
SET "editCount" = "editCount" - 1
|
SET "isEdited" = false
|
||||||
WHERE "id" = OLD."assetId";
|
FROM deleted_edit
|
||||||
|
WHERE asset.id = deleted_edit."assetId" AND asset."isEdited"
|
||||||
|
AND NOT EXISTS (SELECT FROM asset_edit edit WHERE edit."assetId" = asset.id);
|
||||||
RETURN NULL;
|
RETURN NULL;
|
||||||
END
|
END
|
||||||
`,
|
`,
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
import { Kysely, sql } from 'kysely';
|
||||||
|
|
||||||
|
export async function up(db: Kysely<any>): Promise<void> {
|
||||||
|
await sql`CREATE OR REPLACE FUNCTION asset_edit_insert()
|
||||||
|
RETURNS TRIGGER
|
||||||
|
LANGUAGE PLPGSQL
|
||||||
|
AS $$
|
||||||
|
BEGIN
|
||||||
|
UPDATE asset
|
||||||
|
SET "isEdited" = true
|
||||||
|
FROM inserted_edit
|
||||||
|
WHERE asset.id = inserted_edit."assetId" AND NOT asset."isEdited";
|
||||||
|
RETURN NULL;
|
||||||
|
END
|
||||||
|
$$;`.execute(db);
|
||||||
|
await sql`CREATE OR REPLACE FUNCTION asset_edit_delete()
|
||||||
|
RETURNS TRIGGER
|
||||||
|
LANGUAGE PLPGSQL
|
||||||
|
AS $$
|
||||||
|
BEGIN
|
||||||
|
UPDATE asset
|
||||||
|
SET "isEdited" = false
|
||||||
|
FROM deleted_edit
|
||||||
|
WHERE asset.id = deleted_edit."assetId" AND asset."isEdited"
|
||||||
|
AND NOT EXISTS (SELECT FROM asset_edit edit WHERE edit."assetId" = asset.id);
|
||||||
|
RETURN NULL;
|
||||||
|
END
|
||||||
|
$$;`.execute(db);
|
||||||
|
await sql`ALTER TABLE "asset" ADD "isEdited" boolean NOT NULL DEFAULT false;`.execute(db);
|
||||||
|
await sql`CREATE OR REPLACE TRIGGER "asset_edit_delete"
|
||||||
|
AFTER DELETE ON "asset_edit"
|
||||||
|
REFERENCING OLD TABLE AS "deleted_edit"
|
||||||
|
FOR EACH STATEMENT
|
||||||
|
WHEN (pg_trigger_depth() = 0)
|
||||||
|
EXECUTE FUNCTION asset_edit_delete();`.execute(db);
|
||||||
|
await sql`CREATE OR REPLACE TRIGGER "asset_edit_insert"
|
||||||
|
AFTER INSERT ON "asset_edit"
|
||||||
|
REFERENCING NEW TABLE AS "inserted_edit"
|
||||||
|
FOR EACH STATEMENT
|
||||||
|
EXECUTE FUNCTION asset_edit_insert();`.execute(db);
|
||||||
|
await sql`ALTER TABLE "asset" DROP COLUMN "editCount";`.execute(db);
|
||||||
|
await sql`UPDATE "migration_overrides" SET "value" = '{"type":"function","name":"asset_edit_insert","sql":"CREATE OR REPLACE FUNCTION asset_edit_insert()\\n RETURNS TRIGGER\\n LANGUAGE PLPGSQL\\n AS $$\\n BEGIN\\n UPDATE asset\\n SET \\"isEdited\\" = true\\n FROM inserted_edit\\n WHERE asset.id = inserted_edit.\\"assetId\\" AND NOT asset.\\"isEdited\\";\\n RETURN NULL;\\n END\\n $$;"}'::jsonb WHERE "name" = 'function_asset_edit_insert';`.execute(db);
|
||||||
|
await sql`UPDATE "migration_overrides" SET "value" = '{"type":"function","name":"asset_edit_delete","sql":"CREATE OR REPLACE FUNCTION asset_edit_delete()\\n RETURNS TRIGGER\\n LANGUAGE PLPGSQL\\n AS $$\\n BEGIN\\n UPDATE asset\\n SET \\"isEdited\\" = false\\n FROM deleted_edit\\n WHERE asset.id = deleted_edit.\\"assetId\\" AND asset.\\"isEdited\\" \\n AND NOT EXISTS (SELECT FROM asset_edit edit WHERE edit.\\"assetId\\" = asset.id);\\n RETURN NULL;\\n END\\n $$;"}'::jsonb WHERE "name" = 'function_asset_edit_delete';`.execute(db);
|
||||||
|
await sql`UPDATE "migration_overrides" SET "value" = '{"type":"trigger","name":"asset_edit_delete","sql":"CREATE OR REPLACE TRIGGER \\"asset_edit_delete\\"\\n AFTER DELETE ON \\"asset_edit\\"\\n REFERENCING OLD TABLE AS \\"deleted_edit\\"\\n FOR EACH STATEMENT\\n WHEN (pg_trigger_depth() = 0)\\n EXECUTE FUNCTION asset_edit_delete();"}'::jsonb WHERE "name" = 'trigger_asset_edit_delete';`.execute(db);
|
||||||
|
await sql`UPDATE "migration_overrides" SET "value" = '{"type":"trigger","name":"asset_edit_insert","sql":"CREATE OR REPLACE TRIGGER \\"asset_edit_insert\\"\\n AFTER INSERT ON \\"asset_edit\\"\\n REFERENCING NEW TABLE AS \\"inserted_edit\\"\\n FOR EACH STATEMENT\\n EXECUTE FUNCTION asset_edit_insert();"}'::jsonb WHERE "name" = 'trigger_asset_edit_insert';`.execute(db);
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function down(db: Kysely<any>): Promise<void> {
|
||||||
|
await sql`CREATE OR REPLACE FUNCTION public.asset_edit_insert()
|
||||||
|
RETURNS trigger
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS $function$
|
||||||
|
BEGIN
|
||||||
|
UPDATE asset
|
||||||
|
SET "editCount" = "editCount" + 1
|
||||||
|
WHERE "id" = NEW."assetId";
|
||||||
|
RETURN NULL;
|
||||||
|
END
|
||||||
|
$function$
|
||||||
|
`.execute(db);
|
||||||
|
await sql`CREATE OR REPLACE FUNCTION public.asset_edit_delete()
|
||||||
|
RETURNS trigger
|
||||||
|
LANGUAGE plpgsql
|
||||||
|
AS $function$
|
||||||
|
BEGIN
|
||||||
|
UPDATE asset
|
||||||
|
SET "editCount" = "editCount" - 1
|
||||||
|
WHERE "id" = OLD."assetId";
|
||||||
|
RETURN NULL;
|
||||||
|
END
|
||||||
|
$function$
|
||||||
|
`.execute(db);
|
||||||
|
await sql`ALTER TABLE "asset" ADD "editCount" integer NOT NULL DEFAULT 0;`.execute(db);
|
||||||
|
await sql`CREATE OR REPLACE TRIGGER "asset_edit_delete"
|
||||||
|
AFTER DELETE ON "asset_edit"
|
||||||
|
REFERENCING OLD TABLE AS "old"
|
||||||
|
FOR EACH ROW
|
||||||
|
WHEN ((pg_trigger_depth() = 0))
|
||||||
|
EXECUTE FUNCTION asset_edit_delete();`.execute(db);
|
||||||
|
await sql`CREATE OR REPLACE TRIGGER "asset_edit_insert"
|
||||||
|
AFTER INSERT ON "asset_edit"
|
||||||
|
FOR EACH ROW
|
||||||
|
EXECUTE FUNCTION asset_edit_insert();`.execute(db);
|
||||||
|
await sql`ALTER TABLE "asset" DROP COLUMN "isEdited";`.execute(db);
|
||||||
|
await sql`UPDATE "migration_overrides" SET "value" = '{"sql":"CREATE OR REPLACE FUNCTION asset_edit_insert()\\n RETURNS TRIGGER\\n LANGUAGE PLPGSQL\\n AS $$\\n BEGIN\\n UPDATE asset\\n SET \\"editCount\\" = \\"editCount\\" + 1\\n WHERE \\"id\\" = NEW.\\"assetId\\";\\n RETURN NULL;\\n END\\n $$;","name":"asset_edit_insert","type":"function"}'::jsonb WHERE "name" = 'function_asset_edit_insert';`.execute(db);
|
||||||
|
await sql`UPDATE "migration_overrides" SET "value" = '{"sql":"CREATE OR REPLACE FUNCTION asset_edit_delete()\\n RETURNS TRIGGER\\n LANGUAGE PLPGSQL\\n AS $$\\n BEGIN\\n UPDATE asset\\n SET \\"editCount\\" = \\"editCount\\" - 1\\n WHERE \\"id\\" = OLD.\\"assetId\\";\\n RETURN NULL;\\n END\\n $$;","name":"asset_edit_delete","type":"function"}'::jsonb WHERE "name" = 'function_asset_edit_delete';`.execute(db);
|
||||||
|
await sql`UPDATE "migration_overrides" SET "value" = '{"sql":"CREATE OR REPLACE TRIGGER \\"asset_edit_delete\\"\\n AFTER DELETE ON \\"asset_edit\\"\\n REFERENCING OLD TABLE AS \\"old\\"\\n FOR EACH ROW\\n WHEN (pg_trigger_depth() = 0)\\n EXECUTE FUNCTION asset_edit_delete();","name":"asset_edit_delete","type":"trigger"}'::jsonb WHERE "name" = 'trigger_asset_edit_delete';`.execute(db);
|
||||||
|
await sql`UPDATE "migration_overrides" SET "value" = '{"sql":"CREATE OR REPLACE TRIGGER \\"asset_edit_insert\\"\\n AFTER INSERT ON \\"asset_edit\\"\\n FOR EACH ROW\\n EXECUTE FUNCTION asset_edit_insert();","name":"asset_edit_insert","type":"trigger"}'::jsonb WHERE "name" = 'trigger_asset_edit_insert';`.execute(db);
|
||||||
|
}
|
||||||
@@ -12,11 +12,11 @@ import {
|
|||||||
} from 'src/sql-tools';
|
} from 'src/sql-tools';
|
||||||
|
|
||||||
@Table('asset_edit')
|
@Table('asset_edit')
|
||||||
@AfterInsertTrigger({ scope: 'row', function: asset_edit_insert })
|
@AfterInsertTrigger({ scope: 'statement', function: asset_edit_insert, referencingNewTableAs: 'inserted_edit' })
|
||||||
@AfterDeleteTrigger({
|
@AfterDeleteTrigger({
|
||||||
scope: 'row',
|
scope: 'statement',
|
||||||
function: asset_edit_delete,
|
function: asset_edit_delete,
|
||||||
referencingOldTableAs: 'old',
|
referencingOldTableAs: 'deleted_edit',
|
||||||
when: 'pg_trigger_depth() = 0',
|
when: 'pg_trigger_depth() = 0',
|
||||||
})
|
})
|
||||||
export class AssetEditTable<T extends AssetEditAction = AssetEditAction> {
|
export class AssetEditTable<T extends AssetEditAction = AssetEditAction> {
|
||||||
|
|||||||
@@ -144,6 +144,6 @@ export class AssetTable {
|
|||||||
@Column({ type: 'integer', nullable: true })
|
@Column({ type: 'integer', nullable: true })
|
||||||
height!: number | null;
|
height!: number | null;
|
||||||
|
|
||||||
@Column({ type: 'integer', default: 0 })
|
@Column({ type: 'boolean', default: false })
|
||||||
editCount!: Generated<number>;
|
isEdited!: Generated<boolean>;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,7 +100,29 @@ export class JobService extends BaseService {
|
|||||||
const asset = await this.assetRepository.getById(item.data.id);
|
const asset = await this.assetRepository.getById(item.data.id);
|
||||||
|
|
||||||
if (asset) {
|
if (asset) {
|
||||||
this.websocketRepository.clientSend('AssetEditReadyV1', asset.ownerId, { assetId: item.data.id });
|
this.websocketRepository.clientSend('AssetEditReadyV1', asset.ownerId, {
|
||||||
|
asset: {
|
||||||
|
id: asset.id,
|
||||||
|
ownerId: asset.ownerId,
|
||||||
|
originalFileName: asset.originalFileName,
|
||||||
|
thumbhash: asset.thumbhash ? hexOrBufferToBase64(asset.thumbhash) : null,
|
||||||
|
checksum: hexOrBufferToBase64(asset.checksum),
|
||||||
|
fileCreatedAt: asset.fileCreatedAt,
|
||||||
|
fileModifiedAt: asset.fileModifiedAt,
|
||||||
|
localDateTime: asset.localDateTime,
|
||||||
|
duration: asset.duration,
|
||||||
|
type: asset.type,
|
||||||
|
deletedAt: asset.deletedAt,
|
||||||
|
isFavorite: asset.isFavorite,
|
||||||
|
visibility: asset.visibility,
|
||||||
|
livePhotoVideoId: asset.livePhotoVideoId,
|
||||||
|
stackId: asset.stackId,
|
||||||
|
libraryId: asset.libraryId,
|
||||||
|
width: asset.width,
|
||||||
|
height: asset.height,
|
||||||
|
isEdited: asset.isEdited,
|
||||||
|
},
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -153,7 +175,7 @@ export class JobService extends BaseService {
|
|||||||
libraryId: asset.libraryId,
|
libraryId: asset.libraryId,
|
||||||
width: asset.width,
|
width: asset.width,
|
||||||
height: asset.height,
|
height: asset.height,
|
||||||
editCount: asset.editCount,
|
isEdited: asset.isEdited,
|
||||||
},
|
},
|
||||||
exif: {
|
exif: {
|
||||||
assetId: exif.assetId,
|
assetId: exif.assetId,
|
||||||
|
|||||||
Vendored
+25
-25
@@ -86,7 +86,7 @@ export const assetStub = {
|
|||||||
make: 'FUJIFILM',
|
make: 'FUJIFILM',
|
||||||
model: 'X-T50',
|
model: 'X-T50',
|
||||||
lensModel: 'XF27mm F2.8 R WR',
|
lensModel: 'XF27mm F2.8 R WR',
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
...asset,
|
...asset,
|
||||||
}),
|
}),
|
||||||
noResizePath: Object.freeze({
|
noResizePath: Object.freeze({
|
||||||
@@ -126,7 +126,7 @@ export const assetStub = {
|
|||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
edits: [],
|
edits: [],
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
noWebpPath: Object.freeze({
|
noWebpPath: Object.freeze({
|
||||||
@@ -168,7 +168,7 @@ export const assetStub = {
|
|||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
edits: [],
|
edits: [],
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
noThumbhash: Object.freeze({
|
noThumbhash: Object.freeze({
|
||||||
@@ -207,7 +207,7 @@ export const assetStub = {
|
|||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
edits: [],
|
edits: [],
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
primaryImage: Object.freeze({
|
primaryImage: Object.freeze({
|
||||||
@@ -256,7 +256,7 @@ export const assetStub = {
|
|||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
edits: [],
|
edits: [],
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
image: Object.freeze({
|
image: Object.freeze({
|
||||||
@@ -303,7 +303,7 @@ export const assetStub = {
|
|||||||
width: null,
|
width: null,
|
||||||
visibility: AssetVisibility.Timeline,
|
visibility: AssetVisibility.Timeline,
|
||||||
edits: [],
|
edits: [],
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
trashed: Object.freeze({
|
trashed: Object.freeze({
|
||||||
@@ -347,7 +347,7 @@ export const assetStub = {
|
|||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
edits: [],
|
edits: [],
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
trashedOffline: Object.freeze({
|
trashedOffline: Object.freeze({
|
||||||
@@ -391,7 +391,7 @@ export const assetStub = {
|
|||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
edits: [],
|
edits: [],
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
}),
|
}),
|
||||||
archived: Object.freeze({
|
archived: Object.freeze({
|
||||||
id: 'asset-id',
|
id: 'asset-id',
|
||||||
@@ -434,7 +434,7 @@ export const assetStub = {
|
|||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
edits: [],
|
edits: [],
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
external: Object.freeze({
|
external: Object.freeze({
|
||||||
@@ -477,7 +477,7 @@ export const assetStub = {
|
|||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
edits: [],
|
edits: [],
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
image1: Object.freeze({
|
image1: Object.freeze({
|
||||||
@@ -520,7 +520,7 @@ export const assetStub = {
|
|||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
edits: [],
|
edits: [],
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
imageFrom2015: Object.freeze({
|
imageFrom2015: Object.freeze({
|
||||||
@@ -562,7 +562,7 @@ export const assetStub = {
|
|||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
edits: [],
|
edits: [],
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
video: Object.freeze({
|
video: Object.freeze({
|
||||||
@@ -606,7 +606,7 @@ export const assetStub = {
|
|||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
edits: [],
|
edits: [],
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
livePhotoMotionAsset: Object.freeze({
|
livePhotoMotionAsset: Object.freeze({
|
||||||
@@ -627,7 +627,7 @@ export const assetStub = {
|
|||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
edits: [] as AssetEditActionItem[],
|
edits: [] as AssetEditActionItem[],
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
} as MapAsset & { faces: AssetFace[]; files: AssetFile[]; exifInfo: Exif; edits: AssetEditActionItem[] }),
|
} as MapAsset & { faces: AssetFace[]; files: AssetFile[]; exifInfo: Exif; edits: AssetEditActionItem[] }),
|
||||||
|
|
||||||
livePhotoStillAsset: Object.freeze({
|
livePhotoStillAsset: Object.freeze({
|
||||||
@@ -649,7 +649,7 @@ export const assetStub = {
|
|||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
edits: [] as AssetEditActionItem[],
|
edits: [] as AssetEditActionItem[],
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
} as MapAsset & { faces: AssetFace[]; files: AssetFile[]; edits: AssetEditActionItem[] }),
|
} as MapAsset & { faces: AssetFace[]; files: AssetFile[]; edits: AssetEditActionItem[] }),
|
||||||
|
|
||||||
livePhotoWithOriginalFileName: Object.freeze({
|
livePhotoWithOriginalFileName: Object.freeze({
|
||||||
@@ -673,7 +673,7 @@ export const assetStub = {
|
|||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
edits: [] as AssetEditActionItem[],
|
edits: [] as AssetEditActionItem[],
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
} as MapAsset & { faces: AssetFace[]; files: AssetFile[]; edits: AssetEditActionItem[] }),
|
} as MapAsset & { faces: AssetFace[]; files: AssetFile[]; edits: AssetEditActionItem[] }),
|
||||||
|
|
||||||
withLocation: Object.freeze({
|
withLocation: Object.freeze({
|
||||||
@@ -721,7 +721,7 @@ export const assetStub = {
|
|||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
edits: [],
|
edits: [],
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
sidecar: Object.freeze({
|
sidecar: Object.freeze({
|
||||||
@@ -760,7 +760,7 @@ export const assetStub = {
|
|||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
edits: [],
|
edits: [],
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
sidecarWithoutExt: Object.freeze({
|
sidecarWithoutExt: Object.freeze({
|
||||||
@@ -796,7 +796,7 @@ export const assetStub = {
|
|||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
edits: [],
|
edits: [],
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
hasEncodedVideo: Object.freeze({
|
hasEncodedVideo: Object.freeze({
|
||||||
@@ -839,7 +839,7 @@ export const assetStub = {
|
|||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
edits: [],
|
edits: [],
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
hasFileExtension: Object.freeze({
|
hasFileExtension: Object.freeze({
|
||||||
@@ -879,7 +879,7 @@ export const assetStub = {
|
|||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
edits: [],
|
edits: [],
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
imageDng: Object.freeze({
|
imageDng: Object.freeze({
|
||||||
@@ -923,7 +923,7 @@ export const assetStub = {
|
|||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
edits: [],
|
edits: [],
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
imageHif: Object.freeze({
|
imageHif: Object.freeze({
|
||||||
@@ -967,7 +967,7 @@ export const assetStub = {
|
|||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
edits: [],
|
edits: [],
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
panoramaTif: Object.freeze({
|
panoramaTif: Object.freeze({
|
||||||
@@ -1068,7 +1068,7 @@ export const assetStub = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
] as AssetEditActionItem[],
|
] as AssetEditActionItem[],
|
||||||
editCount: 1,
|
isEdited: true,
|
||||||
}),
|
}),
|
||||||
|
|
||||||
withoutEdits: Object.freeze({
|
withoutEdits: Object.freeze({
|
||||||
@@ -1116,6 +1116,6 @@ export const assetStub = {
|
|||||||
width: 2160,
|
width: 2160,
|
||||||
visibility: AssetVisibility.Timeline,
|
visibility: AssetVisibility.Timeline,
|
||||||
edits: [],
|
edits: [],
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
|
|||||||
+1
-1
@@ -159,7 +159,7 @@ export const sharedLinkStub = {
|
|||||||
visibility: AssetVisibility.Timeline,
|
visibility: AssetVisibility.Timeline,
|
||||||
width: 500,
|
width: 500,
|
||||||
height: 500,
|
height: 500,
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
albumId: null,
|
albumId: null,
|
||||||
|
|||||||
@@ -537,7 +537,7 @@ const assetInsert = (asset: Partial<Insertable<AssetTable>> = {}) => {
|
|||||||
fileModifiedAt: now,
|
fileModifiedAt: now,
|
||||||
localDateTime: now,
|
localDateTime: now,
|
||||||
visibility: AssetVisibility.Timeline,
|
visibility: AssetVisibility.Timeline,
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
};
|
};
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
|||||||
@@ -24,32 +24,32 @@ beforeAll(async () => {
|
|||||||
|
|
||||||
describe(AssetEditRepository.name, () => {
|
describe(AssetEditRepository.name, () => {
|
||||||
describe('replaceAll', () => {
|
describe('replaceAll', () => {
|
||||||
it('should increment editCount on insert', async () => {
|
it('should set isEdited on insert', async () => {
|
||||||
const { ctx, sut } = setup();
|
const { ctx, sut } = setup();
|
||||||
const { user } = await ctx.newUser();
|
const { user } = await ctx.newUser();
|
||||||
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
ctx.database.selectFrom('asset').select('editCount').where('id', '=', asset.id).executeTakeFirstOrThrow(),
|
ctx.database.selectFrom('asset').select('isEdited').where('id', '=', asset.id).executeTakeFirstOrThrow(),
|
||||||
).resolves.toEqual({ editCount: 0 });
|
).resolves.toEqual({ isEdited: false });
|
||||||
|
|
||||||
await sut.replaceAll(asset.id, [
|
await sut.replaceAll(asset.id, [
|
||||||
{ action: AssetEditAction.Crop, parameters: { height: 1, width: 1, x: 1, y: 1 } },
|
{ action: AssetEditAction.Crop, parameters: { height: 1, width: 1, x: 1, y: 1 } },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
ctx.database.selectFrom('asset').select('editCount').where('id', '=', asset.id).executeTakeFirstOrThrow(),
|
ctx.database.selectFrom('asset').select('isEdited').where('id', '=', asset.id).executeTakeFirstOrThrow(),
|
||||||
).resolves.toEqual({ editCount: 1 });
|
).resolves.toEqual({ isEdited: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should increment editCount when inserting multiple edits', async () => {
|
it('should set isEdited when inserting multiple edits', async () => {
|
||||||
const { ctx, sut } = setup();
|
const { ctx, sut } = setup();
|
||||||
const { user } = await ctx.newUser();
|
const { user } = await ctx.newUser();
|
||||||
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
ctx.database.selectFrom('asset').select('editCount').where('id', '=', asset.id).executeTakeFirstOrThrow(),
|
ctx.database.selectFrom('asset').select('isEdited').where('id', '=', asset.id).executeTakeFirstOrThrow(),
|
||||||
).resolves.toEqual({ editCount: 0 });
|
).resolves.toEqual({ isEdited: false });
|
||||||
|
|
||||||
await sut.replaceAll(asset.id, [
|
await sut.replaceAll(asset.id, [
|
||||||
{ action: AssetEditAction.Crop, parameters: { height: 1, width: 1, x: 1, y: 1 } },
|
{ action: AssetEditAction.Crop, parameters: { height: 1, width: 1, x: 1, y: 1 } },
|
||||||
@@ -58,18 +58,18 @@ describe(AssetEditRepository.name, () => {
|
|||||||
]);
|
]);
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
ctx.database.selectFrom('asset').select('editCount').where('id', '=', asset.id).executeTakeFirstOrThrow(),
|
ctx.database.selectFrom('asset').select('isEdited').where('id', '=', asset.id).executeTakeFirstOrThrow(),
|
||||||
).resolves.toEqual({ editCount: 3 });
|
).resolves.toEqual({ isEdited: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should decrement editCount', async () => {
|
it('should keep isEdited when removing some edits', async () => {
|
||||||
const { ctx, sut } = setup();
|
const { ctx, sut } = setup();
|
||||||
const { user } = await ctx.newUser();
|
const { user } = await ctx.newUser();
|
||||||
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
ctx.database.selectFrom('asset').select('editCount').where('id', '=', asset.id).executeTakeFirstOrThrow(),
|
ctx.database.selectFrom('asset').select('isEdited').where('id', '=', asset.id).executeTakeFirstOrThrow(),
|
||||||
).resolves.toEqual({ editCount: 0 });
|
).resolves.toEqual({ isEdited: false });
|
||||||
|
|
||||||
await sut.replaceAll(asset.id, [
|
await sut.replaceAll(asset.id, [
|
||||||
{ action: AssetEditAction.Crop, parameters: { height: 1, width: 1, x: 1, y: 1 } },
|
{ action: AssetEditAction.Crop, parameters: { height: 1, width: 1, x: 1, y: 1 } },
|
||||||
@@ -77,23 +77,27 @@ describe(AssetEditRepository.name, () => {
|
|||||||
{ action: AssetEditAction.Rotate, parameters: { angle: 90 } },
|
{ action: AssetEditAction.Rotate, parameters: { angle: 90 } },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
ctx.database.selectFrom('asset').select('isEdited').where('id', '=', asset.id).executeTakeFirstOrThrow(),
|
||||||
|
).resolves.toEqual({ isEdited: true });
|
||||||
|
|
||||||
await sut.replaceAll(asset.id, [
|
await sut.replaceAll(asset.id, [
|
||||||
{ action: AssetEditAction.Crop, parameters: { height: 1, width: 1, x: 1, y: 1 } },
|
{ action: AssetEditAction.Crop, parameters: { height: 1, width: 1, x: 1, y: 1 } },
|
||||||
]);
|
]);
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
ctx.database.selectFrom('asset').select('editCount').where('id', '=', asset.id).executeTakeFirstOrThrow(),
|
ctx.database.selectFrom('asset').select('isEdited').where('id', '=', asset.id).executeTakeFirstOrThrow(),
|
||||||
).resolves.toEqual({ editCount: 1 });
|
).resolves.toEqual({ isEdited: true });
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should set editCount to 0 if all edits are deleted', async () => {
|
it('should set isEdited to false if all edits are deleted', async () => {
|
||||||
const { ctx, sut } = setup();
|
const { ctx, sut } = setup();
|
||||||
const { user } = await ctx.newUser();
|
const { user } = await ctx.newUser();
|
||||||
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
const { asset } = await ctx.newAsset({ ownerId: user.id });
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
ctx.database.selectFrom('asset').select('editCount').where('id', '=', asset.id).executeTakeFirstOrThrow(),
|
ctx.database.selectFrom('asset').select('isEdited').where('id', '=', asset.id).executeTakeFirstOrThrow(),
|
||||||
).resolves.toEqual({ editCount: 0 });
|
).resolves.toEqual({ isEdited: false });
|
||||||
|
|
||||||
await sut.replaceAll(asset.id, [
|
await sut.replaceAll(asset.id, [
|
||||||
{ action: AssetEditAction.Crop, parameters: { height: 1, width: 1, x: 1, y: 1 } },
|
{ action: AssetEditAction.Crop, parameters: { height: 1, width: 1, x: 1, y: 1 } },
|
||||||
@@ -104,8 +108,8 @@ describe(AssetEditRepository.name, () => {
|
|||||||
await sut.replaceAll(asset.id, []);
|
await sut.replaceAll(asset.id, []);
|
||||||
|
|
||||||
await expect(
|
await expect(
|
||||||
ctx.database.selectFrom('asset').select('editCount').where('id', '=', asset.id).executeTakeFirstOrThrow(),
|
ctx.database.selectFrom('asset').select('isEdited').where('id', '=', asset.id).executeTakeFirstOrThrow(),
|
||||||
).resolves.toEqual({ editCount: 0 });
|
).resolves.toEqual({ isEdited: false });
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -83,7 +83,7 @@ describe(SyncRequestType.AlbumAssetsV1, () => {
|
|||||||
libraryId: asset.libraryId,
|
libraryId: asset.libraryId,
|
||||||
width: asset.width,
|
width: asset.width,
|
||||||
height: asset.height,
|
height: asset.height,
|
||||||
editCount: asset.editCount,
|
isEdited: asset.isEdited,
|
||||||
},
|
},
|
||||||
type: SyncEntityType.AlbumAssetCreateV1,
|
type: SyncEntityType.AlbumAssetCreateV1,
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ describe(SyncEntityType.AssetV1, () => {
|
|||||||
libraryId: asset.libraryId,
|
libraryId: asset.libraryId,
|
||||||
width: asset.width,
|
width: asset.width,
|
||||||
height: asset.height,
|
height: asset.height,
|
||||||
editCount: asset.editCount,
|
isEdited: asset.isEdited,
|
||||||
},
|
},
|
||||||
type: 'AssetV1',
|
type: 'AssetV1',
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ describe(SyncRequestType.PartnerAssetsV1, () => {
|
|||||||
type: asset.type,
|
type: asset.type,
|
||||||
visibility: asset.visibility,
|
visibility: asset.visibility,
|
||||||
duration: asset.duration,
|
duration: asset.duration,
|
||||||
editCount: asset.editCount,
|
isEdited: asset.isEdited,
|
||||||
stackId: null,
|
stackId: null,
|
||||||
livePhotoVideoId: null,
|
livePhotoVideoId: null,
|
||||||
libraryId: asset.libraryId,
|
libraryId: asset.libraryId,
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ const assetFactory = (asset: Partial<MapAsset> = {}) => ({
|
|||||||
visibility: AssetVisibility.Timeline,
|
visibility: AssetVisibility.Timeline,
|
||||||
width: null,
|
width: null,
|
||||||
height: null,
|
height: null,
|
||||||
editCount: 0,
|
isEdited: false,
|
||||||
...asset,
|
...asset,
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
import AddToStackAction from '$lib/components/asset-viewer/actions/add-to-stack-action.svelte';
|
import AddToStackAction from '$lib/components/asset-viewer/actions/add-to-stack-action.svelte';
|
||||||
import ArchiveAction from '$lib/components/asset-viewer/actions/archive-action.svelte';
|
import ArchiveAction from '$lib/components/asset-viewer/actions/archive-action.svelte';
|
||||||
import DeleteAction from '$lib/components/asset-viewer/actions/delete-action.svelte';
|
import DeleteAction from '$lib/components/asset-viewer/actions/delete-action.svelte';
|
||||||
|
import EditAction from '$lib/components/asset-viewer/actions/edit-action.svelte';
|
||||||
import KeepThisDeleteOthersAction from '$lib/components/asset-viewer/actions/keep-this-delete-others.svelte';
|
import KeepThisDeleteOthersAction from '$lib/components/asset-viewer/actions/keep-this-delete-others.svelte';
|
||||||
import RatingAction from '$lib/components/asset-viewer/actions/rating-action.svelte';
|
import RatingAction from '$lib/components/asset-viewer/actions/rating-action.svelte';
|
||||||
import RemoveAssetFromStack from '$lib/components/asset-viewer/actions/remove-asset-from-stack.svelte';
|
import RemoveAssetFromStack from '$lib/components/asset-viewer/actions/remove-asset-from-stack.svelte';
|
||||||
@@ -19,6 +20,7 @@
|
|||||||
import UnstackAction from '$lib/components/asset-viewer/actions/unstack-action.svelte';
|
import UnstackAction from '$lib/components/asset-viewer/actions/unstack-action.svelte';
|
||||||
import ButtonContextMenu from '$lib/components/shared-components/context-menu/button-context-menu.svelte';
|
import ButtonContextMenu from '$lib/components/shared-components/context-menu/button-context-menu.svelte';
|
||||||
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
import MenuOption from '$lib/components/shared-components/context-menu/menu-option.svelte';
|
||||||
|
import { ProjectionType } from '$lib/constants';
|
||||||
import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte';
|
import { featureFlagsManager } from '$lib/managers/feature-flags-manager.svelte';
|
||||||
import { Route } from '$lib/route';
|
import { Route } from '$lib/route';
|
||||||
import { getGlobalActions } from '$lib/services/app.service';
|
import { getGlobalActions } from '$lib/services/app.service';
|
||||||
@@ -71,7 +73,7 @@
|
|||||||
onUndoDelete?: OnUndoDelete;
|
onUndoDelete?: OnUndoDelete;
|
||||||
onRunJob: (name: AssetJobName) => void;
|
onRunJob: (name: AssetJobName) => void;
|
||||||
onPlaySlideshow: () => void;
|
onPlaySlideshow: () => void;
|
||||||
// onEdit: () => void;
|
onEdit: () => void;
|
||||||
onClose?: () => void;
|
onClose?: () => void;
|
||||||
playOriginalVideo: boolean;
|
playOriginalVideo: boolean;
|
||||||
setPlayOriginalVideo: (value: boolean) => void;
|
setPlayOriginalVideo: (value: boolean) => void;
|
||||||
@@ -91,7 +93,7 @@
|
|||||||
onRunJob,
|
onRunJob,
|
||||||
onPlaySlideshow,
|
onPlaySlideshow,
|
||||||
onClose,
|
onClose,
|
||||||
// onEdit,
|
onEdit,
|
||||||
playOriginalVideo = false,
|
playOriginalVideo = false,
|
||||||
setPlayOriginalVideo,
|
setPlayOriginalVideo,
|
||||||
}: Props = $props();
|
}: Props = $props();
|
||||||
@@ -126,17 +128,17 @@
|
|||||||
const sharedLink = getSharedLink();
|
const sharedLink = getSharedLink();
|
||||||
|
|
||||||
// TODO: Enable when edits are ready for release
|
// TODO: Enable when edits are ready for release
|
||||||
// let showEditorButton = $derived(
|
let showEditorButton = $derived(
|
||||||
// isOwner &&
|
isOwner &&
|
||||||
// asset.type === AssetTypeEnum.Image &&
|
asset.type === AssetTypeEnum.Image &&
|
||||||
// !(
|
!(
|
||||||
// asset.exifInfo?.projectionType === ProjectionType.EQUIRECTANGULAR ||
|
asset.exifInfo?.projectionType === ProjectionType.EQUIRECTANGULAR ||
|
||||||
// (asset.originalPath && asset.originalPath.toLowerCase().endsWith('.insp'))
|
(asset.originalPath && asset.originalPath.toLowerCase().endsWith('.insp'))
|
||||||
// ) &&
|
) &&
|
||||||
// !(asset.originalPath && asset.originalPath.toLowerCase().endsWith('.gif')) &&
|
!(asset.originalPath && asset.originalPath.toLowerCase().endsWith('.gif')) &&
|
||||||
// !(asset.originalPath && asset.originalPath.toLowerCase().endsWith('.svg')) &&
|
!(asset.originalPath && asset.originalPath.toLowerCase().endsWith('.svg')) &&
|
||||||
// !asset.livePhotoVideoId,
|
!asset.livePhotoVideoId,
|
||||||
// );
|
);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<CommandPaletteDefaultProvider
|
<CommandPaletteDefaultProvider
|
||||||
@@ -189,9 +191,9 @@
|
|||||||
<RatingAction {asset} {onAction} />
|
<RatingAction {asset} {onAction} />
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
<!-- {#if showEditorButton}
|
{#if showEditorButton}
|
||||||
<EditAction onAction={onEdit} />
|
<EditAction onAction={onEdit} />
|
||||||
{/if} -->
|
{/if}
|
||||||
|
|
||||||
{#if isOwner}
|
{#if isOwner}
|
||||||
<DeleteAction {asset} {onAction} {preAction} {onUndoDelete} />
|
<DeleteAction {asset} {onAction} {preAction} {onUndoDelete} />
|
||||||
|
|||||||
@@ -254,12 +254,12 @@
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
// const showEditor = () => {
|
const showEditor = () => {
|
||||||
// if (assetViewerManager.isShowActivityPanel) {
|
if (assetViewerManager.isShowActivityPanel) {
|
||||||
// assetViewerManager.isShowActivityPanel = false;
|
assetViewerManager.isShowActivityPanel = false;
|
||||||
// }
|
}
|
||||||
// isShowEditor = !isShowEditor;
|
isShowEditor = !isShowEditor;
|
||||||
// };
|
};
|
||||||
|
|
||||||
const handleRunJob = async (name: AssetJobName) => {
|
const handleRunJob = async (name: AssetJobName) => {
|
||||||
try {
|
try {
|
||||||
@@ -466,6 +466,7 @@
|
|||||||
preAction={handlePreAction}
|
preAction={handlePreAction}
|
||||||
onAction={handleAction}
|
onAction={handleAction}
|
||||||
{onUndoDelete}
|
{onUndoDelete}
|
||||||
|
onEdit={showEditor}
|
||||||
onRunJob={handleRunJob}
|
onRunJob={handleRunJob}
|
||||||
onPlaySlideshow={() => ($slideshowState = SlideshowState.PlaySlideshow)}
|
onPlaySlideshow={() => ($slideshowState = SlideshowState.PlaySlideshow)}
|
||||||
onClose={onClose ? () => onClose(asset) : undefined}
|
onClose={onClose ? () => onClose(asset) : undefined}
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ export class EditManager {
|
|||||||
// Setup the websocket listener before sending the edit request
|
// Setup the websocket listener before sending the edit request
|
||||||
const editCompleted = waitForWebsocketEvent(
|
const editCompleted = waitForWebsocketEvent(
|
||||||
'AssetEditReadyV1',
|
'AssetEditReadyV1',
|
||||||
(event) => event.assetId === this.currentAsset!.id,
|
(event) => event.asset.id === this.currentAsset!.id,
|
||||||
10_000,
|
10_000,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ export interface Events {
|
|||||||
on_notification: (notification: NotificationDto) => void;
|
on_notification: (notification: NotificationDto) => void;
|
||||||
|
|
||||||
AppRestartV1: (event: AppRestartEvent) => void;
|
AppRestartV1: (event: AppRestartEvent) => void;
|
||||||
AssetEditReadyV1: (data: { assetId: string }) => void;
|
AssetEditReadyV1: (data: { asset: { id: string } }) => void;
|
||||||
}
|
}
|
||||||
|
|
||||||
const websocket: Socket<Events> = io({
|
const websocket: Socket<Events> = io({
|
||||||
|
|||||||
Reference in New Issue
Block a user