🔨 ComicDetail grqphQL refactor
This commit is contained in:
@@ -67,13 +67,8 @@ type ComicDetailProps = {
|
||||
};
|
||||
|
||||
/**
|
||||
* Component for displaying the metadata for a comic in greater detail.
|
||||
*
|
||||
* @component
|
||||
* @example
|
||||
* return (
|
||||
* <ComicDetail/>
|
||||
* )
|
||||
* Displays full comic detail: cover, file info, action menu, and tabbed panels
|
||||
* for metadata, archive operations, and acquisition.
|
||||
*/
|
||||
export const ComicDetail = (data: ComicDetailProps): ReactElement => {
|
||||
const {
|
||||
@@ -84,7 +79,6 @@ export const ComicDetail = (data: ComicDetailProps): ReactElement => {
|
||||
sourcedMetadata: { comicvine, locg, comicInfo },
|
||||
acquisition,
|
||||
createdAt,
|
||||
updatedAt,
|
||||
},
|
||||
userSettings,
|
||||
queryClient,
|
||||
@@ -94,24 +88,10 @@ export const ComicDetail = (data: ComicDetailProps): ReactElement => {
|
||||
const [activeTab, setActiveTab] = useState<number | undefined>(undefined);
|
||||
const [visible, setVisible] = useState(false);
|
||||
const [slidingPanelContentId, setSlidingPanelContentId] = useState("");
|
||||
const [modalIsOpen, setIsOpen] = useState(false);
|
||||
|
||||
const { comicObjectId } = useParams<{ comicObjectId: string }>();
|
||||
const { comicVineMatches, prepareAndFetchMatches } = useComicVineMatching();
|
||||
|
||||
// Modal handlers (currently unused but kept for future use)
|
||||
const openModal = useCallback((filePath: string) => {
|
||||
setIsOpen(true);
|
||||
}, []);
|
||||
|
||||
const afterOpenModal = useCallback((things: any) => {
|
||||
// Modal opened callback
|
||||
}, []);
|
||||
|
||||
const closeModal = useCallback(() => {
|
||||
setIsOpen(false);
|
||||
}, []);
|
||||
|
||||
// Action event handlers
|
||||
const openDrawerWithCVMatches = () => {
|
||||
prepareAndFetchMatches(rawFileDetails, comicvine);
|
||||
@@ -224,10 +204,9 @@ export const ComicDetail = (data: ComicDetailProps): ReactElement => {
|
||||
<div className="grid">
|
||||
<RawFileDetails
|
||||
data={{
|
||||
rawFileDetails: rawFileDetails,
|
||||
inferredMetadata: inferredMetadata,
|
||||
created_at: createdAt,
|
||||
updated_at: updatedAt,
|
||||
rawFileDetails,
|
||||
inferredMetadata,
|
||||
createdAt,
|
||||
}}
|
||||
>
|
||||
{/* action dropdown */}
|
||||
|
||||
@@ -1,12 +1,21 @@
|
||||
import React, { ReactElement } from "react";
|
||||
import { ComicVineSearchForm } from "../ComicVineSearchForm";
|
||||
import MatchResult from "./MatchResult";
|
||||
import { isEmpty } from "lodash";
|
||||
import { useStore } from "../../store";
|
||||
import { useShallow } from "zustand/react/shallow";
|
||||
|
||||
export const ComicVineMatchPanel = (comicVineData): ReactElement => {
|
||||
const { comicObjectId, comicVineMatches, queryClient, onMatchApplied } = comicVineData.props;
|
||||
interface ComicVineMatchPanelProps {
|
||||
props: {
|
||||
comicObjectId: string;
|
||||
comicVineMatches: any[];
|
||||
queryClient?: any;
|
||||
onMatchApplied?: () => void;
|
||||
};
|
||||
}
|
||||
|
||||
/** Displays ComicVine search results or a status message while searching. */
|
||||
export const ComicVineMatchPanel = ({ props: comicVineData }: ComicVineMatchPanelProps): ReactElement => {
|
||||
const { comicObjectId, comicVineMatches, queryClient, onMatchApplied } = comicVineData;
|
||||
const { comicvine } = useStore(
|
||||
useShallow((state) => ({
|
||||
comicvine: state.comicvine,
|
||||
|
||||
@@ -1,55 +1,41 @@
|
||||
import React, { ReactElement, useCallback, useEffect, useState } from "react";
|
||||
import { Form, Field } from "react-final-form";
|
||||
import React, { ReactElement } from "react";
|
||||
import { Form, Field, FieldRenderProps } from "react-final-form";
|
||||
import arrayMutators from "final-form-arrays";
|
||||
import { FieldArray } from "react-final-form-arrays";
|
||||
import AsyncSelectPaginate from "./AsyncSelectPaginate/AsyncSelectPaginate";
|
||||
import TextareaAutosize from "react-textarea-autosize";
|
||||
|
||||
export const EditMetadataPanel = (props): ReactElement => {
|
||||
const validate = async () => {};
|
||||
interface EditMetadataPanelProps {
|
||||
data: {
|
||||
name?: string;
|
||||
[key: string]: any;
|
||||
};
|
||||
}
|
||||
|
||||
/** Adapts react-final-form's Field render prop to AsyncSelectPaginate. */
|
||||
const AsyncSelectPaginateAdapter = ({ input, ...rest }: FieldRenderProps<any>) => (
|
||||
<AsyncSelectPaginate {...input} {...rest} onChange={(value) => input.onChange(value)} />
|
||||
);
|
||||
|
||||
/** Adapts react-final-form's Field render prop to TextareaAutosize. */
|
||||
const TextareaAutosizeAdapter = ({ input, ...rest }: FieldRenderProps<any>) => (
|
||||
<TextareaAutosize {...input} {...rest} onChange={(value) => input.onChange(value)} />
|
||||
);
|
||||
|
||||
/** Sliding panel form for manually editing comic metadata fields. */
|
||||
export const EditMetadataPanel = ({ data }: EditMetadataPanelProps): ReactElement => {
|
||||
const onSubmit = async () => {};
|
||||
|
||||
const { data } = props;
|
||||
|
||||
const AsyncSelectPaginateAdapter = ({ input, ...rest }) => {
|
||||
return (
|
||||
<AsyncSelectPaginate
|
||||
{...input}
|
||||
{...rest}
|
||||
onChange={(value) => input.onChange(value)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
const TextareaAutosizeAdapter = ({ input, ...rest }) => {
|
||||
return (
|
||||
<TextareaAutosize
|
||||
{...input}
|
||||
{...rest}
|
||||
onChange={(value) => input.onChange(value)}
|
||||
/>
|
||||
);
|
||||
};
|
||||
// const rawFileDetails = useSelector(
|
||||
// (state: RootState) => state.comicInfo.comicBookDetail.rawFileDetails.name,
|
||||
// );
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form
|
||||
onSubmit={onSubmit}
|
||||
validate={validate}
|
||||
mutators={{
|
||||
...arrayMutators,
|
||||
}}
|
||||
mutators={{ ...arrayMutators }}
|
||||
render={({
|
||||
handleSubmit,
|
||||
form: {
|
||||
mutators: { push, pop },
|
||||
}, // injected from final-form-arrays above
|
||||
pristine,
|
||||
form,
|
||||
submitting,
|
||||
values,
|
||||
},
|
||||
}) => (
|
||||
<form onSubmit={handleSubmit}>
|
||||
{/* Issue Name */}
|
||||
@@ -80,7 +66,6 @@ export const EditMetadataPanel = (props): ReactElement => {
|
||||
<p className="text-xs">Do not enter the first zero</p>
|
||||
</div>
|
||||
<div>
|
||||
{/* year */}
|
||||
<div className="text-sm">Issue Year</div>
|
||||
<Field
|
||||
name="issue_year"
|
||||
@@ -100,8 +85,6 @@ export const EditMetadataPanel = (props): ReactElement => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* page count */}
|
||||
|
||||
{/* Description */}
|
||||
<div className="mt-2">
|
||||
<label className="text-sm">Description</label>
|
||||
@@ -113,7 +96,7 @@ export const EditMetadataPanel = (props): ReactElement => {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<hr size="1" />
|
||||
<hr />
|
||||
|
||||
<div className="field is-horizontal">
|
||||
<div className="field-label">
|
||||
@@ -153,7 +136,7 @@ export const EditMetadataPanel = (props): ReactElement => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr size="1" />
|
||||
<hr />
|
||||
|
||||
{/* Publisher */}
|
||||
<div className="field is-horizontal">
|
||||
@@ -224,7 +207,7 @@ export const EditMetadataPanel = (props): ReactElement => {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr size="1" />
|
||||
<hr />
|
||||
|
||||
{/* team credits */}
|
||||
<div className="field is-horizontal">
|
||||
@@ -302,7 +285,6 @@ export const EditMetadataPanel = (props): ReactElement => {
|
||||
))
|
||||
}
|
||||
</FieldArray>
|
||||
<pre>{JSON.stringify(values, undefined, 2)}</pre>
|
||||
</form>
|
||||
)}
|
||||
/>
|
||||
|
||||
@@ -1,29 +1,24 @@
|
||||
import React, { ReactElement, ReactNode } from "react";
|
||||
import prettyBytes from "pretty-bytes";
|
||||
import { isEmpty } from "lodash";
|
||||
import { format, parseISO } from "date-fns";
|
||||
import { RawFileDetails as RawFileDetailsType } from "../../graphql/generated";
|
||||
import { format, parseISO, isValid } from "date-fns";
|
||||
import {
|
||||
RawFileDetails as RawFileDetailsType,
|
||||
InferredMetadata,
|
||||
} from "../../graphql/generated";
|
||||
|
||||
type RawFileDetailsProps = {
|
||||
data?: {
|
||||
rawFileDetails?: RawFileDetailsType;
|
||||
inferredMetadata?: {
|
||||
issue?: {
|
||||
year?: string;
|
||||
name?: string;
|
||||
number?: number;
|
||||
subtitle?: string;
|
||||
};
|
||||
};
|
||||
created_at?: string;
|
||||
updated_at?: string;
|
||||
inferredMetadata?: InferredMetadata;
|
||||
createdAt?: string;
|
||||
};
|
||||
children?: ReactNode;
|
||||
};
|
||||
|
||||
/** Renders raw file info, inferred metadata, and import timestamp for a comic. */
|
||||
export const RawFileDetails = (props: RawFileDetailsProps): ReactElement => {
|
||||
const { rawFileDetails, inferredMetadata, created_at, updated_at } =
|
||||
props.data || {};
|
||||
const { rawFileDetails, inferredMetadata, createdAt } = props.data || {};
|
||||
return (
|
||||
<>
|
||||
<div className="max-w-2xl ml-5">
|
||||
@@ -97,10 +92,10 @@ export const RawFileDetails = (props: RawFileDetailsProps): ReactElement => {
|
||||
Import Details
|
||||
</dt>
|
||||
<dd className="mt-1 text-sm text-gray-900 dark:text-gray-400">
|
||||
{created_at ? (
|
||||
{createdAt && isValid(parseISO(createdAt)) ? (
|
||||
<>
|
||||
{format(parseISO(created_at), "dd MMMM, yyyy")},{" "}
|
||||
{format(parseISO(created_at), "h aaaa")}
|
||||
{format(parseISO(createdAt), "dd MMMM, yyyy")},{" "}
|
||||
{format(parseISO(createdAt), "h aaaa")}
|
||||
</>
|
||||
) : "N/A"}
|
||||
</dd>
|
||||
|
||||
@@ -28,6 +28,13 @@ export type AcquisitionSourceInput = {
|
||||
wanted?: InputMaybe<Scalars['Boolean']['input']>;
|
||||
};
|
||||
|
||||
export type AppSettings = {
|
||||
__typename?: 'AppSettings';
|
||||
bittorrent?: Maybe<BittorrentSettings>;
|
||||
directConnect?: Maybe<DirectConnectSettings>;
|
||||
prowlarr?: Maybe<ProwlarrSettings>;
|
||||
};
|
||||
|
||||
export type Archive = {
|
||||
__typename?: 'Archive';
|
||||
expandedPath?: Maybe<Scalars['String']['output']>;
|
||||
@@ -52,6 +59,26 @@ export type AutoMergeSettingsInput = {
|
||||
onMetadataUpdate?: InputMaybe<Scalars['Boolean']['input']>;
|
||||
};
|
||||
|
||||
export type BittorrentClient = {
|
||||
__typename?: 'BittorrentClient';
|
||||
host?: Maybe<HostConfig>;
|
||||
name?: Maybe<Scalars['String']['output']>;
|
||||
};
|
||||
|
||||
export type BittorrentSettings = {
|
||||
__typename?: 'BittorrentSettings';
|
||||
client?: Maybe<BittorrentClient>;
|
||||
};
|
||||
|
||||
export type Bundle = {
|
||||
__typename?: 'Bundle';
|
||||
id?: Maybe<Scalars['Int']['output']>;
|
||||
name?: Maybe<Scalars['String']['output']>;
|
||||
size?: Maybe<Scalars['String']['output']>;
|
||||
speed?: Maybe<Scalars['String']['output']>;
|
||||
status?: Maybe<Scalars['String']['output']>;
|
||||
};
|
||||
|
||||
export type CanonicalMetadata = {
|
||||
__typename?: 'CanonicalMetadata';
|
||||
ageRating?: Maybe<MetadataField>;
|
||||
@@ -123,6 +150,11 @@ export type ComicConnection = {
|
||||
totalCount: Scalars['Int']['output'];
|
||||
};
|
||||
|
||||
export type ComicVineMatchInput = {
|
||||
volume: ComicVineVolumeRefInput;
|
||||
volumeInformation?: InputMaybe<Scalars['JSON']['input']>;
|
||||
};
|
||||
|
||||
export type ComicVineResourceResponse = {
|
||||
__typename?: 'ComicVineResourceResponse';
|
||||
error: Scalars['String']['output'];
|
||||
@@ -143,6 +175,24 @@ export type ComicVineSearchResult = {
|
||||
offset: Scalars['Int']['output'];
|
||||
results: Array<SearchResultItem>;
|
||||
status_code: Scalars['Int']['output'];
|
||||
total: Scalars['Int']['output'];
|
||||
};
|
||||
|
||||
export type ComicVineVolume = {
|
||||
__typename?: 'ComicVineVolume';
|
||||
api_detail_url?: Maybe<Scalars['String']['output']>;
|
||||
count_of_issues?: Maybe<Scalars['Int']['output']>;
|
||||
description?: Maybe<Scalars['String']['output']>;
|
||||
id?: Maybe<Scalars['Int']['output']>;
|
||||
image?: Maybe<VolumeImage>;
|
||||
name?: Maybe<Scalars['String']['output']>;
|
||||
publisher?: Maybe<Publisher>;
|
||||
site_detail_url?: Maybe<Scalars['String']['output']>;
|
||||
start_year?: Maybe<Scalars['String']['output']>;
|
||||
};
|
||||
|
||||
export type ComicVineVolumeRefInput = {
|
||||
api_detail_url: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
export enum ConflictResolutionStrategy {
|
||||
@@ -177,10 +227,22 @@ export type DirectConnectBundleInput = {
|
||||
size?: InputMaybe<Scalars['String']['input']>;
|
||||
};
|
||||
|
||||
export type DirectConnectClient = {
|
||||
__typename?: 'DirectConnectClient';
|
||||
airDCPPUserSettings?: Maybe<Scalars['JSON']['output']>;
|
||||
host?: Maybe<HostConfig>;
|
||||
hubs?: Maybe<Array<Maybe<Scalars['JSON']['output']>>>;
|
||||
};
|
||||
|
||||
export type DirectConnectInput = {
|
||||
downloads?: InputMaybe<Array<DirectConnectBundleInput>>;
|
||||
};
|
||||
|
||||
export type DirectConnectSettings = {
|
||||
__typename?: 'DirectConnectSettings';
|
||||
client?: Maybe<DirectConnectClient>;
|
||||
};
|
||||
|
||||
export type DirectorySize = {
|
||||
__typename?: 'DirectorySize';
|
||||
fileCount: Scalars['Int']['output'];
|
||||
@@ -234,6 +296,37 @@ export type GetVolumesInput = {
|
||||
volumeURI: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
export type HostConfig = {
|
||||
__typename?: 'HostConfig';
|
||||
hostname?: Maybe<Scalars['String']['output']>;
|
||||
password?: Maybe<Scalars['String']['output']>;
|
||||
port?: Maybe<Scalars['String']['output']>;
|
||||
protocol?: Maybe<Scalars['String']['output']>;
|
||||
username?: Maybe<Scalars['String']['output']>;
|
||||
};
|
||||
|
||||
export type HostInput = {
|
||||
hostname: Scalars['String']['input'];
|
||||
password: Scalars['String']['input'];
|
||||
port: Scalars['String']['input'];
|
||||
protocol: Scalars['String']['input'];
|
||||
username: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
export type Hub = {
|
||||
__typename?: 'Hub';
|
||||
description?: Maybe<Scalars['String']['output']>;
|
||||
id?: Maybe<Scalars['Int']['output']>;
|
||||
name?: Maybe<Scalars['String']['output']>;
|
||||
userCount?: Maybe<Scalars['Int']['output']>;
|
||||
};
|
||||
|
||||
export type ImageAnalysisResult = {
|
||||
__typename?: 'ImageAnalysisResult';
|
||||
analyzedData?: Maybe<Scalars['JSON']['output']>;
|
||||
colorHistogramData?: Maybe<Scalars['JSON']['output']>;
|
||||
};
|
||||
|
||||
export type ImageUrls = {
|
||||
__typename?: 'ImageUrls';
|
||||
icon_url?: Maybe<Scalars['String']['output']>;
|
||||
@@ -516,6 +609,8 @@ export type Mutation = {
|
||||
__typename?: 'Mutation';
|
||||
/** Placeholder for future mutations */
|
||||
_empty?: Maybe<Scalars['String']['output']>;
|
||||
analyzeImage: ImageAnalysisResult;
|
||||
applyComicVineMatch: Comic;
|
||||
bulkResolveMetadata: Array<Comic>;
|
||||
forceCompleteSession: ForceCompleteResult;
|
||||
importComic: ImportComicResult;
|
||||
@@ -525,11 +620,23 @@ export type Mutation = {
|
||||
setMetadataField: Comic;
|
||||
startIncrementalImport: IncrementalImportResult;
|
||||
startNewImport: ImportJobResult;
|
||||
uncompressArchive?: Maybe<Scalars['Boolean']['output']>;
|
||||
updateSourcedMetadata: Comic;
|
||||
updateUserPreferences: UserPreferences;
|
||||
};
|
||||
|
||||
|
||||
export type MutationAnalyzeImageArgs = {
|
||||
imageFilePath: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type MutationApplyComicVineMatchArgs = {
|
||||
comicObjectId: Scalars['ID']['input'];
|
||||
match: ComicVineMatchInput;
|
||||
};
|
||||
|
||||
|
||||
export type MutationBulkResolveMetadataArgs = {
|
||||
comicIds: Array<Scalars['ID']['input']>;
|
||||
};
|
||||
@@ -580,6 +687,13 @@ export type MutationStartNewImportArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type MutationUncompressArchiveArgs = {
|
||||
comicObjectId: Scalars['ID']['input'];
|
||||
filePath: Scalars['String']['input'];
|
||||
options?: InputMaybe<Scalars['JSON']['input']>;
|
||||
};
|
||||
|
||||
|
||||
export type MutationUpdateSourcedMetadataArgs = {
|
||||
comicId: Scalars['ID']['input'];
|
||||
metadata: Scalars['String']['input'];
|
||||
@@ -628,6 +742,17 @@ export type Provenance = {
|
||||
url?: Maybe<Scalars['String']['output']>;
|
||||
};
|
||||
|
||||
export type ProwlarrClient = {
|
||||
__typename?: 'ProwlarrClient';
|
||||
apiKey?: Maybe<Scalars['String']['output']>;
|
||||
host?: Maybe<HostConfig>;
|
||||
};
|
||||
|
||||
export type ProwlarrSettings = {
|
||||
__typename?: 'ProwlarrSettings';
|
||||
client?: Maybe<ProwlarrClient>;
|
||||
};
|
||||
|
||||
export type Publisher = {
|
||||
__typename?: 'Publisher';
|
||||
api_detail_url?: Maybe<Scalars['String']['output']>;
|
||||
@@ -644,6 +769,7 @@ export type PublisherStats = {
|
||||
export type Query = {
|
||||
__typename?: 'Query';
|
||||
analyzeMetadataConflicts: Array<MetadataConflict>;
|
||||
bundles: Array<Bundle>;
|
||||
comic?: Maybe<Comic>;
|
||||
comics: ComicConnection;
|
||||
/** Fetch resource from Metron API */
|
||||
@@ -664,13 +790,18 @@ export type Query = {
|
||||
getVolume: VolumeDetailResponse;
|
||||
/** Get weekly pull list from League of Comic Geeks */
|
||||
getWeeklyPullList: MetadataPullListResponse;
|
||||
hubs: Array<Hub>;
|
||||
previewCanonicalMetadata?: Maybe<CanonicalMetadata>;
|
||||
/** Search ComicVine for volumes, issues, characters, etc. */
|
||||
searchComicVine: ComicVineSearchResult;
|
||||
searchIssue: SearchIssueResult;
|
||||
searchTorrents: Array<TorrentSearchResult>;
|
||||
settings?: Maybe<AppSettings>;
|
||||
torrentJobs?: Maybe<TorrentJob>;
|
||||
userPreferences?: Maybe<UserPreferences>;
|
||||
/** Advanced volume-based search with scoring and filtering */
|
||||
volumeBasedSearch: VolumeBasedSearchResponse;
|
||||
walkFolders: Array<Scalars['String']['output']>;
|
||||
};
|
||||
|
||||
|
||||
@@ -679,6 +810,12 @@ export type QueryAnalyzeMetadataConflictsArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type QueryBundlesArgs = {
|
||||
comicObjectId: Scalars['ID']['input'];
|
||||
config?: InputMaybe<Scalars['JSON']['input']>;
|
||||
};
|
||||
|
||||
|
||||
export type QueryComicArgs = {
|
||||
id: Scalars['ID']['input'];
|
||||
};
|
||||
@@ -734,6 +871,11 @@ export type QueryGetWeeklyPullListArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type QueryHubsArgs = {
|
||||
host: HostInput;
|
||||
};
|
||||
|
||||
|
||||
export type QueryPreviewCanonicalMetadataArgs = {
|
||||
comicId: Scalars['ID']['input'];
|
||||
preferences?: InputMaybe<UserPreferencesInput>;
|
||||
@@ -752,6 +894,21 @@ export type QuerySearchIssueArgs = {
|
||||
};
|
||||
|
||||
|
||||
export type QuerySearchTorrentsArgs = {
|
||||
query: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type QuerySettingsArgs = {
|
||||
settingsKey?: InputMaybe<Scalars['String']['input']>;
|
||||
};
|
||||
|
||||
|
||||
export type QueryTorrentJobsArgs = {
|
||||
trigger: Scalars['String']['input'];
|
||||
};
|
||||
|
||||
|
||||
export type QueryUserPreferencesArgs = {
|
||||
userId?: InputMaybe<Scalars['String']['input']>;
|
||||
};
|
||||
@@ -761,6 +918,12 @@ export type QueryVolumeBasedSearchArgs = {
|
||||
input: VolumeSearchInput;
|
||||
};
|
||||
|
||||
|
||||
export type QueryWalkFoldersArgs = {
|
||||
basePathToWalk: Scalars['String']['input'];
|
||||
extensions?: InputMaybe<Array<Scalars['String']['input']>>;
|
||||
};
|
||||
|
||||
export type RawFileDetails = {
|
||||
__typename?: 'RawFileDetails';
|
||||
archive?: Maybe<Archive>;
|
||||
@@ -939,6 +1102,24 @@ export type TeamCredit = {
|
||||
site_detail_url?: Maybe<Scalars['String']['output']>;
|
||||
};
|
||||
|
||||
export type TorrentJob = {
|
||||
__typename?: 'TorrentJob';
|
||||
id?: Maybe<Scalars['String']['output']>;
|
||||
name?: Maybe<Scalars['String']['output']>;
|
||||
};
|
||||
|
||||
export type TorrentSearchResult = {
|
||||
__typename?: 'TorrentSearchResult';
|
||||
downloadUrl?: Maybe<Scalars['String']['output']>;
|
||||
guid?: Maybe<Scalars['String']['output']>;
|
||||
indexer?: Maybe<Scalars['String']['output']>;
|
||||
leechers?: Maybe<Scalars['Int']['output']>;
|
||||
publishDate?: Maybe<Scalars['String']['output']>;
|
||||
seeders?: Maybe<Scalars['Int']['output']>;
|
||||
size?: Maybe<Scalars['Float']['output']>;
|
||||
title?: Maybe<Scalars['String']['output']>;
|
||||
};
|
||||
|
||||
export type UserPreferences = {
|
||||
__typename?: 'UserPreferences';
|
||||
autoMerge: AutoMergeSettings;
|
||||
|
||||
Reference in New Issue
Block a user