mirror of https://github.com/stashapp/stash.git
Add missing gallery components (#969)
* add gallery scrapers to settings page * add galleries to performers page * add galleries to studios page
This commit is contained in:
parent
a96ab9ce6f
commit
c45780dc59
|
@ -1,4 +1,6 @@
|
|||
### 🎨 Improvements
|
||||
* Add gallery tabs to performer and studio pages.
|
||||
* Add gallery scrapers to scraper page.
|
||||
* Add support for setting cookies in scrapers.
|
||||
* Truncate long text and show on hover.
|
||||
* Show scene studio as text where image is missing.
|
||||
|
|
|
@ -22,6 +22,7 @@ import FsLightbox from "fslightbox-react";
|
|||
import { PerformerDetailsPanel } from "./PerformerDetailsPanel";
|
||||
import { PerformerOperationsPanel } from "./PerformerOperationsPanel";
|
||||
import { PerformerScenesPanel } from "./PerformerScenesPanel";
|
||||
import { PerformerGalleriesPanel } from "./PerformerGalleriesPanel";
|
||||
import { PerformerImagesPanel } from "./PerformerImagesPanel";
|
||||
|
||||
interface IPerformerParams {
|
||||
|
@ -60,6 +61,7 @@ export const Performer: React.FC = () => {
|
|||
|
||||
const activeTabKey =
|
||||
tab === "scenes" ||
|
||||
tab === "galleries" ||
|
||||
tab === "images" ||
|
||||
tab === "edit" ||
|
||||
tab === "operations"
|
||||
|
@ -81,6 +83,7 @@ export const Performer: React.FC = () => {
|
|||
Mousetrap.bind("a", () => setActiveTabKey("details"));
|
||||
Mousetrap.bind("e", () => setActiveTabKey("edit"));
|
||||
Mousetrap.bind("c", () => setActiveTabKey("scenes"));
|
||||
Mousetrap.bind("g", () => setActiveTabKey("galleries"));
|
||||
Mousetrap.bind("o", () => setActiveTabKey("operations"));
|
||||
Mousetrap.bind("f", () => setFavorite(!performer.favorite));
|
||||
|
||||
|
@ -163,6 +166,9 @@ export const Performer: React.FC = () => {
|
|||
<Tab eventKey="scenes" title="Scenes">
|
||||
<PerformerScenesPanel performer={performer} />
|
||||
</Tab>
|
||||
<Tab eventKey="galleries" title="Galleries">
|
||||
<PerformerGalleriesPanel performer={performer} />
|
||||
</Tab>
|
||||
<Tab eventKey="images" title="Images">
|
||||
<PerformerImagesPanel performer={performer} />
|
||||
</Tab>
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
import React from "react";
|
||||
import * as GQL from "src/core/generated-graphql";
|
||||
import { GalleryList } from "src/components/Galleries/GalleryList";
|
||||
import { performerFilterHook } from "src/core/performers";
|
||||
|
||||
interface IPerformerDetailsProps {
|
||||
performer: Partial<GQL.PerformerDataFragment>;
|
||||
}
|
||||
|
||||
export const PerformerGalleriesPanel: React.FC<IPerformerDetailsProps> = ({
|
||||
performer,
|
||||
}) => {
|
||||
return <GalleryList filterHook={performerFilterHook(performer)} />;
|
||||
};
|
|
@ -5,6 +5,7 @@ import {
|
|||
useListMovieScrapers,
|
||||
useListPerformerScrapers,
|
||||
useListSceneScrapers,
|
||||
useListGalleryScrapers,
|
||||
} from "src/core/StashService";
|
||||
import { useToast } from "src/hooks";
|
||||
import { TextUtils } from "src/utils";
|
||||
|
@ -75,6 +76,10 @@ export const SettingsScrapersPanel: React.FC = () => {
|
|||
data: sceneScrapers,
|
||||
loading: loadingScenes,
|
||||
} = useListSceneScrapers();
|
||||
const {
|
||||
data: galleryScrapers,
|
||||
loading: loadingGalleries,
|
||||
} = useListGalleryScrapers();
|
||||
const {
|
||||
data: movieScrapers,
|
||||
loading: loadingMovies,
|
||||
|
@ -124,6 +129,25 @@ export const SettingsScrapersPanel: React.FC = () => {
|
|||
);
|
||||
}
|
||||
|
||||
function renderGalleryScrapeTypes(types: ScrapeType[]) {
|
||||
const typeStrings = types.map((t) => {
|
||||
switch (t) {
|
||||
case ScrapeType.Fragment:
|
||||
return "Gallery Metadata";
|
||||
default:
|
||||
return t;
|
||||
}
|
||||
});
|
||||
|
||||
return (
|
||||
<ul>
|
||||
{typeStrings.map((t) => (
|
||||
<li key={t}>{t}</li>
|
||||
))}
|
||||
</ul>
|
||||
);
|
||||
}
|
||||
|
||||
function renderMovieScrapeTypes(types: ScrapeType[]) {
|
||||
const typeStrings = types.map((t) => {
|
||||
switch (t) {
|
||||
|
@ -161,6 +185,22 @@ export const SettingsScrapersPanel: React.FC = () => {
|
|||
return renderTable("Scene scrapers", elements);
|
||||
}
|
||||
|
||||
function renderGalleryScrapers() {
|
||||
const elements = (galleryScrapers?.listGalleryScrapers ?? []).map(
|
||||
(scraper) => (
|
||||
<tr key={scraper.id}>
|
||||
<td>{scraper.name}</td>
|
||||
<td>
|
||||
{renderGalleryScrapeTypes(scraper.gallery?.supported_scrapes ?? [])}
|
||||
</td>
|
||||
<td>{renderURLs(scraper.gallery?.urls ?? [])}</td>
|
||||
</tr>
|
||||
)
|
||||
);
|
||||
|
||||
return renderTable("Gallery Scrapers", elements);
|
||||
}
|
||||
|
||||
function renderPerformerScrapers() {
|
||||
const elements = (performerScrapers?.listPerformerScrapers ?? []).map(
|
||||
(scraper) => (
|
||||
|
@ -213,7 +253,7 @@ export const SettingsScrapersPanel: React.FC = () => {
|
|||
}
|
||||
}
|
||||
|
||||
if (loadingScenes || loadingPerformers || loadingMovies)
|
||||
if (loadingScenes || loadingGalleries || loadingPerformers || loadingMovies)
|
||||
return <LoadingIndicator />;
|
||||
|
||||
return (
|
||||
|
@ -230,6 +270,7 @@ export const SettingsScrapersPanel: React.FC = () => {
|
|||
|
||||
<div>
|
||||
{renderSceneScrapers()}
|
||||
{renderGalleryScrapers()}
|
||||
{renderPerformerScrapers()}
|
||||
{renderMovieScrapers()}
|
||||
</div>
|
||||
|
|
|
@ -21,6 +21,7 @@ import {
|
|||
} from "src/components/Shared";
|
||||
import { useToast } from "src/hooks";
|
||||
import { StudioScenesPanel } from "./StudioScenesPanel";
|
||||
import { StudioGalleriesPanel } from "./StudioGalleriesPanel";
|
||||
import { StudioImagesPanel } from "./StudioImagesPanel";
|
||||
import { StudioChildrenPanel } from "./StudioChildrenPanel";
|
||||
|
||||
|
@ -233,7 +234,9 @@ export const Studio: React.FC = () => {
|
|||
}
|
||||
|
||||
const activeTabKey =
|
||||
tab === "childstudios" || tab === "images" ? tab : "scenes";
|
||||
tab === "childstudios" || tab === "images" || tab === "galleries"
|
||||
? tab
|
||||
: "scenes";
|
||||
const setActiveTabKey = (newTab: string | null) => {
|
||||
if (tab !== newTab) {
|
||||
const tabParam = newTab === "scenes" ? "" : `/${newTab}`;
|
||||
|
@ -329,6 +332,9 @@ export const Studio: React.FC = () => {
|
|||
<Tab eventKey="scenes" title="Scenes">
|
||||
<StudioScenesPanel studio={studio} />
|
||||
</Tab>
|
||||
<Tab eventKey="galleries" title="Galleries">
|
||||
<StudioGalleriesPanel studio={studio} />
|
||||
</Tab>
|
||||
<Tab eventKey="images" title="Images">
|
||||
<StudioImagesPanel studio={studio} />
|
||||
</Tab>
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
import React from "react";
|
||||
import * as GQL from "src/core/generated-graphql";
|
||||
import { GalleryList } from "src/components/Galleries/GalleryList";
|
||||
import { studioFilterHook } from "src/core/studios";
|
||||
|
||||
interface IStudioGalleriesPanel {
|
||||
studio: Partial<GQL.StudioDataFragment>;
|
||||
}
|
||||
|
||||
export const StudioGalleriesPanel: React.FC<IStudioGalleriesPanel> = ({
|
||||
studio,
|
||||
}) => {
|
||||
return <GalleryList filterHook={studioFilterHook(studio)} />;
|
||||
};
|
Loading…
Reference in New Issue