fix: Any asset update disables isFavorite action in GUI. Only owner of asset in album should see favorited image.

This commit is contained in:
Pawel Wojtaszko 2025-08-05 01:10:02 +02:00 committed by mertalev
parent 1b62c2ef55
commit 21835c5287
No known key found for this signature in database
GPG key ID: DF6ABC77AAD98C95
4 changed files with 15 additions and 5 deletions

View file

@ -212,7 +212,7 @@ export function mapAsset(entity: MapAsset, options: AssetMapOptions = {}): Asset
fileModifiedAt: entity.fileModifiedAt,
localDateTime: entity.localDateTime,
updatedAt: entity.updatedAt,
isFavorite: options.auth?.user.id === entity.ownerId ? entity.isFavorite : false,
isFavorite: options.auth?.user.id === entity.ownerId && entity.isFavorite,
isArchived: entity.visibility === AssetVisibility.Archive,
isTrashed: !!entity.deletedAt,
visibility: entity.visibility,

View file

@ -4,6 +4,7 @@ import { isEmpty, isUndefined, omitBy } from 'lodash';
import { InjectKysely } from 'nestjs-kysely';
import { Stack } from 'src/database';
import { Chunked, ChunkedArray, DummyValue, GenerateSql } from 'src/decorators';
import { AuthDto } from 'src/dtos/auth.dto';
import { AssetFileType, AssetMetadataKey, AssetOrder, AssetStatus, AssetType, AssetVisibility } from 'src/enum';
import { DB } from 'src/schema';
import { AssetExifTable } from 'src/schema/tables/asset-exif.table';
@ -591,7 +592,7 @@ export class AssetRepository {
@GenerateSql({
params: [DummyValue.TIME_BUCKET, { withStacked: true }],
})
getTimeBucket(timeBucket: string, options: TimeBucketOptions) {
getTimeBucket(timeBucket: string, options: TimeBucketOptions, auth?: AuthDto) {
const query = this.db
.with('cte', (qb) =>
qb
@ -690,7 +691,16 @@ export class AssetRepository {
eb.fn.coalesce(eb.fn('array_agg', ['duration']), sql.lit('{}')).as('duration'),
eb.fn.coalesce(eb.fn('array_agg', ['id']), sql.lit('{}')).as('id'),
eb.fn.coalesce(eb.fn('array_agg', ['visibility']), sql.lit('{}')).as('visibility'),
eb.fn.coalesce(eb.fn('array_agg', ['isFavorite']), sql.lit('{}')).as('isFavorite'),
eb.fn.coalesce(
eb.fn('array_agg', [
eb.case()
.when(eb.ref('ownerId'), '=', auth?.user.id || '')
.then(eb.ref('isFavorite'))
.else(sql.lit(false))
.end()
]),
sql.lit('{}')
).as('isFavorite'),
eb.fn.coalesce(eb.fn('array_agg', ['isImage']), sql.lit('{}')).as('isImage'),
// TODO: isTrashed is redundant as it will always be all true or false depending on the options
eb.fn.coalesce(eb.fn('array_agg', ['isTrashed']), sql.lit('{}')).as('isTrashed'),

View file

@ -162,7 +162,7 @@ export class NotificationService extends BaseService {
const [asset] = await this.assetRepository.getByIdsWithAllRelationsButStacks([assetId]);
if (asset) {
this.eventRepository.clientSend('on_asset_update', userId, mapAsset(asset));
this.eventRepository.clientSend('on_asset_update', userId, mapAsset(asset, { auth: { user: { id: userId } } as AuthDto }));
}
}

View file

@ -21,7 +21,7 @@ export class TimelineService extends BaseService {
const timeBucketOptions = await this.buildTimeBucketOptions(auth, { ...dto });
// TODO: use id cursor for pagination
const bucket = await this.assetRepository.getTimeBucket(dto.timeBucket, timeBucketOptions);
const bucket = await this.assetRepository.getTimeBucket(dto.timeBucket, timeBucketOptions, auth);
return bucket.assets;
}