feat: show shared link view count

This commit is contained in:
Jason Rasmussen
2025-02-18 17:34:51 -05:00
parent 7bf142dc43
commit 8b0684ee9c
15 changed files with 89 additions and 33 deletions
+1
View File
@@ -312,6 +312,7 @@ export interface SharedLinks {
showExif: Generated<boolean>;
type: string;
userId: string;
viewCount: Generated<number>;
}
export interface SmartSearch {
+8 -26
View File
@@ -94,6 +94,7 @@ export class SharedLinkResponseDto {
type!: SharedLinkType;
createdAt!: Date;
expiresAt!: Date | null;
viewCount!: number;
assets!: AssetResponseDto[];
album?: AlbumResponseDto;
allowUpload!: boolean;
@@ -102,7 +103,7 @@ export class SharedLinkResponseDto {
showMetadata!: boolean;
}
export function mapSharedLink(sharedLink: SharedLinkEntity): SharedLinkResponseDto {
const map = (sharedLink: SharedLinkEntity, { stripMetadata }: { stripMetadata: boolean }) => {
const linkAssets = sharedLink.assets || [];
const albumAssets = (sharedLink?.album?.assets || []).map((asset) => asset);
@@ -115,35 +116,16 @@ export function mapSharedLink(sharedLink: SharedLinkEntity): SharedLinkResponseD
userId: sharedLink.userId,
key: sharedLink.key.toString('base64url'),
type: sharedLink.type,
viewCount: sharedLink.viewCount,
createdAt: sharedLink.createdAt,
expiresAt: sharedLink.expiresAt,
assets: assets.map((asset) => mapAsset(asset)),
album: sharedLink.album ? mapAlbumWithoutAssets(sharedLink.album) : undefined,
allowUpload: sharedLink.allowUpload,
allowDownload: sharedLink.allowDownload,
showMetadata: sharedLink.showExif,
};
}
export function mapSharedLinkWithoutMetadata(sharedLink: SharedLinkEntity): SharedLinkResponseDto {
const linkAssets = sharedLink.assets || [];
const albumAssets = (sharedLink?.album?.assets || []).map((asset) => asset);
const assets = _.uniqBy([...linkAssets, ...albumAssets], (asset) => asset.id);
return {
id: sharedLink.id,
description: sharedLink.description,
password: sharedLink.password,
userId: sharedLink.userId,
key: sharedLink.key.toString('base64url'),
type: sharedLink.type,
createdAt: sharedLink.createdAt,
expiresAt: sharedLink.expiresAt,
assets: assets.map((asset) => mapAsset(asset, { stripMetadata: true })) as AssetResponseDto[],
assets: assets.map((asset) => mapAsset(asset, { stripMetadata })),
album: sharedLink.album ? mapAlbumWithoutAssets(sharedLink.album) : undefined,
allowUpload: sharedLink.allowUpload,
allowDownload: sharedLink.allowDownload,
showMetadata: sharedLink.showExif,
};
}
};
export const mapSharedLink = (sharedLink: SharedLinkEntity) => map(sharedLink, { stripMetadata: false });
export const mapSharedLinkWithoutMetadata = (sharedLink: SharedLinkEntity) => map(sharedLink, { stripMetadata: true });
@@ -62,4 +62,7 @@ export class SharedLinkEntity {
@Column({ type: 'varchar', nullable: true })
albumId!: string | null;
@Column({ default: 0 })
viewCount!: number;
}
@@ -0,0 +1,14 @@
import { MigrationInterface, QueryRunner } from "typeorm";
export class AddViewCount1739916305466 implements MigrationInterface {
name = 'AddViewCount1739916305466'
public async up(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "shared_links" ADD "viewCount" integer NOT NULL DEFAULT '0'`);
}
public async down(queryRunner: QueryRunner): Promise<void> {
await queryRunner.query(`ALTER TABLE "shared_links" DROP COLUMN "viewCount"`);
}
}
@@ -194,3 +194,12 @@ where
"shared_links"."type" = $2
or "albums"."id" is not null
)
-- SharedLinkRepository.incrementViewCount
update "shared_links"
set
"viewCount" = viewCount + 1
where
"shared_links"."id" = $1
returning
*
@@ -216,6 +216,15 @@ export class SharedLinkRepository {
await this.db.deleteFrom('shared_links').where('shared_links.id', '=', entity.id).execute();
}
@GenerateSql({ params: [DummyValue.UUID] })
async incrementViewCount(id: string) {
await this.db
.updateTable('shared_links')
.set('viewCount', sql<number>`"viewCount" + 1`)
.where('shared_links.id', '=', id)
.execute();
}
private getSharedLinks(id: string) {
return this.db
.selectFrom('shared_links')
+4 -1
View File
@@ -35,6 +35,9 @@ export class SharedLinkService extends BaseService {
response.token = this.validateAndRefreshToken(sharedLink, dto);
}
await this.sharedLinkRepository.incrementViewCount(sharedLink.id);
sharedLink.viewCount++;
return response;
}
@@ -195,7 +198,7 @@ export class SharedLinkService extends BaseService {
};
}
private mapToSharedLink(sharedLink: SharedLinkEntity, { withExif }: { withExif: boolean }) {
private mapToSharedLink(sharedLink: SharedLinkEntity, { withExif }: { withExif: boolean }): SharedLinkResponseDto {
return withExif ? mapSharedLink(sharedLink) : mapSharedLinkWithoutMetadata(sharedLink);
}