diff --git a/ui/v2.5/src/App.tsx b/ui/v2.5/src/App.tsx index b3ff5e10fae..7aba652cd80 100644 --- a/ui/v2.5/src/App.tsx +++ b/ui/v2.5/src/App.tsx @@ -66,7 +66,7 @@ const Galleries = lazyComponent( () => import("./components/Galleries/Galleries") ); -const Movies = lazyComponent(() => import("./components/Movies/Movies")); +const Groups = lazyComponent(() => import("./components/Movies/Movies")); const Tags = lazyComponent(() => import("./components/Tags/Tags")); const Images = lazyComponent(() => import("./components/Images/Images")); const Setup = lazyComponent(() => import("./components/Setup/Setup")); @@ -312,7 +312,7 @@ export const App: React.FC = () => { - + = ({ mode, filter, header }) => { ); case GQL.FilterMode.Movies: return ( - = ({ const FilterModeToConfigKey = { [FilterMode.Galleries]: "galleries", [FilterMode.Images]: "images", - [FilterMode.Movies]: "movies", + [FilterMode.Movies]: "groups", [FilterMode.Performers]: "performers", [FilterMode.SceneMarkers]: "sceneMarkers", [FilterMode.Scenes]: "scenes", diff --git a/ui/v2.5/src/components/List/Filters/LabeledIdFilter.tsx b/ui/v2.5/src/components/List/Filters/LabeledIdFilter.tsx index 78f271c0fb2..792c4a7e712 100644 --- a/ui/v2.5/src/components/List/Filters/LabeledIdFilter.tsx +++ b/ui/v2.5/src/components/List/Filters/LabeledIdFilter.tsx @@ -24,7 +24,7 @@ export const LabeledIdFilter: React.FC = ({ inputType !== "performer_tags" && inputType !== "tags" && inputType !== "scenes" && - inputType !== "movies" && + inputType !== "groups" && inputType !== "galleries" ) { return null; diff --git a/ui/v2.5/src/components/List/views.ts b/ui/v2.5/src/components/List/views.ts index 7e8880f9d2e..2b4179014e1 100644 --- a/ui/v2.5/src/components/List/views.ts +++ b/ui/v2.5/src/components/List/views.ts @@ -2,7 +2,7 @@ export enum View { Galleries = "galleries", Images = "images", Scenes = "scenes", - Movies = "movies", + Groups = "groups", Performers = "performers", Tags = "tags", SceneMarkers = "scene_markers", @@ -17,7 +17,7 @@ export enum View { PerformerScenes = "performer_scenes", PerformerGalleries = "performer_galleries", PerformerImages = "performer_images", - PerformerMovies = "performer_movies", + PerformerGroups = "performer_groups", PerformerAppearsWith = "performer_appears_with", StudioGalleries = "studio_galleries", @@ -26,9 +26,9 @@ export enum View { GalleryImages = "gallery_images", StudioScenes = "studio_scenes", - StudioMovies = "studio_movies", + StudioGroups = "studio_groups", StudioPerformers = "studio_performers", StudioChildren = "studio_children", - MovieScenes = "movie_scenes", + GroupScenes = "group_scenes", } diff --git a/ui/v2.5/src/components/MainNavbar.tsx b/ui/v2.5/src/components/MainNavbar.tsx index 89e3563e826..98bbc26c659 100644 --- a/ui/v2.5/src/components/MainNavbar.tsx +++ b/ui/v2.5/src/components/MainNavbar.tsx @@ -1,4 +1,10 @@ -import React, { useEffect, useRef, useState, useCallback } from "react"; +import React, { + useEffect, + useRef, + useState, + useCallback, + useMemo, +} from "react"; import { defineMessages, FormattedMessage, @@ -52,9 +58,9 @@ const messages = defineMessages({ id: "images", defaultMessage: "Images", }, - movies: { - id: "movies", - defaultMessage: "Movies", + groups: { + id: "groups", + defaultMessage: "Groups", }, markers: { id: "markers", @@ -107,9 +113,9 @@ const allMenuItems: IMenuItem[] = [ hotkey: "g i", }, { - name: "movies", - message: messages.movies, - href: "/movies", + name: "groups", + message: messages.groups, + href: "/groups", icon: faFilm, hotkey: "g v", userCreatable: true, @@ -179,20 +185,26 @@ export const MainNavbar: React.FC = () => { const { configuration, loading } = React.useContext(ConfigurationContext); const { openManual } = React.useContext(ManualStateContext); - // Show all menu items by default, unless config says otherwise - const [menuItems, setMenuItems] = useState(allMenuItems); - const [expanded, setExpanded] = useState(false); - useEffect(() => { - const iCfg = configuration?.interface; - if (iCfg?.menuItems) { - setMenuItems( - allMenuItems.filter((menuItem) => - iCfg.menuItems!.includes(menuItem.name) - ) - ); + // Show all menu items by default, unless config says otherwise + const menuItems = useMemo(() => { + let cfgMenuItems = configuration?.interface.menuItems; + if (!cfgMenuItems) { + return allMenuItems; } + + // translate old movies menu item to groups + cfgMenuItems = cfgMenuItems.map((item) => { + if (item === "movies") { + return "groups"; + } + return item; + }); + + return allMenuItems.filter((menuItem) => + cfgMenuItems!.includes(menuItem.name) + ); }, [configuration]); // react-bootstrap typing bug diff --git a/ui/v2.5/src/components/Movies/EditMoviesDialog.tsx b/ui/v2.5/src/components/Movies/EditMoviesDialog.tsx index af48cbeaf35..800bad04471 100644 --- a/ui/v2.5/src/components/Movies/EditMoviesDialog.tsx +++ b/ui/v2.5/src/components/Movies/EditMoviesDialog.tsx @@ -24,7 +24,7 @@ interface IListOperationProps { onClose: (applied: boolean) => void; } -export const EditMoviesDialog: React.FC = ( +export const EditGroupsDialog: React.FC = ( props: IListOperationProps ) => { const intl = useIntl(); @@ -69,7 +69,7 @@ export const EditMoviesDialog: React.FC = ( intl.formatMessage( { id: "toast.updated_entity" }, { - entity: intl.formatMessage({ id: "movies" }).toLocaleLowerCase(), + entity: intl.formatMessage({ id: "groups" }).toLocaleLowerCase(), } ) ); @@ -126,7 +126,7 @@ export const EditMoviesDialog: React.FC = ( icon={faPencilAlt} header={intl.formatMessage( { id: "actions.edit_entity" }, - { entityType: intl.formatMessage({ id: "movies" }) } + { entityType: intl.formatMessage({ id: "groups" }) } )} accept={{ onClick: onSave, diff --git a/ui/v2.5/src/components/Movies/MovieCard.tsx b/ui/v2.5/src/components/Movies/MovieCard.tsx index 1f763649e2d..739761251c3 100644 --- a/ui/v2.5/src/components/Movies/MovieCard.tsx +++ b/ui/v2.5/src/components/Movies/MovieCard.tsx @@ -12,7 +12,7 @@ import { faPlayCircle, faTag } from "@fortawesome/free-solid-svg-icons"; import ScreenUtils from "src/utils/screen"; interface IProps { - movie: GQL.MovieDataFragment; + group: GQL.MovieDataFragment; containerWidth?: number; sceneIndex?: number; selecting?: boolean; @@ -20,8 +20,8 @@ interface IProps { onSelectedChanged?: (selected: boolean, shiftKey: boolean) => void; } -export const MovieCard: React.FC = ({ - movie, +export const GroupCard: React.FC = ({ + group, sceneIndex, containerWidth, selecting, @@ -47,7 +47,7 @@ export const MovieCard: React.FC = ({ return ( <>
- + #{sceneIndex} @@ -55,9 +55,9 @@ export const MovieCard: React.FC = ({ } function maybeRenderScenesPopoverButton() { - if (movie.scenes.length === 0) return; + if (group.scenes.length === 0) return; - const popoverContent = movie.scenes.map((scene) => ( + const popoverContent = group.scenes.map((scene) => ( )); @@ -69,31 +69,31 @@ export const MovieCard: React.FC = ({ > ); } function maybeRenderTagPopoverButton() { - if (movie.tags.length <= 0) return; + if (group.tags.length <= 0) return; - const popoverContent = movie.tags.map((tag) => ( - + const popoverContent = group.tags.map((tag) => ( + )); return ( ); } function maybeRenderPopoverButtonGroup() { - if (sceneIndex || movie.scenes.length > 0 || movie.tags.length > 0) { + if (sceneIndex || group.scenes.length > 0 || group.tags.length > 0) { return ( <> {maybeRenderSceneNumber()} @@ -109,28 +109,28 @@ export const MovieCard: React.FC = ({ return ( {movie.name - + } details={ -
- {movie.date} +
+ {group.date}
diff --git a/ui/v2.5/src/components/Movies/MovieCardGrid.tsx b/ui/v2.5/src/components/Movies/MovieCardGrid.tsx index 4475a0c8a8f..52cbc0f53d6 100644 --- a/ui/v2.5/src/components/Movies/MovieCardGrid.tsx +++ b/ui/v2.5/src/components/Movies/MovieCardGrid.tsx @@ -1,27 +1,27 @@ import React from "react"; import * as GQL from "src/core/generated-graphql"; -import { MovieCard } from "./MovieCard"; +import { GroupCard } from "./MovieCard"; import { useContainerDimensions } from "../Shared/GridCard/GridCard"; -interface IMovieCardGrid { - movies: GQL.MovieDataFragment[]; +interface IGroupCardGrid { + groups: GQL.MovieDataFragment[]; selectedIds: Set; onSelectChange: (id: string, selected: boolean, shiftKey: boolean) => void; } -export const MovieCardGrid: React.FC = ({ - movies, +export const GroupCardGrid: React.FC = ({ + groups, selectedIds, onSelectChange, }) => { const [componentRef, { width }] = useContainerDimensions(); return (
- {movies.map((p) => ( - ( + 0} selected={selectedIds.has(p.id)} onSelectedChanged={(selected: boolean, shiftKey: boolean) => diff --git a/ui/v2.5/src/components/Movies/MovieDetails/Movie.tsx b/ui/v2.5/src/components/Movies/MovieDetails/Movie.tsx index 69aecd20df3..686a92b39f2 100644 --- a/ui/v2.5/src/components/Movies/MovieDetails/Movie.tsx +++ b/ui/v2.5/src/components/Movies/MovieDetails/Movie.tsx @@ -17,12 +17,12 @@ import { LoadingIndicator } from "src/components/Shared/LoadingIndicator"; import { useLightbox } from "src/hooks/Lightbox/hooks"; import { ModalComponent } from "src/components/Shared/Modal"; import { useToast } from "src/hooks/Toast"; -import { MovieScenesPanel } from "./MovieScenesPanel"; +import { GroupScenesPanel } from "./MovieScenesPanel"; import { CompressedMovieDetailsPanel, - MovieDetailsPanel, + GroupDetailsPanel, } from "./MovieDetailsPanel"; -import { MovieEditPanel } from "./MovieEditPanel"; +import { GroupEditPanel } from "./MovieEditPanel"; import { faChevronDown, faChevronUp, @@ -38,14 +38,14 @@ import { useScrollToTopOnMount } from "src/hooks/scrollToTop"; import { ExternalLinksButton } from "src/components/Shared/ExternalLinksButton"; interface IProps { - movie: GQL.MovieDataFragment; + group: GQL.MovieDataFragment; } -interface IMovieParams { +interface IGroupParams { id: string; } -const MoviePage: React.FC = ({ movie }) => { +const GroupPage: React.FC = ({ group }) => { const intl = useIntl(); const history = useHistory(); const Toast = useToast(); @@ -70,35 +70,35 @@ const MoviePage: React.FC = ({ movie }) => { const [encodingImage, setEncodingImage] = useState(false); const defaultImage = - movie.front_image_path && movie.front_image_path.includes("default=true") + group.front_image_path && group.front_image_path.includes("default=true") ? true : false; const lightboxImages = useMemo(() => { const covers = [ - ...(movie.front_image_path && !defaultImage + ...(group.front_image_path && !defaultImage ? [ { paths: { - thumbnail: movie.front_image_path, - image: movie.front_image_path, + thumbnail: group.front_image_path, + image: group.front_image_path, }, }, ] : []), - ...(movie.back_image_path + ...(group.back_image_path ? [ { paths: { - thumbnail: movie.back_image_path, - image: movie.back_image_path, + thumbnail: group.back_image_path, + image: group.back_image_path, }, }, ] : []), ]; return covers; - }, [movie.front_image_path, movie.back_image_path, defaultImage]); + }, [group.front_image_path, group.back_image_path, defaultImage]); const index = lightboxImages.length; @@ -108,7 +108,7 @@ const MoviePage: React.FC = ({ movie }) => { const [updateMovie, { loading: updating }] = useMovieUpdate(); const [deleteMovie, { loading: deleting }] = useMovieDestroy({ - id: movie.id, + id: group.id, }); // set up hotkeys @@ -135,7 +135,7 @@ const MoviePage: React.FC = ({ movie }) => { await updateMovie({ variables: { input: { - id: movie.id, + id: group.id, ...input, }, }, @@ -144,7 +144,7 @@ const MoviePage: React.FC = ({ movie }) => { Toast.success( intl.formatMessage( { id: "toast.updated_entity" }, - { entity: intl.formatMessage({ id: "movie" }).toLocaleLowerCase() } + { entity: intl.formatMessage({ id: "group" }).toLocaleLowerCase() } ) ); } @@ -157,7 +157,7 @@ const MoviePage: React.FC = ({ movie }) => { } // redirect to movies page - history.push(`/movies`); + history.push(`/groups`); } function toggleEditing(value?: boolean) { @@ -187,8 +187,8 @@ const MoviePage: React.FC = ({ movie }) => { id="dialogs.delete_confirm" values={{ entityName: - movie.name ?? - intl.formatMessage({ id: "movie" }).toLocaleLowerCase(), + group.name ?? + intl.formatMessage({ id: "group" }).toLocaleLowerCase(), }} />

@@ -216,7 +216,7 @@ const MoviePage: React.FC = ({ movie }) => { } function renderFrontImage() { - let image = movie.front_image_path; + let image = group.front_image_path; if (isEditing) { if (frontImage === null && image) { const imageURL = new URL(image); @@ -229,14 +229,14 @@ const MoviePage: React.FC = ({ movie }) => { if (image && defaultImage) { return ( -
+
); } else if (image) { return (
@@ -384,9 +384,9 @@ const MoviePage: React.FC = ({ movie }) => { }); return ( -
+
- {movie?.name} + {group?.name}
@@ -399,7 +399,7 @@ const MoviePage: React.FC = ({ movie }) => { message={intl.formatMessage({ id: "actions.encoding_image" })} /> ) : ( -
+
{renderFrontImage()} {renderBackImage()}
@@ -407,15 +407,15 @@ const MoviePage: React.FC = ({ movie }) => {
-
+

- {movie.name} + {group.name} {maybeRenderShowCollapseButton()} {renderClickableIcons()}

{maybeRenderAliases()} setRating(value)} clickToRate withoutContext @@ -428,8 +428,8 @@ const MoviePage: React.FC = ({ movie }) => {
{maybeRenderCompressedDetails()}
-
-
{maybeRenderTab()}
+
+
{maybeRenderTab()}
{renderDeleteAlert()} @@ -437,7 +437,7 @@ const MoviePage: React.FC = ({ movie }) => { ); }; -const MovieLoader: React.FC> = ({ +const GroupLoader: React.FC> = ({ match, }) => { const { id } = match.params; @@ -450,7 +450,7 @@ const MovieLoader: React.FC> = ({ if (!data?.findMovie) return ; - return ; + return ; }; -export default MovieLoader; +export default GroupLoader; diff --git a/ui/v2.5/src/components/Movies/MovieDetails/MovieCreate.tsx b/ui/v2.5/src/components/Movies/MovieDetails/MovieCreate.tsx index a7ab492b99c..2f65463c90a 100644 --- a/ui/v2.5/src/components/Movies/MovieDetails/MovieCreate.tsx +++ b/ui/v2.5/src/components/Movies/MovieDetails/MovieCreate.tsx @@ -5,16 +5,16 @@ import { useHistory, useLocation } from "react-router-dom"; import { useIntl } from "react-intl"; import { LoadingIndicator } from "src/components/Shared/LoadingIndicator"; import { useToast } from "src/hooks/Toast"; -import { MovieEditPanel } from "./MovieEditPanel"; +import { GroupEditPanel } from "./MovieEditPanel"; -const MovieCreate: React.FC = () => { +const GroupCreate: React.FC = () => { const history = useHistory(); const intl = useIntl(); const Toast = useToast(); const location = useLocation(); const query = useMemo(() => new URLSearchParams(location.search), [location]); - const movie = { + const group = { name: query.get("q") ?? undefined, }; @@ -30,7 +30,7 @@ const MovieCreate: React.FC = () => { variables: { input }, }); if (result.data?.movieCreate?.id) { - history.push(`/movies/${result.data.movieCreate.id}`); + history.push(`/groups/${result.data.movieCreate.id}`); Toast.success( intl.formatMessage( { id: "toast.created_entity" }, @@ -43,7 +43,7 @@ const MovieCreate: React.FC = () => { function renderFrontImage() { if (frontImage) { return ( -
+
Front Cover
); @@ -53,7 +53,7 @@ const MovieCreate: React.FC = () => { function renderBackImage() { if (backImage) { return ( -
+
Back Cover
); @@ -63,24 +63,24 @@ const MovieCreate: React.FC = () => { // TODO: CSS class return (
-
+
{encodingImage ? ( ) : ( -
+
{renderFrontImage()} {renderBackImage()}
)}
- history.push("/movies")} + onCancel={() => history.push("/groups")} onDelete={() => {}} setFrontImage={setFrontImage} setBackImage={setBackImage} @@ -91,4 +91,4 @@ const MovieCreate: React.FC = () => { ); }; -export default MovieCreate; +export default GroupCreate; diff --git a/ui/v2.5/src/components/Movies/MovieDetails/MovieDetailsPanel.tsx b/ui/v2.5/src/components/Movies/MovieDetails/MovieDetailsPanel.tsx index 7c5a9cf3a72..8f911c08c76 100644 --- a/ui/v2.5/src/components/Movies/MovieDetails/MovieDetailsPanel.tsx +++ b/ui/v2.5/src/components/Movies/MovieDetails/MovieDetailsPanel.tsx @@ -7,14 +7,14 @@ import { Link } from "react-router-dom"; import { DirectorLink } from "src/components/Shared/Link"; import { TagLink } from "src/components/Shared/TagLink"; -interface IMovieDetailsPanel { - movie: GQL.MovieDataFragment; +interface IGroupDetailsPanel { + group: GQL.MovieDataFragment; collapsed?: boolean; fullWidth?: boolean; } -export const MovieDetailsPanel: React.FC = ({ - movie, +export const GroupDetailsPanel: React.FC = ({ + group, collapsed, fullWidth, }) => { @@ -22,13 +22,13 @@ export const MovieDetailsPanel: React.FC = ({ const intl = useIntl(); function renderTagsField() { - if (!movie.tags.length) { + if (!group.tags.length) { return; } return (
    - {(movie.tags ?? []).map((tag) => ( - + {(group.tags ?? []).map((tag) => ( + ))}
); @@ -40,7 +40,7 @@ export const MovieDetailsPanel: React.FC = ({ <> = ({ - {movie.studio?.name} + group.studio?.id ? ( + + {group.studio?.name} ) : ( "" @@ -84,8 +84,8 @@ export const MovieDetailsPanel: React.FC = ({ + group.director ? ( + ) : ( "" ) @@ -97,8 +97,8 @@ export const MovieDetailsPanel: React.FC = ({ ); }; -export const CompressedMovieDetailsPanel: React.FC = ({ - movie, +export const CompressedMovieDetailsPanel: React.FC = ({ + group, }) => { function scrollToTop() { window.scrollTo({ top: 0, behavior: "smooth" }); @@ -107,13 +107,13 @@ export const CompressedMovieDetailsPanel: React.FC = ({ return (
- scrollToTop()}> - {movie.name} + scrollToTop()}> + {group.name} - {movie?.studio?.name ? ( + {group?.studio?.name ? ( <> / - {movie?.studio?.name} + {group?.studio?.name} ) : ( "" diff --git a/ui/v2.5/src/components/Movies/MovieDetails/MovieEditPanel.tsx b/ui/v2.5/src/components/Movies/MovieDetails/MovieEditPanel.tsx index 5cd4cda7908..0a281df513d 100644 --- a/ui/v2.5/src/components/Movies/MovieDetails/MovieEditPanel.tsx +++ b/ui/v2.5/src/components/Movies/MovieDetails/MovieEditPanel.tsx @@ -15,7 +15,7 @@ import TextUtils from "src/utils/text"; import ImageUtils from "src/utils/image"; import { useFormik } from "formik"; import { Prompt } from "react-router-dom"; -import { MovieScrapeDialog } from "./MovieScrapeDialog"; +import { GroupScrapeDialog } from "./MovieScrapeDialog"; import isEqual from "lodash-es/isEqual"; import { handleUnsavedChanges } from "src/utils/navigation"; import { formikUtils } from "src/utils/form"; @@ -27,8 +27,8 @@ import { import { Studio, StudioSelect } from "src/components/Studios/StudioSelect"; import { useTagsEdit } from "src/hooks/tagsEdit"; -interface IMovieEditPanel { - movie: Partial; +interface IGroupEditPanel { + group: Partial; onSubmit: (movie: GQL.MovieCreateInput) => Promise; onCancel: () => void; onDelete: () => void; @@ -37,8 +37,8 @@ interface IMovieEditPanel { setEncodingImage: (loading: boolean) => void; } -export const MovieEditPanel: React.FC = ({ - movie, +export const GroupEditPanel: React.FC = ({ + group, onSubmit, onCancel, onDelete, @@ -49,7 +49,7 @@ export const MovieEditPanel: React.FC = ({ const intl = useIntl(); const Toast = useToast(); - const isNew = movie.id === undefined; + const isNew = group.id === undefined; const [isLoading, setIsLoading] = useState(false); const [isImageAlertOpen, setIsImageAlertOpen] = useState(false); @@ -57,7 +57,7 @@ export const MovieEditPanel: React.FC = ({ const [imageClipboard, setImageClipboard] = useState(); const Scrapers = useListMovieScrapers(); - const [scrapedMovie, setScrapedMovie] = useState(); + const [scrapedGroup, setScrapedGroup] = useState(); const [studio, setStudio] = useState(null); @@ -76,15 +76,15 @@ export const MovieEditPanel: React.FC = ({ }); const initialValues = { - name: movie?.name ?? "", - aliases: movie?.aliases ?? "", - duration: movie?.duration ?? null, - date: movie?.date ?? "", - studio_id: movie?.studio?.id ?? null, - tag_ids: (movie?.tags ?? []).map((t) => t.id), - director: movie?.director ?? "", - urls: movie?.urls ?? [], - synopsis: movie?.synopsis ?? "", + name: group?.name ?? "", + aliases: group?.aliases ?? "", + duration: group?.duration ?? null, + date: group?.date ?? "", + studio_id: group?.studio?.id ?? null, + tag_ids: (group?.tags ?? []).map((t) => t.id), + director: group?.director ?? "", + urls: group?.urls ?? [], + synopsis: group?.synopsis ?? "", }; type InputValues = yup.InferType; @@ -97,7 +97,7 @@ export const MovieEditPanel: React.FC = ({ }); const { tags, updateTagsStateFromScraper, tagsControl } = useTagsEdit( - movie.tags, + group.tags, (ids) => formik.setFieldValue("tag_ids", ids) ); @@ -107,8 +107,8 @@ export const MovieEditPanel: React.FC = ({ } useEffect(() => { - setStudio(movie.studio ?? null); - }, [movie.studio]); + setStudio(group.studio ?? null); + }, [group.studio]); // set up hotkeys useEffect(() => { @@ -128,7 +128,7 @@ export const MovieEditPanel: React.FC = ({ }; }); - function updateMovieEditStateFromScraper( + function updateGroupEditStateFromScraper( state: Partial ) { if (state.name) { @@ -200,11 +200,11 @@ export const MovieEditPanel: React.FC = ({ return; } - // if this is a new movie, just dump the data + // if this is a new group, just dump the data if (isNew) { - updateMovieEditStateFromScraper(result.data.scrapeMovieURL); + updateGroupEditStateFromScraper(result.data.scrapeMovieURL); } else { - setScrapedMovie(result.data.scrapeMovieURL); + setScrapedGroup(result.data.scrapeMovieURL); } } catch (e) { Toast.error(e); @@ -223,25 +223,25 @@ export const MovieEditPanel: React.FC = ({ } function maybeRenderScrapeDialog() { - if (!scrapedMovie) { + if (!scrapedGroup) { return; } - const currentMovie = { - id: movie.id!, + const currentGroup = { + id: group.id!, ...formik.values, }; // Get image paths for scrape gui - currentMovie.front_image = movie?.front_image_path; - currentMovie.back_image = movie?.back_image_path; + currentGroup.front_image = group?.front_image_path; + currentGroup.back_image = group?.back_image_path; return ( - { onScrapeDialogClosed(m); }} @@ -251,9 +251,9 @@ export const MovieEditPanel: React.FC = ({ function onScrapeDialogClosed(p?: GQL.ScrapedMovieDataFragment) { if (p) { - updateMovieEditStateFromScraper(p); + updateGroupEditStateFromScraper(p); } - setScrapedMovie(undefined); + setScrapedGroup(undefined); } const encodingImage = ImageUtils.usePasteImage(showImageAlert); @@ -373,7 +373,7 @@ export const MovieEditPanel: React.FC = ({

{intl.formatMessage( { id: "actions.add_entity" }, - { entityType: intl.formatMessage({ id: "movie" }) } + { entityType: intl.formatMessage({ id: "group" }) } )}

)} @@ -382,14 +382,14 @@ export const MovieEditPanel: React.FC = ({ when={formik.dirty} message={(location, action) => { // Check if it's a redirect after movie creation - if (action === "PUSH" && location.pathname.startsWith("/movies/")) + if (action === "PUSH" && location.pathname.startsWith("/groups/")) return true; - return handleUnsavedChanges(intl, "movies", movie.id)(location); + return handleUnsavedChanges(intl, "groups", group.id)(location); }} /> -
+ {renderInputField("name")} {renderInputField("aliases")} {renderDurationField("duration")} @@ -402,7 +402,7 @@ export const MovieEditPanel: React.FC = ({ = ({ +export const GroupScenesPanel: React.FC = ({ active, - movie, + group, }) => { function filterHook(filter: ListFilterModel) { - const movieValue = { id: movie.id, label: movie.name }; + const movieValue = { id: group.id, label: group.name }; // if movie is already present, then we modify it, otherwise add let movieCriterion = filter.criteria.find((c) => { return c.criterionOption.type === "movies"; @@ -29,7 +29,7 @@ export const MovieScenesPanel: React.FC = ({ // add the movie if not present if ( !movieCriterion.value.find((p) => { - return p.id === movie.id; + return p.id === group.id; }) ) { movieCriterion.value.push(movieValue); @@ -46,13 +46,13 @@ export const MovieScenesPanel: React.FC = ({ return filter; } - if (movie && movie.id) { + if (group && group.id) { return ( ); } diff --git a/ui/v2.5/src/components/Movies/MovieDetails/MovieScrapeDialog.tsx b/ui/v2.5/src/components/Movies/MovieDetails/MovieScrapeDialog.tsx index b28bded5c89..64456411243 100644 --- a/ui/v2.5/src/components/Movies/MovieDetails/MovieScrapeDialog.tsx +++ b/ui/v2.5/src/components/Movies/MovieDetails/MovieScrapeDialog.tsx @@ -20,33 +20,33 @@ import { uniq } from "lodash-es"; import { Tag } from "src/components/Tags/TagSelect"; import { useScrapedTags } from "src/components/Shared/ScrapeDialog/scrapedTags"; -interface IMovieScrapeDialogProps { - movie: Partial; - movieStudio: Studio | null; - movieTags: Tag[]; +interface IGroupScrapeDialogProps { + group: Partial; + groupStudio: Studio | null; + groupTags: Tag[]; scraped: GQL.ScrapedMovie; onClose: (scrapedMovie?: GQL.ScrapedMovie) => void; } -export const MovieScrapeDialog: React.FC = ({ - movie, - movieStudio, - movieTags, +export const GroupScrapeDialog: React.FC = ({ + group, + groupStudio: groupStudio, + groupTags: groupTags, scraped, onClose, }) => { const intl = useIntl(); const [name, setName] = useState>( - new ScrapeResult(movie.name, scraped.name) + new ScrapeResult(group.name, scraped.name) ); const [aliases, setAliases] = useState>( - new ScrapeResult(movie.aliases, scraped.aliases) + new ScrapeResult(group.aliases, scraped.aliases) ); const [duration, setDuration] = useState>( new ScrapeResult( - TextUtils.secondsToTimestamp(movie.duration || 0), + TextUtils.secondsToTimestamp(group.duration || 0), // convert seconds to string if it's a number scraped.duration && !isNaN(+scraped.duration) ? TextUtils.secondsToTimestamp(parseInt(scraped.duration, 10)) @@ -54,20 +54,20 @@ export const MovieScrapeDialog: React.FC = ({ ) ); const [date, setDate] = useState>( - new ScrapeResult(movie.date, scraped.date) + new ScrapeResult(group.date, scraped.date) ); const [director, setDirector] = useState>( - new ScrapeResult(movie.director, scraped.director) + new ScrapeResult(group.director, scraped.director) ); const [synopsis, setSynopsis] = useState>( - new ScrapeResult(movie.synopsis, scraped.synopsis) + new ScrapeResult(group.synopsis, scraped.synopsis) ); const [studio, setStudio] = useState>( new ObjectScrapeResult( - movieStudio + groupStudio ? { - stored_id: movieStudio.id, - name: movieStudio.name, + stored_id: groupStudio.id, + name: groupStudio.name, } : undefined, scraped.studio?.stored_id ? scraped.studio : undefined @@ -75,17 +75,17 @@ export const MovieScrapeDialog: React.FC = ({ ); const [urls, setURLs] = useState>( new ScrapeResult( - movie.urls, + group.urls, scraped.urls - ? uniq((movie.urls ?? []).concat(scraped.urls ?? [])) + ? uniq((group.urls ?? []).concat(scraped.urls ?? [])) : undefined ) ); const [frontImage, setFrontImage] = useState>( - new ScrapeResult(movie.front_image, scraped.front_image) + new ScrapeResult(group.front_image, scraped.front_image) ); const [backImage, setBackImage] = useState>( - new ScrapeResult(movie.back_image, scraped.back_image) + new ScrapeResult(group.back_image, scraped.back_image) ); const [newStudio, setNewStudio] = useState( @@ -99,7 +99,7 @@ export const MovieScrapeDialog: React.FC = ({ }); const { tags, newTags, scrapedTagsRow } = useScrapedTags( - movieTags, + groupTags, scraped.tags ); @@ -194,13 +194,13 @@ export const MovieScrapeDialog: React.FC = ({ {scrapedTagsRow} setFrontImage(value)} /> setBackImage(value)} /> @@ -212,7 +212,7 @@ export const MovieScrapeDialog: React.FC = ({ { diff --git a/ui/v2.5/src/components/Movies/MovieList.tsx b/ui/v2.5/src/components/Movies/MovieList.tsx index 8b42a3b73ec..d4d4bf1c9aa 100644 --- a/ui/v2.5/src/components/Movies/MovieList.tsx +++ b/ui/v2.5/src/components/Movies/MovieList.tsx @@ -14,11 +14,11 @@ import { import { makeItemList, showWhenSelected } from "../List/ItemList"; import { ExportDialog } from "../Shared/ExportDialog"; import { DeleteEntityDialog } from "../Shared/DeleteEntityDialog"; -import { MovieCardGrid } from "./MovieCardGrid"; -import { EditMoviesDialog } from "./EditMoviesDialog"; +import { GroupCardGrid } from "./MovieCardGrid"; +import { EditGroupsDialog } from "./EditMoviesDialog"; import { View } from "../List/views"; -const MovieItemList = makeItemList({ +const GroupItemList = makeItemList({ filterMode: GQL.FilterMode.Movies, useResult: useFindMovies, getItems(result: GQL.FindMoviesQueryResult) { @@ -29,13 +29,13 @@ const MovieItemList = makeItemList({ }, }); -interface IMovieList { +interface IGroupList { filterHook?: (filter: ListFilterModel) => ListFilterModel; view?: View; alterQuery?: boolean; } -export const MovieList: React.FC = ({ +export const GroupList: React.FC = ({ filterHook, alterQuery, view, @@ -90,7 +90,7 @@ export const MovieList: React.FC = ({ if (singleResult.data.findMovies.movies.length === 1) { const { id } = singleResult.data.findMovies.movies[0]; // navigate to the movie page - history.push(`/movies/${id}`); + history.push(`/groups/${id}`); } } } @@ -111,7 +111,7 @@ export const MovieList: React.FC = ({ selectedIds: Set, onSelectChange: (id: string, selected: boolean, shiftKey: boolean) => void ) { - function maybeRenderMovieExportDialog() { + function maybeRenderGroupExportDialog() { if (isExportDialogOpen) { return ( = ({ } } - function renderMovies() { + function renderGroups() { if (!result.data?.findMovies) return; if (filter.displayMode === DisplayMode.Grid) { return ( - @@ -145,36 +145,36 @@ export const MovieList: React.FC = ({ } return ( <> - {maybeRenderMovieExportDialog()} - {renderMovies()} + {maybeRenderGroupExportDialog()} + {renderGroups()} ); } function renderEditDialog( - selectedMovies: GQL.MovieDataFragment[], + selectedGroups: GQL.MovieDataFragment[], onClose: (applied: boolean) => void ) { - return ; + return ; } function renderDeleteDialog( - selectedMovies: GQL.SlimMovieDataFragment[], + selectedGroups: GQL.SlimMovieDataFragment[], onClose: (confirmed: boolean) => void ) { return ( ); } return ( - = (props: IProps) => { +export const GroupRecommendationRow: React.FC = (props: IProps) => { const result = useFindMovies(props.filter); const cardCount = result.data?.findMovies.count; @@ -24,10 +24,10 @@ export const MovieRecommendationRow: React.FC = (props: IProps) => { return ( + } @@ -40,10 +40,10 @@ export const MovieRecommendationRow: React.FC = (props: IProps) => { > {result.loading ? [...Array(props.filter.itemsPerPage)].map((i) => ( -
+
)) : result.data?.findMovies.movies.map((m) => ( - + ))}
diff --git a/ui/v2.5/src/components/Movies/MovieSelect.tsx b/ui/v2.5/src/components/Movies/MovieSelect.tsx index 279994d1afc..1aa791235de 100644 --- a/ui/v2.5/src/components/Movies/MovieSelect.tsx +++ b/ui/v2.5/src/components/Movies/MovieSelect.tsx @@ -30,13 +30,13 @@ import { sortByRelevance } from "src/utils/query"; import { PatchComponent, PatchFunction } from "src/patch"; import { TruncatedText } from "../Shared/TruncatedText"; -export type Movie = Pick< +export type Group = Pick< GQL.Movie, "id" | "name" | "date" | "front_image_path" | "aliases" > & { studio?: Pick | null; }; -type Option = SelectOption; +type Option = SelectOption; type FindMoviesResult = Awaited< ReturnType @@ -56,9 +56,9 @@ const movieSelectSort = PatchFunction( sortMoviesByRelevance ); -const _MovieSelect: React.FC< +const _GroupSelect: React.FC< IFilterProps & - IFilterValueProps & { + IFilterValueProps & { hoverPlacement?: Placement; excludeIds?: string[]; } @@ -94,7 +94,7 @@ const _MovieSelect: React.FC< })); } - const MovieOption: React.FC> = (optionProps) => { + const GroupOption: React.FC> = (optionProps) => { let thisOptionProps = optionProps; const { object } = optionProps.data; @@ -111,24 +111,24 @@ const _MovieSelect: React.FC< thisOptionProps = { ...optionProps, children: ( - - + + {object.front_image_path && ( )} - + {title} {alias && ( - {` (${alias})`} + {` (${alias})`} )} } @@ -136,13 +136,13 @@ const _MovieSelect: React.FC< /> {object.studio?.name && ( - + {object.studio?.name} )} {object.date && ( - {object.date} + {object.date} )} @@ -153,7 +153,7 @@ const _MovieSelect: React.FC< return ; }; - const MovieMultiValueLabel: React.FC< + const GroupMultiValueLabel: React.FC< MultiValueGenericProps > = (optionProps) => { let thisOptionProps = optionProps; @@ -168,7 +168,7 @@ const _MovieSelect: React.FC< return ; }; - const MovieValueLabel: React.FC> = ( + const GroupValueLabel: React.FC> = ( optionProps ) => { let thisOptionProps = optionProps; @@ -190,7 +190,7 @@ const _MovieSelect: React.FC< return { value: result.data!.movieCreate!.id, item: result.data!.movieCreate!, - message: "Created movie", + message: "Created group", }; }; @@ -201,7 +201,7 @@ const _MovieSelect: React.FC< }; }; - const isValidNewOption = (inputValue: string, options: Movie[]) => { + const isValidNewOption = (inputValue: string, options: Group[]) => { if (!inputValue) { return false; } @@ -221,12 +221,12 @@ const _MovieSelect: React.FC< }; return ( - + {...props} className={cx( - "movie-select", + "group-select", { - "movie-select-active": props.active, + "group-select-active": props.active, }, props.className )} @@ -234,9 +234,9 @@ const _MovieSelect: React.FC< getNamedObject={getNamedObject} isValidNewOption={isValidNewOption} components={{ - Option: MovieOption, - MultiValueLabel: MovieMultiValueLabel, - SingleValue: MovieValueLabel, + Option: GroupOption, + MultiValueLabel: GroupMultiValueLabel, + SingleValue: GroupValueLabel, }} isMulti={props.isMulti ?? false} creatable={props.creatable ?? defaultCreatable} @@ -247,7 +247,7 @@ const _MovieSelect: React.FC< { id: "actions.select_entity" }, { entityType: intl.formatMessage({ - id: props.isMulti ? "movies" : "movie", + id: props.isMulti ? "groups" : "group", }), } ) @@ -257,22 +257,22 @@ const _MovieSelect: React.FC< ); }; -export const MovieSelect = PatchComponent("MovieSelect", _MovieSelect); +export const GroupSelect = PatchComponent("GroupSelect", _GroupSelect); -const _MovieIDSelect: React.FC> = ( +const _GroupIDSelect: React.FC> = ( props ) => { const { ids, onSelect: onSelectValues } = props; - const [values, setValues] = useState([]); + const [values, setValues] = useState([]); const idsChanged = useCompare(ids); - function onSelect(items: Movie[]) { + function onSelect(items: Group[]) { setValues(items); onSelectValues?.(items); } - async function loadObjectsByID(idsToLoad: string[]): Promise { + async function loadObjectsByID(idsToLoad: string[]): Promise { const query = await queryFindMoviesByIDForSelect(idsToLoad); const { movies: loadedMovies } = query.data.findMovies; @@ -303,7 +303,7 @@ const _MovieIDSelect: React.FC> = ( load(); }, [ids, idsChanged, values]); - return ; + return ; }; -export const MovieIDSelect = PatchComponent("MovieIDSelect", _MovieIDSelect); +export const GroupIDSelect = PatchComponent("GroupIDSelect", _GroupIDSelect); diff --git a/ui/v2.5/src/components/Movies/Movies.tsx b/ui/v2.5/src/components/Movies/Movies.tsx index e93e14720b5..202d8f4945a 100644 --- a/ui/v2.5/src/components/Movies/Movies.tsx +++ b/ui/v2.5/src/components/Movies/Movies.tsx @@ -2,30 +2,30 @@ import React from "react"; import { Route, Switch } from "react-router-dom"; import { Helmet } from "react-helmet"; import { useTitleProps } from "src/hooks/title"; -import Movie from "./MovieDetails/Movie"; -import MovieCreate from "./MovieDetails/MovieCreate"; -import { MovieList } from "./MovieList"; +import Group from "./MovieDetails/Movie"; +import GroupCreate from "./MovieDetails/MovieCreate"; +import { GroupList } from "./MovieList"; import { useScrollToTopOnMount } from "src/hooks/scrollToTop"; import { View } from "../List/views"; -const Movies: React.FC = () => { +const Groups: React.FC = () => { useScrollToTopOnMount(); - return ; + return ; }; -const MovieRoutes: React.FC = () => { - const titleProps = useTitleProps({ id: "movies" }); +const GroupRoutes: React.FC = () => { + const titleProps = useTitleProps({ id: "groups" }); return ( <> - - - + + + ); }; -export default MovieRoutes; +export default GroupRoutes; diff --git a/ui/v2.5/src/components/Movies/styles.scss b/ui/v2.5/src/components/Movies/styles.scss index 58071d4b8f3..3d1868fb815 100644 --- a/ui/v2.5/src/components/Movies/styles.scss +++ b/ui/v2.5/src/components/Movies/styles.scss @@ -1,4 +1,4 @@ -.movie-card { +.group-card { width: 240px; @media (max-width: 576px) { @@ -14,7 +14,7 @@ width: 100%; } - .movie-scene-number { + .group-scene-number { text-align: center; } @@ -23,14 +23,14 @@ } } -.movie-images { +.group-images { align-items: center; display: flex; flex-direction: row; justify-content: space-evenly; max-width: 100%; - .movie-image-container { + .group-image-container { box-shadow: none; } @@ -40,17 +40,17 @@ } } -#movie-page .rating-number .text-input { +#group-page .rating-number .text-input { width: auto; } -.movie-select-option { - .movie-select-row { +.group-select-option { + .group-select-row { align-items: center; display: flex; width: 100%; - .movie-select-image { + .group-select-image { background-color: $body-bg; margin-right: 0.4em; max-height: 50px; @@ -59,26 +59,26 @@ object-position: center; } - .movie-select-details { + .group-select-details { display: flex; flex-direction: column; justify-content: flex-start; max-height: 4.1rem; overflow: hidden; - .movie-select-title { + .group-select-title { flex-shrink: 0; white-space: pre-wrap; word-break: break-all; - .movie-select-alias { + .group-select-alias { font-size: 0.8rem; font-weight: bold; } } - .movie-select-date, - .movie-select-studio { + .group-select-date, + .group-select-studio { color: $text-muted; flex-shrink: 0; font-size: 0.9rem; diff --git a/ui/v2.5/src/components/Performers/PerformerCard.tsx b/ui/v2.5/src/components/Performers/PerformerCard.tsx index 4792e452cd3..3d5765adad6 100644 --- a/ui/v2.5/src/components/Performers/PerformerCard.tsx +++ b/ui/v2.5/src/components/Performers/PerformerCard.tsx @@ -178,15 +178,15 @@ export const PerformerCard: React.FC = ({ ); } - function maybeRenderMoviesPopoverButton() { + function maybeRenderGroupsPopoverButton() { if (!performer.movie_count) return; return ( = ({
{maybeRenderScenesPopoverButton()} - {maybeRenderMoviesPopoverButton()} + {maybeRenderGroupsPopoverButton()} {maybeRenderImagesPopoverButton()} {maybeRenderGalleriesPopoverButton()} {maybeRenderTagPopoverButton()} diff --git a/ui/v2.5/src/components/Performers/PerformerDetails/Performer.tsx b/ui/v2.5/src/components/Performers/PerformerDetails/Performer.tsx index 85674e0231d..2c19fa7753c 100644 --- a/ui/v2.5/src/components/Performers/PerformerDetails/Performer.tsx +++ b/ui/v2.5/src/components/Performers/PerformerDetails/Performer.tsx @@ -27,7 +27,7 @@ import { } from "./PerformerDetailsPanel"; import { PerformerScenesPanel } from "./PerformerScenesPanel"; import { PerformerGalleriesPanel } from "./PerformerGalleriesPanel"; -import { PerformerMoviesPanel } from "./PerformerMoviesPanel"; +import { PerformerGroupsPanel } from "./PerformerMoviesPanel"; import { PerformerImagesPanel } from "./PerformerImagesPanel"; import { PerformerAppearsWithPanel } from "./performerAppearsWithPanel"; import { PerformerEditPanel } from "./PerformerEditPanel"; @@ -60,7 +60,7 @@ const validTabs = [ "scenes", "galleries", "images", - "movies", + "groups", "appearswith", ] as const; type TabKey = (typeof validTabs)[number]; @@ -146,7 +146,7 @@ const PerformerPage: React.FC = ({ performer, tabKey }) => { } else if (performer.image_count != 0) { ret = "images"; } else if (performer.movie_count != 0) { - ret = "movies"; + ret = "groups"; } } @@ -191,7 +191,7 @@ const PerformerPage: React.FC = ({ performer, tabKey }) => { Mousetrap.bind("e", () => toggleEditing()); Mousetrap.bind("c", () => setTabKey("scenes")); Mousetrap.bind("g", () => setTabKey("galleries")); - Mousetrap.bind("m", () => setTabKey("movies")); + Mousetrap.bind("m", () => setTabKey("groups")); Mousetrap.bind("f", () => setFavorite(!performer.favorite)); Mousetrap.bind(",", () => setCollapsed(!collapsed)); @@ -319,10 +319,10 @@ const PerformerPage: React.FC = ({ performer, tabKey }) => { /> - {intl.formatMessage({ id: "movies" })} + {intl.formatMessage({ id: "groups" })} = ({ performer, tabKey }) => { } > - diff --git a/ui/v2.5/src/components/Performers/PerformerDetails/PerformerMoviesPanel.tsx b/ui/v2.5/src/components/Performers/PerformerDetails/PerformerMoviesPanel.tsx index 0f1c8b7d583..f9a1f7f5a54 100644 --- a/ui/v2.5/src/components/Performers/PerformerDetails/PerformerMoviesPanel.tsx +++ b/ui/v2.5/src/components/Performers/PerformerDetails/PerformerMoviesPanel.tsx @@ -1,6 +1,6 @@ import React from "react"; import * as GQL from "src/core/generated-graphql"; -import { MovieList } from "src/components/Movies/MovieList"; +import { GroupList } from "src/components/Movies/MovieList"; import { usePerformerFilterHook } from "src/core/performers"; import { View } from "src/components/List/views"; @@ -9,16 +9,16 @@ interface IPerformerDetailsProps { performer: GQL.PerformerDataFragment; } -export const PerformerMoviesPanel: React.FC = ({ +export const PerformerGroupsPanel: React.FC = ({ active, performer, }) => { const filterHook = usePerformerFilterHook(performer); return ( - ); }; diff --git a/ui/v2.5/src/components/SceneDuplicateChecker/SceneDuplicateChecker.tsx b/ui/v2.5/src/components/SceneDuplicateChecker/SceneDuplicateChecker.tsx index 4c3e6ee54cc..9ee04ac68c9 100644 --- a/ui/v2.5/src/components/SceneDuplicateChecker/SceneDuplicateChecker.tsx +++ b/ui/v2.5/src/components/SceneDuplicateChecker/SceneDuplicateChecker.tsx @@ -21,7 +21,7 @@ import { HoverPopover } from "../Shared/HoverPopover"; import { Icon } from "../Shared/Icon"; import { GalleryLink, - MovieLink, + GroupLink, SceneMarkerLink, TagLink, } from "../Shared/TagLink"; @@ -386,14 +386,14 @@ export const SceneDuplicateChecker: React.FC = () => { return ; } - function maybeRenderMoviePopoverButton(scene: GQL.SlimSceneDataFragment) { + function maybeRenderGroupPopoverButton(scene: GQL.SlimSceneDataFragment) { if (scene.movies.length <= 0) return; const popoverContent = scene.movies.map((sceneMovie) => ( -
+
{ src={sceneMovie.movie.front_image_path ?? ""} /> -
@@ -523,7 +523,7 @@ export const SceneDuplicateChecker: React.FC = () => { {maybeRenderTagPopoverButton(scene)} {maybeRenderPerformerPopoverButton(scene)} - {maybeRenderMoviePopoverButton(scene)} + {maybeRenderGroupPopoverButton(scene)} {maybeRenderSceneMarkerPopoverButton(scene)} {maybeRenderOCounter(scene)} {maybeRenderGallery(scene)} diff --git a/ui/v2.5/src/components/Scenes/EditScenesDialog.tsx b/ui/v2.5/src/components/Scenes/EditScenesDialog.tsx index fb85dbf6fc3..f4fc8a1e233 100644 --- a/ui/v2.5/src/components/Scenes/EditScenesDialog.tsx +++ b/ui/v2.5/src/components/Scenes/EditScenesDialog.tsx @@ -13,7 +13,7 @@ import { RatingSystem } from "../Shared/Rating/RatingSystem"; import { getAggregateInputIDs, getAggregateInputValue, - getAggregateMovieIds, + getAggregateGroupIds, getAggregatePerformerIds, getAggregateRating, getAggregateStudioId, @@ -42,11 +42,11 @@ export const EditScenesDialog: React.FC = ( ); const [tagIds, setTagIds] = useState(); const [existingTagIds, setExistingTagIds] = useState(); - const [movieMode, setMovieMode] = React.useState( + const [groupMode, setGroupMode] = React.useState( GQL.BulkUpdateIdMode.Add ); - const [movieIds, setMovieIds] = useState(); - const [existingMovieIds, setExistingMovieIds] = useState(); + const [groupIds, setGroupIds] = useState(); + const [existingGroupIds, setExistingGroupIds] = useState(); const [organized, setOrganized] = useState(); const [updateScenes] = useBulkSceneUpdate(getSceneInput()); @@ -62,7 +62,7 @@ export const EditScenesDialog: React.FC = ( const aggregateStudioId = getAggregateStudioId(props.selected); const aggregatePerformerIds = getAggregatePerformerIds(props.selected); const aggregateTagIds = getAggregateTagIds(props.selected); - const aggregateMovieIds = getAggregateMovieIds(props.selected); + const aggregateGroupIds = getAggregateGroupIds(props.selected); const sceneInput: GQL.BulkSceneUpdateInput = { ids: props.selected.map((scene) => { @@ -80,9 +80,9 @@ export const EditScenesDialog: React.FC = ( ); sceneInput.tag_ids = getAggregateInputIDs(tagMode, tagIds, aggregateTagIds); sceneInput.movie_ids = getAggregateInputIDs( - movieMode, - movieIds, - aggregateMovieIds + groupMode, + groupIds, + aggregateGroupIds ); if (organized !== undefined) { @@ -115,7 +115,7 @@ export const EditScenesDialog: React.FC = ( let updateStudioID: string | undefined; let updatePerformerIds: string[] = []; let updateTagIds: string[] = []; - let updateMovieIds: string[] = []; + let updateGroupIds: string[] = []; let updateOrganized: boolean | undefined; let first = true; @@ -126,14 +126,14 @@ export const EditScenesDialog: React.FC = ( .map((p) => p.id) .sort(); const sceneTagIDs = (scene.tags ?? []).map((p) => p.id).sort(); - const sceneMovieIDs = (scene.movies ?? []).map((m) => m.movie.id).sort(); + const sceneGroupIDs = (scene.movies ?? []).map((m) => m.movie.id).sort(); if (first) { updateRating = sceneRating ?? undefined; updateStudioID = sceneStudioID; updatePerformerIds = scenePerformerIDs; updateTagIds = sceneTagIDs; - updateMovieIds = sceneMovieIDs; + updateGroupIds = sceneGroupIDs; first = false; updateOrganized = scene.organized; } else { @@ -149,8 +149,8 @@ export const EditScenesDialog: React.FC = ( if (!isEqual(sceneTagIDs, updateTagIds)) { updateTagIds = []; } - if (!isEqual(sceneMovieIDs, updateMovieIds)) { - updateMovieIds = []; + if (!isEqual(sceneGroupIDs, updateGroupIds)) { + updateGroupIds = []; } if (scene.organized !== updateOrganized) { updateOrganized = undefined; @@ -162,7 +162,7 @@ export const EditScenesDialog: React.FC = ( setStudioId(updateStudioID); setExistingPerformerIds(updatePerformerIds); setExistingTagIds(updateTagIds); - setExistingMovieIds(updateMovieIds); + setExistingGroupIds(updateGroupIds); setOrganized(updateOrganized); }, [props.selected]); @@ -173,7 +173,7 @@ export const EditScenesDialog: React.FC = ( }, [organized, checkboxRef]); function renderMultiSelect( - type: "performers" | "tags" | "movies", + type: "performers" | "tags" | "groups", ids: string[] | undefined ) { let mode = GQL.BulkUpdateIdMode.Add; @@ -187,9 +187,9 @@ export const EditScenesDialog: React.FC = ( mode = tagMode; existingIds = existingTagIds; break; - case "movies": - mode = movieMode; - existingIds = existingMovieIds; + case "groups": + mode = groupMode; + existingIds = existingGroupIds; break; } @@ -205,8 +205,8 @@ export const EditScenesDialog: React.FC = ( case "tags": setTagIds(itemIDs); break; - case "movies": - setMovieIds(itemIDs); + case "groups": + setGroupIds(itemIDs); break; } }} @@ -218,8 +218,8 @@ export const EditScenesDialog: React.FC = ( case "tags": setTagMode(newMode); break; - case "movies": - setMovieMode(newMode); + case "groups": + setGroupMode(newMode); break; } }} @@ -306,11 +306,11 @@ export const EditScenesDialog: React.FC = ( {renderMultiSelect("tags", tagIds)} - + - + - {renderMultiSelect("movies", movieIds)} + {renderMultiSelect("groups", groupIds)} diff --git a/ui/v2.5/src/components/Scenes/SceneCard.tsx b/ui/v2.5/src/components/Scenes/SceneCard.tsx index b648ec4376e..694d1bdcc56 100644 --- a/ui/v2.5/src/components/Scenes/SceneCard.tsx +++ b/ui/v2.5/src/components/Scenes/SceneCard.tsx @@ -7,7 +7,7 @@ import { Icon } from "../Shared/Icon"; import { GalleryLink, TagLink, - MovieLink, + GroupLink, SceneMarkerLink, } from "../Shared/TagLink"; import { HoverPopover } from "../Shared/HoverPopover"; @@ -143,24 +143,24 @@ const SceneCardPopovers = PatchComponent( return ; } - function maybeRenderMoviePopoverButton() { + function maybeRenderGroupPopoverButton() { if (props.scene.movies.length <= 0) return; - const popoverContent = props.scene.movies.map((sceneMovie) => ( -
+ const popoverContent = props.scene.movies.map((sceneGroup) => ( +
{sceneMovie.movie.name -
@@ -170,7 +170,7 @@ const SceneCardPopovers = PatchComponent(
diff --git a/ui/v2.5/src/components/Shared/Link.tsx b/ui/v2.5/src/components/Shared/Link.tsx index 7bfeef4135b..d3da7eac18d 100644 --- a/ui/v2.5/src/components/Shared/Link.tsx +++ b/ui/v2.5/src/components/Shared/Link.tsx @@ -6,14 +6,14 @@ import NavUtils from "src/utils/navigation"; export const DirectorLink: React.FC<{ director: string; - linkType: "scene" | "movie"; + linkType: "scene" | "group"; }> = ({ director: director, linkType = "scene" }) => { const link = useMemo(() => { switch (linkType) { case "scene": return NavUtils.makeDirectorScenesUrl(director); - case "movie": - return NavUtils.makeDirectorMoviesUrl(director); + case "group": + return NavUtils.makeDirectorGroupsUrl(director); } }, [director, linkType]); diff --git a/ui/v2.5/src/components/Shared/MultiSet.tsx b/ui/v2.5/src/components/Shared/MultiSet.tsx index f92b57ff313..521a2577bef 100644 --- a/ui/v2.5/src/components/Shared/MultiSet.tsx +++ b/ui/v2.5/src/components/Shared/MultiSet.tsx @@ -10,7 +10,7 @@ import { } from "../Galleries/GallerySelect"; interface IMultiSetProps { - type: "performers" | "studios" | "tags" | "movies" | "galleries"; + type: "performers" | "studios" | "tags" | "groups" | "galleries"; existingIds?: string[]; ids?: string[]; mode: GQL.BulkUpdateIdMode; diff --git a/ui/v2.5/src/components/Shared/PopoverCountButton.tsx b/ui/v2.5/src/components/Shared/PopoverCountButton.tsx index c455145fc3c..aada2fe193f 100644 --- a/ui/v2.5/src/components/Shared/PopoverCountButton.tsx +++ b/ui/v2.5/src/components/Shared/PopoverCountButton.tsx @@ -20,7 +20,7 @@ type PopoverLinkType = | "image" | "gallery" | "marker" - | "movie" + | "group" | "performer" | "studio"; @@ -52,7 +52,7 @@ export const PopoverCountButton: React.FC = ({ return faImages; case "marker": return faMapMarkerAlt; - case "movie": + case "group": return faFilm; case "performer": return faUser; @@ -83,10 +83,10 @@ export const PopoverCountButton: React.FC = ({ one: "marker", other: "markers", }; - case "movie": + case "group": return { - one: "movie", - other: "movies", + one: "group", + other: "groups", }; case "performer": return { diff --git a/ui/v2.5/src/components/Shared/ScrapeDialog/ScrapedObjectsRow.tsx b/ui/v2.5/src/components/Shared/ScrapeDialog/ScrapedObjectsRow.tsx index 7184716a744..73589ce926d 100644 --- a/ui/v2.5/src/components/Shared/ScrapeDialog/ScrapedObjectsRow.tsx +++ b/ui/v2.5/src/components/Shared/ScrapeDialog/ScrapedObjectsRow.tsx @@ -8,7 +8,7 @@ import { } from "src/components/Shared/ScrapeDialog/scrapeResult"; import { TagSelect } from "src/components/Tags/TagSelect"; import { StudioSelect } from "src/components/Studios/StudioSelect"; -import { MovieSelect } from "src/components/Movies/MovieSelect"; +import { GroupSelect } from "src/components/Movies/MovieSelect"; interface IScrapedStudioRow { title: string; @@ -196,10 +196,10 @@ export const ScrapedPerformersRow: React.FC< ); }; -export const ScrapedMoviesRow: React.FC< +export const ScrapedGroupsRow: React.FC< IScrapedObjectRowImpl > = ({ title, result, onChange, newObjects, onCreateNew }) => { - const moviesCopy = useMemo(() => { + const groupsCopy = useMemo(() => { return ( newObjects?.map((p) => { const name: string = p.name ?? ""; @@ -208,7 +208,7 @@ export const ScrapedMoviesRow: React.FC< ); }, [newObjects]); - function renderScrapedMovies( + function renderScrapedGroups( scrapeResult: ScrapeResult, isNew?: boolean, onChangeFn?: (value: GQL.ScrapedMovie[]) => void @@ -228,7 +228,7 @@ export const ScrapedMoviesRow: React.FC< }); return ( - title={title} result={result} - renderObjects={renderScrapedMovies} + renderObjects={renderScrapedGroups} onChange={onChange} - newObjects={moviesCopy} + newObjects={groupsCopy} onCreateNew={onCreateNew} getName={(value) => value.name ?? ""} /> diff --git a/ui/v2.5/src/components/Shared/ScrapeDialog/createObjects.ts b/ui/v2.5/src/components/Shared/ScrapeDialog/createObjects.ts index 009677e5940..397681483e0 100644 --- a/ui/v2.5/src/components/Shared/ScrapeDialog/createObjects.ts +++ b/ui/v2.5/src/components/Shared/ScrapeDialog/createObjects.ts @@ -9,7 +9,7 @@ import { import { ObjectScrapeResult, ScrapeResult } from "./scrapeResult"; import { useIntl } from "react-intl"; import { scrapedPerformerToCreateInput } from "src/core/performers"; -import { scrapedMovieToCreateInput } from "src/core/movies"; +import { scrapedGroupToCreateInput } from "src/core/movies"; function useCreateObject( entityTypeID: string, @@ -123,16 +123,16 @@ export function useCreateScrapedPerformer( return useCreateObject("performer", createNewPerformer); } -export function useCreateScrapedMovie( +export function useCreateScrapedGroup( props: IUseCreateNewObjectProps ) { const { scrapeResult, setScrapeResult, newObjects, setNewObjects } = props; - const [createMovie] = useMovieCreate(); + const [createGroup] = useMovieCreate(); - async function createNewMovie(toCreate: GQL.ScrapedMovie) { - const input = scrapedMovieToCreateInput(toCreate); + async function createNewGroup(toCreate: GQL.ScrapedMovie) { + const input = scrapedGroupToCreateInput(toCreate); - const result = await createMovie({ + const result = await createGroup({ variables: { input: input }, }); @@ -150,14 +150,14 @@ export function useCreateScrapedMovie( // remove the object from the list const newObjectsClone = newObjects.concat(); const pIndex = newObjectsClone.findIndex((p) => p.name === toCreate.name); - if (pIndex === -1) throw new Error("Could not find movie to remove"); + if (pIndex === -1) throw new Error("Could not find group to remove"); newObjectsClone.splice(pIndex, 1); setNewObjects(newObjectsClone); } - return useCreateObject("movie", createNewMovie); + return useCreateObject("group", createNewGroup); } export function useCreateScrapedTag( diff --git a/ui/v2.5/src/components/Shared/Select.tsx b/ui/v2.5/src/components/Shared/Select.tsx index 201bb5a3d85..e989c886de2 100644 --- a/ui/v2.5/src/components/Shared/Select.tsx +++ b/ui/v2.5/src/components/Shared/Select.tsx @@ -26,7 +26,7 @@ import { faTableColumns } from "@fortawesome/free-solid-svg-icons"; import { TagIDSelect } from "../Tags/TagSelect"; import { StudioIDSelect } from "../Studios/StudioSelect"; import { GalleryIDSelect } from "../Galleries/GallerySelect"; -import { MovieIDSelect } from "../Movies/MovieSelect"; +import { GroupIDSelect } from "../Movies/MovieSelect"; import { SceneIDSelect } from "../Scenes/SceneSelect"; export type SelectObject = { @@ -44,7 +44,7 @@ interface ITypeProps { | "scene_tags" | "performer_tags" | "scenes" - | "movies" + | "groups" | "galleries"; } interface IFilterProps { @@ -364,8 +364,8 @@ export const StudioSelect: React.FC< return ; }; -export const MovieSelect: React.FC = (props) => { - return ; +export const GroupSelect: React.FC = (props) => { + return ; }; export const TagSelect: React.FC< @@ -382,8 +382,8 @@ export const FilterSelect: React.FC = (props) => { return ; case "scenes": return ; - case "movies": - return ; + case "groups": + return ; case "galleries": return ; default: diff --git a/ui/v2.5/src/components/Shared/TagLink.tsx b/ui/v2.5/src/components/Shared/TagLink.tsx index f2fe7c49ff6..d01de3eac42 100644 --- a/ui/v2.5/src/components/Shared/TagLink.tsx +++ b/ui/v2.5/src/components/Shared/TagLink.tsx @@ -71,25 +71,25 @@ export const PerformerLink: React.FC = ({ ); }; -interface IMovieLinkProps { - movie: INamedObject; +interface IGroupLinkProps { + group: INamedObject; linkType?: "scene"; className?: string; } -export const MovieLink: React.FC = ({ - movie, +export const GroupLink: React.FC = ({ + group, linkType = "scene", className, }) => { const link = useMemo(() => { switch (linkType) { case "scene": - return NavUtils.makeMovieScenesUrl(movie); + return NavUtils.makeGroupScenesUrl(group); } - }, [movie, linkType]); + }, [group, linkType]); - const title = movie.name || ""; + const title = group.name || ""; return ( @@ -197,7 +197,7 @@ interface ITagLinkProps { | "image" | "details" | "performer" - | "movie" + | "group" | "studio"; className?: string; hoverPlacement?: Placement; @@ -225,8 +225,8 @@ export const TagLink: React.FC = ({ return NavUtils.makeTagGalleriesUrl(tag); case "image": return NavUtils.makeTagImagesUrl(tag); - case "movie": - return NavUtils.makeTagMoviesUrl(tag); + case "group": + return NavUtils.makeTagGroupsUrl(tag); case "details": return NavUtils.makeTagUrl(tag.id ?? ""); } diff --git a/ui/v2.5/src/components/Stats.tsx b/ui/v2.5/src/components/Stats.tsx index f177aa46194..608afc0e2c3 100644 --- a/ui/v2.5/src/components/Stats.tsx +++ b/ui/v2.5/src/components/Stats.tsx @@ -53,7 +53,7 @@ export const Stats: React.FC = () => {

- +

diff --git a/ui/v2.5/src/components/Studios/StudioCard.tsx b/ui/v2.5/src/components/Studios/StudioCard.tsx index 1c1e5e6eeac..62604555e2a 100644 --- a/ui/v2.5/src/components/Studios/StudioCard.tsx +++ b/ui/v2.5/src/components/Studios/StudioCard.tsx @@ -142,15 +142,15 @@ export const StudioCard: React.FC = ({ ); } - function maybeRenderMoviesPopoverButton() { + function maybeRenderGroupsPopoverButton() { if (!studio.movie_count) return; return ( ); } @@ -199,7 +199,7 @@ export const StudioCard: React.FC = ({
{maybeRenderScenesPopoverButton()} - {maybeRenderMoviesPopoverButton()} + {maybeRenderGroupsPopoverButton()} {maybeRenderImagesPopoverButton()} {maybeRenderGalleriesPopoverButton()} {maybeRenderPerformersPopoverButton()} diff --git a/ui/v2.5/src/components/Studios/StudioDetails/Studio.tsx b/ui/v2.5/src/components/Studios/StudioDetails/Studio.tsx index 35052b091c4..870db812c55 100644 --- a/ui/v2.5/src/components/Studios/StudioDetails/Studio.tsx +++ b/ui/v2.5/src/components/Studios/StudioDetails/Studio.tsx @@ -31,7 +31,7 @@ import { CompressedStudioDetailsPanel, StudioDetailsPanel, } from "./StudioDetailsPanel"; -import { StudioMoviesPanel } from "./StudioMoviesPanel"; +import { StudioGroupsPanel } from "./StudioMoviesPanel"; import { faTrashAlt, faLink, @@ -63,7 +63,7 @@ const validTabs = [ "galleries", "images", "performers", - "movies", + "groups", "childstudios", ] as const; type TabKey = (typeof validTabs)[number]; @@ -108,7 +108,7 @@ const StudioPage: React.FC = ({ studio, tabKey }) => { (showAllCounts ? studio.image_count_all : studio.image_count) ?? 0; const performerCount = (showAllCounts ? studio.performer_count_all : studio.performer_count) ?? 0; - const movieCount = + const groupCount = (showAllCounts ? studio.movie_count_all : studio.movie_count) ?? 0; const populatedDefaultTab = useMemo(() => { @@ -120,8 +120,8 @@ const StudioPage: React.FC = ({ studio, tabKey }) => { ret = "images"; } else if (performerCount != 0) { ret = "performers"; - } else if (movieCount != 0) { - ret = "movies"; + } else if (groupCount != 0) { + ret = "groups"; } else if (studio.child_studios.length != 0) { ret = "childstudios"; } @@ -133,7 +133,7 @@ const StudioPage: React.FC = ({ studio, tabKey }) => { galleryCount, imageCount, performerCount, - movieCount, + groupCount, studio, ]); @@ -437,19 +437,19 @@ const StudioPage: React.FC = ({ studio, tabKey }) => { /> - {intl.formatMessage({ id: "movies" })} + {intl.formatMessage({ id: "groups" })} } > - + = ({ +export const StudioGroupsPanel: React.FC = ({ active, studio, }) => { const filterHook = useStudioFilterHook(studio); return ( - ); }; diff --git a/ui/v2.5/src/components/Tags/TagCard.tsx b/ui/v2.5/src/components/Tags/TagCard.tsx index 424f8c5f518..770e0bb9134 100644 --- a/ui/v2.5/src/components/Tags/TagCard.tsx +++ b/ui/v2.5/src/components/Tags/TagCard.tsx @@ -236,15 +236,15 @@ export const TagCard: React.FC = ({ ); } - function maybeRenderMoviesPopoverButton() { + function maybeRenderGroupsPopoverButton() { if (!tag.movie_count) return; return ( ); } @@ -258,7 +258,7 @@ export const TagCard: React.FC = ({ {maybeRenderScenesPopoverButton()} {maybeRenderImagesPopoverButton()} {maybeRenderGalleriesPopoverButton()} - {maybeRenderMoviesPopoverButton()} + {maybeRenderGroupsPopoverButton()} {maybeRenderSceneMarkersPopoverButton()} {maybeRenderPerformersPopoverButton()} {maybeRenderStudiosPopoverButton()} diff --git a/ui/v2.5/src/components/Tags/TagDetails/Tag.tsx b/ui/v2.5/src/components/Tags/TagDetails/Tag.tsx index c80473db8fd..51a334c11b4 100644 --- a/ui/v2.5/src/components/Tags/TagDetails/Tag.tsx +++ b/ui/v2.5/src/components/Tags/TagDetails/Tag.tsx @@ -42,7 +42,7 @@ import { import { DetailImage } from "src/components/Shared/DetailImage"; import { useLoadStickyHeader } from "src/hooks/detailsPanel"; import { useScrollToTopOnMount } from "src/hooks/scrollToTop"; -import { TagMoviesPanel } from "./TagMoviesPanel"; +import { TagGroupsPanel } from "./TagMoviesPanel"; interface IProps { tag: GQL.TagDataFragment; @@ -59,7 +59,7 @@ const validTabs = [ "scenes", "images", "galleries", - "movies", + "groups", "markers", "performers", "studios", @@ -105,7 +105,7 @@ const TagPage: React.FC = ({ tag, tabKey }) => { (showAllCounts ? tag.image_count_all : tag.image_count) ?? 0; const galleryCount = (showAllCounts ? tag.gallery_count_all : tag.gallery_count) ?? 0; - const movieCount = + const groupCount = (showAllCounts ? tag.movie_count_all : tag.movie_count) ?? 0; const sceneMarkerCount = (showAllCounts ? tag.scene_marker_count_all : tag.scene_marker_count) ?? 0; @@ -121,8 +121,8 @@ const TagPage: React.FC = ({ tag, tabKey }) => { ret = "images"; } else if (galleryCount != 0) { ret = "galleries"; - } else if (movieCount != 0) { - ret = "movies"; + } else if (groupCount != 0) { + ret = "groups"; } else if (sceneMarkerCount != 0) { ret = "markers"; } else if (performerCount != 0) { @@ -140,7 +140,7 @@ const TagPage: React.FC = ({ tag, tabKey }) => { sceneMarkerCount, performerCount, studioCount, - movieCount, + groupCount, ]); const setTabKey = useCallback( @@ -484,19 +484,19 @@ const TagPage: React.FC = ({ tag, tabKey }) => { - {intl.formatMessage({ id: "movies" })} + {intl.formatMessage({ id: "groups" })} } > - + = ({ active, tag }) => { const filterHook = useTagFilterHook(tag); - return ; + return ; }; diff --git a/ui/v2.5/src/core/config.ts b/ui/v2.5/src/core/config.ts index 3e7585df76d..e8f8290617f 100644 --- a/ui/v2.5/src/core/config.ts +++ b/ui/v2.5/src/core/config.ts @@ -143,7 +143,7 @@ export function generateDefaultFrontPageContent(intl: IntlShape) { return [ recentlyReleased(intl, FilterMode.Scenes, "scenes"), recentlyAdded(intl, FilterMode.Studios, "studios"), - recentlyReleased(intl, FilterMode.Movies, "movies"), + recentlyReleased(intl, FilterMode.Movies, "groups"), recentlyAdded(intl, FilterMode.Performers, "performers"), recentlyReleased(intl, FilterMode.Galleries, "galleries"), ]; @@ -156,8 +156,8 @@ export function generatePremadeFrontPageContent(intl: IntlShape) { recentlyReleased(intl, FilterMode.Galleries, "galleries"), recentlyAdded(intl, FilterMode.Galleries, "galleries"), recentlyAdded(intl, FilterMode.Images, "images"), - recentlyReleased(intl, FilterMode.Movies, "movies"), - recentlyAdded(intl, FilterMode.Movies, "movies"), + recentlyReleased(intl, FilterMode.Movies, "groups"), + recentlyAdded(intl, FilterMode.Movies, "groups"), recentlyAdded(intl, FilterMode.Studios, "studios"), recentlyAdded(intl, FilterMode.Performers, "performers"), ]; diff --git a/ui/v2.5/src/core/movies.ts b/ui/v2.5/src/core/movies.ts index 470de21eea2..1183785f16d 100644 --- a/ui/v2.5/src/core/movies.ts +++ b/ui/v2.5/src/core/movies.ts @@ -1,7 +1,7 @@ import * as GQL from "src/core/generated-graphql"; import TextUtils from "src/utils/text"; -export const scrapedMovieToCreateInput = (toCreate: GQL.ScrapedMovie) => { +export const scrapedGroupToCreateInput = (toCreate: GQL.ScrapedMovie) => { const input: GQL.MovieCreateInput = { name: toCreate.name ?? "", url: toCreate.url, diff --git a/ui/v2.5/src/index.scss b/ui/v2.5/src/index.scss index 2e9587f9632..df3cd9e2406 100755 --- a/ui/v2.5/src/index.scss +++ b/ui/v2.5/src/index.scss @@ -54,7 +54,7 @@ body { } } -#movie-page, +#group-page, #performer-page, #studio-page, #tag-page { @@ -83,7 +83,7 @@ dd { display: none; } - .movie-name, + .group-name, .performer-name, .studio-name, .tag-name { @@ -93,7 +93,7 @@ dd { .sticky.detail-header-group { padding: 1rem 2.5rem; - a.movie-name, + a.group-name, a.performer-name, a.studio-name, a.tag-name { @@ -313,7 +313,7 @@ dd { justify-content: center; padding: 0 1rem; - .movie-images { + .group-images { height: 100%; } @@ -322,7 +322,7 @@ dd { height: auto; padding: 0; - .movie-images { + .group-images { .img { max-width: 100%; } @@ -335,18 +335,18 @@ dd { transition: 0.5s; } - .movie-images img { + .group-images img { @media (max-width: 576px) { max-width: 100%; } } } -#movie-page .detail-header-image .movie-images img { +#group-page .detail-header-image .group-images img { max-width: 13rem; } -#movie-page .detail-header-image img, +#group-page .detail-header-image img, #performer-page .detail-header-image img, #tag-page .detail-header-image img { border-radius: 0.5rem; diff --git a/ui/v2.5/src/locales/en-GB.json b/ui/v2.5/src/locales/en-GB.json index 805eb9b50a9..5145ea829cd 100644 --- a/ui/v2.5/src/locales/en-GB.json +++ b/ui/v2.5/src/locales/en-GB.json @@ -798,9 +798,9 @@ "countables": { "files": "{count, plural, one {File} other {Files}}", "galleries": "{count, plural, one {Gallery} other {Galleries}}", + "groups": "{count, plural, one {Group} other {Groups}}", "images": "{count, plural, one {Image} other {Images}}", "markers": "{count, plural, one {Marker} other {Markers}}", - "movies": "{count, plural, one {Movie} other {Movies}}", "performers": "{count, plural, one {Performer} other {Performers}}", "scenes": "{count, plural, one {Scene} other {Scenes}}", "studios": "{count, plural, one {Studio} other {Studios}}", @@ -1060,6 +1060,10 @@ "TRANSGENDER_FEMALE": "Transgender Female", "TRANSGENDER_MALE": "Transgender Male" }, + "group": "Group", + "group_count": "Group Count", + "group_scene_number": "Scene Number", + "groups": "Groups", "hair_color": "Hair Colour", "handy_connection_status": { "connecting": "Connecting", @@ -1117,10 +1121,6 @@ }, "megabits_per_second": "{value} mbps", "metadata": "Metadata", - "movie": "Movie", - "movie_count": "Movie Count", - "movie_scene_number": "Scene Number", - "movies": "Movies", "name": "Name", "new": "New", "none": "None", diff --git a/ui/v2.5/src/models/list-filter/criteria/criterion.ts b/ui/v2.5/src/models/list-filter/criteria/criterion.ts index 90874b70a57..6be7d604087 100644 --- a/ui/v2.5/src/models/list-filter/criteria/criterion.ts +++ b/ui/v2.5/src/models/list-filter/criteria/criterion.ts @@ -173,7 +173,7 @@ export type InputType = | "performer_tags" | "scenes" | "scene_tags" - | "movies" + | "groups" | "galleries" | undefined; diff --git a/ui/v2.5/src/models/list-filter/criteria/movies.ts b/ui/v2.5/src/models/list-filter/criteria/movies.ts index 547fc40b6f9..391fdb1d27c 100644 --- a/ui/v2.5/src/models/list-filter/criteria/movies.ts +++ b/ui/v2.5/src/models/list-filter/criteria/movies.ts @@ -1,9 +1,9 @@ import { ILabeledIdCriterion, ILabeledIdCriterionOption } from "./criterion"; -const inputType = "movies"; +const inputType = "groups"; export const MoviesCriterionOption = new ILabeledIdCriterionOption( - "movies", + "groups", "movies", false, inputType, diff --git a/ui/v2.5/src/models/list-filter/scenes.ts b/ui/v2.5/src/models/list-filter/scenes.ts index c25ee97668d..9a8e3f5e1db 100644 --- a/ui/v2.5/src/models/list-filter/scenes.ts +++ b/ui/v2.5/src/models/list-filter/scenes.ts @@ -47,7 +47,6 @@ const sortByOptions = [ "resume_time", "play_duration", "play_count", - "movie_scene_number", "interactive", "interactive_speed", "perceptual_similarity", @@ -59,6 +58,10 @@ const sortByOptions = [ messageID: "o_count", value: "o_counter", }, + { + messageID: "group_scene_number", + value: "movie_scene_number", + }, ]); const displayModeOptions = [ DisplayMode.Grid, diff --git a/ui/v2.5/src/models/list-filter/tags.ts b/ui/v2.5/src/models/list-filter/tags.ts index 51df9ed896c..dc84a9676bd 100644 --- a/ui/v2.5/src/models/list-filter/tags.ts +++ b/ui/v2.5/src/models/list-filter/tags.ts @@ -36,7 +36,7 @@ const sortByOptions = ["name", "random"] value: "scenes_count", }, { - messageID: "movie_count", + messageID: "group_count", value: "movies_count", }, { @@ -62,7 +62,7 @@ const criterionOptions = [ createMandatoryNumberCriterionOption("gallery_count"), createMandatoryNumberCriterionOption("performer_count"), createMandatoryNumberCriterionOption("studio_count"), - createMandatoryNumberCriterionOption("movie_count"), + createMandatoryNumberCriterionOption("movie_count", "group_count"), createMandatoryNumberCriterionOption("marker_count"), ParentTagsCriterionOption, new MandatoryNumberCriterionOption("parent_tag_count", "parent_count"), diff --git a/ui/v2.5/src/pluginApi.d.ts b/ui/v2.5/src/pluginApi.d.ts index ae292ceeeb3..9d3aad40f90 100644 --- a/ui/v2.5/src/pluginApi.d.ts +++ b/ui/v2.5/src/pluginApi.d.ts @@ -693,12 +693,12 @@ declare namespace PluginApi { function makePerformerScenesUrl(...args: any[]): any; function makePerformerImagesUrl(...args: any[]): any; function makePerformerGalleriesUrl(...args: any[]): any; - function makePerformerMoviesUrl(...args: any[]): any; + function makePerformerGroupsUrl(...args: any[]): any; function makePerformersCountryUrl(...args: any[]): any; function makeStudioScenesUrl(...args: any[]): any; function makeStudioImagesUrl(...args: any[]): any; function makeStudioGalleriesUrl(...args: any[]): any; - function makeStudioMoviesUrl(...args: any[]): any; + function makeStudioGroupsUrl(...args: any[]): any; function makeStudioPerformersUrl(...args: any[]): any; function makeTagUrl(...args: any[]): any; function makeParentTagsUrl(...args: any[]): any; @@ -710,7 +710,7 @@ declare namespace PluginApi { function makeTagImagesUrl(...args: any[]): any; function makeScenesPHashMatchUrl(...args: any[]): any; function makeSceneMarkerUrl(...args: any[]): any; - function makeMovieScenesUrl(...args: any[]): any; + function makeGroupScenesUrl(...args: any[]): any; function makeChildStudiosUrl(...args: any[]): any; function makeGalleryImagesUrl(...args: any[]): any; } diff --git a/ui/v2.5/src/utils/bulkUpdate.ts b/ui/v2.5/src/utils/bulkUpdate.ts index 22b5d3a68a7..9856c933690 100644 --- a/ui/v2.5/src/utils/bulkUpdate.ts +++ b/ui/v2.5/src/utils/bulkUpdate.ts @@ -81,11 +81,11 @@ export function getAggregateTagIds(state: { tags: IHasID[] }[]) { return getAggregateIds(sortedLists); } -interface IMovie { +interface IGroup { movie: IHasID; } -export function getAggregateMovieIds(state: { movies: IMovie[] }[]) { +export function getAggregateGroupIds(state: { movies: IGroup[] }[]) { const sortedLists = state.map((o) => o.movies.map((oo) => oo.movie.id).sort() ); diff --git a/ui/v2.5/src/utils/navigation.ts b/ui/v2.5/src/utils/navigation.ts index 864618fd414..c246d699a50 100644 --- a/ui/v2.5/src/utils/navigation.ts +++ b/ui/v2.5/src/utils/navigation.ts @@ -103,7 +103,7 @@ const makePerformerGalleriesUrl = ( return `/galleries?${filter.makeQueryParameters()}`; }; -const makePerformerMoviesUrl = ( +const makePerformerGroupsUrl = ( performer: Partial, extraPerformer?: ILabeledId, extraCriteria?: Criterion[] @@ -121,7 +121,7 @@ const makePerformerMoviesUrl = ( filter.criteria.push(criterion); addExtraCriteria(filter.criteria, extraCriteria); - return `/movies?${filter.makeQueryParameters()}`; + return `/groups?${filter.makeQueryParameters()}`; }; const makePerformersCountryUrl = ( @@ -174,7 +174,7 @@ const makeStudioGalleriesUrl = (studio: Partial) => { return `/galleries?${filter.makeQueryParameters()}`; }; -const makeStudioMoviesUrl = (studio: Partial) => { +const makeStudioGroupsUrl = (studio: Partial) => { if (!studio.id) return "#"; const filter = new ListFilterModel(GQL.FilterMode.Movies, undefined); const criterion = new StudiosCriterion(); @@ -184,7 +184,7 @@ const makeStudioMoviesUrl = (studio: Partial) => { depth: 0, }; filter.criteria.push(criterion); - return `/movies?${filter.makeQueryParameters()}`; + return `/groups?${filter.makeQueryParameters()}`; }; const makeStudioPerformersUrl = (studio: Partial) => { @@ -211,12 +211,12 @@ const makeChildStudiosUrl = (studio: Partial) => { return `/studios?${filter.makeQueryParameters()}`; }; -const makeMovieScenesUrl = (movie: Partial) => { - if (!movie.id) return "#"; +const makeGroupScenesUrl = (group: Partial) => { + if (!group.id) return "#"; const filter = new ListFilterModel(GQL.FilterMode.Scenes, undefined); const criterion = new MoviesCriterion(); criterion.value = [ - { id: movie.id, label: movie.name || `Movie ${movie.id}` }, + { id: group.id, label: group.name || `Group ${group.id}` }, ]; filter.criteria.push(criterion); return `/scenes?${filter.makeQueryParameters()}`; @@ -298,8 +298,8 @@ const makeTagImagesUrl = (tag: INamedObject) => { return `/images?${makeTagFilter(GQL.FilterMode.Images, tag)}`; }; -const makeTagMoviesUrl = (tag: INamedObject) => { - return `/movies?${makeTagFilter(GQL.FilterMode.Movies, tag)}`; +const makeTagGroupsUrl = (tag: INamedObject) => { + return `/groups?${makeTagFilter(GQL.FilterMode.Movies, tag)}`; }; type SceneMarkerDataFragment = Pick & { @@ -349,13 +349,13 @@ const makeDirectorScenesUrl = (director: string) => { return `/scenes?${filter.makeQueryParameters()}`; }; -const makeDirectorMoviesUrl = (director: string) => { +const makeDirectorGroupsUrl = (director: string) => { if (director.length == 0) return "#"; const filter = new ListFilterModel(GQL.FilterMode.Movies, undefined); filter.criteria.push( stringEqualsCriterion(createStringCriterionOption("director"), director) ); - return `/movies?${filter.makeQueryParameters()}`; + return `/groups?${filter.makeQueryParameters()}`; }; const makePhotographerGalleriesUrl = (photographer: string) => { @@ -401,12 +401,12 @@ const NavUtils = { makePerformerScenesUrl, makePerformerImagesUrl, makePerformerGalleriesUrl, - makePerformerMoviesUrl, + makePerformerGroupsUrl, makePerformersCountryUrl, makeStudioScenesUrl, makeStudioImagesUrl, makeStudioGalleriesUrl, - makeStudioMoviesUrl, + makeStudioGroupsUrl: makeStudioGroupsUrl, makeStudioPerformersUrl, makeTagUrl, makeParentTagsUrl, @@ -417,16 +417,16 @@ const NavUtils = { makeTagStudiosUrl, makeTagGalleriesUrl, makeTagImagesUrl, - makeTagMoviesUrl, + makeTagGroupsUrl, makeScenesPHashMatchUrl, makeSceneMarkerUrl, - makeMovieScenesUrl, + makeGroupScenesUrl, makeChildStudiosUrl, makeGalleryImagesUrl, makeDirectorScenesUrl, makePhotographerGalleriesUrl, makePhotographerImagesUrl, - makeDirectorMoviesUrl, + makeDirectorGroupsUrl, }; export default NavUtils;