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:
src/core/generated-graphql.tsx:
config:
noNamespaces: true
optionalType: "undefined"
noHOC: true
noComponents: true
withHooks: true
withHOC: false
withComponents: false
plugins:
- add: "/* tslint:disable */"
- add: "/* eslint-disable */"
- time
- "typescript-common"
- "typescript-client"
- "typescript-react-apollo"
- typescript
- typescript-operations
- typescript-react-apollo

View File

@@ -3,30 +3,36 @@
"version": "0.1.0",
"private": true,
"dependencies": {
"@apollo/react-hooks": "^3.1.3",
"@fortawesome/fontawesome-svg-core": "^1.2.26",
"@fortawesome/free-solid-svg-icons": "^5.12.0",
"@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-utilities": "^1.3.3",
"axios": "0.18.1",
"bootstrap": "^4.4.1",
"classnames": "^2.2.6",
"formik": "1.5.7",
"graphql": "14.3.1",
"formik": "^2.1.2",
"graphql": "^14.5.8",
"graphql-tag": "^2.10.1",
"localforage": "1.7.3",
"lodash": "4.17.13",
"node-sass": "4.12.0",
"lodash": "^4.17.15",
"node-sass": "4.13.1",
"normalize.css": "^8.0.1",
"query-string": "6.5.0",
"query-string": "6.10.1",
"react": "~16.12.0",
"react-apollo": "2.5.6",
"react-apollo-hooks": "0.4.5",
"react-apollo": "^3.1.3",
"react-bootstrap": "^1.0.0-beta.16",
"react-dom": "16.12.0",
"react-hotkeys": "^2.0.0",
"react-images": "0.5.19",
"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-dom": "^5.1.2",
"react-scripts": "3.3.0",
@@ -51,13 +57,19 @@
"not op_mini all"
],
"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/jest": "24.0.13",
"@types/lodash": "4.14.132",
"@types/node": "11.13.0",
"@types/query-string": "6.3.0",
"@types/react": "16.9.15",
"@types/react-dom": "16.9.4",
"@types/lodash": "^4.14.149",
"@types/node": "13.1.8",
"@types/react": "16.9.19",
"@types/react-dom": "^16.9.5",
"@types/react-images": "^0.5.1",
"@types/react-router-bootstrap": "^0.24.5",
"@types/react-router-dom": "5.1.3",
@@ -69,12 +81,6 @@
"eslint-config-airbnb-typescript": "^6.3.1",
"eslint-config-prettier": "^6.9.0",
"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",
"typescript": "~3.7.4"
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -38,7 +38,7 @@ export const SceneFileInfoPanel: React.FC<ISceneFileInfoPanelProps> = (
<tr>
<td>Stream</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>
</tr>
);
@@ -51,7 +51,7 @@ export const SceneFileInfoPanel: React.FC<ISceneFileInfoPanelProps> = (
return (
<tr>
<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>
);
}
@@ -63,7 +63,7 @@ export const SceneFileInfoPanel: React.FC<ISceneFileInfoPanelProps> = (
return (
<tr>
<td>Duration</td>
<td>{TextUtils.secondsToTimestamp(props.scene.file.duration)}</td>
<td>{TextUtils.secondsToTimestamp(props.scene.file.duration ?? 0)}</td>
</tr>
);
}
@@ -101,7 +101,7 @@ export const SceneFileInfoPanel: React.FC<ISceneFileInfoPanelProps> = (
return (
<tr>
<td>Bit Rate</td>
<td>{TextUtils.bitRate(props.scene.file.bitrate)}</td>
<td>{TextUtils.bitRate(props.scene.file.bitrate ?? 0)}</td>
</tr>
);
}

View File

@@ -41,9 +41,9 @@ export const SceneMarkersPanel: React.FC<ISceneMarkersPanelProps> = (
setEditingMarker
] = useState<GQL.SceneMarkerDataFragment | null>(null);
const sceneMarkerCreate = StashService.useSceneMarkerCreate();
const sceneMarkerUpdate = StashService.useSceneMarkerUpdate();
const sceneMarkerDestroy = StashService.useSceneMarkerDestroy();
const [sceneMarkerCreate] = StashService.useSceneMarkerCreate();
const [sceneMarkerUpdate] = StashService.useSceneMarkerUpdate();
const [sceneMarkerDestroy] = StashService.useSceneMarkerDestroy();
const jwplayer = SceneHelpers.getPlayer();
@@ -57,7 +57,7 @@ export const SceneMarkersPanel: React.FC<ISceneMarkersPanelProps> = (
}
function renderTags() {
function renderMarkers(primaryTag: GQL.FindSceneSceneMarkerTags) {
function renderMarkers(primaryTag: GQL.SceneMarkerTag) {
const markers = primaryTag.scene_markers.map(marker => {
const markerTags = marker.tags.map(tag => (
<Badge key={tag.id} variant="secondary" className="tag-item">
@@ -102,7 +102,7 @@ export const SceneMarkersPanel: React.FC<ISceneMarkersPanelProps> = (
flex: "0 0 auto"
};
const tags = (props.scene as any).scene_marker_tags.map(
(primaryTag: GQL.FindSceneSceneMarkerTags) => {
(primaryTag: GQL.SceneMarkerTag) => {
return (
<div key={primaryTag.tag.id} style={{ padding: "1px" }}>
<Card style={style}>
@@ -122,8 +122,8 @@ export const SceneMarkersPanel: React.FC<ISceneMarkersPanelProps> = (
function onSubmit(values: IFormFields) {
const isEditing = !!editingMarker;
const variables:
| GQL.SceneMarkerCreateVariables
| GQL.SceneMarkerUpdateVariables = {
| GQL.SceneMarkerUpdateInput
| GQL.SceneMarkerCreateInput = {
title: values.title,
seconds: parseFloat(values.seconds),
scene_id: props.scene.id,
@@ -138,7 +138,7 @@ export const SceneMarkersPanel: React.FC<ISceneMarkersPanelProps> = (
})
.catch(err => Toast.error(err));
} else {
const updateVariables = variables as GQL.SceneMarkerUpdateVariables;
const updateVariables = variables as GQL.SceneMarkerUpdateInput;
updateVariables.id = editingMarker!.id;
sceneMarkerUpdate({ variables: updateVariables })
.then(() => {
@@ -178,7 +178,7 @@ export const SceneMarkersPanel: React.FC<ISceneMarkersPanelProps> = (
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
key={performer.id}
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";
class ParserResult<T> {
public value: GQL.Maybe<T>;
public originalValue: GQL.Maybe<T>;
public value: GQL.Maybe<T> = null;
public originalValue: GQL.Maybe<T> = null;
public set: boolean = false;
public setOriginalValue(v: GQL.Maybe<T>) {
@@ -110,60 +110,52 @@ class SceneParserResult {
public title: 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 tags: ParserResult<GQL.SlimSceneDataTags[]> = new ParserResult();
public tags: ParserResult<GQL.Tag[]> = new ParserResult();
public tagIds: ParserResult<string[]> = new ParserResult();
public performers: ParserResult<
GQL.SlimSceneDataPerformers[]
> = new ParserResult();
public performers: ParserResult<Partial<GQL.Performer>[]> = new ParserResult();
public performerIds: ParserResult<string[]> = new ParserResult();
public scene: GQL.SlimSceneDataFragment;
constructor(result: GQL.ParseSceneFilenamesResults) {
constructor(result: GQL.ParseSceneFilenamesQuery["parseSceneFilenames"]["results"][0]) {
this.scene = result.scene;
this.id = this.scene.id;
this.filename = TextUtils.fileNameFromPath(this.scene.path);
this.title.setOriginalValue(this.scene.title);
this.date.setOriginalValue(this.scene.date);
this.title.setOriginalValue(this.scene.title ?? null);
this.date.setOriginalValue(this.scene.date ?? null);
this.performerIds.setOriginalValue(this.scene.performers.map(p => p.id));
this.performers.setOriginalValue(this.scene.performers);
this.tagIds.setOriginalValue(this.scene.tags.map(t => t.id));
this.tags.setOriginalValue(this.scene.tags);
this.studioId.setOriginalValue(
this.scene.studio ? this.scene.studio.id : undefined
);
this.studio.setOriginalValue(this.scene.studio);
this.studioId.setOriginalValue(this.scene.studio?.id ?? null);
this.studio.setOriginalValue(this.scene.studio ?? null);
this.title.setValue(result.title);
this.date.setValue(result.date);
this.performerIds.setValue(result.performer_ids);
this.tagIds.setValue(result.tag_ids);
this.studioId.setValue(result.studio_id);
this.title.setValue(result.title ?? null);
this.date.setValue(result.date ?? null);
this.performerIds.setValue(result.performer_ids ?? []);
this.tagIds.setValue(result.tag_ids ?? []);
this.studioId.setValue(result.studio_id ?? null);
if (result.performer_ids) {
this.performers.setValue(
result.performer_ids.map(p => {
return {
id: p,
name: "",
favorite: false,
image_path: ""
};
})
(result.performer_ids ?? []).map(p => ({
id: p,
name: "",
favorite: false,
image_path: ""
} as GQL.Performer))
);
}
if (result.tag_ids) {
this.tags.setValue(
result.tag_ids.map(t => {
return {
result.tag_ids.map(t => ({
id: t,
name: ""
};
})
}))
);
}
@@ -172,7 +164,7 @@ class SceneParserResult {
id: result.studio_id,
name: "",
image_path: ""
});
} as GQL.Studio);
}
}
@@ -324,7 +316,7 @@ export const SceneFilenameParser: React.FC = () => {
// Network state
const [isLoading, setIsLoading] = useState(false);
const updateScenes = StashService.useScenesUpdate(getScenesUpdateData());
const [updateScenes] = StashService.useScenesUpdate(getScenesUpdateData());
const determineFieldsToHide = useCallback(() => {
const { pattern } = parserInput;
@@ -351,7 +343,7 @@ export const SceneFilenameParser: React.FC = () => {
}, [parserInput]);
const parseResults = useCallback(
(results: GQL.ParseSceneFilenamesResults[]) => {
(results: GQL.ParseSceneFilenamesQuery["parseSceneFilenames"]["results"]) => {
if (results) {
const result = results
.map(r => {
@@ -905,7 +897,7 @@ export const SceneFilenameParser: React.FC = () => {
fieldName="Title"
className="parser-field-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)}
renderOriginalInputField={renderOriginalInputGroup}
renderNewInputField={renderNewInputGroup}
@@ -915,7 +907,7 @@ export const SceneFilenameParser: React.FC = () => {
fieldName="Date"
className="parser-field-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)}
renderOriginalInputField={renderOriginalInputGroup}
renderNewInputField={renderNewInputGroup}
@@ -927,7 +919,7 @@ export const SceneFilenameParser: React.FC = () => {
parserResult={props.scene.performerIds}
originalParserResult={props.scene.performers}
onSetChanged={set =>
onPerformerIdsChanged(set, props.scene.performerIds.value)
onPerformerIdsChanged(set, props.scene.performerIds.value ?? undefined)
}
onValueChanged={value =>
onPerformerIdsChanged(props.scene.performerIds.set, value)
@@ -941,7 +933,7 @@ export const SceneFilenameParser: React.FC = () => {
className="parser-field-tags"
parserResult={props.scene.tagIds}
originalParserResult={props.scene.tags}
onSetChanged={set => onTagIdsChanged(set, props.scene.tagIds.value)}
onSetChanged={set => onTagIdsChanged(set, props.scene.tagIds.value ?? undefined)}
onValueChanged={value =>
onTagIdsChanged(props.scene.tagIds.set, value)
}
@@ -955,7 +947,7 @@ export const SceneFilenameParser: React.FC = () => {
parserResult={props.scene.studioId}
originalParserResult={props.scene.studio}
onSetChanged={set =>
onStudioIdChanged(set, props.scene.studioId.value)
onStudioIdChanged(set, props.scene.studioId.value ?? undefined)
}
onValueChanged={value =>
onStudioIdChanged(props.scene.studioId.set, value)

View File

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

View File

@@ -34,10 +34,10 @@ export const SceneListTable: React.FC<ISceneListTableProps> = (
if (scene.file.duration === undefined) {
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 => (
<Link to={NavUtils.makeTagScenesUrl(tag)}>
<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 => (
<Link to={NavUtils.makePerformerScenesUrl(performer)}>
<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) {
return (
<Link to={NavUtils.makeStudioScenesUrl(studio)}>
@@ -78,7 +78,7 @@ export const SceneListTable: React.FC<ISceneListTableProps> = (
<td>{renderDuration(scene)}</td>
<td>{renderTags(scene.tags)}</td>
<td>{renderPerformers(scene.performers)}</td>
<td>{renderStudio(scene.studio)}</td>
<td>{renderStudio(scene.studio ?? undefined)}</td>
</tr>
);
}

View File

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

View File

@@ -138,7 +138,7 @@ export class ScenePlayerImpl extends React.Component<
if (!this.props.scene.is_streamable) {
getDurationHook = () => {
return this.props.scene.file.duration;
return this.props.scene.file.duration ?? null;
};
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 updateScenes = StashService.useBulkSceneUpdate(getSceneInput());
const [updateScenes] = StashService.useBulkSceneUpdate(getSceneInput());
// Network state
const [isLoading, setIsLoading] = useState(false);
@@ -111,7 +111,7 @@ export const SceneSelectedOptions: React.FC<IListOperationProps> = (
state.forEach((scene: GQL.SlimSceneDataFragment) => {
if (first) {
ret = scene.rating;
ret = scene.rating ?? undefined;
first = false;
} else if (ret !== scene.rating) {
ret = undefined;

View File

@@ -1,7 +1,8 @@
import ApolloClient from "apollo-client";
import { WebSocketLink } from "apollo-link-ws";
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 { ListFilterModel } from "../models/list-filter/filter";
import * as GQL from "./generated-graphql";
@@ -43,8 +44,8 @@ export class StashService {
const link = split(
({ query }) => {
const { kind, operation } = getMainDefinition(query);
return kind === "OperationDefinition" && operation === "subscription";
const definition = getMainDefinition(query);
return definition.kind === "OperationDefinition" && definition.operation === "subscription";
},
wsLink,
httpLink
@@ -60,10 +61,6 @@ export class StashService {
return StashService.client;
}
private static invalidateCache() {
StashService.client.resetStore();
}
private static invalidateQueries(queries: string[]) {
if (StashService.cache) {
const cache = StashService.cache as any;
@@ -85,7 +82,7 @@ export class StashService {
}
public static useFindGalleries(filter: ListFilterModel) {
return GQL.useFindGalleries({
return GQL.useFindGalleriesQuery({
variables: {
filter: filter.makeFindFilter()
}
@@ -103,7 +100,7 @@ export class StashService {
// });
// }
return GQL.useFindScenes({
return GQL.useFindScenesQuery({
variables: {
filter: filter.makeFindFilter(),
scene_filter: sceneFilter
@@ -135,7 +132,7 @@ export class StashService {
// });
// }
return GQL.useFindSceneMarkers({
return GQL.useFindSceneMarkersQuery({
variables: {
filter: filter.makeFindFilter(),
scene_marker_filter: sceneMarkerFilter
@@ -157,7 +154,7 @@ export class StashService {
}
public static useFindStudios(filter: ListFilterModel) {
return GQL.useFindStudios({
return GQL.useFindStudiosQuery({
variables: {
filter: filter.makeFindFilter()
}
@@ -175,7 +172,7 @@ export class StashService {
// });
// }
return GQL.useFindPerformers({
return GQL.useFindPerformersQuery({
variables: {
filter: filter.makeFindFilter(),
performer_filter: performerFilter
@@ -197,18 +194,18 @@ export class StashService {
}
public static useFindGallery(id: string) {
return GQL.useFindGallery({ variables: { id } });
return GQL.useFindGalleryQuery({ variables: { id } });
}
public static useFindScene(id: string) {
return GQL.useFindScene({ variables: { id } });
return GQL.useFindSceneQuery({ variables: { id } });
}
public static useFindPerformer(id: string) {
const skip = id === "new";
return GQL.useFindPerformer({ variables: { id }, skip });
return GQL.useFindPerformerQuery({ variables: { id }, skip });
}
public static useFindStudio(id: string) {
const skip = id === "new";
return GQL.useFindStudio({ variables: { id }, skip });
return GQL.useFindStudioQuery({ variables: { id }, skip });
}
// TODO - scene marker manipulation functions are handled differently
@@ -220,20 +217,20 @@ export class StashService {
];
public static useSceneMarkerCreate() {
return GQL.useSceneMarkerCreate({ refetchQueries: ["FindScene"] });
return GQL.useSceneMarkerCreateMutation({ refetchQueries: ["FindScene"] });
}
public static useSceneMarkerUpdate() {
return GQL.useSceneMarkerUpdate({ refetchQueries: ["FindScene"] });
return GQL.useSceneMarkerUpdateMutation({ refetchQueries: ["FindScene"] });
}
public static useSceneMarkerDestroy() {
return GQL.useSceneMarkerDestroy({ refetchQueries: ["FindScene"] });
return GQL.useSceneMarkerDestroyMutation({ refetchQueries: ["FindScene"] });
}
public static useListPerformerScrapers() {
return GQL.useListPerformerScrapers();
return GQL.useListPerformerScrapersQuery();
}
public static useScrapePerformerList(scraperId: string, q: string) {
return GQL.useScrapePerformerList({
return GQL.useScrapePerformerListQuery({
variables: { scraper_id: scraperId, query: q },
skip: q === ""
});
@@ -242,48 +239,48 @@ export class StashService {
scraperId: string,
scrapedPerformer: GQL.ScrapedPerformerInput
) {
return GQL.useScrapePerformer({
return GQL.useScrapePerformerQuery({
variables: { scraper_id: scraperId, scraped_performer: scrapedPerformer }
});
}
public static useListSceneScrapers() {
return GQL.useListSceneScrapers();
return GQL.useListSceneScrapersQuery();
}
public static useScrapeFreeonesPerformers(q: string) {
return GQL.useScrapeFreeonesPerformers({ variables: { q } });
return GQL.useScrapeFreeonesPerformersQuery({ variables: { q } });
}
public static useMarkerStrings() {
return GQL.useMarkerStrings();
return GQL.useMarkerStringsQuery();
}
public static useAllTags() {
return GQL.useAllTags();
return GQL.useAllTagsQuery();
}
public static useAllTagsForFilter() {
return GQL.useAllTagsForFilter();
return GQL.useAllTagsForFilterQuery();
}
public static useAllPerformersForFilter() {
return GQL.useAllPerformersForFilter();
return GQL.useAllPerformersForFilterQuery();
}
public static useAllStudiosForFilter() {
return GQL.useAllStudiosForFilter();
return GQL.useAllStudiosForFilterQuery();
}
public static useValidGalleriesForScene(sceneId: string) {
return GQL.useValidGalleriesForScene({ variables: { scene_id: sceneId } });
return GQL.useValidGalleriesForSceneQuery({ variables: { scene_id: sceneId } });
}
public static useStats() {
return GQL.useStats();
return GQL.useStatsQuery();
}
public static useVersion() {
return GQL.useVersion();
return GQL.useVersionQuery();
}
public static useConfiguration() {
return GQL.useConfiguration();
return GQL.useConfigurationQuery();
}
public static useDirectories(path?: string) {
return GQL.useDirectories({ variables: { path } });
return GQL.useDirectoriesQuery({ variables: { path } });
}
private static performerMutationImpactedQueries = [
@@ -294,7 +291,7 @@ export class StashService {
];
public static usePerformerCreate(input: GQL.PerformerCreateInput) {
return GQL.usePerformerCreate({
return GQL.usePerformerCreateMutation({
variables: input,
update: () =>
StashService.invalidateQueries(
@@ -303,7 +300,7 @@ export class StashService {
});
}
public static usePerformerUpdate(input: GQL.PerformerUpdateInput) {
return GQL.usePerformerUpdate({
return GQL.usePerformerUpdateMutation({
variables: input,
update: () =>
StashService.invalidateQueries(
@@ -312,7 +309,7 @@ export class StashService {
});
}
public static usePerformerDestroy(input: GQL.PerformerDestroyInput) {
return GQL.usePerformerDestroy({
return GQL.usePerformerDestroyMutation({
variables: input,
update: () =>
StashService.invalidateQueries(
@@ -331,7 +328,7 @@ export class StashService {
];
public static useSceneUpdate(input: GQL.SceneUpdateInput) {
return GQL.useSceneUpdate({
return GQL.useSceneUpdateMutation({
variables: input,
update: () =>
StashService.invalidateQueries(
@@ -351,7 +348,7 @@ export class StashService {
];
public static useBulkSceneUpdate(input: GQL.BulkSceneUpdateInput) {
return GQL.useBulkSceneUpdate({
return GQL.useBulkSceneUpdateMutation({
variables: input,
update: () =>
StashService.invalidateQueries(
@@ -361,11 +358,11 @@ export class StashService {
}
public static useScenesUpdate(input: GQL.SceneUpdateInput[]) {
return GQL.useScenesUpdate({ variables: { input } });
return GQL.useScenesUpdateMutation({ variables: { input } });
}
public static useSceneDestroy(input: GQL.SceneDestroyInput) {
return GQL.useSceneDestroy({
return GQL.useSceneDestroyMutation({
variables: input,
update: () =>
StashService.invalidateQueries(
@@ -381,7 +378,7 @@ export class StashService {
];
public static useStudioCreate(input: GQL.StudioCreateInput) {
return GQL.useStudioCreate({
return GQL.useStudioCreateMutation({
variables: input,
update: () =>
StashService.invalidateQueries(
@@ -391,7 +388,7 @@ export class StashService {
}
public static useStudioUpdate(input: GQL.StudioUpdateInput) {
return GQL.useStudioUpdate({
return GQL.useStudioUpdateMutation({
variables: input,
update: () =>
StashService.invalidateQueries(
@@ -401,7 +398,7 @@ export class StashService {
}
public static useStudioDestroy(input: GQL.StudioDestroyInput) {
return GQL.useStudioDestroy({
return GQL.useStudioDestroyMutation({
variables: input,
update: () =>
StashService.invalidateQueries(
@@ -418,20 +415,20 @@ export class StashService {
];
public static useTagCreate(input: GQL.TagCreateInput) {
return GQL.useTagCreate({
return GQL.useTagCreateMutation({
variables: input,
refetchQueries: ["AllTags", "AllTagsForFilter"]
// update: () => StashService.invalidateQueries(StashService.tagMutationImpactedQueries)
});
}
public static useTagUpdate(input: GQL.TagUpdateInput) {
return GQL.useTagUpdate({
return GQL.useTagUpdateMutation({
variables: input,
refetchQueries: ["AllTags", "AllTagsForFilter"]
});
}
public static useTagDestroy(input: GQL.TagDestroyInput) {
return GQL.useTagDestroy({
return GQL.useTagDestroyMutation({
variables: input,
refetchQueries: ["AllTags", "AllTagsForFilter"],
update: () =>
@@ -440,35 +437,35 @@ export class StashService {
}
public static useConfigureGeneral(input: GQL.ConfigGeneralInput) {
return GQL.useConfigureGeneral({
return GQL.useConfigureGeneralMutation({
variables: { input },
refetchQueries: ["Configuration"]
});
}
public static useConfigureInterface(input: GQL.ConfigInterfaceInput) {
return GQL.useConfigureInterface({
return GQL.useConfigureInterfaceMutation({
variables: { input },
refetchQueries: ["Configuration"]
});
}
public static useMetadataUpdate() {
return GQL.useMetadataUpdate();
return GQL.useMetadataUpdateSubscription();
}
public static useLoggingSubscribe() {
return GQL.useLoggingSubscribe();
return GQL.useLoggingSubscribeSubscription();
}
public static useLogs() {
return GQL.useLogs({
return GQL.useLogsQuery({
fetchPolicy: "no-cache"
});
}
public static useJobStatus() {
return GQL.useJobStatus({
return GQL.useJobStatusQuery({
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 React, { useState } from "react";
import { Spinner } from "react-bootstrap";
import { QueryHookResult } from "react-apollo-hooks";
import { ApolloError } from "apollo-client";
import { useHistory } from "react-router-dom";
import {
FindScenesQuery,
FindScenesVariables,
SlimSceneDataFragment,
FindSceneMarkersQuery,
FindSceneMarkersVariables,
FindSceneMarkersSceneMarkers,
FindGalleriesQuery,
FindGalleriesVariables,
SceneMarkerDataFragment,
GalleryDataFragment,
FindStudiosQuery,
FindStudiosVariables,
StudioDataFragment,
FindPerformersQuery,
FindPerformersVariables,
PerformerDataFragment
PerformerDataFragment,
FindScenesQueryResult,
FindSceneMarkersQueryResult,
FindGalleriesQueryResult,
FindStudiosQueryResult,
FindPerformersQueryResult
} from "src/core/generated-graphql";
import { ListFilter } from "../components/list/ListFilter";
import { Pagination } from "../components/list/Pagination";
@@ -307,69 +301,55 @@ const useList = <QueryResult extends IQueryResult, QueryData extends IDataItem>(
return { filter, template, onSelectChange };
};
type ScenesQuery = QueryHookResult<FindScenesQuery, FindScenesVariables>;
export const useScenesList = (props: IListHookOptions<ScenesQuery>) =>
useList<ScenesQuery, SlimSceneDataFragment>({
export const useScenesList = (props: IListHookOptions<FindScenesQueryResult>) =>
useList<FindScenesQueryResult, SlimSceneDataFragment>({
...props,
filterMode: FilterMode.Scenes,
useData: StashService.useFindScenes,
getData: (result: ScenesQuery) => result?.data?.findScenes?.scenes ?? [],
getCount: (result: ScenesQuery) => result?.data?.findScenes?.count ?? 0
getData: (result: FindScenesQueryResult) => result?.data?.findScenes?.scenes ?? [],
getCount: (result: FindScenesQueryResult) => result?.data?.findScenes?.count ?? 0
});
type SceneMarkersQuery = QueryHookResult<
FindSceneMarkersQuery,
FindSceneMarkersVariables
>;
export const useSceneMarkersList = (
props: IListHookOptions<SceneMarkersQuery>
props: IListHookOptions<FindSceneMarkersQueryResult>
) =>
useList<SceneMarkersQuery, FindSceneMarkersSceneMarkers>({
useList<FindSceneMarkersQueryResult, SceneMarkerDataFragment>({
...props,
filterMode: FilterMode.SceneMarkers,
useData: StashService.useFindSceneMarkers,
getData: (result: SceneMarkersQuery) =>
getData: (result: FindSceneMarkersQueryResult) =>
result?.data?.findSceneMarkers?.scene_markers ?? [],
getCount: (result: SceneMarkersQuery) =>
getCount: (result: FindSceneMarkersQueryResult) =>
result?.data?.findSceneMarkers?.count ?? 0
});
type GalleriesQuery = QueryHookResult<
FindGalleriesQuery,
FindGalleriesVariables
>;
export const useGalleriesList = (props: IListHookOptions<GalleriesQuery>) =>
useList<GalleriesQuery, GalleryDataFragment>({
export const useGalleriesList = (props: IListHookOptions<FindGalleriesQueryResult>) =>
useList<FindGalleriesQueryResult, GalleryDataFragment>({
...props,
filterMode: FilterMode.Galleries,
useData: StashService.useFindGalleries,
getData: (result: GalleriesQuery) =>
getData: (result: FindGalleriesQueryResult) =>
result?.data?.findGalleries?.galleries ?? [],
getCount: (result: GalleriesQuery) =>
getCount: (result: FindGalleriesQueryResult) =>
result?.data?.findGalleries?.count ?? 0
});
type StudiosQuery = QueryHookResult<FindStudiosQuery, FindStudiosVariables>;
export const useStudiosList = (props: IListHookOptions<StudiosQuery>) =>
useList<StudiosQuery, StudioDataFragment>({
export const useStudiosList = (props: IListHookOptions<FindStudiosQueryResult>) =>
useList<FindStudiosQueryResult, StudioDataFragment>({
...props,
filterMode: FilterMode.Studios,
useData: StashService.useFindStudios,
getData: (result: StudiosQuery) => result?.data?.findStudios?.studios ?? [],
getCount: (result: StudiosQuery) => result?.data?.findStudios?.count ?? 0
getData: (result: FindStudiosQueryResult) => result?.data?.findStudios?.studios ?? [],
getCount: (result: FindStudiosQueryResult) => result?.data?.findStudios?.count ?? 0
});
type PerformersQuery = QueryHookResult<
FindPerformersQuery,
FindPerformersVariables
>;
export const usePerformersList = (props: IListHookOptions<PerformersQuery>) =>
useList<PerformersQuery, PerformerDataFragment>({
export const usePerformersList = (props: IListHookOptions<FindPerformersQueryResult>) =>
useList<FindPerformersQueryResult, PerformerDataFragment>({
...props,
filterMode: FilterMode.Performers,
useData: StashService.useFindPerformers,
getData: (result: PerformersQuery) =>
getData: (result: FindPerformersQueryResult) =>
result?.data?.findPerformers?.performers ?? [],
getCount: (result: PerformersQuery) =>
getCount: (result: FindPerformersQueryResult) =>
result?.data?.findPerformers?.count ?? 0
});

View File

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

View File

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

View File

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

File diff suppressed because it is too large Load Diff