From b87a8a43e08eea92e10d760fef5be4e06e7a036e Mon Sep 17 00:00:00 2001 From: KoloMl Date: Sun, 30 Aug 2026 06:23:58 +0200 Subject: [PATCH] Display ratings when duplicate reports have different ratings --- src/config/tags.ts | 12 ++++++++++ .../components/philomena/dupe/DupeDiff.ts | 23 +++++++++++++++++++ .../philomena/dupe/DupeReportRow.ts | 13 +++++++++++ src/styles/content/duplicate-reports.scss | 10 +++++++- 4 files changed, 57 insertions(+), 1 deletion(-) diff --git a/src/config/tags.ts b/src/config/tags.ts index 2065e88..98583ad 100644 --- a/src/config/tags.ts +++ b/src/config/tags.ts @@ -128,3 +128,15 @@ export const tagsBlacklist: string[] = (__CURRENT_SITE__ === 'furbooru' ? [ "solo oc", "tag your shit" ]); + +/** + * Core rating tags used in the Philomena. These rarely change, so they're pretty safe to hardcode into the source code. + */ +export const ratingTags: string[] = [ + 'safe', + 'suggestive', + 'questionable', + 'explicit', + 'grimdark', + 'grotesque', +]; diff --git a/src/content/components/philomena/dupe/DupeDiff.ts b/src/content/components/philomena/dupe/DupeDiff.ts index 636411b..d2a397e 100644 --- a/src/content/components/philomena/dupe/DupeDiff.ts +++ b/src/content/components/philomena/dupe/DupeDiff.ts @@ -8,13 +8,16 @@ const twitterIcon = ['x-twitter', brandsSubtype]; export default class DupeDiff extends BaseComponent { #sourcesLine: HTMLElement | null = null; + #ratingsLine: HTMLElement | null = null; protected init() { const { "6": sourcesLine, + "7": ratingsLine, } = this.container.querySelectorAll('table tr > td') this.#sourcesLine = sourcesLine; + this.#ratingsLine = ratingsLine; } renderSources(leftSources: string[], rightSources: string[]): void { @@ -39,6 +42,26 @@ export default class DupeDiff extends BaseComponent { this.#sourcesLine.append(sourceIconsContainer); } + renderRatings(leftRating: string | null, rightRating: string | null) { + if (!this.#ratingsLine) { + return; + } + + for (const childElement of this.#ratingsLine.children) { + childElement.remove(); + } + + if (leftRating === rightRating) { + return; + } + + const ratingDifference = document.createElement('span'); + ratingDifference.classList.add('ratings-difference'); + ratingDifference.textContent = `(${leftRating || '(none)'} vs ${rightRating || '(none)'})`; + + this.#ratingsLine.append(ratingDifference); + } + #renderSourceIcons(sourcesList: string[]): HTMLElement { const iconsContainer = document.createElement('span'); iconsContainer.classList.add('source-icons__list'); diff --git a/src/content/components/philomena/dupe/DupeReportRow.ts b/src/content/components/philomena/dupe/DupeReportRow.ts index 1fcdbf7..5b9ab9f 100644 --- a/src/content/components/philomena/dupe/DupeReportRow.ts +++ b/src/content/components/philomena/dupe/DupeReportRow.ts @@ -1,6 +1,7 @@ import { BaseComponent } from "$content/components/base/BaseComponent"; import DupeDiff from "$content/components/philomena/dupe/DupeDiff"; import DupeImage from "$content/components/philomena/dupe/DupeImage"; +import { ratingTags } from "$config/tags"; export default class DupeReportRow extends BaseComponent { #leftImage: DupeImage; @@ -23,6 +24,7 @@ export default class DupeReportRow extends BaseComponent { protected init() { this.#extractAndRenderSourcesIcons(); + this.#extractAndDisplayRatings(); } #extractAndRenderSourcesIcons() { @@ -31,4 +33,15 @@ export default class DupeReportRow extends BaseComponent { this.#rightImage.imageContainer.extractSources(), ); } + + #extractAndDisplayRatings() { + this.#difference.renderRatings( + DupeReportRow.#extractRating(this.#leftImage), + DupeReportRow.#extractRating(this.#rightImage), + ); + } + + static #extractRating(image: DupeImage): string | null { + return image.imageContainer.extractActualTags().find(tagName => ratingTags.includes(tagName)) || null; + } } diff --git a/src/styles/content/duplicate-reports.scss b/src/styles/content/duplicate-reports.scss index 7cb33e5..99c0fa4 100644 --- a/src/styles/content/duplicate-reports.scss +++ b/src/styles/content/duplicate-reports.scss @@ -1,10 +1,18 @@ +%with-margin { + margin-left: .5em; +} + .dr__diff { .source-icons { - margin-left: .5em; + @extend %with-margin; &__list { display: inline-flex; gap: .25em; } } + + .ratings-difference { + @extend %with-margin; + } }