Library updates

This commit is contained in:
Infinite
2020-01-22 20:52:04 +01:00
parent 111d5dd7c5
commit dcfd445040
32 changed files with 6902 additions and 4455 deletions

View File

@@ -4,15 +4,12 @@ documents: "../../graphql/documents/**/*.graphql"
generates: generates:
src/core/generated-graphql.tsx: src/core/generated-graphql.tsx:
config: config:
noNamespaces: true
optionalType: "undefined"
noHOC: true
noComponents: true
withHooks: true withHooks: true
withHOC: false
withComponents: false
plugins: plugins:
- add: "/* tslint:disable */"
- add: "/* eslint-disable */" - add: "/* eslint-disable */"
- time - time
- "typescript-common" - typescript
- "typescript-client" - typescript-operations
- "typescript-react-apollo" - typescript-react-apollo

View File

@@ -3,30 +3,36 @@
"version": "0.1.0", "version": "0.1.0",
"private": true, "private": true,
"dependencies": { "dependencies": {
"@apollo/react-hooks": "^3.1.3",
"@fortawesome/fontawesome-svg-core": "^1.2.26", "@fortawesome/fontawesome-svg-core": "^1.2.26",
"@fortawesome/free-solid-svg-icons": "^5.12.0", "@fortawesome/free-solid-svg-icons": "^5.12.0",
"@fortawesome/react-fontawesome": "^0.1.8", "@fortawesome/react-fontawesome": "^0.1.8",
"apollo-boost": "0.4.0", "apollo-cache": "^1.3.4",
"apollo-cache-inmemory": "^1.6.5",
"apollo-client": "^2.6.8",
"apollo-link": "^1.2.13",
"apollo-link-http": "^1.5.16",
"apollo-link-ws": "^1.0.19", "apollo-link-ws": "^1.0.19",
"apollo-utilities": "^1.3.3",
"axios": "0.18.1", "axios": "0.18.1",
"bootstrap": "^4.4.1", "bootstrap": "^4.4.1",
"classnames": "^2.2.6", "classnames": "^2.2.6",
"formik": "1.5.7", "formik": "^2.1.2",
"graphql": "14.3.1", "graphql": "^14.5.8",
"graphql-tag": "^2.10.1",
"localforage": "1.7.3", "localforage": "1.7.3",
"lodash": "4.17.13", "lodash": "^4.17.15",
"node-sass": "4.12.0", "node-sass": "4.13.1",
"normalize.css": "^8.0.1", "normalize.css": "^8.0.1",
"query-string": "6.5.0", "query-string": "6.10.1",
"react": "~16.12.0", "react": "~16.12.0",
"react-apollo": "2.5.6", "react-apollo": "^3.1.3",
"react-apollo-hooks": "0.4.5",
"react-bootstrap": "^1.0.0-beta.16", "react-bootstrap": "^1.0.0-beta.16",
"react-dom": "16.12.0", "react-dom": "16.12.0",
"react-hotkeys": "^2.0.0", "react-hotkeys": "^2.0.0",
"react-images": "0.5.19", "react-images": "0.5.19",
"react-jw-player": "1.19.0", "react-jw-player": "1.19.0",
"react-photo-gallery": "7.0.2", "react-photo-gallery": "^8.0.0",
"react-router-bootstrap": "^0.25.0", "react-router-bootstrap": "^0.25.0",
"react-router-dom": "^5.1.2", "react-router-dom": "^5.1.2",
"react-scripts": "3.3.0", "react-scripts": "3.3.0",
@@ -51,13 +57,19 @@
"not op_mini all" "not op_mini all"
], ],
"devDependencies": { "devDependencies": {
"@graphql-codegen/add": "^1.11.2",
"@graphql-codegen/cli": "^1.11.2",
"@graphql-codegen/time": "^1.11.2",
"@graphql-codegen/typescript": "^1.11.2",
"@graphql-codegen/typescript-compatibility": "^1.11.2",
"@graphql-codegen/typescript-operations": "^1.11.2",
"@graphql-codegen/typescript-react-apollo": "^1.11.2",
"@types/classnames": "^2.2.9", "@types/classnames": "^2.2.9",
"@types/jest": "24.0.13", "@types/jest": "24.0.13",
"@types/lodash": "4.14.132", "@types/lodash": "^4.14.149",
"@types/node": "11.13.0", "@types/node": "13.1.8",
"@types/query-string": "6.3.0", "@types/react": "16.9.19",
"@types/react": "16.9.15", "@types/react-dom": "^16.9.5",
"@types/react-dom": "16.9.4",
"@types/react-images": "^0.5.1", "@types/react-images": "^0.5.1",
"@types/react-router-bootstrap": "^0.24.5", "@types/react-router-bootstrap": "^0.24.5",
"@types/react-router-dom": "5.1.3", "@types/react-router-dom": "5.1.3",
@@ -69,12 +81,6 @@
"eslint-config-airbnb-typescript": "^6.3.1", "eslint-config-airbnb-typescript": "^6.3.1",
"eslint-config-prettier": "^6.9.0", "eslint-config-prettier": "^6.9.0",
"eslint-plugin-jsx-a11y": "^6.2.3", "eslint-plugin-jsx-a11y": "^6.2.3",
"graphql-code-generator": "0.18.2",
"graphql-codegen-add": "0.18.2",
"graphql-codegen-time": "0.18.2",
"graphql-codegen-typescript-client": "0.18.2",
"graphql-codegen-typescript-common": "0.18.2",
"graphql-codegen-typescript-react-apollo": "0.18.2",
"prettier": "1.19.1", "prettier": "1.19.1",
"typescript": "~3.7.4" "typescript": "~3.7.4"
} }

View File

@@ -1,10 +1,8 @@
import React from "react"; import React from "react";
import { Table } from "react-bootstrap"; import { Table } from "react-bootstrap";
import { QueryHookResult } from "react-apollo-hooks";
import { Link } from "react-router-dom"; import { Link } from "react-router-dom";
import { import {
FindGalleriesQuery, FindGalleriesQueryResult,
FindGalleriesVariables
} from "src/core/generated-graphql"; } from "src/core/generated-graphql";
import { useGalleriesList } from "src/hooks"; import { useGalleriesList } from "src/hooks";
import { ListFilterModel } from "src/models/list-filter/filter"; import { ListFilterModel } from "src/models/list-filter/filter";
@@ -16,7 +14,7 @@ export const GalleryList: React.FC = () => {
}); });
function renderContent( function renderContent(
result: QueryHookResult<FindGalleriesQuery, FindGalleriesVariables>, result: FindGalleriesQueryResult,
filter: ListFilterModel filter: ListFilterModel
) { ) {
if (!result.data || !result.data.findGalleries) { if (!result.data || !result.data.findGalleries) {

View File

@@ -1,5 +1,5 @@
import React, { FunctionComponent, useState } from "react"; import React, { FunctionComponent, useState } from "react";
import Lightbox from "react-images"; import Lightbox from 'react-images';
import Gallery from "react-photo-gallery"; import Gallery from "react-photo-gallery";
import * as GQL from "src/core/generated-graphql"; import * as GQL from "src/core/generated-graphql";
@@ -30,14 +30,15 @@ export const GalleryViewer: FunctionComponent<IProps> = ({ gallery }) => {
} }
const photos = gallery.files.map(file => ({ const photos = gallery.files.map(file => ({
src: file.path || "", src: file.path ?? '',
caption: file.name caption: file.name ?? ''
})); }));
const thumbs = gallery.files.map(file => ({ const thumbs = gallery.files.map(file => ({
src: `${file.path}?thumb=true` || "", src: `${file.path}?thumb=true` || "",
width: 1, width: 1,
height: 1 height: 1
})); }));
return ( return (
<div> <div>
<Gallery photos={thumbs} columns={15} onClick={openLightbox} /> <Gallery photos={thumbs} columns={15} onClick={openLightbox} />
@@ -47,8 +48,8 @@ export const GalleryViewer: FunctionComponent<IProps> = ({ gallery }) => {
onClickPrev={gotoPrevious} onClickPrev={gotoPrevious}
onClickNext={gotoNext} onClickNext={gotoNext}
currentImage={currentImage} currentImage={currentImage}
onClickImage={() => window.open(photos[currentImage].src ?? '', "_blank")}
isOpen={lightboxIsOpen} isOpen={lightboxIsOpen}
onClickImage={() => window.open(photos[currentImage].src, "_blank")}
width={9999} width={9999}
/> />
</div> </div>

View File

@@ -32,7 +32,7 @@ export const SettingsConfigurationPanel: React.FC = () => {
const { data, error, loading } = StashService.useConfiguration(); const { data, error, loading } = StashService.useConfiguration();
const updateGeneralConfig = StashService.useConfigureGeneral({ const [updateGeneralConfig] = StashService.useConfigureGeneral({
stashes, stashes,
databasePath, databasePath,
generatedPath, generatedPath,
@@ -55,11 +55,11 @@ export const SettingsConfigurationPanel: React.FC = () => {
setStashes(conf.general.stashes ?? []); setStashes(conf.general.stashes ?? []);
setDatabasePath(conf.general.databasePath); setDatabasePath(conf.general.databasePath);
setGeneratedPath(conf.general.generatedPath); setGeneratedPath(conf.general.generatedPath);
setMaxTranscodeSize(conf.general.maxTranscodeSize); setMaxTranscodeSize(conf.general.maxTranscodeSize ?? undefined);
setMaxStreamingTranscodeSize(conf.general.maxStreamingTranscodeSize); setMaxStreamingTranscodeSize(conf.general.maxStreamingTranscodeSize ?? undefined);
setUsername(conf.general.username); setUsername(conf.general.username);
setPassword(conf.general.password); setPassword(conf.general.password);
setLogFile(conf.general.logFile); setLogFile(conf.general.logFile ?? undefined);
setLogOut(conf.general.logOut); setLogOut(conf.general.logOut);
setLogLevel(conf.general.logLevel); setLogLevel(conf.general.logLevel);
setLogAccess(conf.general.logAccess); setLogAccess(conf.general.logAccess);

View File

@@ -14,7 +14,7 @@ export const SettingsInterfacePanel: React.FC = () => {
const [css, setCSS] = useState<string>(); const [css, setCSS] = useState<string>();
const [cssEnabled, setCSSEnabled] = useState<boolean>(); const [cssEnabled, setCSSEnabled] = useState<boolean>();
const updateInterfaceConfig = StashService.useConfigureInterface({ const [updateInterfaceConfig] = StashService.useConfigureInterface({
soundOnPreview, soundOnPreview,
wallShowTitle, wallShowTitle,
maximumLoopDuration, maximumLoopDuration,

View File

@@ -49,7 +49,7 @@ export const SettingsTasksPanel: React.FC = () => {
if (newProgress < 0) { if (newProgress < 0) {
setProgress(0); setProgress(0);
} else { } else {
setProgress(newProgress); setProgress(newProgress * 100);
} }
} }
}, [jobStatus]); }, [jobStatus]);
@@ -61,7 +61,7 @@ export const SettingsTasksPanel: React.FC = () => {
if (newProgress < 0) { if (newProgress < 0) {
setProgress(0); setProgress(0);
} else { } else {
setProgress(newProgress); setProgress(newProgress * 100);
} }
} }
}, [metadataUpdate]); }, [metadataUpdate]);

View File

@@ -24,9 +24,9 @@ interface IProps {
onImageChange: (event: React.FormEvent<HTMLInputElement>) => void; onImageChange: (event: React.FormEvent<HTMLInputElement>) => void;
// TODO: only for performers. make generic // TODO: only for performers. make generic
scrapers?: GQL.ListPerformerScrapersListPerformerScrapers[]; scrapers?: Pick<GQL.Scraper, 'id' | 'name'>[];
onDisplayScraperDialog?: ( onDisplayScraperDialog?: (
scraper: GQL.ListPerformerScrapersListPerformerScrapers scraper: Pick<GQL.Scraper, 'id' | 'name'>
) => void; ) => void;
} }
@@ -96,8 +96,7 @@ export const DetailsEditNavbar: React.FC<IProps> = (props: IProps) => {
<Button <Button
variant="link" variant="link"
onClick={() => onClick={() =>
props.onDisplayScraperDialog && props.onDisplayScraperDialog?.(s)
props.onDisplayScraperDialog(s)
} }
> >
{s.name} {s.name}

View File

@@ -8,9 +8,9 @@ import { StashService } from "src/core/StashService";
import { useToast } from "src/hooks"; import { useToast } from "src/hooks";
type ValidTypes = type ValidTypes =
| GQL.AllPerformersForFilterAllPerformers | GQL.SlimPerformerDataFragment
| GQL.AllTagsForFilterAllTags | GQL.Tag
| GQL.AllStudiosForFilterAllStudios; | GQL.SlimStudioDataFragment;
type Option = { value: string; label: string }; type Option = { value: string; label: string };
interface ITypeProps { interface ITypeProps {
@@ -41,7 +41,7 @@ interface ISceneGallerySelect {
initialId?: string; initialId?: string;
sceneId: string; sceneId: string;
onSelect: ( onSelect: (
item: GQL.ValidGalleriesForSceneValidGalleriesForScene | undefined item: GQL.ValidGalleriesForSceneQuery["validGalleriesForScene"][0] | undefined
) => void; ) => void;
} }
@@ -79,7 +79,7 @@ export const SceneGallerySelect: React.FC<ISceneGallerySelect> = props => {
interface IScrapePerformerSuggestProps { interface IScrapePerformerSuggestProps {
scraperId: string; scraperId: string;
onSelectPerformer: ( onSelectPerformer: (
query: GQL.ScrapePerformerListScrapePerformerList performer: GQL.ScrapedPerformerDataFragment
) => void; ) => void;
placeholder?: string; placeholder?: string;
} }
@@ -90,20 +90,25 @@ export const ScrapePerformerSuggest: React.FC<IScrapePerformerSuggestProps> = pr
query query
); );
const performers = data?.scrapePerformerList ?? [];
const items = performers.map(item => ({
label: item.name ?? "",
value: item.name ?? ""
}));
const onInputChange = useCallback( const onInputChange = useCallback(
debounce((input: string) => { debounce((input: string) => {
setQuery(input); setQuery(input);
}, 500), }, 500),
[] []
); );
const onChange = (selectedItems: ValueType<Option>) => const onChange = (selectedItems: ValueType<Option>) => {
props.onSelectPerformer(getSelectedValues(selectedItems)[0]); const name = getSelectedValues(selectedItems)[0];
const performer = performers.find(p => p.name === name);
if(performer)
props.onSelectPerformer(performer)
};
const performers = data?.scrapePerformerList ?? [];
const items = performers.map(item => ({
label: item.name ?? "",
value: item.name ?? ""
}));
return ( return (
<SelectComponent <SelectComponent
onChange={onChange} onChange={onChange}
@@ -214,7 +219,7 @@ export const TagSelect: React.FC<IFilterProps> = props => {
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
const [selectedIds, setSelectedIds] = useState<string[]>([]); const [selectedIds, setSelectedIds] = useState<string[]>([]);
const { data, loading: dataLoading } = StashService.useAllTagsForFilter(); const { data, loading: dataLoading } = StashService.useAllTagsForFilter();
const createTag = StashService.useTagCreate({ name: "" }); const [createTag] = StashService.useTagCreate({ name: "" });
const Toast = useToast(); const Toast = useToast();
const placeholder = props.noSelectionString ?? "Select tags..."; const placeholder = props.noSelectionString ?? "Select tags...";
@@ -234,10 +239,11 @@ export const TagSelect: React.FC<IFilterProps> = props => {
variables: { name: tagName } variables: { name: tagName }
}); });
if(result?.data?.tagCreate) {
setSelectedIds([...selectedIds, result.data.tagCreate.id]); setSelectedIds([...selectedIds, result.data.tagCreate.id]);
props.onSelect( props.onSelect(
[...tags, result.data.tagCreate].filter( [...tags, result.data.tagCreate].filter(
item => selected.indexOf(item.id) !== -1 item => selectedIds.indexOf(item.id) !== -1
) )
); );
setLoading(false); setLoading(false);
@@ -249,6 +255,7 @@ export const TagSelect: React.FC<IFilterProps> = props => {
</span> </span>
) )
}); });
}
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }

View File

@@ -31,25 +31,25 @@ export const Studio: React.FC = () => {
); );
const { data, error, loading } = StashService.useFindStudio(id); const { data, error, loading } = StashService.useFindStudio(id);
const updateStudio = StashService.useStudioUpdate( const [updateStudio] = StashService.useStudioUpdate(
getStudioInput() as GQL.StudioUpdateInput getStudioInput() as GQL.StudioUpdateInput
); );
const createStudio = StashService.useStudioCreate( const [createStudio] = StashService.useStudioCreate(
getStudioInput() as GQL.StudioCreateInput getStudioInput() as GQL.StudioCreateInput
); );
const deleteStudio = StashService.useStudioDestroy( const [deleteStudio] = StashService.useStudioDestroy(
getStudioInput() as GQL.StudioDestroyInput getStudioInput() as GQL.StudioDestroyInput
); );
function updateStudioEditState(state: Partial<GQL.StudioDataFragment>) { function updateStudioEditState(state: Partial<GQL.StudioDataFragment>) {
setName(state.name); setName(state.name);
setUrl(state.url); setUrl(state.url ?? undefined);
} }
function updateStudioData(studioData: Partial<GQL.StudioDataFragment>) { function updateStudioData(studioData: Partial<GQL.StudioDataFragment>) {
setImage(undefined); setImage(undefined);
updateStudioEditState(studioData); updateStudioEditState(studioData);
setImagePreview(studioData.image_path); setImagePreview(studioData.image_path ?? undefined);
setStudio(studioData); setStudio(studioData);
} }
@@ -57,7 +57,7 @@ export const Studio: React.FC = () => {
if (data && data.findStudio) { if (data && data.findStudio) {
setImage(undefined); setImage(undefined);
updateStudioEditState(data.findStudio); updateStudioEditState(data.findStudio);
setImagePreview(data.findStudio.image_path); setImagePreview(data.findStudio.image_path ?? undefined);
setStudio(data.findStudio); setStudio(data.findStudio);
} }
}, [data]); }, [data]);
@@ -92,10 +92,13 @@ export const Studio: React.FC = () => {
try { try {
if (!isNew) { if (!isNew) {
const result = await updateStudio(); const result = await updateStudio();
if (result.data?.studioUpdate) {
updateStudioData(result.data.studioUpdate); updateStudioData(result.data.studioUpdate);
setIsEditing(false); setIsEditing(false);
}
} else { } else {
const result = await createStudio(); const result = await createStudio();
if(result.data?.studioCreate?.id)
history.push(`/studios/${result.data.studioCreate.id}`); history.push(`/studios/${result.data.studioCreate.id}`);
} }
} catch (e) { } catch (e) {
@@ -169,7 +172,7 @@ export const Studio: React.FC = () => {
<tbody> <tbody>
{TableUtils.renderInputGroup({ {TableUtils.renderInputGroup({
title: "URL", title: "URL",
value: studio.url, value: studio.url ?? undefined,
isEditing, isEditing,
onChange: (val: string) => setUrl(val) onChange: (val: string) => setUrl(val)
})} })}

View File

@@ -1,8 +1,6 @@
import React from "react"; import React from "react";
import { QueryHookResult } from "react-apollo-hooks";
import { import {
FindStudiosQuery, FindStudiosQueryResult
FindStudiosVariables
} from "src/core/generated-graphql"; } from "src/core/generated-graphql";
import { useStudiosList } from "src/hooks"; import { useStudiosList } from "src/hooks";
import { ListFilterModel } from "src/models/list-filter/filter"; import { ListFilterModel } from "src/models/list-filter/filter";
@@ -15,7 +13,7 @@ export const StudioList: React.FC = () => {
}); });
function renderContent( function renderContent(
result: QueryHookResult<FindStudiosQuery, FindStudiosVariables>, result: FindStudiosQueryResult,
filter: ListFilterModel filter: ListFilterModel
) { ) {
if (!result.data || !result.data.findStudios) { if (!result.data || !result.data.findStudios) {

View File

@@ -19,13 +19,13 @@ export const TagList: React.FC = () => {
> | null>(null); > | null>(null);
const { data, error } = StashService.useAllTags(); const { data, error } = StashService.useAllTags();
const updateTag = StashService.useTagUpdate( const [updateTag] = StashService.useTagUpdate(
getTagInput() as GQL.TagUpdateInput getTagInput() as GQL.TagUpdateInput
); );
const createTag = StashService.useTagCreate( const [createTag] = StashService.useTagCreate(
getTagInput() as GQL.TagCreateInput getTagInput() as GQL.TagCreateInput
); );
const deleteTag = StashService.useTagDestroy( const [deleteTag] = StashService.useTagDestroy(
getDeleteTagInput() as GQL.TagDestroyInput getDeleteTagInput() as GQL.TagDestroyInput
); );

View File

@@ -22,84 +22,70 @@ export const Performer: React.FC = () => {
// Editing state // Editing state
const [isEditing, setIsEditing] = useState<boolean>(isNew); const [isEditing, setIsEditing] = useState<boolean>(isNew);
const [isDisplayingScraperDialog, setIsDisplayingScraperDialog] = useState< const [isDisplayingScraperDialog, setIsDisplayingScraperDialog] = useState<GQL.Scraper>();
GQL.ListPerformerScrapersListPerformerScrapers | undefined const [scrapePerformerDetails, setScrapePerformerDetails] = useState<GQL.ScrapedPerformerDataFragment>();
>(undefined);
const [scrapePerformerDetails, setScrapePerformerDetails] = useState<
GQL.ScrapePerformerListScrapePerformerList | undefined
>(undefined);
// Editing performer state // Editing performer state
const [image, setImage] = useState<string | undefined>(undefined); const [image, setImage] = useState<string>();
const [name, setName] = useState<string | undefined>(undefined); const [name, setName] = useState<string>();
const [aliases, setAliases] = useState<string | undefined>(undefined); const [aliases, setAliases] = useState<string>();
const [favorite, setFavorite] = useState<boolean | undefined>(undefined); const [favorite, setFavorite] = useState<boolean>();
const [birthdate, setBirthdate] = useState<string | undefined>(undefined); const [birthdate, setBirthdate] = useState<string>();
const [ethnicity, setEthnicity] = useState<string | undefined>(undefined); const [ethnicity, setEthnicity] = useState<string>();
const [country, setCountry] = useState<string | undefined>(undefined); const [country, setCountry] = useState<string>();
const [eyeColor, setEyeColor] = useState<string | undefined>(undefined); const [eyeColor, setEyeColor] = useState<string>();
const [height, setHeight] = useState<string | undefined>(undefined); const [height, setHeight] = useState<string>();
const [measurements, setMeasurements] = useState<string | undefined>( const [measurements, setMeasurements] = useState<string>();
undefined const [fakeTits, setFakeTits] = useState<string>();
); const [careerLength, setCareerLength] = useState<string>();
const [fakeTits, setFakeTits] = useState<string | undefined>(undefined); const [tattoos, setTattoos] = useState<string>();
const [careerLength, setCareerLength] = useState<string | undefined>( const [piercings, setPiercings] = useState<string>();
undefined const [url, setUrl] = useState<string>();
); const [twitter, setTwitter] = useState<string>();
const [tattoos, setTattoos] = useState<string | undefined>(undefined); const [instagram, setInstagram] = useState<string>();
const [piercings, setPiercings] = useState<string | undefined>(undefined);
const [url, setUrl] = useState<string | undefined>(undefined);
const [twitter, setTwitter] = useState<string | undefined>(undefined);
const [instagram, setInstagram] = useState<string | undefined>(undefined);
// Performer state // Performer state
const [performer, setPerformer] = useState< const [performer, setPerformer] = useState<Partial<GQL.PerformerDataFragment>>({});
Partial<GQL.PerformerDataFragment> const [imagePreview, setImagePreview] = useState<string>();
>({});
const [imagePreview, setImagePreview] = useState<string | undefined>(
undefined
);
// Network state // Network state
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const Scrapers = StashService.useListPerformerScrapers(); const Scrapers = StashService.useListPerformerScrapers();
const [queryableScrapers, setQueryableScrapers] = useState< const [queryableScrapers, setQueryableScrapers] = useState<GQL.Scraper[]>([]);
GQL.ListPerformerScrapersListPerformerScrapers[]
>([]);
const { data, error } = StashService.useFindPerformer(id); const { data, error } = StashService.useFindPerformer(id);
const updatePerformer = StashService.usePerformerUpdate( const [updatePerformer] = StashService.usePerformerUpdate(
getPerformerInput() as GQL.PerformerUpdateInput getPerformerInput() as GQL.PerformerUpdateInput
); );
const createPerformer = StashService.usePerformerCreate( const [createPerformer] = StashService.usePerformerCreate(
getPerformerInput() as GQL.PerformerCreateInput getPerformerInput() as GQL.PerformerCreateInput
); );
const deletePerformer = StashService.usePerformerDestroy( const [deletePerformer] = StashService.usePerformerDestroy(
getPerformerInput() as GQL.PerformerDestroyInput getPerformerInput() as GQL.PerformerDestroyInput
); );
function updatePerformerEditState( function updatePerformerEditState(
state: Partial<GQL.PerformerDataFragment | GQL.ScrapeFreeonesScrapeFreeones> state: Partial<GQL.PerformerDataFragment | GQL.ScrapedPerformer>
) { ) {
if ((state as GQL.PerformerDataFragment).favorite !== undefined) { if ((state as GQL.PerformerDataFragment).favorite !== undefined) {
setFavorite((state as GQL.PerformerDataFragment).favorite); setFavorite((state as GQL.PerformerDataFragment).favorite);
} }
setName(state.name); setName(state.name ?? undefined);
setAliases(state.aliases); setAliases(state.aliases ?? undefined);
setBirthdate(state.birthdate); setBirthdate(state.birthdate ?? undefined);
setEthnicity(state.ethnicity); setEthnicity(state.ethnicity ?? undefined);
setCountry(state.country); setCountry(state.country ?? undefined);
setEyeColor(state.eye_color); setEyeColor(state.eye_color ?? undefined);
setHeight(state.height); setHeight(state.height ?? undefined);
setMeasurements(state.measurements); setMeasurements(state.measurements ?? undefined);
setFakeTits(state.fake_tits); setFakeTits(state.fake_tits ?? undefined);
setCareerLength(state.career_length); setCareerLength(state.career_length ?? undefined);
setTattoos(state.tattoos); setTattoos(state.tattoos ?? undefined);
setPiercings(state.piercings); setPiercings(state.piercings ?? undefined);
setUrl(state.url); setUrl(state.url ?? undefined);
setTwitter(state.twitter); setTwitter(state.twitter ?? undefined);
setInstagram(state.instagram); setInstagram(state.instagram ?? undefined);
} }
useEffect(() => { useEffect(() => {
@@ -108,9 +94,10 @@ export const Performer: React.FC = () => {
}, [data]); }, [data]);
useEffect(() => { useEffect(() => {
setImagePreview(performer.image_path); setImagePreview(performer.image_path ?? undefined);
setImage(undefined); setImage(undefined);
updatePerformerEditState(performer); updatePerformerEditState(performer);
if (!isNew)
setIsEditing(false); setIsEditing(false);
}, [performer]); }, [performer]);
@@ -122,19 +109,12 @@ export const Performer: React.FC = () => {
ImageUtils.usePasteImage(onImageLoad); ImageUtils.usePasteImage(onImageLoad);
useEffect(() => { useEffect(() => {
let newQueryableScrapers: GQL.ListPerformerScrapersListPerformerScrapers[] = []; const newQueryableScrapers = (Scrapers?.data?.listPerformerScrapers ?? []).filter(s => (
s.performer?.supported_scrapes.includes(GQL.ScrapeType.Name)
if (!!Scrapers.data && Scrapers.data.listPerformerScrapers) { ));
newQueryableScrapers = Scrapers.data.listPerformerScrapers.filter(s => {
return (
s.performer &&
s.performer.supported_scrapes.includes(GQL.ScrapeType.Name)
);
});
}
setQueryableScrapers(newQueryableScrapers); setQueryableScrapers(newQueryableScrapers);
}, [Scrapers.data]); }, [Scrapers]);
if ((!isNew && !isEditing && !data?.findPerformer) || isLoading) if ((!isNew && !isEditing && !data?.findPerformer) || isLoading)
return <Spinner animation="border" variant="light" />; return <Spinner animation="border" variant="light" />;
@@ -174,12 +154,15 @@ export const Performer: React.FC = () => {
try { try {
if (!isNew) { if (!isNew) {
const result = await updatePerformer(); const result = await updatePerformer();
setPerformer(result.data.performerUpdate); if(result.data?.performerUpdate)
setPerformer(result.data?.performerUpdate);
} else { } else {
const result = await createPerformer(); const result = await createPerformer();
if(result.data?.performerCreate) {
setPerformer(result.data.performerCreate); setPerformer(result.data.performerCreate);
history.push(`/performers/${result.data.performerCreate.id}`); history.push(`/performers/${result.data.performerCreate.id}`);
} }
}
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }
@@ -200,7 +183,7 @@ export const Performer: React.FC = () => {
} }
async function onAutoTag() { async function onAutoTag() {
if (!performer || !performer.id) { if (!performer.id) {
return; return;
} }
try { try {
@@ -216,7 +199,7 @@ export const Performer: React.FC = () => {
} }
function onDisplayFreeOnesDialog( function onDisplayFreeOnesDialog(
scraper: GQL.ListPerformerScrapersListPerformerScrapers scraper: GQL.Scraper
) { ) {
setIsDisplayingScraperDialog(scraper); setIsDisplayingScraperDialog(scraper);
} }
@@ -225,6 +208,7 @@ export const Performer: React.FC = () => {
if (!scrapePerformerDetails) return {}; if (!scrapePerformerDetails) return {};
const { __typename, ...ret } = scrapePerformerDetails; const { __typename, ...ret } = scrapePerformerDetails;
debugger;
return ret; return ret;
} }

View File

@@ -1,10 +1,8 @@
import _ from "lodash"; import _ from "lodash";
import React from "react"; import React from "react";
import { QueryHookResult } from "react-apollo-hooks";
import { useHistory } from "react-router-dom"; import { useHistory } from "react-router-dom";
import { import {
FindPerformersQuery, FindPerformersQueryResult,
FindPerformersVariables
} from "src/core/generated-graphql"; } from "src/core/generated-graphql";
import { StashService } from "src/core/StashService"; import { StashService } from "src/core/StashService";
import { usePerformersList } from "src/hooks"; import { usePerformersList } from "src/hooks";
@@ -28,7 +26,7 @@ export const PerformerList: React.FC = () => {
}); });
async function getRandom( async function getRandom(
result: QueryHookResult<FindPerformersQuery, FindPerformersVariables>, result: FindPerformersQueryResult,
filter: ListFilterModel filter: ListFilterModel
) { ) {
if (result.data && result.data.findPerformers) { if (result.data && result.data.findPerformers) {
@@ -51,7 +49,7 @@ export const PerformerList: React.FC = () => {
} }
function renderContent( function renderContent(
result: QueryHookResult<FindPerformersQuery, FindPerformersVariables>, result: FindPerformersQueryResult,
filter: ListFilterModel filter: ListFilterModel
) { ) {
if (!result.data || !result.data.findPerformers) { if (!result.data || !result.data.findPerformers) {

View File

@@ -18,16 +18,13 @@ interface ISceneCardProps {
export const SceneCard: React.FC<ISceneCardProps> = ( export const SceneCard: React.FC<ISceneCardProps> = (
props: ISceneCardProps props: ISceneCardProps
) => { ) => {
const [previewPath, setPreviewPath] = useState<string | undefined>(undefined); const [previewPath, setPreviewPath] = useState<string>();
const videoHoverHook = VideoHoverHook.useVideoHover({ const videoHoverHook = VideoHoverHook.useVideoHover({
resetOnMouseLeave: false resetOnMouseLeave: false
}); });
const config = StashService.useConfiguration(); const config = StashService.useConfiguration();
const showStudioAsText = const showStudioAsText = config?.data?.configuration.interface.showStudioAsText ?? false;
!!config.data && !!config.data.configuration
? config.data.configuration.interface.showStudioAsText
: false;
function maybeRenderRatingBanner() { function maybeRenderRatingBanner() {
if (!props.scene.rating) { if (!props.scene.rating) {
@@ -55,9 +52,8 @@ export const SceneCard: React.FC<ISceneCardProps> = (
) : ( ) : (
"" ""
)} )}
{props.scene.file.duration !== undefined && { (props.scene.file.duration ?? 0) >= 1
props.scene.file.duration >= 1 ? TextUtils.secondsToTimestamp(props.scene.file.duration ?? 0)
? TextUtils.secondsToTimestamp(props.scene.file.duration)
: ""} : ""}
</div> </div>
); );
@@ -225,7 +221,7 @@ export const SceneCard: React.FC<ISceneCardProps> = (
: TextUtils.fileNameFromPath(props.scene.path)} : TextUtils.fileNameFromPath(props.scene.path)}
</h4> </h4>
<span>{props.scene.date}</span> <span>{props.scene.date}</span>
<p>{TextUtils.truncate(props.scene.details, 100, "... (continued)")}</p> <p>{TextUtils.truncate(props.scene.details ?? "", 100, "... (continued)")}</p>
</div> </div>
{maybeRenderPopoverButtonGroup()} {maybeRenderPopoverButtonGroup()}

View File

@@ -29,52 +29,40 @@ interface IProps {
export const SceneEditPanel: React.FC<IProps> = (props: IProps) => { export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
const Toast = useToast(); const Toast = useToast();
const [title, setTitle] = useState<string | undefined>(undefined); const [title, setTitle] = useState<string>();
const [details, setDetails] = useState<string | undefined>(undefined); const [details, setDetails] = useState<string>();
const [url, setUrl] = useState<string | undefined>(undefined); const [url, setUrl] = useState<string>();
const [date, setDate] = useState<string | undefined>(undefined); const [date, setDate] = useState<string>();
const [rating, setRating] = useState<number | undefined>(undefined); const [rating, setRating] = useState<number>();
const [galleryId, setGalleryId] = useState<string | undefined>(undefined); const [galleryId, setGalleryId] = useState<string>();
const [studioId, setStudioId] = useState<string | undefined>(undefined); const [studioId, setStudioId] = useState<string>();
const [performerIds, setPerformerIds] = useState<string[] | undefined>( const [performerIds, setPerformerIds] = useState<string[]>();
undefined const [tagIds, setTagIds] = useState<string[]>();
); const [coverImage, setCoverImage] = useState<string>();
const [tagIds, setTagIds] = useState<string[] | undefined>(undefined);
const [coverImage, setCoverImage] = useState<string | undefined>(undefined);
const Scrapers = StashService.useListSceneScrapers(); const Scrapers = StashService.useListSceneScrapers();
const [queryableScrapers, setQueryableScrapers] = useState< const [queryableScrapers, setQueryableScrapers] = useState<GQL.Scraper[]>([]);
GQL.ListSceneScrapersListSceneScrapers[]
>([]);
const [isDeleteAlertOpen, setIsDeleteAlertOpen] = useState<boolean>(false); const [isDeleteAlertOpen, setIsDeleteAlertOpen] = useState<boolean>(false);
const [deleteFile, setDeleteFile] = useState<boolean>(false); const [deleteFile, setDeleteFile] = useState<boolean>(false);
const [deleteGenerated, setDeleteGenerated] = useState<boolean>(true); const [deleteGenerated, setDeleteGenerated] = useState<boolean>(true);
const [isCoverImageOpen, setIsCoverImageOpen] = useState<boolean>(false); const [isCoverImageOpen, setIsCoverImageOpen] = useState<boolean>(false);
const [coverImagePreview, setCoverImagePreview] = useState< const [coverImagePreview, setCoverImagePreview] = useState<string>();
string | undefined
>(undefined);
// Network state // Network state
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const updateScene = StashService.useSceneUpdate(getSceneInput()); const [updateScene] = StashService.useSceneUpdate(getSceneInput());
const deleteScene = StashService.useSceneDestroy(getSceneDeleteInput()); const [deleteScene] = StashService.useSceneDestroy(getSceneDeleteInput());
useEffect(() => { useEffect(() => {
let newQueryableScrapers: GQL.ListSceneScrapersListSceneScrapers[] = []; const newQueryableScrapers = (Scrapers?.data?.listSceneScrapers ?? []).filter(s => (
s.scene?.supported_scrapes.includes(GQL.ScrapeType.Fragment)
if (!!Scrapers.data && Scrapers.data.listSceneScrapers) { ));
newQueryableScrapers = Scrapers.data.listSceneScrapers.filter(s => {
return (
s.scene && s.scene.supported_scrapes.includes(GQL.ScrapeType.Fragment)
);
});
}
setQueryableScrapers(newQueryableScrapers); setQueryableScrapers(newQueryableScrapers);
}, [Scrapers.data]); }, [Scrapers]);
function updateSceneEditState(state: Partial<GQL.SceneDataFragment>) { function updateSceneEditState(state: Partial<GQL.SceneDataFragment>) {
const perfIds = state.performers const perfIds = state.performers
@@ -82,20 +70,20 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
: undefined; : undefined;
const tIds = state.tags ? state.tags.map(tag => tag.id) : undefined; const tIds = state.tags ? state.tags.map(tag => tag.id) : undefined;
setTitle(state.title); setTitle(state.title ?? undefined);
setDetails(state.details); setDetails(state.details ?? undefined);
setUrl(state.url); setUrl(state.url ?? undefined);
setDate(state.date); setDate(state.date ?? undefined);
setRating(state.rating === null ? NaN : state.rating); setRating(state.rating === null ? NaN : state.rating);
setGalleryId(state.gallery ? state.gallery.id : undefined); setGalleryId(state?.gallery?.id ?? undefined);
setStudioId(state.studio ? state.studio.id : undefined); setStudioId(state?.studio?.id ?? undefined);
setPerformerIds(perfIds); setPerformerIds(perfIds);
setTagIds(tIds); setTagIds(tIds);
} }
useEffect(() => { useEffect(() => {
updateSceneEditState(props.scene); updateSceneEditState(props.scene);
setCoverImagePreview(props.scene.paths.screenshot); setCoverImagePreview(props.scene?.paths?.screenshot ?? undefined);
}, [props.scene]); }, [props.scene]);
ImageUtils.usePasteImage(onImageLoad); ImageUtils.usePasteImage(onImageLoad);
@@ -120,8 +108,10 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
setIsLoading(true); setIsLoading(true);
try { try {
const result = await updateScene(); const result = await updateScene();
if(result.data?.sceneUpdate) {
props.onUpdate(result.data.sceneUpdate); props.onUpdate(result.data.sceneUpdate);
Toast.success({ content: "Updated scene" }); Toast.success({ content: "Updated scene" });
}
} catch (e) { } catch (e) {
Toast.error(e); Toast.error(e);
} }
@@ -213,7 +203,7 @@ export const SceneEditPanel: React.FC<IProps> = (props: IProps) => {
} }
async function onScrapeClicked( async function onScrapeClicked(
scraper: GQL.ListSceneScrapersListSceneScrapers scraper: GQL.Scraper
) { ) {
setIsLoading(true); setIsLoading(true);
try { try {

View File

@@ -38,7 +38,7 @@ export const SceneFileInfoPanel: React.FC<ISceneFileInfoPanelProps> = (
<tr> <tr>
<td>Stream</td> <td>Stream</td>
<td> <td>
<a href={props.scene.paths.stream}>{props.scene.paths.stream}</a>{" "} <a href={props.scene.paths.stream ?? ''}>{props.scene.paths.stream}</a>{" "}
</td> </td>
</tr> </tr>
); );
@@ -51,7 +51,7 @@ export const SceneFileInfoPanel: React.FC<ISceneFileInfoPanelProps> = (
return ( return (
<tr> <tr>
<td>File Size</td> <td>File Size</td>
<td>{TextUtils.fileSize(parseInt(props.scene.file.size, 10))}</td> <td>{TextUtils.fileSize(parseInt(props.scene.file.size ?? '0', 10))}</td>
</tr> </tr>
); );
} }
@@ -63,7 +63,7 @@ export const SceneFileInfoPanel: React.FC<ISceneFileInfoPanelProps> = (
return ( return (
<tr> <tr>
<td>Duration</td> <td>Duration</td>
<td>{TextUtils.secondsToTimestamp(props.scene.file.duration)}</td> <td>{TextUtils.secondsToTimestamp(props.scene.file.duration ?? 0)}</td>
</tr> </tr>
); );
} }
@@ -101,7 +101,7 @@ export const SceneFileInfoPanel: React.FC<ISceneFileInfoPanelProps> = (
return ( return (
<tr> <tr>
<td>Bit Rate</td> <td>Bit Rate</td>
<td>{TextUtils.bitRate(props.scene.file.bitrate)}</td> <td>{TextUtils.bitRate(props.scene.file.bitrate ?? 0)}</td>
</tr> </tr>
); );
} }

View File

@@ -41,9 +41,9 @@ export const SceneMarkersPanel: React.FC<ISceneMarkersPanelProps> = (
setEditingMarker setEditingMarker
] = useState<GQL.SceneMarkerDataFragment | null>(null); ] = useState<GQL.SceneMarkerDataFragment | null>(null);
const sceneMarkerCreate = StashService.useSceneMarkerCreate(); const [sceneMarkerCreate] = StashService.useSceneMarkerCreate();
const sceneMarkerUpdate = StashService.useSceneMarkerUpdate(); const [sceneMarkerUpdate] = StashService.useSceneMarkerUpdate();
const sceneMarkerDestroy = StashService.useSceneMarkerDestroy(); const [sceneMarkerDestroy] = StashService.useSceneMarkerDestroy();
const jwplayer = SceneHelpers.getPlayer(); const jwplayer = SceneHelpers.getPlayer();
@@ -57,7 +57,7 @@ export const SceneMarkersPanel: React.FC<ISceneMarkersPanelProps> = (
} }
function renderTags() { function renderTags() {
function renderMarkers(primaryTag: GQL.FindSceneSceneMarkerTags) { function renderMarkers(primaryTag: GQL.SceneMarkerTag) {
const markers = primaryTag.scene_markers.map(marker => { const markers = primaryTag.scene_markers.map(marker => {
const markerTags = marker.tags.map(tag => ( const markerTags = marker.tags.map(tag => (
<Badge key={tag.id} variant="secondary" className="tag-item"> <Badge key={tag.id} variant="secondary" className="tag-item">
@@ -102,7 +102,7 @@ export const SceneMarkersPanel: React.FC<ISceneMarkersPanelProps> = (
flex: "0 0 auto" flex: "0 0 auto"
}; };
const tags = (props.scene as any).scene_marker_tags.map( const tags = (props.scene as any).scene_marker_tags.map(
(primaryTag: GQL.FindSceneSceneMarkerTags) => { (primaryTag: GQL.SceneMarkerTag) => {
return ( return (
<div key={primaryTag.tag.id} style={{ padding: "1px" }}> <div key={primaryTag.tag.id} style={{ padding: "1px" }}>
<Card style={style}> <Card style={style}>
@@ -122,8 +122,8 @@ export const SceneMarkersPanel: React.FC<ISceneMarkersPanelProps> = (
function onSubmit(values: IFormFields) { function onSubmit(values: IFormFields) {
const isEditing = !!editingMarker; const isEditing = !!editingMarker;
const variables: const variables:
| GQL.SceneMarkerCreateVariables | GQL.SceneMarkerUpdateInput
| GQL.SceneMarkerUpdateVariables = { | GQL.SceneMarkerCreateInput = {
title: values.title, title: values.title,
seconds: parseFloat(values.seconds), seconds: parseFloat(values.seconds),
scene_id: props.scene.id, scene_id: props.scene.id,
@@ -138,7 +138,7 @@ export const SceneMarkersPanel: React.FC<ISceneMarkersPanelProps> = (
}) })
.catch(err => Toast.error(err)); .catch(err => Toast.error(err));
} else { } else {
const updateVariables = variables as GQL.SceneMarkerUpdateVariables; const updateVariables = variables as GQL.SceneMarkerUpdateInput;
updateVariables.id = editingMarker!.id; updateVariables.id = editingMarker!.id;
sceneMarkerUpdate({ variables: updateVariables }) sceneMarkerUpdate({ variables: updateVariables })
.then(() => { .then(() => {
@@ -178,7 +178,7 @@ export const SceneMarkersPanel: React.FC<ISceneMarkersPanelProps> = (
Math.round(jwplayer.getPosition()) Math.round(jwplayer.getPosition())
) )
} }
numericValue={fieldProps.field.value} numericValue={Number.parseInt(fieldProps.field.value.seconds, 10)}
/> />
); );
} }

View File

@@ -13,7 +13,7 @@ export const ScenePerformerPanel: FunctionComponent<IScenePerformerPanelProps> =
<PerformerCard <PerformerCard
key={performer.id} key={performer.id}
performer={performer} performer={performer}
ageFromDate={props.scene.date} ageFromDate={props.scene.date ?? undefined}
/> />
)); ));

View File

@@ -21,8 +21,8 @@ import { useToast } from "src/hooks";
import { Pagination } from "../list/Pagination"; import { Pagination } from "../list/Pagination";
class ParserResult<T> { class ParserResult<T> {
public value: GQL.Maybe<T>; public value: GQL.Maybe<T> = null;
public originalValue: GQL.Maybe<T>; public originalValue: GQL.Maybe<T> = null;
public set: boolean = false; public set: boolean = false;
public setOriginalValue(v: GQL.Maybe<T>) { public setOriginalValue(v: GQL.Maybe<T>) {
@@ -110,60 +110,52 @@ class SceneParserResult {
public title: ParserResult<string> = new ParserResult(); public title: ParserResult<string> = new ParserResult();
public date: ParserResult<string> = new ParserResult(); public date: ParserResult<string> = new ParserResult();
public studio: ParserResult<GQL.SlimSceneDataStudio> = new ParserResult(); public studio: ParserResult<Partial<GQL.Studio>> = new ParserResult();
public studioId: ParserResult<string> = new ParserResult(); public studioId: ParserResult<string> = new ParserResult();
public tags: ParserResult<GQL.SlimSceneDataTags[]> = new ParserResult(); public tags: ParserResult<GQL.Tag[]> = new ParserResult();
public tagIds: ParserResult<string[]> = new ParserResult(); public tagIds: ParserResult<string[]> = new ParserResult();
public performers: ParserResult< public performers: ParserResult<Partial<GQL.Performer>[]> = new ParserResult();
GQL.SlimSceneDataPerformers[]
> = new ParserResult();
public performerIds: ParserResult<string[]> = new ParserResult(); public performerIds: ParserResult<string[]> = new ParserResult();
public scene: GQL.SlimSceneDataFragment; public scene: GQL.SlimSceneDataFragment;
constructor(result: GQL.ParseSceneFilenamesResults) { constructor(result: GQL.ParseSceneFilenamesQuery["parseSceneFilenames"]["results"][0]) {
this.scene = result.scene; this.scene = result.scene;
this.id = this.scene.id; this.id = this.scene.id;
this.filename = TextUtils.fileNameFromPath(this.scene.path); this.filename = TextUtils.fileNameFromPath(this.scene.path);
this.title.setOriginalValue(this.scene.title); this.title.setOriginalValue(this.scene.title ?? null);
this.date.setOriginalValue(this.scene.date); this.date.setOriginalValue(this.scene.date ?? null);
this.performerIds.setOriginalValue(this.scene.performers.map(p => p.id)); this.performerIds.setOriginalValue(this.scene.performers.map(p => p.id));
this.performers.setOriginalValue(this.scene.performers); this.performers.setOriginalValue(this.scene.performers);
this.tagIds.setOriginalValue(this.scene.tags.map(t => t.id)); this.tagIds.setOriginalValue(this.scene.tags.map(t => t.id));
this.tags.setOriginalValue(this.scene.tags); this.tags.setOriginalValue(this.scene.tags);
this.studioId.setOriginalValue( this.studioId.setOriginalValue(this.scene.studio?.id ?? null);
this.scene.studio ? this.scene.studio.id : undefined this.studio.setOriginalValue(this.scene.studio ?? null);
);
this.studio.setOriginalValue(this.scene.studio);
this.title.setValue(result.title); this.title.setValue(result.title ?? null);
this.date.setValue(result.date); this.date.setValue(result.date ?? null);
this.performerIds.setValue(result.performer_ids); this.performerIds.setValue(result.performer_ids ?? []);
this.tagIds.setValue(result.tag_ids); this.tagIds.setValue(result.tag_ids ?? []);
this.studioId.setValue(result.studio_id); this.studioId.setValue(result.studio_id ?? null);
if (result.performer_ids) { if (result.performer_ids) {
this.performers.setValue( this.performers.setValue(
result.performer_ids.map(p => { (result.performer_ids ?? []).map(p => ({
return {
id: p, id: p,
name: "", name: "",
favorite: false, favorite: false,
image_path: "" image_path: ""
}; } as GQL.Performer))
})
); );
} }
if (result.tag_ids) { if (result.tag_ids) {
this.tags.setValue( this.tags.setValue(
result.tag_ids.map(t => { result.tag_ids.map(t => ({
return {
id: t, id: t,
name: "" name: ""
}; }))
})
); );
} }
@@ -172,7 +164,7 @@ class SceneParserResult {
id: result.studio_id, id: result.studio_id,
name: "", name: "",
image_path: "" image_path: ""
}); } as GQL.Studio);
} }
} }
@@ -324,7 +316,7 @@ export const SceneFilenameParser: React.FC = () => {
// Network state // Network state
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const updateScenes = StashService.useScenesUpdate(getScenesUpdateData()); const [updateScenes] = StashService.useScenesUpdate(getScenesUpdateData());
const determineFieldsToHide = useCallback(() => { const determineFieldsToHide = useCallback(() => {
const { pattern } = parserInput; const { pattern } = parserInput;
@@ -351,7 +343,7 @@ export const SceneFilenameParser: React.FC = () => {
}, [parserInput]); }, [parserInput]);
const parseResults = useCallback( const parseResults = useCallback(
(results: GQL.ParseSceneFilenamesResults[]) => { (results: GQL.ParseSceneFilenamesQuery["parseSceneFilenames"]["results"]) => {
if (results) { if (results) {
const result = results const result = results
.map(r => { .map(r => {
@@ -905,7 +897,7 @@ export const SceneFilenameParser: React.FC = () => {
fieldName="Title" fieldName="Title"
className="parser-field-title" className="parser-field-title"
parserResult={props.scene.title} parserResult={props.scene.title}
onSetChanged={set => onTitleChanged(set, props.scene.title.value)} onSetChanged={set => onTitleChanged(set, props.scene.title.value ?? undefined)}
onValueChanged={value => onTitleChanged(props.scene.title.set, value)} onValueChanged={value => onTitleChanged(props.scene.title.set, value)}
renderOriginalInputField={renderOriginalInputGroup} renderOriginalInputField={renderOriginalInputGroup}
renderNewInputField={renderNewInputGroup} renderNewInputField={renderNewInputGroup}
@@ -915,7 +907,7 @@ export const SceneFilenameParser: React.FC = () => {
fieldName="Date" fieldName="Date"
className="parser-field-date" className="parser-field-date"
parserResult={props.scene.date} parserResult={props.scene.date}
onSetChanged={set => onDateChanged(set, props.scene.date.value)} onSetChanged={set => onDateChanged(set, props.scene.date.value ?? undefined)}
onValueChanged={value => onDateChanged(props.scene.date.set, value)} onValueChanged={value => onDateChanged(props.scene.date.set, value)}
renderOriginalInputField={renderOriginalInputGroup} renderOriginalInputField={renderOriginalInputGroup}
renderNewInputField={renderNewInputGroup} renderNewInputField={renderNewInputGroup}
@@ -927,7 +919,7 @@ export const SceneFilenameParser: React.FC = () => {
parserResult={props.scene.performerIds} parserResult={props.scene.performerIds}
originalParserResult={props.scene.performers} originalParserResult={props.scene.performers}
onSetChanged={set => onSetChanged={set =>
onPerformerIdsChanged(set, props.scene.performerIds.value) onPerformerIdsChanged(set, props.scene.performerIds.value ?? undefined)
} }
onValueChanged={value => onValueChanged={value =>
onPerformerIdsChanged(props.scene.performerIds.set, value) onPerformerIdsChanged(props.scene.performerIds.set, value)
@@ -941,7 +933,7 @@ export const SceneFilenameParser: React.FC = () => {
className="parser-field-tags" className="parser-field-tags"
parserResult={props.scene.tagIds} parserResult={props.scene.tagIds}
originalParserResult={props.scene.tags} originalParserResult={props.scene.tags}
onSetChanged={set => onTagIdsChanged(set, props.scene.tagIds.value)} onSetChanged={set => onTagIdsChanged(set, props.scene.tagIds.value ?? undefined)}
onValueChanged={value => onValueChanged={value =>
onTagIdsChanged(props.scene.tagIds.set, value) onTagIdsChanged(props.scene.tagIds.set, value)
} }
@@ -955,7 +947,7 @@ export const SceneFilenameParser: React.FC = () => {
parserResult={props.scene.studioId} parserResult={props.scene.studioId}
originalParserResult={props.scene.studio} originalParserResult={props.scene.studio}
onSetChanged={set => onSetChanged={set =>
onStudioIdChanged(set, props.scene.studioId.value) onStudioIdChanged(set, props.scene.studioId.value ?? undefined)
} }
onValueChanged={value => onValueChanged={value =>
onStudioIdChanged(props.scene.studioId.set, value) onStudioIdChanged(props.scene.studioId.set, value)

View File

@@ -1,10 +1,8 @@
import React from "react"; import React from "react";
import _ from "lodash"; import _ from "lodash";
import { QueryHookResult } from "react-apollo-hooks";
import { useHistory } from "react-router-dom"; import { useHistory } from "react-router-dom";
import { import {
FindScenesQuery, FindScenesQueryResult,
FindScenesVariables,
SlimSceneDataFragment SlimSceneDataFragment
} from "src/core/generated-graphql"; } from "src/core/generated-graphql";
import { StashService } from "src/core/StashService"; import { StashService } from "src/core/StashService";
@@ -33,7 +31,7 @@ export const SceneList: React.FC = () => {
}); });
async function playRandom( async function playRandom(
result: QueryHookResult<FindScenesQuery, FindScenesVariables>, result: FindScenesQueryResult,
filter: ListFilterModel filter: ListFilterModel
) { ) {
// query for a random scene // query for a random scene
@@ -59,7 +57,7 @@ export const SceneList: React.FC = () => {
} }
function renderSelectedOptions( function renderSelectedOptions(
result: QueryHookResult<FindScenesQuery, FindScenesVariables>, result: FindScenesQueryResult,
selectedIds: Set<string> selectedIds: Set<string>
) { ) {
// find the selected items from the ids // find the selected items from the ids
@@ -107,7 +105,7 @@ export const SceneList: React.FC = () => {
} }
function renderContent( function renderContent(
result: QueryHookResult<FindScenesQuery, FindScenesVariables>, result: FindScenesQueryResult,
filter: ListFilterModel, filter: ListFilterModel,
selectedIds: Set<string>, selectedIds: Set<string>,
zoomIndex: number zoomIndex: number

View File

@@ -34,10 +34,10 @@ export const SceneListTable: React.FC<ISceneListTableProps> = (
if (scene.file.duration === undefined) { if (scene.file.duration === undefined) {
return; return;
} }
return TextUtils.secondsToTimestamp(scene.file.duration); return TextUtils.secondsToTimestamp(scene.file.duration ?? 0);
} }
function renderTags(tags: GQL.SlimSceneDataTags[]) { function renderTags(tags: GQL.Tag[]) {
return tags.map(tag => ( return tags.map(tag => (
<Link to={NavUtils.makeTagScenesUrl(tag)}> <Link to={NavUtils.makeTagScenesUrl(tag)}>
<h6>{tag.name}</h6> <h6>{tag.name}</h6>
@@ -45,7 +45,7 @@ export const SceneListTable: React.FC<ISceneListTableProps> = (
)); ));
} }
function renderPerformers(performers: GQL.SlimSceneDataPerformers[]) { function renderPerformers(performers: Partial<GQL.Performer>[]) {
return performers.map(performer => ( return performers.map(performer => (
<Link to={NavUtils.makePerformerScenesUrl(performer)}> <Link to={NavUtils.makePerformerScenesUrl(performer)}>
<h6>{performer.name}</h6> <h6>{performer.name}</h6>
@@ -53,7 +53,7 @@ export const SceneListTable: React.FC<ISceneListTableProps> = (
)); ));
} }
function renderStudio(studio: GQL.SlimSceneDataStudio | undefined) { function renderStudio(studio: Partial<GQL.Studio> | undefined) {
if (studio) { if (studio) {
return ( return (
<Link to={NavUtils.makeStudioScenesUrl(studio)}> <Link to={NavUtils.makeStudioScenesUrl(studio)}>
@@ -78,7 +78,7 @@ export const SceneListTable: React.FC<ISceneListTableProps> = (
<td>{renderDuration(scene)}</td> <td>{renderDuration(scene)}</td>
<td>{renderTags(scene.tags)}</td> <td>{renderTags(scene.tags)}</td>
<td>{renderPerformers(scene.performers)}</td> <td>{renderPerformers(scene.performers)}</td>
<td>{renderStudio(scene.studio)}</td> <td>{renderStudio(scene.studio ?? undefined)}</td>
</tr> </tr>
); );
} }

View File

@@ -1,10 +1,8 @@
import _ from "lodash"; import _ from "lodash";
import React from "react"; import React from "react";
import { QueryHookResult } from "react-apollo-hooks";
import { useHistory } from "react-router-dom"; import { useHistory } from "react-router-dom";
import { import {
FindSceneMarkersQuery, FindSceneMarkersQueryResult
FindSceneMarkersVariables
} from "src/core/generated-graphql"; } from "src/core/generated-graphql";
import { StashService } from "src/core/StashService"; import { StashService } from "src/core/StashService";
import { NavUtils } from "src/utils"; import { NavUtils } from "src/utils";
@@ -28,7 +26,7 @@ export const SceneMarkerList: React.FC = () => {
}); });
async function playRandom( async function playRandom(
result: QueryHookResult<FindSceneMarkersQuery, FindSceneMarkersVariables>, result: FindSceneMarkersQueryResult,
filter: ListFilterModel filter: ListFilterModel
) { ) {
// query for a random scene // query for a random scene
@@ -56,7 +54,7 @@ export const SceneMarkerList: React.FC = () => {
} }
function renderContent( function renderContent(
result: QueryHookResult<FindSceneMarkersQuery, FindSceneMarkersVariables>, result: FindSceneMarkersQueryResult,
filter: ListFilterModel filter: ListFilterModel
) { ) {
if (!result?.data?.findSceneMarkers) return; if (!result?.data?.findSceneMarkers) return;

View File

@@ -138,7 +138,7 @@ export class ScenePlayerImpl extends React.Component<
if (!this.props.scene.is_streamable) { if (!this.props.scene.is_streamable) {
getDurationHook = () => { getDurationHook = () => {
return this.props.scene.file.duration; return this.props.scene.file.duration ?? null;
}; };
seekHook = (seekToPosition: number, _videoTag: any) => { seekHook = (seekToPosition: number, _videoTag: any) => {

View File

@@ -22,7 +22,7 @@ export const SceneSelectedOptions: React.FC<IListOperationProps> = (
); );
const [tagIds, setTagIds] = useState<string[] | undefined>(undefined); const [tagIds, setTagIds] = useState<string[] | undefined>(undefined);
const updateScenes = StashService.useBulkSceneUpdate(getSceneInput()); const [updateScenes] = StashService.useBulkSceneUpdate(getSceneInput());
// Network state // Network state
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
@@ -111,7 +111,7 @@ export const SceneSelectedOptions: React.FC<IListOperationProps> = (
state.forEach((scene: GQL.SlimSceneDataFragment) => { state.forEach((scene: GQL.SlimSceneDataFragment) => {
if (first) { if (first) {
ret = scene.rating; ret = scene.rating ?? undefined;
first = false; first = false;
} else if (ret !== scene.rating) { } else if (ret !== scene.rating) {
ret = undefined; ret = undefined;

View File

@@ -1,7 +1,8 @@
import ApolloClient from "apollo-client"; import ApolloClient from "apollo-client";
import { WebSocketLink } from "apollo-link-ws"; import { WebSocketLink } from "apollo-link-ws";
import { InMemoryCache } from "apollo-cache-inmemory"; import { InMemoryCache } from "apollo-cache-inmemory";
import { HttpLink, split } from "apollo-boost"; import { HttpLink } from 'apollo-link-http';
import { split } from 'apollo-link';
import { getMainDefinition } from "apollo-utilities"; import { getMainDefinition } from "apollo-utilities";
import { ListFilterModel } from "../models/list-filter/filter"; import { ListFilterModel } from "../models/list-filter/filter";
import * as GQL from "./generated-graphql"; import * as GQL from "./generated-graphql";
@@ -43,8 +44,8 @@ export class StashService {
const link = split( const link = split(
({ query }) => { ({ query }) => {
const { kind, operation } = getMainDefinition(query); const definition = getMainDefinition(query);
return kind === "OperationDefinition" && operation === "subscription"; return definition.kind === "OperationDefinition" && definition.operation === "subscription";
}, },
wsLink, wsLink,
httpLink httpLink
@@ -60,10 +61,6 @@ export class StashService {
return StashService.client; return StashService.client;
} }
private static invalidateCache() {
StashService.client.resetStore();
}
private static invalidateQueries(queries: string[]) { private static invalidateQueries(queries: string[]) {
if (StashService.cache) { if (StashService.cache) {
const cache = StashService.cache as any; const cache = StashService.cache as any;
@@ -85,7 +82,7 @@ export class StashService {
} }
public static useFindGalleries(filter: ListFilterModel) { public static useFindGalleries(filter: ListFilterModel) {
return GQL.useFindGalleries({ return GQL.useFindGalleriesQuery({
variables: { variables: {
filter: filter.makeFindFilter() filter: filter.makeFindFilter()
} }
@@ -103,7 +100,7 @@ export class StashService {
// }); // });
// } // }
return GQL.useFindScenes({ return GQL.useFindScenesQuery({
variables: { variables: {
filter: filter.makeFindFilter(), filter: filter.makeFindFilter(),
scene_filter: sceneFilter scene_filter: sceneFilter
@@ -135,7 +132,7 @@ export class StashService {
// }); // });
// } // }
return GQL.useFindSceneMarkers({ return GQL.useFindSceneMarkersQuery({
variables: { variables: {
filter: filter.makeFindFilter(), filter: filter.makeFindFilter(),
scene_marker_filter: sceneMarkerFilter scene_marker_filter: sceneMarkerFilter
@@ -157,7 +154,7 @@ export class StashService {
} }
public static useFindStudios(filter: ListFilterModel) { public static useFindStudios(filter: ListFilterModel) {
return GQL.useFindStudios({ return GQL.useFindStudiosQuery({
variables: { variables: {
filter: filter.makeFindFilter() filter: filter.makeFindFilter()
} }
@@ -175,7 +172,7 @@ export class StashService {
// }); // });
// } // }
return GQL.useFindPerformers({ return GQL.useFindPerformersQuery({
variables: { variables: {
filter: filter.makeFindFilter(), filter: filter.makeFindFilter(),
performer_filter: performerFilter performer_filter: performerFilter
@@ -197,18 +194,18 @@ export class StashService {
} }
public static useFindGallery(id: string) { public static useFindGallery(id: string) {
return GQL.useFindGallery({ variables: { id } }); return GQL.useFindGalleryQuery({ variables: { id } });
} }
public static useFindScene(id: string) { public static useFindScene(id: string) {
return GQL.useFindScene({ variables: { id } }); return GQL.useFindSceneQuery({ variables: { id } });
} }
public static useFindPerformer(id: string) { public static useFindPerformer(id: string) {
const skip = id === "new"; const skip = id === "new";
return GQL.useFindPerformer({ variables: { id }, skip }); return GQL.useFindPerformerQuery({ variables: { id }, skip });
} }
public static useFindStudio(id: string) { public static useFindStudio(id: string) {
const skip = id === "new"; const skip = id === "new";
return GQL.useFindStudio({ variables: { id }, skip }); return GQL.useFindStudioQuery({ variables: { id }, skip });
} }
// TODO - scene marker manipulation functions are handled differently // TODO - scene marker manipulation functions are handled differently
@@ -220,20 +217,20 @@ export class StashService {
]; ];
public static useSceneMarkerCreate() { public static useSceneMarkerCreate() {
return GQL.useSceneMarkerCreate({ refetchQueries: ["FindScene"] }); return GQL.useSceneMarkerCreateMutation({ refetchQueries: ["FindScene"] });
} }
public static useSceneMarkerUpdate() { public static useSceneMarkerUpdate() {
return GQL.useSceneMarkerUpdate({ refetchQueries: ["FindScene"] }); return GQL.useSceneMarkerUpdateMutation({ refetchQueries: ["FindScene"] });
} }
public static useSceneMarkerDestroy() { public static useSceneMarkerDestroy() {
return GQL.useSceneMarkerDestroy({ refetchQueries: ["FindScene"] }); return GQL.useSceneMarkerDestroyMutation({ refetchQueries: ["FindScene"] });
} }
public static useListPerformerScrapers() { public static useListPerformerScrapers() {
return GQL.useListPerformerScrapers(); return GQL.useListPerformerScrapersQuery();
} }
public static useScrapePerformerList(scraperId: string, q: string) { public static useScrapePerformerList(scraperId: string, q: string) {
return GQL.useScrapePerformerList({ return GQL.useScrapePerformerListQuery({
variables: { scraper_id: scraperId, query: q }, variables: { scraper_id: scraperId, query: q },
skip: q === "" skip: q === ""
}); });
@@ -242,48 +239,48 @@ export class StashService {
scraperId: string, scraperId: string,
scrapedPerformer: GQL.ScrapedPerformerInput scrapedPerformer: GQL.ScrapedPerformerInput
) { ) {
return GQL.useScrapePerformer({ return GQL.useScrapePerformerQuery({
variables: { scraper_id: scraperId, scraped_performer: scrapedPerformer } variables: { scraper_id: scraperId, scraped_performer: scrapedPerformer }
}); });
} }
public static useListSceneScrapers() { public static useListSceneScrapers() {
return GQL.useListSceneScrapers(); return GQL.useListSceneScrapersQuery();
} }
public static useScrapeFreeonesPerformers(q: string) { public static useScrapeFreeonesPerformers(q: string) {
return GQL.useScrapeFreeonesPerformers({ variables: { q } }); return GQL.useScrapeFreeonesPerformersQuery({ variables: { q } });
} }
public static useMarkerStrings() { public static useMarkerStrings() {
return GQL.useMarkerStrings(); return GQL.useMarkerStringsQuery();
} }
public static useAllTags() { public static useAllTags() {
return GQL.useAllTags(); return GQL.useAllTagsQuery();
} }
public static useAllTagsForFilter() { public static useAllTagsForFilter() {
return GQL.useAllTagsForFilter(); return GQL.useAllTagsForFilterQuery();
} }
public static useAllPerformersForFilter() { public static useAllPerformersForFilter() {
return GQL.useAllPerformersForFilter(); return GQL.useAllPerformersForFilterQuery();
} }
public static useAllStudiosForFilter() { public static useAllStudiosForFilter() {
return GQL.useAllStudiosForFilter(); return GQL.useAllStudiosForFilterQuery();
} }
public static useValidGalleriesForScene(sceneId: string) { public static useValidGalleriesForScene(sceneId: string) {
return GQL.useValidGalleriesForScene({ variables: { scene_id: sceneId } }); return GQL.useValidGalleriesForSceneQuery({ variables: { scene_id: sceneId } });
} }
public static useStats() { public static useStats() {
return GQL.useStats(); return GQL.useStatsQuery();
} }
public static useVersion() { public static useVersion() {
return GQL.useVersion(); return GQL.useVersionQuery();
} }
public static useConfiguration() { public static useConfiguration() {
return GQL.useConfiguration(); return GQL.useConfigurationQuery();
} }
public static useDirectories(path?: string) { public static useDirectories(path?: string) {
return GQL.useDirectories({ variables: { path } }); return GQL.useDirectoriesQuery({ variables: { path } });
} }
private static performerMutationImpactedQueries = [ private static performerMutationImpactedQueries = [
@@ -294,7 +291,7 @@ export class StashService {
]; ];
public static usePerformerCreate(input: GQL.PerformerCreateInput) { public static usePerformerCreate(input: GQL.PerformerCreateInput) {
return GQL.usePerformerCreate({ return GQL.usePerformerCreateMutation({
variables: input, variables: input,
update: () => update: () =>
StashService.invalidateQueries( StashService.invalidateQueries(
@@ -303,7 +300,7 @@ export class StashService {
}); });
} }
public static usePerformerUpdate(input: GQL.PerformerUpdateInput) { public static usePerformerUpdate(input: GQL.PerformerUpdateInput) {
return GQL.usePerformerUpdate({ return GQL.usePerformerUpdateMutation({
variables: input, variables: input,
update: () => update: () =>
StashService.invalidateQueries( StashService.invalidateQueries(
@@ -312,7 +309,7 @@ export class StashService {
}); });
} }
public static usePerformerDestroy(input: GQL.PerformerDestroyInput) { public static usePerformerDestroy(input: GQL.PerformerDestroyInput) {
return GQL.usePerformerDestroy({ return GQL.usePerformerDestroyMutation({
variables: input, variables: input,
update: () => update: () =>
StashService.invalidateQueries( StashService.invalidateQueries(
@@ -331,7 +328,7 @@ export class StashService {
]; ];
public static useSceneUpdate(input: GQL.SceneUpdateInput) { public static useSceneUpdate(input: GQL.SceneUpdateInput) {
return GQL.useSceneUpdate({ return GQL.useSceneUpdateMutation({
variables: input, variables: input,
update: () => update: () =>
StashService.invalidateQueries( StashService.invalidateQueries(
@@ -351,7 +348,7 @@ export class StashService {
]; ];
public static useBulkSceneUpdate(input: GQL.BulkSceneUpdateInput) { public static useBulkSceneUpdate(input: GQL.BulkSceneUpdateInput) {
return GQL.useBulkSceneUpdate({ return GQL.useBulkSceneUpdateMutation({
variables: input, variables: input,
update: () => update: () =>
StashService.invalidateQueries( StashService.invalidateQueries(
@@ -361,11 +358,11 @@ export class StashService {
} }
public static useScenesUpdate(input: GQL.SceneUpdateInput[]) { public static useScenesUpdate(input: GQL.SceneUpdateInput[]) {
return GQL.useScenesUpdate({ variables: { input } }); return GQL.useScenesUpdateMutation({ variables: { input } });
} }
public static useSceneDestroy(input: GQL.SceneDestroyInput) { public static useSceneDestroy(input: GQL.SceneDestroyInput) {
return GQL.useSceneDestroy({ return GQL.useSceneDestroyMutation({
variables: input, variables: input,
update: () => update: () =>
StashService.invalidateQueries( StashService.invalidateQueries(
@@ -381,7 +378,7 @@ export class StashService {
]; ];
public static useStudioCreate(input: GQL.StudioCreateInput) { public static useStudioCreate(input: GQL.StudioCreateInput) {
return GQL.useStudioCreate({ return GQL.useStudioCreateMutation({
variables: input, variables: input,
update: () => update: () =>
StashService.invalidateQueries( StashService.invalidateQueries(
@@ -391,7 +388,7 @@ export class StashService {
} }
public static useStudioUpdate(input: GQL.StudioUpdateInput) { public static useStudioUpdate(input: GQL.StudioUpdateInput) {
return GQL.useStudioUpdate({ return GQL.useStudioUpdateMutation({
variables: input, variables: input,
update: () => update: () =>
StashService.invalidateQueries( StashService.invalidateQueries(
@@ -401,7 +398,7 @@ export class StashService {
} }
public static useStudioDestroy(input: GQL.StudioDestroyInput) { public static useStudioDestroy(input: GQL.StudioDestroyInput) {
return GQL.useStudioDestroy({ return GQL.useStudioDestroyMutation({
variables: input, variables: input,
update: () => update: () =>
StashService.invalidateQueries( StashService.invalidateQueries(
@@ -418,20 +415,20 @@ export class StashService {
]; ];
public static useTagCreate(input: GQL.TagCreateInput) { public static useTagCreate(input: GQL.TagCreateInput) {
return GQL.useTagCreate({ return GQL.useTagCreateMutation({
variables: input, variables: input,
refetchQueries: ["AllTags", "AllTagsForFilter"] refetchQueries: ["AllTags", "AllTagsForFilter"]
// update: () => StashService.invalidateQueries(StashService.tagMutationImpactedQueries) // update: () => StashService.invalidateQueries(StashService.tagMutationImpactedQueries)
}); });
} }
public static useTagUpdate(input: GQL.TagUpdateInput) { public static useTagUpdate(input: GQL.TagUpdateInput) {
return GQL.useTagUpdate({ return GQL.useTagUpdateMutation({
variables: input, variables: input,
refetchQueries: ["AllTags", "AllTagsForFilter"] refetchQueries: ["AllTags", "AllTagsForFilter"]
}); });
} }
public static useTagDestroy(input: GQL.TagDestroyInput) { public static useTagDestroy(input: GQL.TagDestroyInput) {
return GQL.useTagDestroy({ return GQL.useTagDestroyMutation({
variables: input, variables: input,
refetchQueries: ["AllTags", "AllTagsForFilter"], refetchQueries: ["AllTags", "AllTagsForFilter"],
update: () => update: () =>
@@ -440,35 +437,35 @@ export class StashService {
} }
public static useConfigureGeneral(input: GQL.ConfigGeneralInput) { public static useConfigureGeneral(input: GQL.ConfigGeneralInput) {
return GQL.useConfigureGeneral({ return GQL.useConfigureGeneralMutation({
variables: { input }, variables: { input },
refetchQueries: ["Configuration"] refetchQueries: ["Configuration"]
}); });
} }
public static useConfigureInterface(input: GQL.ConfigInterfaceInput) { public static useConfigureInterface(input: GQL.ConfigInterfaceInput) {
return GQL.useConfigureInterface({ return GQL.useConfigureInterfaceMutation({
variables: { input }, variables: { input },
refetchQueries: ["Configuration"] refetchQueries: ["Configuration"]
}); });
} }
public static useMetadataUpdate() { public static useMetadataUpdate() {
return GQL.useMetadataUpdate(); return GQL.useMetadataUpdateSubscription();
} }
public static useLoggingSubscribe() { public static useLoggingSubscribe() {
return GQL.useLoggingSubscribe(); return GQL.useLoggingSubscribeSubscription();
} }
public static useLogs() { public static useLogs() {
return GQL.useLogs({ return GQL.useLogsQuery({
fetchPolicy: "no-cache" fetchPolicy: "no-cache"
}); });
} }
public static useJobStatus() { public static useJobStatus() {
return GQL.useJobStatus({ return GQL.useJobStatusQuery({
fetchPolicy: "no-cache" fetchPolicy: "no-cache"
}); });
} }

File diff suppressed because it is too large Load Diff

View File

@@ -2,25 +2,19 @@ import _ from "lodash";
import queryString from "query-string"; import queryString from "query-string";
import React, { useState } from "react"; import React, { useState } from "react";
import { Spinner } from "react-bootstrap"; import { Spinner } from "react-bootstrap";
import { QueryHookResult } from "react-apollo-hooks";
import { ApolloError } from "apollo-client"; import { ApolloError } from "apollo-client";
import { useHistory } from "react-router-dom"; import { useHistory } from "react-router-dom";
import { import {
FindScenesQuery,
FindScenesVariables,
SlimSceneDataFragment, SlimSceneDataFragment,
FindSceneMarkersQuery, SceneMarkerDataFragment,
FindSceneMarkersVariables,
FindSceneMarkersSceneMarkers,
FindGalleriesQuery,
FindGalleriesVariables,
GalleryDataFragment, GalleryDataFragment,
FindStudiosQuery,
FindStudiosVariables,
StudioDataFragment, StudioDataFragment,
FindPerformersQuery, PerformerDataFragment,
FindPerformersVariables, FindScenesQueryResult,
PerformerDataFragment FindSceneMarkersQueryResult,
FindGalleriesQueryResult,
FindStudiosQueryResult,
FindPerformersQueryResult
} from "src/core/generated-graphql"; } from "src/core/generated-graphql";
import { ListFilter } from "../components/list/ListFilter"; import { ListFilter } from "../components/list/ListFilter";
import { Pagination } from "../components/list/Pagination"; import { Pagination } from "../components/list/Pagination";
@@ -307,69 +301,55 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
return { filter, template, onSelectChange }; return { filter, template, onSelectChange };
}; };
type ScenesQuery = QueryHookResult<FindScenesQuery, FindScenesVariables>; export const useScenesList = (props: IListHookOptions<FindScenesQueryResult>) =>
export const useScenesList = (props: IListHookOptions<ScenesQuery>) => useList<FindScenesQueryResult, SlimSceneDataFragment>({
useList<ScenesQuery, SlimSceneDataFragment>({
...props, ...props,
filterMode: FilterMode.Scenes, filterMode: FilterMode.Scenes,
useData: StashService.useFindScenes, useData: StashService.useFindScenes,
getData: (result: ScenesQuery) => result?.data?.findScenes?.scenes ?? [], getData: (result: FindScenesQueryResult) => result?.data?.findScenes?.scenes ?? [],
getCount: (result: ScenesQuery) => result?.data?.findScenes?.count ?? 0 getCount: (result: FindScenesQueryResult) => result?.data?.findScenes?.count ?? 0
}); });
type SceneMarkersQuery = QueryHookResult<
FindSceneMarkersQuery,
FindSceneMarkersVariables
>;
export const useSceneMarkersList = ( export const useSceneMarkersList = (
props: IListHookOptions<SceneMarkersQuery> props: IListHookOptions<FindSceneMarkersQueryResult>
) => ) =>
useList<SceneMarkersQuery, FindSceneMarkersSceneMarkers>({ useList<FindSceneMarkersQueryResult, SceneMarkerDataFragment>({
...props, ...props,
filterMode: FilterMode.SceneMarkers, filterMode: FilterMode.SceneMarkers,
useData: StashService.useFindSceneMarkers, useData: StashService.useFindSceneMarkers,
getData: (result: SceneMarkersQuery) => getData: (result: FindSceneMarkersQueryResult) =>
result?.data?.findSceneMarkers?.scene_markers ?? [], result?.data?.findSceneMarkers?.scene_markers ?? [],
getCount: (result: SceneMarkersQuery) => getCount: (result: FindSceneMarkersQueryResult) =>
result?.data?.findSceneMarkers?.count ?? 0 result?.data?.findSceneMarkers?.count ?? 0
}); });
type GalleriesQuery = QueryHookResult< export const useGalleriesList = (props: IListHookOptions<FindGalleriesQueryResult>) =>
FindGalleriesQuery, useList<FindGalleriesQueryResult, GalleryDataFragment>({
FindGalleriesVariables
>;
export const useGalleriesList = (props: IListHookOptions<GalleriesQuery>) =>
useList<GalleriesQuery, GalleryDataFragment>({
...props, ...props,
filterMode: FilterMode.Galleries, filterMode: FilterMode.Galleries,
useData: StashService.useFindGalleries, useData: StashService.useFindGalleries,
getData: (result: GalleriesQuery) => getData: (result: FindGalleriesQueryResult) =>
result?.data?.findGalleries?.galleries ?? [], result?.data?.findGalleries?.galleries ?? [],
getCount: (result: GalleriesQuery) => getCount: (result: FindGalleriesQueryResult) =>
result?.data?.findGalleries?.count ?? 0 result?.data?.findGalleries?.count ?? 0
}); });
type StudiosQuery = QueryHookResult<FindStudiosQuery, FindStudiosVariables>; export const useStudiosList = (props: IListHookOptions<FindStudiosQueryResult>) =>
export const useStudiosList = (props: IListHookOptions<StudiosQuery>) => useList<FindStudiosQueryResult, StudioDataFragment>({
useList<StudiosQuery, StudioDataFragment>({
...props, ...props,
filterMode: FilterMode.Studios, filterMode: FilterMode.Studios,
useData: StashService.useFindStudios, useData: StashService.useFindStudios,
getData: (result: StudiosQuery) => result?.data?.findStudios?.studios ?? [], getData: (result: FindStudiosQueryResult) => result?.data?.findStudios?.studios ?? [],
getCount: (result: StudiosQuery) => result?.data?.findStudios?.count ?? 0 getCount: (result: FindStudiosQueryResult) => result?.data?.findStudios?.count ?? 0
}); });
type PerformersQuery = QueryHookResult< export const usePerformersList = (props: IListHookOptions<FindPerformersQueryResult>) =>
FindPerformersQuery, useList<FindPerformersQueryResult, PerformerDataFragment>({
FindPerformersVariables
>;
export const usePerformersList = (props: IListHookOptions<PerformersQuery>) =>
useList<PerformersQuery, PerformerDataFragment>({
...props, ...props,
filterMode: FilterMode.Performers, filterMode: FilterMode.Performers,
useData: StashService.useFindPerformers, useData: StashService.useFindPerformers,
getData: (result: PerformersQuery) => getData: (result: FindPerformersQueryResult) =>
result?.data?.findPerformers?.performers ?? [], result?.data?.findPerformers?.performers ?? [],
getCount: (result: PerformersQuery) => getCount: (result: FindPerformersQueryResult) =>
result?.data?.findPerformers?.count ?? 0 result?.data?.findPerformers?.count ?? 0
}); });

View File

@@ -1,5 +1,5 @@
import React from "react"; import React from "react";
import { ApolloProvider } from "react-apollo-hooks"; import { ApolloProvider } from "react-apollo";
import ReactDOM from "react-dom"; import ReactDOM from "react-dom";
import { BrowserRouter } from "react-router-dom"; import { BrowserRouter } from "react-router-dom";
import { App } from "./App"; import { App } from "./App";

View File

@@ -3,7 +3,7 @@ import { ILabeledId } from "../types";
import { Criterion, CriterionType, ICriterionOption } from "./criterion"; import { Criterion, CriterionType, ICriterionOption } from "./criterion";
export class TagsCriterion extends Criterion< export class TagsCriterion extends Criterion<
GQL.AllTagsForFilterAllTags, GQL.Tag,
ILabeledId[] ILabeledId[]
> { > {
public type: CriterionType; public type: CriterionType;
@@ -14,7 +14,7 @@ export class TagsCriterion extends Criterion<
Criterion.getModifierOption(GQL.CriterionModifier.Includes), Criterion.getModifierOption(GQL.CriterionModifier.Includes),
Criterion.getModifierOption(GQL.CriterionModifier.Excludes) Criterion.getModifierOption(GQL.CriterionModifier.Excludes)
]; ];
public options: GQL.AllTagsForFilterAllTags[] = []; public options: GQL.Tag[] = [];
public value: ILabeledId[] = []; public value: ILabeledId[] = [];
constructor(type: "tags" | "sceneTags") { constructor(type: "tags" | "sceneTags") {

View File

@@ -42,7 +42,7 @@ const fileNameFromPath = (path: string) => {
return path.replace(/^.*[\\/]/, ""); return path.replace(/^.*[\\/]/, "");
}; };
const getAge = (dateString?: string, fromDateString?: string) => { const getAge = (dateString?: string|null, fromDateString?: string) => {
if (!dateString) return 0; if (!dateString) return 0;
const birthdate = new Date(dateString); const birthdate = new Date(dateString);

File diff suppressed because it is too large Load Diff