From e32593023ecbcdeac95ea5c54095f82db820e675 Mon Sep 17 00:00:00 2001 From: dogwithakeyboard <128322708+dogwithakeyboard@users.noreply.github.com> Date: Mon, 20 May 2024 04:10:36 +0100 Subject: [PATCH] Add additional fields and restyle Movie select and Gallery select (#4851) * Add new fields and restyle gallery selector * Add new fields and style movie selector --- pkg/sqlite/movies.go | 2 +- ui/v2.5/graphql/data/gallery.graphql | 10 +++ ui/v2.5/graphql/data/movie-slim.graphql | 5 ++ .../components/Galleries/GallerySelect.tsx | 42 ++++++++++-- ui/v2.5/src/components/Galleries/styles.scss | 51 ++++++++++++-- ui/v2.5/src/components/Movies/MovieSelect.tsx | 66 +++++++++++++++++-- ui/v2.5/src/components/Movies/styles.scss | 46 +++++++++++++ ui/v2.5/src/components/Scenes/SceneSelect.tsx | 2 - .../Shared/ScrapeDialog/ScrapedObjectsRow.tsx | 2 +- 9 files changed, 210 insertions(+), 16 deletions(-) diff --git a/pkg/sqlite/movies.go b/pkg/sqlite/movies.go index 6dc03f9fbf4..5e5434d68cb 100644 --- a/pkg/sqlite/movies.go +++ b/pkg/sqlite/movies.go @@ -358,7 +358,7 @@ func (qb *MovieStore) makeQuery(ctx context.Context, movieFilter *models.MovieFi distinctIDs(&query, movieTable) if q := findFilter.Q; q != nil && *q != "" { - searchColumns := []string{"movies.name"} + searchColumns := []string{"movies.name", "movies.aliases"} query.parseQueryString(searchColumns, *q) } diff --git a/ui/v2.5/graphql/data/gallery.graphql b/ui/v2.5/graphql/data/gallery.graphql index 6f25599b9bd..5a5db3c1ace 100644 --- a/ui/v2.5/graphql/data/gallery.graphql +++ b/ui/v2.5/graphql/data/gallery.graphql @@ -42,6 +42,16 @@ fragment GalleryData on Gallery { fragment SelectGalleryData on Gallery { id title + date + code + studio { + name + } + cover { + paths { + thumbnail + } + } files { path } diff --git a/ui/v2.5/graphql/data/movie-slim.graphql b/ui/v2.5/graphql/data/movie-slim.graphql index 0e533f650c9..2db5b80bd45 100644 --- a/ui/v2.5/graphql/data/movie-slim.graphql +++ b/ui/v2.5/graphql/data/movie-slim.graphql @@ -8,5 +8,10 @@ fragment SlimMovieData on Movie { fragment SelectMovieData on Movie { id name + aliases + date + studio { + name + } front_image_path } diff --git a/ui/v2.5/src/components/Galleries/GallerySelect.tsx b/ui/v2.5/src/components/Galleries/GallerySelect.tsx index 5ccd0d5e41d..e91df6b2b13 100644 --- a/ui/v2.5/src/components/Galleries/GallerySelect.tsx +++ b/ui/v2.5/src/components/Galleries/GallerySelect.tsx @@ -33,10 +33,13 @@ import { CriterionValue, } from "src/models/list-filter/criteria/criterion"; import { PathCriterion } from "src/models/list-filter/criteria/path"; +import { TruncatedText } from "../Shared/TruncatedText"; -export type Gallery = Pick & { +export type Gallery = Pick & { + studio?: Pick | null; files: Pick[]; folder?: Pick | null; + cover?: Pick | null; }; type Option = SelectOption; @@ -111,10 +114,41 @@ const _GallerySelect: React.FC< thisOptionProps = { ...optionProps, children: ( - - {title} + + + {object.cover?.paths?.thumbnail && ( + + )} + + + + + {object.studio?.name && ( + + {object.studio?.name} + + )} + + {object.date && ( + {object.date} + )} + + {object.code && ( + {object.code} + )} + + + {matchedPath && ( - {` (${matchedPath})`} + {`(${matchedPath})`} )} ), diff --git a/ui/v2.5/src/components/Galleries/styles.scss b/ui/v2.5/src/components/Galleries/styles.scss index 8e073e3a2ce..f9fdaffcd01 100644 --- a/ui/v2.5/src/components/Galleries/styles.scss +++ b/ui/v2.5/src/components/Galleries/styles.scss @@ -349,8 +349,51 @@ $galleryTabWidth: 450px; padding-right: 2px; } -.gallery-select-alias { - font-size: 0.8rem; - font-weight: bold; - white-space: pre; +.gallery-select-option { + .gallery-select-row { + align-items: center; + display: flex; + width: 100%; + + .gallery-select-image { + background-color: $body-bg; + margin-right: 0.4em; + max-height: 50px; + max-width: 89px; + object-fit: contain; + object-position: center; + } + + .gallery-select-details { + display: flex; + flex-direction: column; + justify-content: flex-start; + max-height: 4.1rem; + overflow: hidden; + + .gallery-select-title { + flex-shrink: 0; + white-space: pre-wrap; + word-break: break-all; + } + + .gallery-select-date, + .gallery-select-studio, + .gallery-select-code { + color: $text-muted; + flex-shrink: 0; + font-size: 0.9rem; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + } + } + + .gallery-select-alias { + font-size: 0.8rem; + font-weight: bold; + width: 100%; + word-break: break-all; + } } diff --git a/ui/v2.5/src/components/Movies/MovieSelect.tsx b/ui/v2.5/src/components/Movies/MovieSelect.tsx index 141ab008bee..95b233f3e11 100644 --- a/ui/v2.5/src/components/Movies/MovieSelect.tsx +++ b/ui/v2.5/src/components/Movies/MovieSelect.tsx @@ -28,8 +28,14 @@ import { useCompare } from "src/hooks/state"; import { Placement } from "react-bootstrap/esm/Overlay"; import { sortByRelevance } from "src/utils/query"; import { PatchComponent } from "src/patch"; +import { TruncatedText } from "../Shared/TruncatedText"; -export type Movie = Pick; +export type Movie = Pick< + GQL.Movie, + "id" | "name" | "date" | "front_image_path" | "aliases" +> & { + studio?: Pick | null; +}; type Option = SelectOption; const _MovieSelect: React.FC< @@ -64,7 +70,12 @@ const _MovieSelect: React.FC< return !exclude.includes(movie.id.toString()); }); - return sortByRelevance(input, ret, (m) => m.name).map((movie) => ({ + return sortByRelevance( + input, + ret, + (m) => m.name, + (m) => (m.aliases ? [m.aliases] : []) + ).map((movie) => ({ value: movie.id, object: movie, })); @@ -77,9 +88,53 @@ const _MovieSelect: React.FC< const title = object.name; + // if name does not match the input value but an alias does, show the alias + const { inputValue } = optionProps.selectProps; + let alias: string | undefined = ""; + if (!title.toLowerCase().includes(inputValue.toLowerCase())) { + alias = object.aliases || undefined; + } + thisOptionProps = { ...optionProps, - children: {title}, + children: ( + + + {object.front_image_path && ( + + )} + + + + {title} + {alias && ( + {` (${alias})`} + )} + + } + lineCount={1} + /> + + {object.studio?.name && ( + + {object.studio?.name} + + )} + + {object.date && ( + {object.date} + )} + + + + ), }; return ; @@ -140,7 +195,10 @@ const _MovieSelect: React.FC< if ( options.some((o) => { - return o.name.toLowerCase() === inputValue.toLowerCase(); + return ( + o.name.toLowerCase() === inputValue.toLowerCase() || + o.aliases?.toLowerCase() === inputValue.toLowerCase() + ); }) ) { return false; diff --git a/ui/v2.5/src/components/Movies/styles.scss b/ui/v2.5/src/components/Movies/styles.scss index ae400086f11..58071d4b8f3 100644 --- a/ui/v2.5/src/components/Movies/styles.scss +++ b/ui/v2.5/src/components/Movies/styles.scss @@ -43,3 +43,49 @@ #movie-page .rating-number .text-input { width: auto; } + +.movie-select-option { + .movie-select-row { + align-items: center; + display: flex; + width: 100%; + + .movie-select-image { + background-color: $body-bg; + margin-right: 0.4em; + max-height: 50px; + max-width: 89px; + object-fit: contain; + object-position: center; + } + + .movie-select-details { + display: flex; + flex-direction: column; + justify-content: flex-start; + max-height: 4.1rem; + overflow: hidden; + + .movie-select-title { + flex-shrink: 0; + white-space: pre-wrap; + word-break: break-all; + + .movie-select-alias { + font-size: 0.8rem; + font-weight: bold; + } + } + + .movie-select-date, + .movie-select-studio { + color: $text-muted; + flex-shrink: 0; + font-size: 0.9rem; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + } + } +} diff --git a/ui/v2.5/src/components/Scenes/SceneSelect.tsx b/ui/v2.5/src/components/Scenes/SceneSelect.tsx index 4826ef1f54e..1a74623f542 100644 --- a/ui/v2.5/src/components/Scenes/SceneSelect.tsx +++ b/ui/v2.5/src/components/Scenes/SceneSelect.tsx @@ -36,9 +36,7 @@ import { TruncatedText } from "../Shared/TruncatedText"; export type Scene = Pick & { studio?: Pick | null; -} & { files?: Pick[]; -} & { paths?: Pick; }; diff --git a/ui/v2.5/src/components/Shared/ScrapeDialog/ScrapedObjectsRow.tsx b/ui/v2.5/src/components/Shared/ScrapeDialog/ScrapedObjectsRow.tsx index 8d01029853e..8113c90a888 100644 --- a/ui/v2.5/src/components/Shared/ScrapeDialog/ScrapedObjectsRow.tsx +++ b/ui/v2.5/src/components/Shared/ScrapeDialog/ScrapedObjectsRow.tsx @@ -215,7 +215,7 @@ export const ScrapedMoviesRow: React.FC< const value = resultValue ?? []; const selectValue = value.map((p) => { - const aliases: string[] = []; + const aliases: string = ""; return { id: p.stored_id ?? "", name: p.name ?? "",