mirror of
https://github.com/immich-app/immich.git
synced 2026-01-23 09:58:56 -08:00
feat: send edit information on AssetEditReadyV1
This commit is contained in:
@@ -257,6 +257,7 @@ class SyncStreamService {
|
||||
_logger.info('Processing batch of ${batchData.length} AssetEditReadyV1 events');
|
||||
|
||||
final List<SyncAssetV1> assets = [];
|
||||
final List<SyncAssetEditV1> assetEdits = [];
|
||||
|
||||
try {
|
||||
for (final data in batchData) {
|
||||
@@ -266,20 +267,33 @@ class SyncStreamService {
|
||||
|
||||
final payload = data;
|
||||
final assetData = payload['asset'];
|
||||
final editData = payload['edit'];
|
||||
|
||||
if (assetData == null) {
|
||||
if (assetData == null || editData == null) {
|
||||
continue;
|
||||
}
|
||||
|
||||
final asset = SyncAssetV1.fromJson(assetData);
|
||||
final edits = (editData as List<dynamic>)
|
||||
.map((e) => SyncAssetEditV1.fromJson(e))
|
||||
.whereType<SyncAssetEditV1>()
|
||||
.toList();
|
||||
|
||||
if (asset != null) {
|
||||
assets.add(asset);
|
||||
assetEdits.addAll(edits);
|
||||
}
|
||||
}
|
||||
|
||||
if (assets.isNotEmpty) {
|
||||
await _syncStreamRepository.updateAssetsV1(assets, debugLabel: 'websocket-edit');
|
||||
|
||||
// edits that are sent replace previous edits, so we delete existing ones first
|
||||
await _syncStreamRepository.deleteAssetEditsV1(
|
||||
assets.map((asset) => SyncAssetEditDeleteV1(assetId: asset.id)).toList(),
|
||||
debugLabel: 'websocket-edit',
|
||||
);
|
||||
await _syncStreamRepository.updateAssetEditsV1(assetEdits, debugLabel: 'websocket-edit');
|
||||
_logger.info('Successfully processed ${assets.length} edited assets');
|
||||
}
|
||||
} catch (error, stackTrace) {
|
||||
|
||||
@@ -279,7 +279,7 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> updateAssetEditsV1(Iterable<SyncAssetEditV1> data) async {
|
||||
Future<void> updateAssetEditsV1(Iterable<SyncAssetEditV1> data, {String debugLabel = 'user'}) async {
|
||||
try {
|
||||
await _db.batch((batch) {
|
||||
for (final edit in data) {
|
||||
@@ -295,12 +295,12 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||
}
|
||||
});
|
||||
} catch (error, stack) {
|
||||
_logger.severe('Error: updateAssetEditsV1', error, stack);
|
||||
_logger.severe('Error: updateAssetEditsV1 - $debugLabel', error, stack);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> deleteAssetEditsV1(Iterable<SyncAssetEditDeleteV1> data) async {
|
||||
Future<void> deleteAssetEditsV1(Iterable<SyncAssetEditDeleteV1> data, {String debugLabel = 'user'}) async {
|
||||
try {
|
||||
await _db.batch((batch) {
|
||||
for (final edit in data) {
|
||||
@@ -308,7 +308,7 @@ class SyncStreamRepository extends DriftDatabaseRepository {
|
||||
}
|
||||
});
|
||||
} catch (error, stack) {
|
||||
_logger.severe('Error: deleteAssetEditsV1', error, stack);
|
||||
_logger.severe('Error: deleteAssetEditsV1 - $debugLabel', error, stack);
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,4 +39,16 @@ export class AssetEditRepository {
|
||||
.orderBy('sequence', 'asc')
|
||||
.execute() as Promise<AssetEditActionItem[]>;
|
||||
}
|
||||
|
||||
@GenerateSql({
|
||||
params: [DummyValue.UUID],
|
||||
})
|
||||
getWithSyncInfo(assetId: string) {
|
||||
return this.db
|
||||
.selectFrom('asset_edit')
|
||||
.select(['id', 'assetId', 'sequence', 'action', 'parameters'])
|
||||
.where('assetId', '=', assetId)
|
||||
.orderBy('sequence', 'asc')
|
||||
.execute();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import { AssetResponseDto } from 'src/dtos/asset-response.dto';
|
||||
import { AuthDto } from 'src/dtos/auth.dto';
|
||||
import { NotificationDto } from 'src/dtos/notification.dto';
|
||||
import { ReleaseNotification, ServerVersionResponseDto } from 'src/dtos/server.dto';
|
||||
import { SyncAssetExifV1, SyncAssetV1 } from 'src/dtos/sync.dto';
|
||||
import { SyncAssetEditV1, SyncAssetExifV1, SyncAssetV1 } from 'src/dtos/sync.dto';
|
||||
import { AppRestartEvent, ArgsOf, EventRepository } from 'src/repositories/event.repository';
|
||||
import { LoggingRepository } from 'src/repositories/logging.repository';
|
||||
import { handlePromiseError } from 'src/utils/misc';
|
||||
@@ -37,7 +37,7 @@ export interface ClientEventMap {
|
||||
|
||||
AssetUploadReadyV1: [{ asset: SyncAssetV1; exif: SyncAssetExifV1 }];
|
||||
AppRestartV1: [AppRestartEvent];
|
||||
AssetEditReadyV1: [{ asset: SyncAssetV1 }];
|
||||
AssetEditReadyV1: [{ asset: SyncAssetV1; edit: SyncAssetEditV1[] }];
|
||||
}
|
||||
|
||||
export type AuthFn = (client: Socket) => Promise<AuthDto>;
|
||||
|
||||
@@ -540,6 +540,7 @@ export class AssetService extends BaseService {
|
||||
async getAssetEdits(auth: AuthDto, id: string): Promise<AssetEditsDto> {
|
||||
await this.requireAccess({ auth, permission: Permission.AssetRead, ids: [id] });
|
||||
const edits = await this.assetEditRepository.getAll(id);
|
||||
|
||||
return {
|
||||
assetId: id,
|
||||
edits,
|
||||
|
||||
@@ -98,6 +98,7 @@ export class JobService extends BaseService {
|
||||
|
||||
case JobName.AssetEditThumbnailGeneration: {
|
||||
const asset = await this.assetRepository.getById(item.data.id);
|
||||
const edits = await this.assetEditRepository.getWithSyncInfo(item.data.id);
|
||||
|
||||
if (asset) {
|
||||
this.websocketRepository.clientSend('AssetEditReadyV1', asset.ownerId, {
|
||||
@@ -122,6 +123,7 @@ export class JobService extends BaseService {
|
||||
height: asset.height,
|
||||
isEdited: asset.isEdited,
|
||||
},
|
||||
edit: edits,
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ export interface Events {
|
||||
AppRestartV1: (event: AppRestartEvent) => void;
|
||||
|
||||
MaintenanceStatusV1: (event: MaintenanceStatusResponseDto) => void;
|
||||
AssetEditReadyV1: (data: { asset: { id: string } }) => void;
|
||||
AssetEditReadyV1: (data: { asset: { id: string }; edits: object }) => void;
|
||||
}
|
||||
|
||||
const websocket: Socket<Events> = io({
|
||||
|
||||
Reference in New Issue
Block a user