From bf2a083749c3d17f4b9b0b655fd6f6e8defd5801 Mon Sep 17 00:00:00 2001 From: pickleahead Date: Fri, 1 Jul 2022 23:18:15 +0200 Subject: [PATCH] display tag description and tag image on hover closes #2575 --- graphql/documents/data/config.graphql | 1 + graphql/schema/types/config.graphql | 6 ++ internal/api/resolver_mutation_configure.go | 1 + internal/api/resolver_query_configuration.go | 2 + internal/manager/config/config.go | 6 ++ .../SettingsInterfacePanel.tsx | 8 +++ ui/v2.5/src/components/Shared/Select.tsx | 7 ++- ui/v2.5/src/components/Shared/TagLink.tsx | 7 ++- ui/v2.5/src/components/Tags/TagPopover.tsx | 57 +++++++++++++++++++ ui/v2.5/src/components/Tags/styles.scss | 19 +++++++ ui/v2.5/src/locales/en-GB.json | 4 ++ 11 files changed, 116 insertions(+), 2 deletions(-) create mode 100644 ui/v2.5/src/components/Tags/TagPopover.tsx diff --git a/graphql/documents/data/config.graphql b/graphql/documents/data/config.graphql index 58ba6d7a919..956df9649ac 100644 --- a/graphql/documents/data/config.graphql +++ b/graphql/documents/data/config.graphql @@ -49,6 +49,7 @@ fragment ConfigGeneralData on ConfigGeneralResult { fragment ConfigInterfaceData on ConfigInterfaceResult { menuItems + showTagCardOnHover soundOnPreview wallShowTitle wallPlayback diff --git a/graphql/schema/types/config.graphql b/graphql/schema/types/config.graphql index 9a84f0cc651..087d641919b 100644 --- a/graphql/schema/types/config.graphql +++ b/graphql/schema/types/config.graphql @@ -233,6 +233,9 @@ input ConfigInterfaceInput { """Ordered list of items that should be shown in the menu""" menuItems: [String!] + """Show tag card when hovering tags""" + showTagCardOnHover: Boolean + """Enable sound on mouseover previews""" soundOnPreview: Boolean @@ -291,6 +294,9 @@ type ConfigInterfaceResult { """Ordered list of items that should be shown in the menu""" menuItems: [String!] + """Show tag card when hovering tags""" + showTagCardOnHover: Boolean + """Enable sound on mouseover previews""" soundOnPreview: Boolean diff --git a/internal/api/resolver_mutation_configure.go b/internal/api/resolver_mutation_configure.go index f1e35239de5..96cee47a7b5 100644 --- a/internal/api/resolver_mutation_configure.go +++ b/internal/api/resolver_mutation_configure.go @@ -302,6 +302,7 @@ func (r *mutationResolver) ConfigureInterface(ctx context.Context, input ConfigI c.Set(config.MenuItems, input.MenuItems) } + setBool(config.ShowTagCardOnHover, input.ShowTagCardOnHover) setBool(config.SoundOnPreview, input.SoundOnPreview) setBool(config.WallShowTitle, input.WallShowTitle) diff --git a/internal/api/resolver_query_configuration.go b/internal/api/resolver_query_configuration.go index f3469de978c..02382acc92a 100644 --- a/internal/api/resolver_query_configuration.go +++ b/internal/api/resolver_query_configuration.go @@ -128,6 +128,7 @@ func makeConfigGeneralResult() *ConfigGeneralResult { func makeConfigInterfaceResult() *ConfigInterfaceResult { config := config.GetInstance() menuItems := config.GetMenuItems() + showTagCardOnHover := config.GetShowTagCardOnHover() soundOnPreview := config.GetSoundOnPreview() wallShowTitle := config.GetWallShowTitle() showScrubber := config.GetShowScrubber() @@ -151,6 +152,7 @@ func makeConfigInterfaceResult() *ConfigInterfaceResult { return &ConfigInterfaceResult{ MenuItems: menuItems, + ShowTagCardOnHover: &showTagCardOnHover, SoundOnPreview: &soundOnPreview, WallShowTitle: &wallShowTitle, WallPlayback: &wallPlayback, diff --git a/internal/manager/config/config.go b/internal/manager/config/config.go index 3be7be32af3..e1405a0e743 100644 --- a/internal/manager/config/config.go +++ b/internal/manager/config/config.go @@ -125,6 +125,8 @@ const ( // Interface options MenuItems = "menu_items" + ShowTagCardOnHover = "show_tag_card_on_hover" + SoundOnPreview = "sound_on_preview" WallShowTitle = "wall_show_title" @@ -877,6 +879,10 @@ func (i *Instance) GetMenuItems() []string { return defaultMenuItems } +func (i *Instance) GetShowTagCardOnHover() bool { + return i.getBool(ShowTagCardOnHover) +} + func (i *Instance) GetSoundOnPreview() bool { return i.getBool(SoundOnPreview) } diff --git a/ui/v2.5/src/components/Settings/SettingsInterfacePanel/SettingsInterfacePanel.tsx b/ui/v2.5/src/components/Settings/SettingsInterfacePanel/SettingsInterfacePanel.tsx index b3fde0c1a05..c4c6ea72399 100644 --- a/ui/v2.5/src/components/Settings/SettingsInterfacePanel/SettingsInterfacePanel.tsx +++ b/ui/v2.5/src/components/Settings/SettingsInterfacePanel/SettingsInterfacePanel.tsx @@ -130,6 +130,14 @@ export const SettingsInterfacePanel: React.FC = () => { onChange={(v) => saveInterface({ menuItems: v })} /> + + saveInterface({ showTagCardOnHover: v })} + /> diff --git a/ui/v2.5/src/components/Shared/Select.tsx b/ui/v2.5/src/components/Shared/Select.tsx index f90a6943268..7bd85eba097 100644 --- a/ui/v2.5/src/components/Shared/Select.tsx +++ b/ui/v2.5/src/components/Shared/Select.tsx @@ -27,6 +27,7 @@ import { ConfigurationContext } from "src/hooks/Config"; import { useIntl } from "react-intl"; import { objectTitle } from "src/core/files"; import { galleryTitle } from "src/core/galleries"; +import { TagPopover } from "../Tags/TagPopover"; export type ValidTypes = | GQL.SlimPerformerDataFragment @@ -659,7 +660,11 @@ export const TagSelect: React.FC = ( }; } - return ; + return ( + + + + ); }; const filterOption = (option: Option, rawInput: string): boolean => { diff --git a/ui/v2.5/src/components/Shared/TagLink.tsx b/ui/v2.5/src/components/Shared/TagLink.tsx index 441c0c3acf1..dedb8b6e3f7 100644 --- a/ui/v2.5/src/components/Shared/TagLink.tsx +++ b/ui/v2.5/src/components/Shared/TagLink.tsx @@ -14,6 +14,7 @@ import TextUtils from "src/utils/text"; import { objectTitle } from "src/core/files"; import { galleryTitle } from "src/core/galleries"; import * as GQL from "src/core/generated-graphql"; +import { TagPopover } from "../Tags/TagPopover"; interface IFile { path: string; @@ -37,6 +38,7 @@ interface IProps { } export const TagLink: React.FC = (props: IProps) => { + let id: string = ""; let link: string = "#"; let title: string = ""; if (props.tag) { @@ -55,6 +57,7 @@ export const TagLink: React.FC = (props: IProps) => { link = NavUtils.makeTagImagesUrl(props.tag); break; } + id = props.tag.id || ""; title = props.tag.name || ""; } else if (props.performer) { link = NavUtils.makePerformerScenesUrl(props.performer); @@ -76,7 +79,9 @@ export const TagLink: React.FC = (props: IProps) => { } return ( - {title} + + {title} + ); }; diff --git a/ui/v2.5/src/components/Tags/TagPopover.tsx b/ui/v2.5/src/components/Tags/TagPopover.tsx new file mode 100644 index 00000000000..cb59753846c --- /dev/null +++ b/ui/v2.5/src/components/Tags/TagPopover.tsx @@ -0,0 +1,57 @@ +import React from "react"; +import { ErrorMessage, LoadingIndicator } from "../Shared"; +import { HoverPopover } from "src/components/Shared"; +import { useFindTag } from "../../core/StashService"; +import { TagCard } from "./TagCard"; +import { ConfigurationContext } from "../../hooks/Config"; + +interface ITagPopoverProps { + id?: string; +} + +export const TagPopoverCard: React.FC = ({ id }) => { + const { data, loading, error } = useFindTag(id ?? ""); + + if (loading) + return ( +
+ +
+ ); + if (error) return ; + if (!data?.findTag) + return ; + + const tag = data.findTag; + + return ( +
+ +
+ ); +}; + +export const TagPopover: React.FC = ({ id, children }) => { + const { configuration: config } = React.useContext(ConfigurationContext); + + const showTagCardOnHover = config?.interface.showTagCardOnHover ?? true; + + if (!id || !showTagCardOnHover) { + return <>{children}; + } + + return ( + } + > + {children} + + ); +}; + +interface ITagPopoverCardProps { + id?: string; +} diff --git a/ui/v2.5/src/components/Tags/styles.scss b/ui/v2.5/src/components/Tags/styles.scss index 3c153893ca6..ba325207e61 100644 --- a/ui/v2.5/src/components/Tags/styles.scss +++ b/ui/v2.5/src/components/Tags/styles.scss @@ -49,3 +49,22 @@ margin-top: 1rem; } } + +.tag-popover-card-placeholder { + display: flex; + max-width: 240px; + min-height: 314px; + width: calc(100vw - 2rem); +} + +.tag-popover-card { + padding: 0.5rem; + text-align: left; + + .card { + background: transparent; + box-shadow: none; + max-width: calc(100vw - 2rem); + padding: 0; + } +} diff --git a/ui/v2.5/src/locales/en-GB.json b/ui/v2.5/src/locales/en-GB.json index 7f289daae08..d6e0b9e6e39 100644 --- a/ui/v2.5/src/locales/en-GB.json +++ b/ui/v2.5/src/locales/en-GB.json @@ -491,6 +491,10 @@ "description": "Show or hide different types of content on the navigation bar", "heading": "Menu Items" }, + "show_tag_card_on_hover": { + "description": "Show tag card when hovering tag badges", + "heading": "Tag card tooltips" + }, "performers": { "options": { "image_location": {