mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 12:24:38 +03:00
[Feature] Better resolution search (#1568)
* Fix width in database test setup * Added more filters on resolution field * added test to verify resolution range is defined for every resolution * Refactor UI code Co-authored-by: WithoutPants <53250216+WithoutPants@users.noreply.github.com>
This commit is contained in:
@@ -28,6 +28,11 @@ enum ResolutionEnum {
|
|||||||
"8k", EIGHT_K
|
"8k", EIGHT_K
|
||||||
}
|
}
|
||||||
|
|
||||||
|
input ResolutionCriterionInput {
|
||||||
|
value: ResolutionEnum!
|
||||||
|
modifier: CriterionModifier!
|
||||||
|
}
|
||||||
|
|
||||||
input PerformerFilterType {
|
input PerformerFilterType {
|
||||||
AND: PerformerFilterType
|
AND: PerformerFilterType
|
||||||
OR: PerformerFilterType
|
OR: PerformerFilterType
|
||||||
@@ -126,7 +131,7 @@ input SceneFilterType {
|
|||||||
"""Filter by o-counter"""
|
"""Filter by o-counter"""
|
||||||
o_counter: IntCriterionInput
|
o_counter: IntCriterionInput
|
||||||
"""Filter by resolution"""
|
"""Filter by resolution"""
|
||||||
resolution: ResolutionEnum
|
resolution: ResolutionCriterionInput
|
||||||
"""Filter by duration (in seconds)"""
|
"""Filter by duration (in seconds)"""
|
||||||
duration: IntCriterionInput
|
duration: IntCriterionInput
|
||||||
"""Filter to only include scenes which have markers. `true` or `false`"""
|
"""Filter to only include scenes which have markers. `true` or `false`"""
|
||||||
@@ -215,7 +220,7 @@ input GalleryFilterType {
|
|||||||
"""Filter by organized"""
|
"""Filter by organized"""
|
||||||
organized: Boolean
|
organized: Boolean
|
||||||
"""Filter by average image resolution"""
|
"""Filter by average image resolution"""
|
||||||
average_resolution: ResolutionEnum
|
average_resolution: ResolutionCriterionInput
|
||||||
"""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"""
|
||||||
@@ -282,7 +287,7 @@ input ImageFilterType {
|
|||||||
"""Filter by o-counter"""
|
"""Filter by o-counter"""
|
||||||
o_counter: IntCriterionInput
|
o_counter: IntCriterionInput
|
||||||
"""Filter by resolution"""
|
"""Filter by resolution"""
|
||||||
resolution: ResolutionEnum
|
resolution: ResolutionCriterionInput
|
||||||
"""Filter to only include images missing this property"""
|
"""Filter to only include images missing this property"""
|
||||||
is_missing: String
|
is_missing: String
|
||||||
"""Filter to only include images with this studio"""
|
"""Filter to only include images with this studio"""
|
||||||
|
|||||||
@@ -1,65 +1,33 @@
|
|||||||
package models
|
package models
|
||||||
|
|
||||||
var resolutionMax = []int{
|
type ResolutionRange struct {
|
||||||
240,
|
min, max int
|
||||||
360,
|
}
|
||||||
480,
|
|
||||||
540,
|
var resolutionRanges = map[ResolutionEnum]ResolutionRange{
|
||||||
720,
|
ResolutionEnum("VERY_LOW"): {144, 239},
|
||||||
1080,
|
ResolutionEnum("LOW"): {240, 359},
|
||||||
1440,
|
ResolutionEnum("R360P"): {360, 479},
|
||||||
1920,
|
ResolutionEnum("STANDARD"): {480, 539},
|
||||||
2160,
|
ResolutionEnum("WEB_HD"): {540, 719},
|
||||||
2880,
|
ResolutionEnum("STANDARD_HD"): {720, 1079},
|
||||||
3384,
|
ResolutionEnum("FULL_HD"): {1080, 1439},
|
||||||
4320,
|
ResolutionEnum("QUAD_HD"): {1440, 1919},
|
||||||
0,
|
ResolutionEnum("VR_HD"): {1920, 2159},
|
||||||
|
ResolutionEnum("FOUR_K"): {2160, 2879},
|
||||||
|
ResolutionEnum("FIVE_K"): {2880, 3383},
|
||||||
|
ResolutionEnum("SIX_K"): {3384, 4319},
|
||||||
|
ResolutionEnum("EIGHT_K"): {4320, 8639},
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMaxResolution returns the maximum width or height that media must be
|
// GetMaxResolution returns the maximum width or height that media must be
|
||||||
// to qualify as this resolution. A return value of 0 means that there is no
|
// to qualify as this resolution.
|
||||||
// maximum.
|
|
||||||
func (r *ResolutionEnum) GetMaxResolution() int {
|
func (r *ResolutionEnum) GetMaxResolution() int {
|
||||||
if !r.IsValid() {
|
return resolutionRanges[*r].max
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// sanity check - length of arrays must be the same
|
|
||||||
if len(resolutionMax) != len(AllResolutionEnum) {
|
|
||||||
panic("resolutionMax array length != AllResolutionEnum array length")
|
|
||||||
}
|
|
||||||
|
|
||||||
for i, rr := range AllResolutionEnum {
|
|
||||||
if rr == *r {
|
|
||||||
return resolutionMax[i]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetMinResolution returns the minimum width or height that media must be
|
// GetMinResolution returns the minimum width or height that media must be
|
||||||
// to qualify as this resolution.
|
// to qualify as this resolution.
|
||||||
func (r *ResolutionEnum) GetMinResolution() int {
|
func (r *ResolutionEnum) GetMinResolution() int {
|
||||||
if !r.IsValid() {
|
return resolutionRanges[*r].min
|
||||||
return 0
|
|
||||||
}
|
|
||||||
|
|
||||||
// sanity check - length of arrays must be the same
|
|
||||||
if len(resolutionMax) != len(AllResolutionEnum) {
|
|
||||||
panic("resolutionMax array length != AllResolutionEnum array length")
|
|
||||||
}
|
|
||||||
|
|
||||||
// use the previous resolution max as this resolution min
|
|
||||||
for i, rr := range AllResolutionEnum {
|
|
||||||
if rr == *r {
|
|
||||||
if i > 0 {
|
|
||||||
return resolutionMax[i-1]
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package sqlite
|
|||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
|
||||||
|
|
||||||
"github.com/stashapp/stash/pkg/models"
|
"github.com/stashapp/stash/pkg/models"
|
||||||
)
|
)
|
||||||
@@ -426,23 +425,25 @@ func galleryPerformerTagsCriterionHandler(qb *galleryQueryBuilder, performerTags
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func galleryAverageResolutionCriterionHandler(qb *galleryQueryBuilder, resolution *models.ResolutionEnum) criterionHandlerFunc {
|
func galleryAverageResolutionCriterionHandler(qb *galleryQueryBuilder, resolution *models.ResolutionCriterionInput) criterionHandlerFunc {
|
||||||
return func(f *filterBuilder) {
|
return func(f *filterBuilder) {
|
||||||
if resolution != nil && resolution.IsValid() {
|
if resolution != nil && resolution.Value.IsValid() {
|
||||||
qb.imagesRepository().join(f, "images_join", "galleries.id")
|
qb.imagesRepository().join(f, "images_join", "galleries.id")
|
||||||
f.addJoin("images", "", "images_join.image_id = images.id")
|
f.addJoin("images", "", "images_join.image_id = images.id")
|
||||||
|
|
||||||
min := resolution.GetMinResolution()
|
min := resolution.Value.GetMinResolution()
|
||||||
max := resolution.GetMaxResolution()
|
max := resolution.Value.GetMaxResolution()
|
||||||
|
|
||||||
const widthHeight = "avg(MIN(images.width, images.height))"
|
const widthHeight = "avg(MIN(images.width, images.height))"
|
||||||
|
|
||||||
if min > 0 {
|
if resolution.Modifier == models.CriterionModifierEquals {
|
||||||
f.addHaving(widthHeight + " >= " + strconv.Itoa(min))
|
f.addHaving(fmt.Sprintf("%s BETWEEN %d AND %d", widthHeight, min, max))
|
||||||
}
|
} else if resolution.Modifier == models.CriterionModifierNotEquals {
|
||||||
|
f.addHaving(fmt.Sprintf("%s NOT BETWEEN %d AND %d", widthHeight, min, max))
|
||||||
if max > 0 {
|
} else if resolution.Modifier == models.CriterionModifierLessThan {
|
||||||
f.addHaving(widthHeight + " < " + strconv.Itoa(max))
|
f.addHaving(fmt.Sprintf("%s < %d", widthHeight, min))
|
||||||
|
} else if resolution.Modifier == models.CriterionModifierGreaterThan {
|
||||||
|
f.addHaving(fmt.Sprintf("%s > %d", widthHeight, max))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -914,7 +914,10 @@ func TestGalleryQueryAverageResolution(t *testing.T) {
|
|||||||
qb := r.Gallery()
|
qb := r.Gallery()
|
||||||
resolution := models.ResolutionEnumLow
|
resolution := models.ResolutionEnumLow
|
||||||
galleryFilter := models.GalleryFilterType{
|
galleryFilter := models.GalleryFilterType{
|
||||||
AverageResolution: &resolution,
|
AverageResolution: &models.ResolutionCriterionInput{
|
||||||
|
Value: resolution,
|
||||||
|
Modifier: models.CriterionModifierEquals,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
// not verifying average - just ensure we get at least one
|
// not verifying average - just ensure we get at least one
|
||||||
|
|||||||
@@ -389,7 +389,10 @@ func verifyImagesResolution(t *testing.T, resolution models.ResolutionEnum) {
|
|||||||
withTxn(func(r models.Repository) error {
|
withTxn(func(r models.Repository) error {
|
||||||
sqb := r.Image()
|
sqb := r.Image()
|
||||||
imageFilter := models.ImageFilterType{
|
imageFilter := models.ImageFilterType{
|
||||||
Resolution: &resolution,
|
Resolution: &models.ResolutionCriterionInput{
|
||||||
|
Value: resolution,
|
||||||
|
Modifier: models.CriterionModifierEquals,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
images, _, err := sqb.Query(&imageFilter, nil)
|
images, _, err := sqb.Query(&imageFilter, nil)
|
||||||
|
|||||||
@@ -495,20 +495,22 @@ func getDurationWhereClause(durationFilter models.IntCriterionInput, column stri
|
|||||||
return clause, args
|
return clause, args
|
||||||
}
|
}
|
||||||
|
|
||||||
func resolutionCriterionHandler(resolution *models.ResolutionEnum, heightColumn string, widthColumn string) criterionHandlerFunc {
|
func resolutionCriterionHandler(resolution *models.ResolutionCriterionInput, heightColumn string, widthColumn string) criterionHandlerFunc {
|
||||||
return func(f *filterBuilder) {
|
return func(f *filterBuilder) {
|
||||||
if resolution != nil && resolution.IsValid() {
|
if resolution != nil && resolution.Value.IsValid() {
|
||||||
min := resolution.GetMinResolution()
|
min := resolution.Value.GetMinResolution()
|
||||||
max := resolution.GetMaxResolution()
|
max := resolution.Value.GetMaxResolution()
|
||||||
|
|
||||||
widthHeight := fmt.Sprintf("MIN(%s, %s)", widthColumn, heightColumn)
|
widthHeight := fmt.Sprintf("MIN(%s, %s)", widthColumn, heightColumn)
|
||||||
|
|
||||||
if min > 0 {
|
if resolution.Modifier == models.CriterionModifierEquals {
|
||||||
f.addWhere(widthHeight + " >= " + strconv.Itoa(min))
|
f.addWhere(fmt.Sprintf("%s BETWEEN %d AND %d", widthHeight, min, max))
|
||||||
}
|
} else if resolution.Modifier == models.CriterionModifierNotEquals {
|
||||||
|
f.addWhere(fmt.Sprintf("%s NOT BETWEEN %d AND %d", widthHeight, min, max))
|
||||||
if max > 0 {
|
} else if resolution.Modifier == models.CriterionModifierLessThan {
|
||||||
f.addWhere(widthHeight + " < " + strconv.Itoa(max))
|
f.addWhere(fmt.Sprintf("%s < %d", widthHeight, min))
|
||||||
|
} else if resolution.Modifier == models.CriterionModifierGreaterThan {
|
||||||
|
f.addWhere(fmt.Sprintf("%s > %d", widthHeight, max))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -648,7 +648,10 @@ func verifyScenesResolution(t *testing.T, resolution models.ResolutionEnum) {
|
|||||||
withTxn(func(r models.Repository) error {
|
withTxn(func(r models.Repository) error {
|
||||||
sqb := r.Scene()
|
sqb := r.Scene()
|
||||||
sceneFilter := models.SceneFilterType{
|
sceneFilter := models.SceneFilterType{
|
||||||
Resolution: &resolution,
|
Resolution: &models.ResolutionCriterionInput{
|
||||||
|
Value: resolution,
|
||||||
|
Modifier: models.CriterionModifierEquals,
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
scenes := queryScene(t, sqb, &sceneFilter, nil)
|
scenes := queryScene(t, sqb, &sceneFilter, nil)
|
||||||
@@ -679,6 +682,76 @@ func verifySceneResolution(t *testing.T, height sql.NullInt64, resolution models
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAllResolutionsHaveResolutionRange(t *testing.T) {
|
||||||
|
for _, resolution := range models.AllResolutionEnum {
|
||||||
|
assert.NotZero(t, resolution.GetMinResolution(), "Define resolution range for %s in extension_resolution.go", resolution)
|
||||||
|
assert.NotZero(t, resolution.GetMaxResolution(), "Define resolution range for %s in extension_resolution.go", resolution)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSceneQueryResolutionModifiers(t *testing.T) {
|
||||||
|
if err := withRollbackTxn(func(r models.Repository) error {
|
||||||
|
qb := r.Scene()
|
||||||
|
sceneNoResolution, _ := createScene(qb, 0, 0)
|
||||||
|
firstScene540P, _ := createScene(qb, 960, 540)
|
||||||
|
secondScene540P, _ := createScene(qb, 1280, 719)
|
||||||
|
firstScene720P, _ := createScene(qb, 1280, 720)
|
||||||
|
secondScene720P, _ := createScene(qb, 1280, 721)
|
||||||
|
thirdScene720P, _ := createScene(qb, 1920, 1079)
|
||||||
|
scene1080P, _ := createScene(qb, 1920, 1080)
|
||||||
|
|
||||||
|
scenesEqualTo720P := queryScenes(t, qb, models.ResolutionEnumStandardHd, models.CriterionModifierEquals)
|
||||||
|
scenesNotEqualTo720P := queryScenes(t, qb, models.ResolutionEnumStandardHd, models.CriterionModifierNotEquals)
|
||||||
|
scenesGreaterThan720P := queryScenes(t, qb, models.ResolutionEnumStandardHd, models.CriterionModifierGreaterThan)
|
||||||
|
scenesLessThan720P := queryScenes(t, qb, models.ResolutionEnumStandardHd, models.CriterionModifierLessThan)
|
||||||
|
|
||||||
|
assert.Subset(t, scenesEqualTo720P, []*models.Scene{firstScene720P, secondScene720P, thirdScene720P})
|
||||||
|
assert.NotSubset(t, scenesEqualTo720P, []*models.Scene{sceneNoResolution, firstScene540P, secondScene540P, scene1080P})
|
||||||
|
|
||||||
|
assert.Subset(t, scenesNotEqualTo720P, []*models.Scene{sceneNoResolution, firstScene540P, secondScene540P, scene1080P})
|
||||||
|
assert.NotSubset(t, scenesNotEqualTo720P, []*models.Scene{firstScene720P, secondScene720P, thirdScene720P})
|
||||||
|
|
||||||
|
assert.Subset(t, scenesGreaterThan720P, []*models.Scene{scene1080P})
|
||||||
|
assert.NotSubset(t, scenesGreaterThan720P, []*models.Scene{sceneNoResolution, firstScene540P, secondScene540P, firstScene720P, secondScene720P, thirdScene720P})
|
||||||
|
|
||||||
|
assert.Subset(t, scenesLessThan720P, []*models.Scene{sceneNoResolution, firstScene540P, secondScene540P})
|
||||||
|
assert.NotSubset(t, scenesLessThan720P, []*models.Scene{scene1080P, firstScene720P, secondScene720P, thirdScene720P})
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}); err != nil {
|
||||||
|
t.Error(err.Error())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func queryScenes(t *testing.T, queryBuilder models.SceneReaderWriter, resolution models.ResolutionEnum, modifier models.CriterionModifier) []*models.Scene {
|
||||||
|
sceneFilter := models.SceneFilterType{
|
||||||
|
Resolution: &models.ResolutionCriterionInput{
|
||||||
|
Value: resolution,
|
||||||
|
Modifier: modifier,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
return queryScene(t, queryBuilder, &sceneFilter, nil)
|
||||||
|
}
|
||||||
|
|
||||||
|
func createScene(queryBuilder models.SceneReaderWriter, width int64, height int64) (*models.Scene, error) {
|
||||||
|
name := fmt.Sprintf("TestSceneQueryResolutionModifiers %d %d", width, height)
|
||||||
|
scene := models.Scene{
|
||||||
|
Path: name,
|
||||||
|
Width: sql.NullInt64{
|
||||||
|
Int64: width,
|
||||||
|
Valid: true,
|
||||||
|
},
|
||||||
|
Height: sql.NullInt64{
|
||||||
|
Int64: height,
|
||||||
|
Valid: true,
|
||||||
|
},
|
||||||
|
Checksum: sql.NullString{String: utils.MD5FromString(name), Valid: true},
|
||||||
|
}
|
||||||
|
|
||||||
|
return queryBuilder.Create(scene)
|
||||||
|
}
|
||||||
|
|
||||||
func TestSceneQueryHasMarkers(t *testing.T) {
|
func TestSceneQueryHasMarkers(t *testing.T) {
|
||||||
withTxn(func(r models.Repository) error {
|
withTxn(func(r models.Repository) error {
|
||||||
sqb := r.Scene()
|
sqb := r.Scene()
|
||||||
|
|||||||
@@ -605,6 +605,7 @@ func createScenes(sqb models.SceneReaderWriter, n int) error {
|
|||||||
OCounter: getOCounter(i),
|
OCounter: getOCounter(i),
|
||||||
Duration: getSceneDuration(i),
|
Duration: getSceneDuration(i),
|
||||||
Height: getHeight(i),
|
Height: getHeight(i),
|
||||||
|
Width: getWidth(i),
|
||||||
Date: getSceneDate(i),
|
Date: getSceneDate(i),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,6 @@
|
|||||||
|
### ✨ New Features
|
||||||
|
* Added not equals/greater than/less than modifiers for resolution criteria. ([#1568](https://github.com/stashapp/stash/pull/1568))
|
||||||
|
|
||||||
### 🎨 Improvements
|
### 🎨 Improvements
|
||||||
* Added de-DE language option. ([#1578](https://github.com/stashapp/stash/pull/1578))
|
* Added de-DE language option. ([#1578](https://github.com/stashapp/stash/pull/1578))
|
||||||
|
|
||||||
|
|||||||
@@ -1,37 +1,20 @@
|
|||||||
import { ResolutionEnum } from "src/core/generated-graphql";
|
import {
|
||||||
|
ResolutionCriterionInput,
|
||||||
|
CriterionModifier,
|
||||||
|
} from "src/core/generated-graphql";
|
||||||
|
import { stringToResolution, resolutionStrings } from "src/utils/resolution";
|
||||||
import { CriterionType } from "../types";
|
import { CriterionType } from "../types";
|
||||||
import { CriterionOption, StringCriterion } from "./criterion";
|
import { CriterionOption, StringCriterion } from "./criterion";
|
||||||
|
|
||||||
abstract class AbstractResolutionCriterion extends StringCriterion {
|
abstract class AbstractResolutionCriterion extends StringCriterion {
|
||||||
protected toCriterionInput(): ResolutionEnum | undefined {
|
protected toCriterionInput(): ResolutionCriterionInput | undefined {
|
||||||
switch (this.value) {
|
const value = stringToResolution(this.value);
|
||||||
case "144p":
|
|
||||||
return ResolutionEnum.VeryLow;
|
if (value !== undefined) {
|
||||||
case "240p":
|
return {
|
||||||
return ResolutionEnum.Low;
|
value,
|
||||||
case "360p":
|
modifier: this.modifier,
|
||||||
return ResolutionEnum.R360P;
|
};
|
||||||
case "480p":
|
|
||||||
return ResolutionEnum.Standard;
|
|
||||||
case "540p":
|
|
||||||
return ResolutionEnum.WebHd;
|
|
||||||
case "720p":
|
|
||||||
return ResolutionEnum.StandardHd;
|
|
||||||
case "1080p":
|
|
||||||
return ResolutionEnum.FullHd;
|
|
||||||
case "1440p":
|
|
||||||
return ResolutionEnum.QuadHd;
|
|
||||||
case "1920p":
|
|
||||||
return ResolutionEnum.VrHd;
|
|
||||||
case "4k":
|
|
||||||
return ResolutionEnum.FourK;
|
|
||||||
case "5k":
|
|
||||||
return ResolutionEnum.FiveK;
|
|
||||||
case "6k":
|
|
||||||
return ResolutionEnum.SixK;
|
|
||||||
case "8k":
|
|
||||||
return ResolutionEnum.EightK;
|
|
||||||
// no default
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -42,20 +25,13 @@ class ResolutionCriterionOptionType extends CriterionOption {
|
|||||||
messageID: value,
|
messageID: value,
|
||||||
type: value,
|
type: value,
|
||||||
parameterName: value,
|
parameterName: value,
|
||||||
options: [
|
modifierOptions: [
|
||||||
"144p",
|
CriterionModifier.Equals,
|
||||||
"240p",
|
CriterionModifier.NotEquals,
|
||||||
"360p",
|
CriterionModifier.GreaterThan,
|
||||||
"480p",
|
CriterionModifier.LessThan,
|
||||||
"540p",
|
|
||||||
"720p",
|
|
||||||
"1080p",
|
|
||||||
"1440p",
|
|
||||||
"4k",
|
|
||||||
"5k",
|
|
||||||
"6k",
|
|
||||||
"8k",
|
|
||||||
],
|
],
|
||||||
|
options: resolutionStrings,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
42
ui/v2.5/src/utils/resolution.ts
Normal file
42
ui/v2.5/src/utils/resolution.ts
Normal file
@@ -0,0 +1,42 @@
|
|||||||
|
import { ResolutionEnum } from "src/core/generated-graphql";
|
||||||
|
|
||||||
|
const stringResolutionMap = new Map<string, ResolutionEnum>([
|
||||||
|
["144p", ResolutionEnum.VeryLow],
|
||||||
|
["240p", ResolutionEnum.Low],
|
||||||
|
["360p", ResolutionEnum.R360P],
|
||||||
|
["480p", ResolutionEnum.Standard],
|
||||||
|
["540p", ResolutionEnum.WebHd],
|
||||||
|
["720p", ResolutionEnum.StandardHd],
|
||||||
|
["1080p", ResolutionEnum.FullHd],
|
||||||
|
["1440p", ResolutionEnum.QuadHd],
|
||||||
|
["1920p", ResolutionEnum.VrHd],
|
||||||
|
["4k", ResolutionEnum.FourK],
|
||||||
|
["5k", ResolutionEnum.FiveK],
|
||||||
|
["6k", ResolutionEnum.SixK],
|
||||||
|
["8k", ResolutionEnum.EightK],
|
||||||
|
]);
|
||||||
|
|
||||||
|
export const stringToResolution = (
|
||||||
|
value?: string | null,
|
||||||
|
caseInsensitive?: boolean
|
||||||
|
) => {
|
||||||
|
if (!value) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ret = stringResolutionMap.get(value);
|
||||||
|
if (ret || !caseInsensitive) {
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
const asUpper = value.toUpperCase();
|
||||||
|
const foundEntry = Array.from(stringResolutionMap.entries()).find((e) => {
|
||||||
|
return e[0].toUpperCase() === asUpper;
|
||||||
|
});
|
||||||
|
|
||||||
|
if (foundEntry) {
|
||||||
|
return foundEntry[1];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
export const resolutionStrings = Array.from(stringResolutionMap.keys());
|
||||||
Reference in New Issue
Block a user