diff --git a/ui/v2.5/src/components/Changelog/versions/v090.md b/ui/v2.5/src/components/Changelog/versions/v090.md index 2d2798242..b84aba52c 100644 --- a/ui/v2.5/src/components/Changelog/versions/v090.md +++ b/ui/v2.5/src/components/Changelog/versions/v090.md @@ -11,6 +11,7 @@ * Added not equals/greater than/less than modifiers for resolution criteria. ([#1568](https://github.com/stashapp/stash/pull/1568)) ### 🎨 Improvements +* Move Play Selected Scenes, and Add/Remove Gallery Image buttons to button toolbar. ([#1673](https://github.com/stashapp/stash/pull/1673)) * Add image and gallery counts to tag list view. ([#1672](https://github.com/stashapp/stash/pull/1672)) * Prompt when leaving gallery edit page with unsaved changes. ([#1654](https://github.com/stashapp/stash/pull/1654)) * Show largest duplicates first in scene duplicate checker. ([#1639](https://github.com/stashapp/stash/pull/1639)) diff --git a/ui/v2.5/src/components/Galleries/GalleryDetails/GalleryAddPanel.tsx b/ui/v2.5/src/components/Galleries/GalleryDetails/GalleryAddPanel.tsx index 10b710795..a25908a3c 100644 --- a/ui/v2.5/src/components/Galleries/GalleryDetails/GalleryAddPanel.tsx +++ b/ui/v2.5/src/components/Galleries/GalleryDetails/GalleryAddPanel.tsx @@ -8,6 +8,7 @@ import { mutateAddGalleryImages } from "src/core/StashService"; import { useToast } from "src/hooks"; import { TextUtils } from "src/utils"; import { useIntl } from "react-intl"; +import { IconProp } from "@fortawesome/fontawesome-svg-core"; interface IGalleryAddProps { gallery: Partial; @@ -87,6 +88,7 @@ export const GalleryAddPanel: React.FC = ({ gallery }) => { onClick: addImages, isDisplayed: showWhenSelected, postRefetch: true, + icon: "plus" as IconProp, }, ]; diff --git a/ui/v2.5/src/components/Galleries/GalleryDetails/GalleryImagesPanel.tsx b/ui/v2.5/src/components/Galleries/GalleryDetails/GalleryImagesPanel.tsx index 0e3b1c662..ff3d38567 100644 --- a/ui/v2.5/src/components/Galleries/GalleryDetails/GalleryImagesPanel.tsx +++ b/ui/v2.5/src/components/Galleries/GalleryDetails/GalleryImagesPanel.tsx @@ -8,6 +8,7 @@ import { showWhenSelected, PersistanceLevel } from "src/hooks/ListHook"; import { useToast } from "src/hooks"; import { TextUtils } from "src/utils"; import { useIntl } from "react-intl"; +import { IconProp } from "@fortawesome/fontawesome-svg-core"; interface IGalleryDetailsProps { gallery: GQL.GalleryDataFragment; @@ -81,6 +82,8 @@ export const GalleryImagesPanel: React.FC = ({ onClick: removeImages, isDisplayed: showWhenSelected, postRefetch: true, + icon: "minus" as IconProp, + buttonVariant: "danger", }, ]; diff --git a/ui/v2.5/src/components/List/ListOperationButtons.tsx b/ui/v2.5/src/components/List/ListOperationButtons.tsx index f93246d6c..7b4da09e4 100644 --- a/ui/v2.5/src/components/List/ListOperationButtons.tsx +++ b/ui/v2.5/src/components/List/ListOperationButtons.tsx @@ -8,12 +8,15 @@ import { } from "react-bootstrap"; import Mousetrap from "mousetrap"; import { FormattedMessage, useIntl } from "react-intl"; +import { IconProp } from "@fortawesome/fontawesome-svg-core"; import { Icon } from "../Shared"; interface IListFilterOperation { text: string; onClick: () => void; isDisplayed?: () => boolean; + icon?: IconProp; + buttonVariant?: string; } interface IListOperationButtonsProps { @@ -60,37 +63,53 @@ export const ListOperationButtons: React.FC = ({ }; }); - function maybeRenderSelectedButtons() { - if (itemsSelected && (onEdit || onDelete)) { + function maybeRenderButtons() { + const buttons = (otherOperations ?? []).filter((o) => { + if (!o.icon) { + return false; + } + + if (!o.isDisplayed) { + return true; + } + + return o.isDisplayed(); + }); + if (itemsSelected) { + if (onEdit) { + buttons.push({ + icon: "pencil-alt", + text: intl.formatMessage({ id: "actions.edit" }), + onClick: onEdit, + }); + } + if (onDelete) { + buttons.push({ + icon: "trash", + text: intl.formatMessage({ id: "actions.delete" }), + onClick: onDelete, + buttonVariant: "danger", + }); + } + } + + if (buttons.length > 0) { return ( - {onEdit && ( - - {intl.formatMessage({ id: "actions.edit" })} - - } - > - - - )} - - {onDelete && ( - - {intl.formatMessage({ id: "actions.delete" })} - - } - > - - - )} + {buttons.map((button) => { + return ( + {button.text}} + > + + + ); + })} ); } @@ -165,7 +184,7 @@ export const ListOperationButtons: React.FC = ({ return ( <> - {maybeRenderSelectedButtons()} + {maybeRenderButtons()}
{renderMore()}
diff --git a/ui/v2.5/src/components/Scenes/SceneList.tsx b/ui/v2.5/src/components/Scenes/SceneList.tsx index 65eb6bed0..8f64035ec 100644 --- a/ui/v2.5/src/components/Scenes/SceneList.tsx +++ b/ui/v2.5/src/components/Scenes/SceneList.tsx @@ -3,6 +3,7 @@ import _ from "lodash"; import { useIntl } from "react-intl"; import { useHistory } from "react-router-dom"; import Mousetrap from "mousetrap"; +import { IconProp } from "@fortawesome/fontawesome-svg-core"; import { FindScenesQueryResult, SlimSceneDataFragment, @@ -44,6 +45,7 @@ export const SceneList: React.FC = ({ text: intl.formatMessage({ id: "actions.play_selected" }), onClick: playSelected, isDisplayed: showWhenSelected, + icon: "play" as IconProp, }, { text: intl.formatMessage({ id: "actions.play_random" }), diff --git a/ui/v2.5/src/hooks/ListHook.tsx b/ui/v2.5/src/hooks/ListHook.tsx index 3a5ebb2a1..0d9d040d4 100644 --- a/ui/v2.5/src/hooks/ListHook.tsx +++ b/ui/v2.5/src/hooks/ListHook.tsx @@ -10,6 +10,7 @@ import React, { import { ApolloError } from "@apollo/client"; import { useHistory, useLocation } from "react-router-dom"; import Mousetrap from "mousetrap"; +import { IconProp } from "@fortawesome/fontawesome-svg-core"; import { SlimSceneDataFragment, SceneMarkerDataFragment, @@ -96,6 +97,8 @@ export interface IListHookOperation { selectedIds: Set ) => boolean; postRefetch?: boolean; + icon?: IconProp; + buttonVariant?: string; } export enum PersistanceLevel { @@ -357,6 +360,8 @@ const RenderList = < return true; }, + icon: o.icon, + buttonVariant: o.buttonVariant, })); function onEdit() {