diff --git a/graphql/schema/types/filters.graphql b/graphql/schema/types/filters.graphql index 3af1310a1..7dba266b4 100644 --- a/graphql/schema/types/filters.graphql +++ b/graphql/schema/types/filters.graphql @@ -12,11 +12,19 @@ input FindFilterType { } enum ResolutionEnum { + "144p", VERY_LOW "240p", LOW + "360p", R360P "480p", STANDARD + "540p", WEB_HD "720p", STANDARD_HD "1080p", FULL_HD + "1440p", QUAD_HD + "1920p", VR_HD "4k", FOUR_K + "5k", FIVE_K + "6k", SIX_K + "8k", EIGHT_K } input PerformerFilterType { diff --git a/pkg/models/querybuilder_gallery.go b/pkg/models/querybuilder_gallery.go index 23c40138d..4a8c8ff2d 100644 --- a/pkg/models/querybuilder_gallery.go +++ b/pkg/models/querybuilder_gallery.go @@ -313,30 +313,54 @@ func (qb *GalleryQueryBuilder) handleAverageResolutionFilter(query *queryBuilder var high int switch resolution { + case "VERY_LOW": + high = 240 case "LOW": + low = 240 + high = 360 + case "R360P": + low = 360 high = 480 case "STANDARD": low = 480 + high = 540 + case "WEB_HD": + low = 540 high = 720 case "STANDARD_HD": low = 720 high = 1080 case "FULL_HD": low = 1080 + high = 1440 + case "QUAD_HD": + low = 1440 + high = 1920 + case "VR_HD": + low = 1920 high = 2160 case "FOUR_K": low = 2160 + high = 2880 + case "FIVE_K": + low = 2880 + high = 3384 + case "SIX_K": + low = 3384 + high = 4320 + case "EIGHT_K": + low = 4320 } havingClause := "" if low != 0 { - havingClause = "avg(images.height) >= " + strconv.Itoa(low) + havingClause = "avg(MIN(images.width, images.height)) >= " + strconv.Itoa(low) } if high != 0 { if havingClause != "" { havingClause += " AND " } - havingClause += "avg(images.height) < " + strconv.Itoa(high) + havingClause += "avg(MIN(images.width, images.height)) < " + strconv.Itoa(high) } if havingClause != "" { diff --git a/pkg/models/querybuilder_image.go b/pkg/models/querybuilder_image.go index 48ad119b8..04fb54df5 100644 --- a/pkg/models/querybuilder_image.go +++ b/pkg/models/querybuilder_image.go @@ -322,16 +322,32 @@ func (qb *ImageQueryBuilder) Query(imageFilter *ImageFilterType, findFilter *Fin if resolutionFilter := imageFilter.Resolution; resolutionFilter != nil { if resolution := resolutionFilter.String(); resolutionFilter.IsValid() { switch resolution { + case "VERY_LOW": + query.addWhere("MIN(images.height, images.width) < 240") case "LOW": - query.addWhere("images.height < 480") + query.addWhere("(MIN(images.height, images.width) >= 240 AND MIN(images.height, images.width) < 360)") + case "R360P": + query.addWhere("(MIN(images.height, images.width) >= 360 AND MIN(images.height, images.width) < 480)") case "STANDARD": - query.addWhere("(images.height >= 480 AND images.height < 720)") + query.addWhere("(MIN(images.height, images.width) >= 480 AND MIN(images.height, images.width) < 540)") + case "WEB_HD": + query.addWhere("(MIN(images.height, images.width) >= 540 AND MIN(images.height, images.width) < 720)") case "STANDARD_HD": - query.addWhere("(images.height >= 720 AND images.height < 1080)") + query.addWhere("(MIN(images.height, images.width) >= 720 AND MIN(images.height, images.width) < 1080)") case "FULL_HD": - query.addWhere("(images.height >= 1080 AND images.height < 2160)") + query.addWhere("(MIN(images.height, images.width) >= 1080 AND MIN(images.height, images.width) < 1440)") + case "QUAD_HD": + query.addWhere("(MIN(images.height, images.width) >= 1440 AND MIN(images.height, images.width) < 1920)") + case "VR_HD": + query.addWhere("(MIN(images.height, images.width) >= 1920 AND MIN(images.height, images.width) < 2160)") case "FOUR_K": - query.addWhere("images.height >= 2160") + query.addWhere("(MIN(images.height, images.width) >= 2160 AND MIN(images.height, images.width) < 2880)") + case "FIVE_K": + query.addWhere("(MIN(images.height, images.width) >= 2880 AND MIN(images.height, images.width) < 3384)") + case "SIX_K": + query.addWhere("(MIN(images.height, images.width) >= 3384 AND MIN(images.height, images.width) < 4320)") + case "EIGHT_K": + query.addWhere("(MIN(images.height, images.width) >= 4320") } } } diff --git a/pkg/models/querybuilder_scene.go b/pkg/models/querybuilder_scene.go index 039bb1597..e9524da02 100644 --- a/pkg/models/querybuilder_scene.go +++ b/pkg/models/querybuilder_scene.go @@ -344,16 +344,32 @@ func (qb *SceneQueryBuilder) Query(sceneFilter *SceneFilterType, findFilter *Fin if resolutionFilter := sceneFilter.Resolution; resolutionFilter != nil { if resolution := resolutionFilter.String(); resolutionFilter.IsValid() { switch resolution { + case "VERY_LOW": + query.addWhere("MIN(scenes.height, scenes.width) < 240") case "LOW": - query.addWhere("scenes.height < 480") + query.addWhere("(MIN(scenes.height, scenes.width) >= 240 AND MIN(scenes.height, scenes.width) < 360)") + case "R360P": + query.addWhere("(MIN(scenes.height, scenes.width) >= 360 AND MIN(scenes.height, scenes.width) < 480)") case "STANDARD": - query.addWhere("(scenes.height >= 480 AND scenes.height < 720)") + query.addWhere("(MIN(scenes.height, scenes.width) >= 480 AND MIN(scenes.height, scenes.width) < 540)") + case "WEB_HD": + query.addWhere("(MIN(scenes.height, scenes.width) >= 540 AND MIN(scenes.height, scenes.width) < 720)") case "STANDARD_HD": - query.addWhere("(scenes.height >= 720 AND scenes.height < 1080)") + query.addWhere("(MIN(scenes.height, scenes.width) >= 720 AND MIN(scenes.height, scenes.width) < 1080)") case "FULL_HD": - query.addWhere("(scenes.height >= 1080 AND scenes.height < 2160)") + query.addWhere("(MIN(scenes.height, scenes.width) >= 1080 AND MIN(scenes.height, scenes.width) < 1440)") + case "QUAD_HD": + query.addWhere("(MIN(scenes.height, scenes.width) >= 1440 AND MIN(scenes.height, scenes.width) < 1920)") + case "VR_HD": + query.addWhere("(MIN(scenes.height, scenes.width) >= 1920 AND MIN(scenes.height, scenes.width) < 2160)") case "FOUR_K": - query.addWhere("scenes.height >= 2160") + query.addWhere("(MIN(scenes.height, scenes.width) >= 2160 AND MIN(scenes.height, scenes.width) < 2880)") + case "FIVE_K": + query.addWhere("(MIN(scenes.height, scenes.width) >= 2880 AND MIN(scenes.height, scenes.width) < 3384)") + case "SIX_K": + query.addWhere("(MIN(scenes.height, scenes.width) >= 3384 AND MIN(scenes.height, scenes.width) < 4320)") + case "EIGHT_K": + query.addWhere("(MIN(scenes.height, scenes.width) >= 4320") } } } diff --git a/ui/v2.5/src/components/Changelog/versions/v050.md b/ui/v2.5/src/components/Changelog/versions/v050.md index 7dd01e09c..1b9f2410a 100644 --- a/ui/v2.5/src/components/Changelog/versions/v050.md +++ b/ui/v2.5/src/components/Changelog/versions/v050.md @@ -6,6 +6,7 @@ * Allow configuration of visible navbar items. ### 🎨 Improvements +* Add more video/image resolution tags. * Add option to strip file extension from scene title when populating from scanning task. * Pagination support and general improvements for image lightbox. * Add mouse click support for CDP scrapers. @@ -19,6 +20,7 @@ * Support configurable number of threads for scanning and generation. ### 🐛 Bug fixes +* Fixed resolution tags and querying for portrait videos and images. * Corrected file sizes on 32bit platforms * Fixed login redirect to remember the current page. * Fixed scene tagger config saving diff --git a/ui/v2.5/src/components/Images/ImageDetails/ImageDetailPanel.tsx b/ui/v2.5/src/components/Images/ImageDetails/ImageDetailPanel.tsx index e0126df2f..a093e33c6 100644 --- a/ui/v2.5/src/components/Images/ImageDetails/ImageDetailPanel.tsx +++ b/ui/v2.5/src/components/Images/ImageDetails/ImageDetailPanel.tsx @@ -78,8 +78,14 @@ export const ImageDetailPanel: React.FC = (props) => { "" )} {renderGalleries()} - {props.image.file.height ? ( -
Resolution: {TextUtils.resolution(props.image.file.height)}
+ {props.image.file.width && props.image.file.height ? ( +
+ Resolution:{" "} + {TextUtils.resolution( + props.image.file.width, + props.image.file.height + )} +
) : ( "" )} diff --git a/ui/v2.5/src/components/Scenes/SceneCard.tsx b/ui/v2.5/src/components/Scenes/SceneCard.tsx index 495eef3c3..1dfb22271 100644 --- a/ui/v2.5/src/components/Scenes/SceneCard.tsx +++ b/ui/v2.5/src/components/Scenes/SceneCard.tsx @@ -102,10 +102,13 @@ export const SceneCard: React.FC = ( function maybeRenderSceneSpecsOverlay() { return (
- {props.scene.file.height ? ( + {props.scene.file.width && props.scene.file.height ? ( {" "} - {TextUtils.resolution(props.scene.file.height)} + {TextUtils.resolution( + props.scene.file.width, + props.scene.file.height + )} ) : ( "" diff --git a/ui/v2.5/src/components/Scenes/SceneDetails/SceneDetailPanel.tsx b/ui/v2.5/src/components/Scenes/SceneDetails/SceneDetailPanel.tsx index 7973010dd..a811ebc60 100644 --- a/ui/v2.5/src/components/Scenes/SceneDetails/SceneDetailPanel.tsx +++ b/ui/v2.5/src/components/Scenes/SceneDetails/SceneDetailPanel.tsx @@ -88,8 +88,14 @@ export const SceneDetailPanel: React.FC = (props) => { ) : ( "" )} - {props.scene.file.height && ( -
Resolution: {TextUtils.resolution(props.scene.file.height)}
+ {props.scene.file.width && props.scene.file.height && ( +
+ Resolution:{" "} + {TextUtils.resolution( + props.scene.file.width, + props.scene.file.height + )} +
)}
{props.scene.studio && ( diff --git a/ui/v2.5/src/models/list-filter/criteria/resolution.ts b/ui/v2.5/src/models/list-filter/criteria/resolution.ts index edcd03128..3b7b7c2b0 100644 --- a/ui/v2.5/src/models/list-filter/criteria/resolution.ts +++ b/ui/v2.5/src/models/list-filter/criteria/resolution.ts @@ -6,7 +6,20 @@ export class ResolutionCriterion extends Criterion { public parameterName: string = "resolution"; public modifier = CriterionModifier.Equals; public modifierOptions = []; - public options: string[] = ["240p", "480p", "720p", "1080p", "4k"]; + public options: string[] = [ + "144p", + "240p", + "360p", + "480p", + "540p", + "720p", + "1080p", + "1440p", + "4k", + "5k", + "6k", + "8k", + ]; public value: string = ""; } diff --git a/ui/v2.5/src/models/list-filter/filter.ts b/ui/v2.5/src/models/list-filter/filter.ts index 4d6bb3e65..f7f64b344 100644 --- a/ui/v2.5/src/models/list-filter/filter.ts +++ b/ui/v2.5/src/models/list-filter/filter.ts @@ -462,21 +462,45 @@ export class ListFilterModel { } case "resolution": { switch ((criterion as ResolutionCriterion).value) { + case "144p": + result.resolution = ResolutionEnum.VeryLow; + break; case "240p": result.resolution = ResolutionEnum.Low; break; + case "360p": + result.resolution = ResolutionEnum.R360P; + break; case "480p": result.resolution = ResolutionEnum.Standard; break; + case "540p": + result.resolution = ResolutionEnum.WebHd; + break; case "720p": result.resolution = ResolutionEnum.StandardHd; break; case "1080p": result.resolution = ResolutionEnum.FullHd; break; + case "1440p": + result.resolution = ResolutionEnum.QuadHd; + break; + case "1920p": + result.resolution = ResolutionEnum.VrHd; + break; case "4k": result.resolution = ResolutionEnum.FourK; break; + case "5k": + result.resolution = ResolutionEnum.FiveK; + break; + case "6k": + result.resolution = ResolutionEnum.SixK; + break; + case "8k": + result.resolution = ResolutionEnum.EightK; + break; // no default } break; @@ -700,21 +724,45 @@ export class ListFilterModel { } case "resolution": { switch ((criterion as ResolutionCriterion).value) { + case "144p": + result.resolution = ResolutionEnum.VeryLow; + break; case "240p": result.resolution = ResolutionEnum.Low; break; + case "360p": + result.resolution = ResolutionEnum.R360P; + break; case "480p": result.resolution = ResolutionEnum.Standard; break; + case "540p": + result.resolution = ResolutionEnum.WebHd; + break; case "720p": result.resolution = ResolutionEnum.StandardHd; break; case "1080p": result.resolution = ResolutionEnum.FullHd; break; + case "1440p": + result.resolution = ResolutionEnum.QuadHd; + break; + case "1920p": + result.resolution = ResolutionEnum.VrHd; + break; case "4k": result.resolution = ResolutionEnum.FourK; break; + case "5k": + result.resolution = ResolutionEnum.FiveK; + break; + case "6k": + result.resolution = ResolutionEnum.SixK; + break; + case "8k": + result.resolution = ResolutionEnum.EightK; + break; // no default } break; @@ -827,21 +875,45 @@ export class ListFilterModel { } case "average_resolution": { switch ((criterion as AverageResolutionCriterion).value) { + case "144p": + result.average_resolution = ResolutionEnum.VeryLow; + break; case "240p": result.average_resolution = ResolutionEnum.Low; break; + case "360p": + result.average_resolution = ResolutionEnum.R360P; + break; case "480p": result.average_resolution = ResolutionEnum.Standard; break; + case "540p": + result.average_resolution = ResolutionEnum.WebHd; + break; case "720p": result.average_resolution = ResolutionEnum.StandardHd; break; case "1080p": result.average_resolution = ResolutionEnum.FullHd; break; + case "1440p": + result.average_resolution = ResolutionEnum.QuadHd; + break; + case "1920p": + result.average_resolution = ResolutionEnum.VrHd; + break; case "4k": result.average_resolution = ResolutionEnum.FourK; break; + case "5k": + result.average_resolution = ResolutionEnum.FiveK; + break; + case "6k": + result.average_resolution = ResolutionEnum.SixK; + break; + case "8k": + result.average_resolution = ResolutionEnum.EightK; + break; // no default } break; diff --git a/ui/v2.5/src/utils/text.ts b/ui/v2.5/src/utils/text.ts index b2710414b..4d2182c8e 100644 --- a/ui/v2.5/src/utils/text.ts +++ b/ui/v2.5/src/utils/text.ts @@ -82,21 +82,46 @@ const bitRate = (bitrate: number) => { return `${megabits.toFixed(2)} megabits per second`; }; -const resolution = (height: number) => { - if (height >= 240 && height < 480) { - return "240p"; +const resolution = (width: number, height: number) => { + const number = width > height ? height : width; + if (number >= 4320) { + return "8K"; } - if (height >= 480 && height < 720) { - return "480p"; + if (number >= 3384) { + return "6K"; } - if (height >= 720 && height < 1080) { - return "720p"; + if (number >= 2880) { + return "5K"; } - if (height >= 1080 && height < 2160) { + if (number >= 2160) { + return "4K"; + } + if (number >= 1920) { + return "1920p"; + } + if (number >= 1440) { + return "1440p"; + } + if (number >= 1080) { return "1080p"; } - if (height >= 2160) { - return "4K"; + if (number >= 720) { + return "720p"; + } + if (number >= 540) { + return "540p"; + } + if (number >= 480) { + return "480p"; + } + if (number >= 360) { + return "360p"; + } + if (number >= 240) { + return "240p"; + } + if (number >= 144) { + return "144p"; } };