From 6c8aca0007f28e3f861fee94ced01ca82d122578 Mon Sep 17 00:00:00 2001 From: double beep <38133098+double-beep@users.noreply.github.com> Date: Tue, 22 Aug 2023 10:39:16 +0000 Subject: [PATCH] Avoid flagging duplicate answers as plagiarism --- src/Configuration.ts | 30 +++++++++++++++++------------- src/FlagTypes.ts | 4 ++-- src/modals/comments/main.ts | 2 +- src/modals/comments/rows.ts | 11 ++++++----- src/modals/comments/submit.ts | 13 ++++++++----- src/popover.ts | 6 +++--- src/shared.ts | 14 +++++++++++--- 7 files changed, 48 insertions(+), 32 deletions(-) diff --git a/src/Configuration.ts b/src/Configuration.ts index 53f4165..d7811df 100644 --- a/src/Configuration.ts +++ b/src/Configuration.ts @@ -16,15 +16,17 @@ import { import { buildConfigurationOverlay } from './modals/config'; import { setupCommentsAndFlagsModal } from './modals/comments/main'; -export function isPlagiarismOrNoFlag(flagName: Flags): boolean { - const result = - [ - FlagNames.NoFlag, - FlagNames.Plagiarism - ] - .some(reportType => reportType === flagName); - - return result; +export function isSpecialFlag(flagName: Flags, checkNoFlag = true): boolean { + const arrayOfFlags: Flags[] = [ + FlagNames.ModFlag, + FlagNames.Plagiarism + ]; + + if (checkNoFlag) { + arrayOfFlags.push(FlagNames.NoFlag); + } + + return arrayOfFlags.includes(flagName); } export function wrapInFlexItem(element: HTMLElement): HTMLElement { @@ -40,7 +42,7 @@ export function cacheFlags(): void { return category.FlagTypes.map(flagType => { return Object.assign(flagType, { belongsTo: category.name, - downvote: !isPlagiarismOrNoFlag(flagType.reportType), + downvote: !isSpecialFlag(flagType.reportType), enabled: true // all flags should be enabled by default }); }); @@ -83,10 +85,12 @@ function setupDefaults(): void { cacheCategories(); } - // PostOther is no more! - // Replace with PlagiarizedContent. + // PostOther can be replaced with PlagiarizedContent + // for "Plagiarism" flag type. cachedFlagTypes.forEach(cachedFlag => { - if (cachedFlag.reportType as Flags | 'PostOther' !== 'PostOther') return; + // Plagiarism and Bad Attribution flag types, + // filter by id because names can be edited by the user + if (cachedFlag.id !== 3 && cachedFlag.id !== 5) return; cachedFlag.reportType = FlagNames.Plagiarism; }); diff --git a/src/FlagTypes.ts b/src/FlagTypes.ts index 1f1a99d..74f4a7c 100644 --- a/src/FlagTypes.ts +++ b/src/FlagTypes.ts @@ -4,7 +4,7 @@ export type Flags = 'AnswerNotAnAnswer' | 'PostOffensive' | 'PostSpam' | 'NoFlag' - //| 'PostOther' + | 'PostOther' | 'PostLowQuality' | 'PlagiarizedContent'; @@ -75,7 +75,7 @@ export const flagCategories: FlagCategory[] = [ { id: 4, displayName: 'Duplicate answer', - reportType: FlagNames.Plagiarism, + reportType: FlagNames.ModFlag, flagText: 'The post is a repost of their other answer, but as there are slight differences ' + '(see $COPYPASTOR$), an auto flag would not be raised.', comments: { diff --git a/src/modals/comments/main.ts b/src/modals/comments/main.ts index 8d9049e..fe0f577 100644 --- a/src/modals/comments/main.ts +++ b/src/modals/comments/main.ts @@ -70,7 +70,7 @@ import { ] Notes: - - The ReportType can't be changed to/from PlagiarizedContent for default flags. + - The ReportType can't be changed to/from PostOther/PlagiarizedContent for default flags. - The Human field is retrieved on runtime when the flag is raised based on ReportType. - Each s-card div has a data-flag-id attribute based on which we can store the information on cache again. diff --git a/src/modals/comments/rows.ts b/src/modals/comments/rows.ts index 02344f7..71b3be1 100644 --- a/src/modals/comments/rows.ts +++ b/src/modals/comments/rows.ts @@ -4,10 +4,9 @@ import { BotNames, AllFeedbacks, possibleFeedbacks, - FlagNames, } from '../../shared'; import { flagCategories } from '../../FlagTypes'; -import { wrapInFlexItem, isPlagiarismOrNoFlag } from '../../Configuration'; +import { wrapInFlexItem, isSpecialFlag } from '../../Configuration'; import { toggleHideIfNeeded } from './main'; import { @@ -247,6 +246,8 @@ function getFlagSelect( id: CachedFlag['id'], reportType: CachedFlag['reportType'] ): HTMLElement[] { + const shouldDisable = isSpecialFlag(reportType, false); + const options = flagNames.map(flagName => { return { value: flagName, @@ -258,7 +259,7 @@ function getFlagSelect( const select = Select.makeStacksSelect( `advanced-flagging-select-flag-${id}`, options, - { disabled: reportType === FlagNames.Plagiarism } + { disabled: shouldDisable } ); select.className = 'd-flex ai-center'; @@ -271,7 +272,7 @@ function getFlagSelect( flagLabel.classList.add('fw-bold', 'ps-relative', 'z-selected', 'l12', 'fs-body1', 'flex--item'); flagLabel.innerText = 'Flag:'; - if (reportType === FlagNames.Plagiarism) { + if (shouldDisable) { flagLabel.classList.add('o50'); } @@ -319,7 +320,7 @@ export function getSelectRow({ wrapInFlexItem(downvoteBox) ); - if (!isPlagiarismOrNoFlag(reportType)) { + if (!isSpecialFlag(reportType)) { container.append(wrapInFlexItem(feedback)); } diff --git a/src/modals/comments/submit.ts b/src/modals/comments/submit.ts index d5634bc..f774a06 100644 --- a/src/modals/comments/submit.ts +++ b/src/modals/comments/submit.ts @@ -5,9 +5,9 @@ import { FlagTypeFeedbacks, getFlagTypeFromFlagId, updateFlagTypes, - FlagNames, } from '../../shared'; import { Flags } from '../../FlagTypes'; +import { isSpecialFlag } from '../../Configuration'; function saveName( card: HTMLElement, @@ -48,11 +48,14 @@ function saveReportType( const select = expandable.querySelector('select'); const newReportType = select?.value as Flags; - // can't select to flag for plagiarism - // unless it's disabled, meaning it's a Guttenberg flag type - if (newReportType === FlagNames.Plagiarism && !select?.disabled) { + // can't select to flag for plagiarism/mod attention + // (if disabled, it's a Guttenberg flag type) + if ( + isSpecialFlag(newReportType, false) + && !select?.disabled + ) { displayStacksToast( - 'This type of flag cannot be raised with this option', + 'You cannot use this type of flag!', 'danger', true ); diff --git a/src/popover.ts b/src/popover.ts index afea719..a9723e7 100644 --- a/src/popover.ts +++ b/src/popover.ts @@ -10,7 +10,6 @@ import { cachedCategories, cachedFlagTypes, - FlagNames, isStackOverflow, getFullFlag, getCachedConfigBotKey, @@ -33,6 +32,7 @@ import { GenericBotAPI } from './UserscriptTools/GenericBotAPI'; import { CopyPastorAPI } from './UserscriptTools/CopyPastorAPI'; import { Menu } from '@userscripters/stacks-helpers'; +import { isSpecialFlag } from './Configuration'; const noneSpan = document.createElement('span'); noneSpan.classList.add('o50'); @@ -382,8 +382,8 @@ function getReportLinks( cachedFlagTypes // exclude disabled and non-SO flag types .filter(({ reportType, id, belongsTo, enabled }) => { - // only Guttenberg reports (can) have ReportType === 'PlagiarizedContent' - const isGuttenbergItem = reportType === FlagNames.Plagiarism; + // only Guttenberg reports (can) have ReportType === 'PlagiarizedContent/PostOther' + const isGuttenbergItem = isSpecialFlag(reportType, false); const showGutReport = Boolean(copypastorId) // a CopyPastor id must exist // https://github.com/SOBotics/AdvancedFlagging/issues/16 diff --git a/src/shared.ts b/src/shared.ts index 9dbbc74..3a55ee8 100644 --- a/src/shared.ts +++ b/src/shared.ts @@ -56,7 +56,8 @@ export enum FlagNames { NAA = 'AnswerNotAnAnswer', VLQ = 'PostLowQuality', NoFlag = 'NoFlag', - Plagiarism = 'PlagiarizedContent' + Plagiarism = 'PlagiarizedContent', + ModFlag = 'PostOther' } // Constants @@ -236,7 +237,13 @@ export function getFlagTypeFromFlagId(flagId: number): CachedFlag | null { return cachedFlagTypes.find(({ id }) => id === flagId) || null; } -export type HumanFlags = 'as NAA' | 'as R/A' | 'as spam' | 'for plagiarism' | 'as VLQ' | ''; +export type HumanFlags = 'as NAA' + | 'as R/A' + | 'as spam' + | 'for plagiarism' + | 'as VLQ' + | 'for moderator attention' + | ''; export function getHumanFromDisplayName(displayName: Flags): HumanFlags { const flags = { @@ -245,7 +252,8 @@ export function getHumanFromDisplayName(displayName: Flags): HumanFlags { [FlagNames.NAA]: 'as NAA', [FlagNames.VLQ]: 'as VLQ', [FlagNames.NoFlag]: '', - [FlagNames.Plagiarism]: 'for plagiarism' + [FlagNames.Plagiarism]: 'for plagiarism', + [FlagNames.ModFlag]: 'for moderator attention', } as const; return flags[displayName] || '';