diff --git a/pages/scene/+Page.vue b/pages/scene/+Page.vue index ae1a372..730234b 100644 --- a/pages/scene/+Page.vue +++ b/pages/scene/+Page.vue @@ -343,6 +343,43 @@ +
+

Fingerprints

+ +
+ + + + + + + + + + + + + + + + + + + + + + +
HashTypeDurationSubmissionsSourceFirst added
{{ fingerprint.hash }}{{ fingerprint.type.toUpperCase() }}{{ formatDuration(fingerprint.duration) }}{{ fingerprint.submissions }}{{ fingerprint.source || 'traxxx' }}{{ formatDate(fingerprint.createdAt, 'yyyy-MM-dd') }}
+
+
+
@@ -740,6 +777,55 @@ function copySummary() { display: none; } +.fingerprints { + margin-top: 1.5rem; +} + +.fingerprints-container { + max-height: 10rem; + overflow-y: auto; + resize: vertical; + + &[style*="height"] { + max-height: unset; + } +} + +.fingerprints-table { + width: 100%; +} + +.fingerprints-head { + background: var(--background-base-10); + position: sticky; + top: 0; +} + +.fingerprints-heading { + color: var(--shadow); + font-weight: normal; + padding: .25rem; + text-align: left; +} + +.fingerprint { + &:nth-child(2n + 1) { + background: var(--shadow-weak-50); + } + + &:hover { + background: var(--shadow-weak-40); + } +} + +.fingerprint-field { + padding: .25rem; +} + +.fingerprint-hash { + user-select: all; +} + @media(--compact) { .content { margin: 0; diff --git a/src/scenes.js b/src/scenes.js index 32d03fb..8f21b10 100644 --- a/src/scenes.js +++ b/src/scenes.js @@ -112,6 +112,14 @@ function curateScene(rawScene, assets) { photos: assets.photos?.map((photo) => curateMedia(photo, { type: 'photo' })) || [], caps: assets.caps?.map((cap) => curateMedia(cap, { type: 'cap' })) || [], stashes: assets.stashes?.map((stash) => curateStash(stash)) || [], + fingerprints: assets.fingerprints?.map((fingerprint) => ({ + hash: fingerprint.hash, + type: fingerprint.type, + duration: fingerprint.duration, + source: fingerprint.source, + submissions: fingerprint.source_submissions, + createdAt: fingerprint.created_at, + })) || [], createdBatchId: rawScene.created_batch_id, updatedBatchId: rawScene.updated_batch_id, isNew: assets.lastBatchId === rawScene.created_batch_id, @@ -138,6 +146,7 @@ export async function fetchScenesById(sceneIds, { reqUser, ...context } = {}) { caps, trailers, teasers, + fingerprints, stashes, lastBatch: { id: lastBatchId }, } = await promiseProps({ @@ -259,6 +268,20 @@ export async function fetchScenesById(sceneIds, { reqUser, ...context } = {}) { .whereIn('release_id', sceneIds) .leftJoin('media', 'media.id', 'releases_teasers.media_id'); }) : [], + fingerprints: context.includeAssets ? knex.transaction(async (trx) => { + if (reqUser) { + await trx.select(knex.raw('set_config(\'user.id\', :userId, true)', { userId: reqUser.id })); + } + + return trx('releases_fingerprints') + .select('scene_id', 'hash', 'type', 'duration', 'source', 'source_submissions', knex.raw('min(coalesce(source_created_at, created_at)) as created_at')) + .whereIn('scene_id', sceneIds) + .orderBy([ + { column: 'source_submissions', order: 'desc' }, + { column: knex.raw('min(coalesce(source_created_at, created_at))'), order: 'desc' }, + ]) + .groupBy(['scene_id', 'hash', 'type', 'duration', 'source', 'source_submissions']); + }) : [], lastBatch: knex('batches') .select('id') .where('showcased', true) @@ -299,6 +322,7 @@ export async function fetchScenesById(sceneIds, { reqUser, ...context } = {}) { const sceneCaps = caps.filter((cap) => cap.release_id === sceneId); const sceneTrailers = trailers.find((trailer) => trailer.release_id === sceneId); const sceneTeasers = teasers.find((teaser) => teaser.release_id === sceneId); + const sceneFingerprints = fingerprints.filter((fingerprint) => fingerprint.scene_id === sceneId); const sceneStashes = stashes.filter((stash) => stash.scene_id === sceneId); const sceneActorStashes = sceneActors.map((actor) => actorStashes.find((stash) => stash.actor_id === actor.id)).filter(Boolean); @@ -316,6 +340,7 @@ export async function fetchScenesById(sceneIds, { reqUser, ...context } = {}) { caps: sceneCaps, trailer: sceneTrailers, teaser: sceneTeasers, + fingerprints: sceneFingerprints, stashes: sceneStashes, actorStashes: sceneActorStashes, lastBatchId,