mirror of
https://github.com/stashapp/stash.git
synced 2025-12-06 08:26:00 +01:00
Add scenes filter to galleries (#4840)
This commit is contained in:
parent
769540be55
commit
3e3e8b95e2
10 changed files with 51 additions and 1 deletions
|
|
@ -378,6 +378,8 @@ input GalleryFilterType {
|
||||||
average_resolution: ResolutionCriterionInput
|
average_resolution: ResolutionCriterionInput
|
||||||
"Filter to only include galleries that have chapters. `true` or `false`"
|
"Filter to only include galleries that have chapters. `true` or `false`"
|
||||||
has_chapters: String
|
has_chapters: String
|
||||||
|
"Filter to only include galleries with these scenes"
|
||||||
|
scenes: MultiCriterionInput
|
||||||
"Filter to only include galleries with this studio"
|
"Filter to only include galleries with this studio"
|
||||||
studios: HierarchicalMultiCriterionInput
|
studios: HierarchicalMultiCriterionInput
|
||||||
"Filter to only include galleries with these tags"
|
"Filter to only include galleries with these tags"
|
||||||
|
|
|
||||||
|
|
@ -27,6 +27,8 @@ type GalleryFilterType struct {
|
||||||
AverageResolution *ResolutionCriterionInput `json:"average_resolution"`
|
AverageResolution *ResolutionCriterionInput `json:"average_resolution"`
|
||||||
// Filter to only include scenes which have chapters. `true` or `false`
|
// Filter to only include scenes which have chapters. `true` or `false`
|
||||||
HasChapters *string `json:"has_chapters"`
|
HasChapters *string `json:"has_chapters"`
|
||||||
|
// Filter to only include galleries with these scenes
|
||||||
|
Scenes *MultiCriterionInput `json:"scenes"`
|
||||||
// Filter to only include galleries with this studio
|
// Filter to only include galleries with this studio
|
||||||
Studios *HierarchicalMultiCriterionInput `json:"studios"`
|
Studios *HierarchicalMultiCriterionInput `json:"studios"`
|
||||||
// Filter to only include galleries with these tags
|
// Filter to only include galleries with these tags
|
||||||
|
|
|
||||||
|
|
@ -699,6 +699,7 @@ func (qb *GalleryStore) makeFilter(ctx context.Context, galleryFilter *models.Ga
|
||||||
query.handleCriterion(ctx, galleryPerformersCriterionHandler(qb, galleryFilter.Performers))
|
query.handleCriterion(ctx, galleryPerformersCriterionHandler(qb, galleryFilter.Performers))
|
||||||
query.handleCriterion(ctx, galleryPerformerCountCriterionHandler(qb, galleryFilter.PerformerCount))
|
query.handleCriterion(ctx, galleryPerformerCountCriterionHandler(qb, galleryFilter.PerformerCount))
|
||||||
query.handleCriterion(ctx, hasChaptersCriterionHandler(galleryFilter.HasChapters))
|
query.handleCriterion(ctx, hasChaptersCriterionHandler(galleryFilter.HasChapters))
|
||||||
|
query.handleCriterion(ctx, galleryScenesCriterionHandler(qb, galleryFilter.Scenes))
|
||||||
query.handleCriterion(ctx, studioCriterionHandler(galleryTable, galleryFilter.Studios))
|
query.handleCriterion(ctx, studioCriterionHandler(galleryTable, galleryFilter.Studios))
|
||||||
query.handleCriterion(ctx, galleryPerformerTagsCriterionHandler(qb, galleryFilter.PerformerTags))
|
query.handleCriterion(ctx, galleryPerformerTagsCriterionHandler(qb, galleryFilter.PerformerTags))
|
||||||
query.handleCriterion(ctx, galleryAverageResolutionCriterionHandler(qb, galleryFilter.AverageResolution))
|
query.handleCriterion(ctx, galleryAverageResolutionCriterionHandler(qb, galleryFilter.AverageResolution))
|
||||||
|
|
@ -827,6 +828,17 @@ func galleryURLsCriterionHandler(url *models.StringCriterionInput) criterionHand
|
||||||
return h.handler(url)
|
return h.handler(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (qb *GalleryStore) getMultiCriterionHandlerBuilder(foreignTable, joinTable, foreignFK string, addJoinsFunc func(f *filterBuilder)) multiCriterionHandlerBuilder {
|
||||||
|
return multiCriterionHandlerBuilder{
|
||||||
|
primaryTable: galleryTable,
|
||||||
|
foreignTable: foreignTable,
|
||||||
|
joinTable: joinTable,
|
||||||
|
primaryFK: galleryIDColumn,
|
||||||
|
foreignFK: foreignFK,
|
||||||
|
addJoinsFunc: addJoinsFunc,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (qb *GalleryStore) galleryPathCriterionHandler(c *models.StringCriterionInput) criterionHandlerFunc {
|
func (qb *GalleryStore) galleryPathCriterionHandler(c *models.StringCriterionInput) criterionHandlerFunc {
|
||||||
return func(ctx context.Context, f *filterBuilder) {
|
return func(ctx context.Context, f *filterBuilder) {
|
||||||
if c != nil {
|
if c != nil {
|
||||||
|
|
@ -958,6 +970,15 @@ func galleryTagCountCriterionHandler(qb *GalleryStore, tagCount *models.IntCrite
|
||||||
return h.handler(tagCount)
|
return h.handler(tagCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func galleryScenesCriterionHandler(qb *GalleryStore, scenes *models.MultiCriterionInput) criterionHandlerFunc {
|
||||||
|
addJoinsFunc := func(f *filterBuilder) {
|
||||||
|
qb.scenesRepository().join(f, "", "galleries.id")
|
||||||
|
f.addLeftJoin("scenes", "", "scenes_galleries.scene_id = scenes.id")
|
||||||
|
}
|
||||||
|
h := qb.getMultiCriterionHandlerBuilder(sceneTable, galleriesScenesTable, "scene_id", addJoinsFunc)
|
||||||
|
return h.handler(scenes)
|
||||||
|
}
|
||||||
|
|
||||||
func galleryPerformersCriterionHandler(qb *GalleryStore, performers *models.MultiCriterionInput) criterionHandlerFunc {
|
func galleryPerformersCriterionHandler(qb *GalleryStore, performers *models.MultiCriterionInput) criterionHandlerFunc {
|
||||||
h := joinedMultiCriterionHandlerBuilder{
|
h := joinedMultiCriterionHandlerBuilder{
|
||||||
primaryTable: galleryTable,
|
primaryTable: galleryTable,
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,7 @@ export const LabeledIdFilter: React.FC<ILabeledIdFilterProps> = ({
|
||||||
inputType !== "scene_tags" &&
|
inputType !== "scene_tags" &&
|
||||||
inputType !== "performer_tags" &&
|
inputType !== "performer_tags" &&
|
||||||
inputType !== "tags" &&
|
inputType !== "tags" &&
|
||||||
|
inputType !== "scenes" &&
|
||||||
inputType !== "movies" &&
|
inputType !== "movies" &&
|
||||||
inputType !== "galleries"
|
inputType !== "galleries"
|
||||||
) {
|
) {
|
||||||
|
|
|
||||||
|
|
@ -43,6 +43,7 @@ interface ITypeProps {
|
||||||
| "tags"
|
| "tags"
|
||||||
| "scene_tags"
|
| "scene_tags"
|
||||||
| "performer_tags"
|
| "performer_tags"
|
||||||
|
| "scenes"
|
||||||
| "movies"
|
| "movies"
|
||||||
| "galleries";
|
| "galleries";
|
||||||
}
|
}
|
||||||
|
|
@ -379,6 +380,8 @@ export const FilterSelect: React.FC<IFilterProps & ITypeProps> = (props) => {
|
||||||
return <PerformerSelect {...props} creatable={false} />;
|
return <PerformerSelect {...props} creatable={false} />;
|
||||||
case "studios":
|
case "studios":
|
||||||
return <StudioSelect {...props} creatable={false} />;
|
return <StudioSelect {...props} creatable={false} />;
|
||||||
|
case "scenes":
|
||||||
|
return <SceneSelect {...props} creatable={false} />;
|
||||||
case "movies":
|
case "movies":
|
||||||
return <MovieSelect {...props} creatable={false} />;
|
return <MovieSelect {...props} creatable={false} />;
|
||||||
case "galleries":
|
case "galleries":
|
||||||
|
|
|
||||||
|
|
@ -171,6 +171,7 @@ export type InputType =
|
||||||
| "studios"
|
| "studios"
|
||||||
| "tags"
|
| "tags"
|
||||||
| "performer_tags"
|
| "performer_tags"
|
||||||
|
| "scenes"
|
||||||
| "scene_tags"
|
| "scene_tags"
|
||||||
| "movies"
|
| "movies"
|
||||||
| "galleries"
|
| "galleries"
|
||||||
|
|
|
||||||
17
ui/v2.5/src/models/list-filter/criteria/scenes.ts
Normal file
17
ui/v2.5/src/models/list-filter/criteria/scenes.ts
Normal file
|
|
@ -0,0 +1,17 @@
|
||||||
|
import { ILabeledIdCriterion, ILabeledIdCriterionOption } from "./criterion";
|
||||||
|
|
||||||
|
const inputType = "scenes";
|
||||||
|
|
||||||
|
export const ScenesCriterionOption = new ILabeledIdCriterionOption(
|
||||||
|
"scenes",
|
||||||
|
"scenes",
|
||||||
|
true,
|
||||||
|
inputType,
|
||||||
|
() => new ScenesCriterion()
|
||||||
|
);
|
||||||
|
|
||||||
|
export class ScenesCriterion extends ILabeledIdCriterion {
|
||||||
|
constructor() {
|
||||||
|
super(ScenesCriterionOption);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,6 +10,7 @@ import { OrganizedCriterionOption } from "./criteria/organized";
|
||||||
import { HasChaptersCriterionOption } from "./criteria/has-chapters";
|
import { HasChaptersCriterionOption } from "./criteria/has-chapters";
|
||||||
import { PerformersCriterionOption } from "./criteria/performers";
|
import { PerformersCriterionOption } from "./criteria/performers";
|
||||||
import { AverageResolutionCriterionOption } from "./criteria/resolution";
|
import { AverageResolutionCriterionOption } from "./criteria/resolution";
|
||||||
|
import { ScenesCriterionOption } from "./criteria/scenes";
|
||||||
import { StudiosCriterionOption } from "./criteria/studios";
|
import { StudiosCriterionOption } from "./criteria/studios";
|
||||||
import {
|
import {
|
||||||
PerformerTagsCriterionOption,
|
PerformerTagsCriterionOption,
|
||||||
|
|
@ -61,6 +62,7 @@ const criterionOptions = [
|
||||||
createMandatoryNumberCriterionOption("performer_age"),
|
createMandatoryNumberCriterionOption("performer_age"),
|
||||||
PerformerFavoriteCriterionOption,
|
PerformerFavoriteCriterionOption,
|
||||||
createMandatoryNumberCriterionOption("image_count"),
|
createMandatoryNumberCriterionOption("image_count"),
|
||||||
|
ScenesCriterionOption,
|
||||||
StudiosCriterionOption,
|
StudiosCriterionOption,
|
||||||
createStringCriterionOption("url"),
|
createStringCriterionOption("url"),
|
||||||
createMandatoryNumberCriterionOption("file_count", "zip_file_count"),
|
createMandatoryNumberCriterionOption("file_count", "zip_file_count"),
|
||||||
|
|
|
||||||
|
|
@ -145,6 +145,7 @@ export type CriterionType =
|
||||||
| "tag_count"
|
| "tag_count"
|
||||||
| "performers"
|
| "performers"
|
||||||
| "studios"
|
| "studios"
|
||||||
|
| "scenes"
|
||||||
| "movies"
|
| "movies"
|
||||||
| "galleries"
|
| "galleries"
|
||||||
| "birth_year"
|
| "birth_year"
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue