mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 04:44:37 +03:00
Add SFW content mode option (#6262)
* Use more neutral language for content * Add sfw mode setting * Make configuration context mandatory * Add sfw class when sfw mode active * Hide nsfw performer fields in sfw mode * Hide nsfw sort options * Hide nsfw filter/sort options in sfw mode * Replace o-count with like counter in sfw mode * Use sfw label for o-counter filter in sfw mode * Use likes instead of o-count in sfw mode in other places * Rename sfw mode to sfw content mode * Use sfw image for default performers in sfw mode * Document SFW content mode * Add SFW mode setting to setup * Clarify README * Change wording of sfw mode description * Handle configuration loading error correctly * Hide age in performer cards
This commit is contained in:
@@ -78,7 +78,7 @@ export abstract class Criterion {
|
||||
|
||||
protected cloneValues() {}
|
||||
|
||||
public abstract getLabel(intl: IntlShape): string;
|
||||
public abstract getLabel(intl: IntlShape, sfwContentMode?: boolean): string;
|
||||
|
||||
public getId(): string {
|
||||
return `${this.criterionOption.type}`;
|
||||
@@ -148,7 +148,7 @@ export abstract class ModifierCriterion<
|
||||
: "";
|
||||
}
|
||||
|
||||
public getLabel(intl: IntlShape): string {
|
||||
public getLabel(intl: IntlShape, sfwContentMode: boolean = false): string {
|
||||
const modifierString = ModifierCriterion.getModifierLabel(
|
||||
intl,
|
||||
this.modifier
|
||||
@@ -162,10 +162,14 @@ export abstract class ModifierCriterion<
|
||||
valueString = this.getLabelValue(intl);
|
||||
}
|
||||
|
||||
const messageID = !sfwContentMode
|
||||
? this.criterionOption.messageID
|
||||
: this.criterionOption.sfwMessageID ?? this.criterionOption.messageID;
|
||||
|
||||
return intl.formatMessage(
|
||||
{ id: "criterion_modifier.format_string" },
|
||||
{
|
||||
criterion: intl.formatMessage({ id: this.criterionOption.messageID }),
|
||||
criterion: intl.formatMessage({ id: messageID }),
|
||||
modifierString,
|
||||
valueString,
|
||||
}
|
||||
@@ -257,12 +261,14 @@ interface ICriterionOptionParams {
|
||||
type: CriterionType;
|
||||
makeCriterion: MakeCriterionFn;
|
||||
hidden?: boolean;
|
||||
sfwMessageID?: string;
|
||||
}
|
||||
|
||||
export class CriterionOption {
|
||||
public readonly type: CriterionType;
|
||||
public readonly messageID: string;
|
||||
public readonly makeCriterionFn: MakeCriterionFn;
|
||||
public readonly sfwMessageID?: string;
|
||||
|
||||
// used for legacy criteria that are not shown in the UI
|
||||
public readonly hidden: boolean = false;
|
||||
@@ -272,6 +278,7 @@ export class CriterionOption {
|
||||
this.messageID = options.messageID;
|
||||
this.makeCriterionFn = options.makeCriterion;
|
||||
this.hidden = options.hidden ?? false;
|
||||
this.sfwMessageID = options.sfwMessageID;
|
||||
}
|
||||
|
||||
public makeCriterion(config?: ConfigDataFragment) {
|
||||
@@ -478,7 +485,7 @@ export class IHierarchicalLabeledIdCriterion extends ModifierCriterion<IHierarch
|
||||
);
|
||||
}
|
||||
|
||||
public getLabel(intl: IntlShape): string {
|
||||
public getLabel(intl: IntlShape, sfwContentMode?: boolean): string {
|
||||
let id = "criterion_modifier.format_string";
|
||||
let modifierString = ModifierCriterion.getModifierLabel(
|
||||
intl,
|
||||
@@ -511,10 +518,14 @@ export class IHierarchicalLabeledIdCriterion extends ModifierCriterion<IHierarch
|
||||
}
|
||||
}
|
||||
|
||||
const messageID = !sfwContentMode
|
||||
? this.criterionOption.messageID
|
||||
: this.criterionOption.sfwMessageID ?? this.criterionOption.messageID;
|
||||
|
||||
return intl.formatMessage(
|
||||
{ id },
|
||||
{
|
||||
criterion: intl.formatMessage({ id: this.criterionOption.messageID }),
|
||||
criterion: intl.formatMessage({ id: messageID }),
|
||||
modifierString,
|
||||
valueString,
|
||||
excludedString,
|
||||
@@ -552,9 +563,14 @@ export class StringCriterionOption extends ModifierCriterionOption {
|
||||
|
||||
export function createStringCriterionOption(
|
||||
type: CriterionType,
|
||||
messageID?: string
|
||||
messageID?: string,
|
||||
options?: { nsfw?: boolean }
|
||||
) {
|
||||
return new StringCriterionOption({ messageID: messageID ?? type, type });
|
||||
return new StringCriterionOption({
|
||||
messageID: messageID ?? type,
|
||||
type,
|
||||
...options,
|
||||
});
|
||||
}
|
||||
|
||||
export class MandatoryStringCriterionOption extends ModifierCriterionOption {
|
||||
@@ -755,7 +771,8 @@ export class MandatoryNumberCriterionOption extends ModifierCriterionOption {
|
||||
constructor(
|
||||
messageID: string,
|
||||
value: CriterionType,
|
||||
makeCriterion?: () => ModifierCriterion<CriterionValue>
|
||||
makeCriterion?: () => ModifierCriterion<CriterionValue>,
|
||||
options?: { sfwMessageID?: string }
|
||||
) {
|
||||
super({
|
||||
messageID,
|
||||
@@ -773,15 +790,22 @@ export class MandatoryNumberCriterionOption extends ModifierCriterionOption {
|
||||
makeCriterion: makeCriterion
|
||||
? makeCriterion
|
||||
: () => new NumberCriterion(this),
|
||||
...options,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
export function createMandatoryNumberCriterionOption(
|
||||
value: CriterionType,
|
||||
messageID?: string
|
||||
messageID?: string,
|
||||
options?: { sfwMessageID?: string }
|
||||
) {
|
||||
return new MandatoryNumberCriterionOption(messageID ?? value, value);
|
||||
return new MandatoryNumberCriterionOption(
|
||||
messageID ?? value,
|
||||
value,
|
||||
undefined,
|
||||
options
|
||||
);
|
||||
}
|
||||
|
||||
export function encodeRangeValue<V>(
|
||||
|
||||
@@ -4,6 +4,7 @@ import { DisplayMode } from "./types";
|
||||
export interface ISortByOption {
|
||||
messageID: string;
|
||||
value: string;
|
||||
sfwMessageID?: string;
|
||||
}
|
||||
|
||||
export const MediaSortByOptions = [
|
||||
@@ -22,7 +23,7 @@ export class ListFilterOptions {
|
||||
public readonly displayModeOptions: DisplayMode[] = [];
|
||||
public readonly criterionOptions: CriterionOption[] = [];
|
||||
|
||||
public static createSortBy(value: string) {
|
||||
public static createSortBy(value: string): ISortByOption {
|
||||
return {
|
||||
messageID: value,
|
||||
value,
|
||||
|
||||
@@ -38,6 +38,7 @@ const sortByOptions = [
|
||||
{
|
||||
messageID: "o_count",
|
||||
value: "o_counter",
|
||||
sfwMessageID: "o_count_sfw",
|
||||
},
|
||||
]);
|
||||
const displayModeOptions = [DisplayMode.Grid];
|
||||
@@ -53,7 +54,9 @@ const criterionOptions = [
|
||||
RatingCriterionOption,
|
||||
PerformersCriterionOption,
|
||||
createDateCriterionOption("date"),
|
||||
createMandatoryNumberCriterionOption("o_counter", "o_count"),
|
||||
createMandatoryNumberCriterionOption("o_counter", "o_count", {
|
||||
sfwMessageID: "o_count_sfw",
|
||||
}),
|
||||
ContainingGroupsCriterionOption,
|
||||
SubGroupsCriterionOption,
|
||||
createMandatoryNumberCriterionOption("containing_group_count"),
|
||||
|
||||
@@ -31,6 +31,7 @@ const sortByOptions = ["filesize", "file_count", "date", ...MediaSortByOptions]
|
||||
{
|
||||
messageID: "o_count",
|
||||
value: "o_counter",
|
||||
sfwMessageID: "o_count_sfw",
|
||||
},
|
||||
]);
|
||||
const displayModeOptions = [DisplayMode.Grid, DisplayMode.Wall];
|
||||
@@ -43,7 +44,9 @@ const criterionOptions = [
|
||||
PathCriterionOption,
|
||||
GalleriesCriterionOption,
|
||||
OrganizedCriterionOption,
|
||||
createMandatoryNumberCriterionOption("o_counter", "o_count"),
|
||||
createMandatoryNumberCriterionOption("o_counter", "o_count", {
|
||||
sfwMessageID: "o_count_sfw",
|
||||
}),
|
||||
ResolutionCriterionOption,
|
||||
OrientationCriterionOption,
|
||||
ImageIsMissingCriterionOption,
|
||||
|
||||
@@ -31,7 +31,6 @@ const sortByOptions = [
|
||||
"penis_length",
|
||||
"play_count",
|
||||
"last_played_at",
|
||||
"last_o_at",
|
||||
"career_length",
|
||||
"weight",
|
||||
"measurements",
|
||||
@@ -54,6 +53,12 @@ const sortByOptions = [
|
||||
{
|
||||
messageID: "o_count",
|
||||
value: "o_counter",
|
||||
sfwMessageID: "o_count_sfw",
|
||||
},
|
||||
{
|
||||
messageID: "last_o_at",
|
||||
value: "last_o_at",
|
||||
sfwMessageID: "last_o_at_sfw",
|
||||
},
|
||||
]);
|
||||
|
||||
@@ -102,7 +107,9 @@ const criterionOptions = [
|
||||
createMandatoryNumberCriterionOption("image_count"),
|
||||
createMandatoryNumberCriterionOption("gallery_count"),
|
||||
createMandatoryNumberCriterionOption("play_count"),
|
||||
createMandatoryNumberCriterionOption("o_counter", "o_count"),
|
||||
createMandatoryNumberCriterionOption("o_counter", "o_count", {
|
||||
sfwMessageID: "o_count_sfw",
|
||||
}),
|
||||
createBooleanCriterionOption("ignore_auto_tag"),
|
||||
CountryCriterionOption,
|
||||
createNumberCriterionOption("height_cm", "height"),
|
||||
|
||||
@@ -46,7 +46,6 @@ const sortByOptions = [
|
||||
"framerate",
|
||||
"bitrate",
|
||||
"last_played_at",
|
||||
"last_o_at",
|
||||
"resume_time",
|
||||
"play_duration",
|
||||
"play_count",
|
||||
@@ -62,6 +61,12 @@ const sortByOptions = [
|
||||
{
|
||||
messageID: "o_count",
|
||||
value: "o_counter",
|
||||
sfwMessageID: "o_count_sfw",
|
||||
},
|
||||
{
|
||||
messageID: "last_o_at",
|
||||
value: "last_o_at",
|
||||
sfwMessageID: "last_o_at_sfw",
|
||||
},
|
||||
{
|
||||
messageID: "group_scene_number",
|
||||
@@ -97,7 +102,9 @@ const criterionOptions = [
|
||||
DuplicatedCriterionOption,
|
||||
OrganizedCriterionOption,
|
||||
RatingCriterionOption,
|
||||
createMandatoryNumberCriterionOption("o_counter", "o_count"),
|
||||
createMandatoryNumberCriterionOption("o_counter", "o_count", {
|
||||
sfwMessageID: "o_count_sfw",
|
||||
}),
|
||||
ResolutionCriterionOption,
|
||||
OrientationCriterionOption,
|
||||
createMandatoryNumberCriterionOption("framerate"),
|
||||
|
||||
Reference in New Issue
Block a user