Add O-counter (#334)

This commit is contained in:
Infinite
2020-02-08 16:54:20 +01:00
parent f23247d9c8
commit e6d9d385a7
11 changed files with 369 additions and 11 deletions

View File

@@ -5,7 +5,7 @@ import cx from "classnames";
import * as GQL from "src/core/generated-graphql"; import * as GQL from "src/core/generated-graphql";
import { StashService } from "src/core/StashService"; import { StashService } from "src/core/StashService";
import { VideoHoverHook } from "src/hooks"; import { VideoHoverHook } from "src/hooks";
import { Icon, TagLink, HoverPopover } from "src/components/Shared"; import { Icon, TagLink, HoverPopover, SweatDrops } from "src/components/Shared";
import { TextUtils } from "src/utils"; import { TextUtils } from "src/utils";
interface ISceneCardProps { interface ISceneCardProps {
@@ -135,11 +135,25 @@ export const SceneCard: React.FC<ISceneCardProps> = (
); );
} }
function maybeRenderOCounter() {
if (props.scene.o_counter) {
return (
<div>
<Button className="minimal">
<SweatDrops />
<span>{props.scene.o_counter}</span>
</Button>
</div>
)
}
}
function maybeRenderPopoverButtonGroup() { function maybeRenderPopoverButtonGroup() {
if ( if (
props.scene.tags.length > 0 || props.scene.tags.length > 0 ||
props.scene.performers.length > 0 || props.scene.performers.length > 0 ||
props.scene.scene_markers.length > 0 props.scene.scene_markers.length > 0 ||
props.scene?.o_counter
) { ) {
return ( return (
<> <>
@@ -148,6 +162,7 @@ export const SceneCard: React.FC<ISceneCardProps> = (
{maybeRenderTagPopoverButton()} {maybeRenderTagPopoverButton()}
{maybeRenderPerformerPopoverButton()} {maybeRenderPerformerPopoverButton()}
{maybeRenderSceneMarkerPopoverButton()} {maybeRenderSceneMarkerPopoverButton()}
{maybeRenderOCounter()}
</ButtonGroup> </ButtonGroup>
</> </>
); );

View File

@@ -0,0 +1,67 @@
import React from "react";
import { Button, Spinner } from 'react-bootstrap';
import { Icon, HoverPopover, SweatDrops } from 'src/components/Shared';
export interface IOCounterButtonProps {
loading: boolean
value: number
onIncrement: () => void
onDecrement: () => void
onReset: () => void
onMenuOpened?: () => void
onMenuClosed?: () => void
}
export const OCounterButton: React.FC<IOCounterButtonProps> = (props: IOCounterButtonProps) => {
if(props.loading)
return <Spinner animation="border" role="status" />;
const renderButton = () => (
<Button
className="minimal"
onClick={props.onIncrement}
variant="secondary"
>
<SweatDrops />
<span className="ml-2">{props.value}</span>
</Button>
);
if (props.value) {
return (
<HoverPopover
content={
<div>
<div>
<Button
className="minimal"
onClick={props.onDecrement}
variant="secondary"
>
<Icon icon="minus" />
<span>Decrement</span>
</Button>
</div>
<div>
<Button
className="minimal"
onClick={props.onReset}
variant="secondary"
>
<Icon icon="ban" />
<span>Reset</span>
</Button>
</div>
</div>
}
enterDelay={1000}
placement="bottom"
onOpen={props.onMenuOpened}
onClose={props.onMenuClosed}
>
{ renderButton() }
</HoverPopover>
);
}
return renderButton();
}

View File

@@ -6,20 +6,27 @@ import * as GQL from "src/core/generated-graphql";
import { StashService } from "src/core/StashService"; import { StashService } from "src/core/StashService";
import { GalleryViewer } from "src/components/Galleries/GalleryViewer"; import { GalleryViewer } from "src/components/Galleries/GalleryViewer";
import { LoadingIndicator } from "src/components/Shared"; import { LoadingIndicator } from "src/components/Shared";
import { useToast } from 'src/hooks';
import { ScenePlayer } from "src/components/ScenePlayer"; import { ScenePlayer } from "src/components/ScenePlayer";
import { ScenePerformerPanel } from "./ScenePerformerPanel"; import { ScenePerformerPanel } from "./ScenePerformerPanel";
import { SceneMarkersPanel } from "./SceneMarkersPanel"; import { SceneMarkersPanel } from "./SceneMarkersPanel";
import { SceneFileInfoPanel } from "./SceneFileInfoPanel"; import { SceneFileInfoPanel } from "./SceneFileInfoPanel";
import { SceneEditPanel } from "./SceneEditPanel"; import { SceneEditPanel } from "./SceneEditPanel";
import { SceneDetailPanel } from "./SceneDetailPanel"; import { SceneDetailPanel } from "./SceneDetailPanel";
import { OCounterButton } from './OCounterButton';
export const Scene: React.FC = () => { export const Scene: React.FC = () => {
const { id = "new" } = useParams(); const { id = "new" } = useParams();
const location = useLocation(); const location = useLocation();
const history = useHistory(); const history = useHistory();
const Toast = useToast();
const [timestamp, setTimestamp] = useState<number>(getInitialTimestamp()); const [timestamp, setTimestamp] = useState<number>(getInitialTimestamp());
const [scene, setScene] = useState<GQL.SceneDataFragment | undefined>(); const [scene, setScene] = useState<GQL.SceneDataFragment | undefined>();
const { data, error, loading } = StashService.useFindScene(id); const { data, error, loading } = StashService.useFindScene(id);
const [oLoading, setOLoading] = useState(false);
const [incrementO] = StashService.useSceneIncrementO(scene?.id ?? "0");
const [decrementO] = StashService.useSceneDecrementO(scene?.id ?? "0");
const [resetO] = StashService.useSceneResetO(scene?.id ?? "0");
const queryParams = queryString.parse(location.search); const queryParams = queryString.parse(location.search);
const autoplay = queryParams?.autoplay === "true"; const autoplay = queryParams?.autoplay === "true";
@@ -37,6 +44,51 @@ export const Scene: React.FC = () => {
); );
} }
const updateOCounter = (newValue: number) => {
const modifiedScene = { ...scene } as GQL.SceneDataFragment;
modifiedScene.o_counter = newValue;
setScene(modifiedScene);
}
const onIncrementClick = async () => {
try {
setOLoading(true);
const result = await incrementO();
if(result.data)
updateOCounter(result.data.sceneIncrementO);
} catch (e) {
Toast.error(e);
} finally {
setOLoading(false);
}
}
const onDecrementClick = async () => {
try {
setOLoading(true);
const result = await decrementO();
if(result.data)
updateOCounter(result.data.sceneDecrementO);
} catch (e) {
Toast.error(e);
} finally {
setOLoading(false);
}
}
const onResetClick = async () => {
try {
setOLoading(true);
const result = await resetO();
if(result.data)
updateOCounter(result.data.sceneResetO);
} catch (e) {
Toast.error(e);
} finally {
setOLoading(false);
}
}
function onClickMarker(marker: GQL.SceneMarkerDataFragment) { function onClickMarker(marker: GQL.SceneMarkerDataFragment) {
setTimestamp(marker.seconds); setTimestamp(marker.seconds);
} }
@@ -51,6 +103,15 @@ export const Scene: React.FC = () => {
<> <>
<ScenePlayer scene={scene} timestamp={timestamp} autoplay={autoplay} /> <ScenePlayer scene={scene} timestamp={timestamp} autoplay={autoplay} />
<div id="scene-details-container" className="col col-sm-9 m-sm-auto"> <div id="scene-details-container" className="col col-sm-9 m-sm-auto">
<div className="float-right">
<OCounterButton
loading={oLoading}
value={scene.o_counter || 0}
onIncrement={onIncrementClick}
onDecrement={onDecrementClick}
onReset={onResetClick}
/>
</div>
<Tabs id="scene-tabs" mountOnEnter> <Tabs id="scene-tabs" mountOnEnter>
<Tab eventKey="scene-details-panel" title="Details"> <Tab eventKey="scene-details-panel" title="Details">
<SceneDetailPanel scene={scene} /> <SceneDetailPanel scene={scene} />

View File

@@ -7,6 +7,8 @@ interface IHoverPopover {
content: JSX.Element[] | JSX.Element | string; content: JSX.Element[] | JSX.Element | string;
className?: string; className?: string;
placement?: OverlayProps["placement"]; placement?: OverlayProps["placement"];
onOpen?: () => void;
onClose?: () => void;
} }
export const HoverPopover: React.FC<IHoverPopover> = ({ export const HoverPopover: React.FC<IHoverPopover> = ({
@@ -15,7 +17,9 @@ export const HoverPopover: React.FC<IHoverPopover> = ({
content, content,
children, children,
className, className,
placement = "top" placement = "top",
onOpen,
onClose
}) => { }) => {
const [show, setShow] = useState(false); const [show, setShow] = useState(false);
const triggerRef = useRef<HTMLDivElement>(null); const triggerRef = useRef<HTMLDivElement>(null);
@@ -24,13 +28,19 @@ export const HoverPopover: React.FC<IHoverPopover> = ({
const handleMouseEnter = useCallback(() => { const handleMouseEnter = useCallback(() => {
window.clearTimeout(leaveTimer.current); window.clearTimeout(leaveTimer.current);
enterTimer.current = window.setTimeout(() => setShow(true), enterDelay); enterTimer.current = window.setTimeout(() => {
}, [enterDelay]); setShow(true)
onOpen?.();
}, enterDelay);
}, [enterDelay, onOpen]);
const handleMouseLeave = useCallback(() => { const handleMouseLeave = useCallback(() => {
window.clearTimeout(enterTimer.current); window.clearTimeout(enterTimer.current);
leaveTimer.current = window.setTimeout(() => setShow(false), leaveDelay); leaveTimer.current = window.setTimeout(() => {
}, [leaveDelay]); setShow(false)
onClose?.();
}, leaveDelay);
}, [leaveDelay, onClose]);
useEffect( useEffect(
() => () => { () => () => {

View File

@@ -0,0 +1,10 @@
import React from 'react';
export const SweatDrops = () => (
<span>
<svg xmlns="http://www.w3.org/2000/svg" xmlnsXlink="http://www.w3.org/1999/xlink" aria-hidden="true" focusable="false" width="1em" height="1em" style={{transform: "rotate(360deg)"}} preserveAspectRatio="xMidYMid meet" viewBox="0 0 36 36">
<path fill="currentColor" d="M22.855.758L7.875 7.024l12.537 9.733c2.633 2.224 6.377 2.937 9.77 1.518c4.826-2.018 7.096-7.576 5.072-12.413C33.232 1.024 27.68-1.261 22.855.758zm-9.962 17.924L2.05 10.284L.137 23.529a7.993 7.993 0 0 0 2.958 7.803a8.001 8.001 0 0 0 9.798-12.65zm15.339 7.015l-8.156-4.69l-.033 9.223c-.088 2 .904 3.98 2.75 5.041a5.462 5.462 0 0 0 7.479-2.051c1.499-2.644.589-6.013-2.04-7.523z" />
<rect x="0" y="0" width="36" height="36" fill="rgba(0, 0, 0, 0)" />
</svg>
</span>
);

View File

@@ -16,3 +16,4 @@ export { TagLink } from "./TagLink";
export { HoverPopover } from "./HoverPopover"; export { HoverPopover } from "./HoverPopover";
export { default as LoadingIndicator } from "./LoadingIndicator"; export { default as LoadingIndicator } from "./LoadingIndicator";
export { ImageInput } from "./ImageInput"; export { ImageInput } from "./ImageInput";
export { SweatDrops } from './SweatDrops';

View File

@@ -369,6 +369,24 @@ export class StashService {
return GQL.useScenesUpdateMutation({ variables: { input } }); return GQL.useScenesUpdateMutation({ variables: { input } });
} }
public static useSceneIncrementO(id: string) {
return GQL.useSceneIncrementOMutation({
variables: {id}
});
}
public static useSceneDecrementO(id: string) {
return GQL.useSceneDecrementOMutation({
variables: {id}
});
}
public static useSceneResetO(id: string) {
return GQL.useSceneResetOMutation({
variables: {id}
});
}
public static useSceneDestroy(input: GQL.SceneDestroyInput) { public static useSceneDestroy(input: GQL.SceneDestroyInput) {
return GQL.useSceneDestroyMutation({ return GQL.useSceneDestroyMutation({
variables: input, variables: input,

View File

@@ -7,7 +7,7 @@ import * as ApolloReactHooks from '@apollo/react-hooks';
export type Maybe<T> = T | null; export type Maybe<T> = T | null;
export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>; export type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>;
// Generated in 2020-02-06T18:11:21+01:00 // Generated in 2020-02-08T16:10:44+01:00
/** All built-in and custom scalars, mapped to their actual values */ /** All built-in and custom scalars, mapped to their actual values */
export type Scalars = { export type Scalars = {
@@ -271,6 +271,12 @@ export type Mutation = {
bulkSceneUpdate?: Maybe<Array<Scene>>, bulkSceneUpdate?: Maybe<Array<Scene>>,
sceneDestroy: Scalars['Boolean'], sceneDestroy: Scalars['Boolean'],
scenesUpdate?: Maybe<Array<Maybe<Scene>>>, scenesUpdate?: Maybe<Array<Maybe<Scene>>>,
/** Increments the o-counter for a scene. Returns the new value */
sceneIncrementO: Scalars['Int'],
/** Decrements the o-counter for a scene. Returns the new value */
sceneDecrementO: Scalars['Int'],
/** Resets the o-counter for a scene to 0. Returns the new value */
sceneResetO: Scalars['Int'],
sceneMarkerCreate?: Maybe<SceneMarker>, sceneMarkerCreate?: Maybe<SceneMarker>,
sceneMarkerUpdate?: Maybe<SceneMarker>, sceneMarkerUpdate?: Maybe<SceneMarker>,
sceneMarkerDestroy: Scalars['Boolean'], sceneMarkerDestroy: Scalars['Boolean'],
@@ -309,6 +315,21 @@ export type MutationScenesUpdateArgs = {
}; };
export type MutationSceneIncrementOArgs = {
id: Scalars['ID']
};
export type MutationSceneDecrementOArgs = {
id: Scalars['ID']
};
export type MutationSceneResetOArgs = {
id: Scalars['ID']
};
export type MutationSceneMarkerCreateArgs = { export type MutationSceneMarkerCreateArgs = {
input: SceneMarkerCreateInput input: SceneMarkerCreateInput
}; };
@@ -762,6 +783,7 @@ export type Scene = {
url?: Maybe<Scalars['String']>, url?: Maybe<Scalars['String']>,
date?: Maybe<Scalars['String']>, date?: Maybe<Scalars['String']>,
rating?: Maybe<Scalars['Int']>, rating?: Maybe<Scalars['Int']>,
o_counter?: Maybe<Scalars['Int']>,
path: Scalars['String'], path: Scalars['String'],
file: SceneFileType, file: SceneFileType,
paths: ScenePathsType, paths: ScenePathsType,
@@ -794,6 +816,8 @@ export type SceneFileType = {
export type SceneFilterType = { export type SceneFilterType = {
/** Filter by rating */ /** Filter by rating */
rating?: Maybe<IntCriterionInput>, rating?: Maybe<IntCriterionInput>,
/** Filter by o-counter */
o_counter?: Maybe<IntCriterionInput>,
/** Filter by resolution */ /** Filter by resolution */
resolution?: Maybe<ResolutionEnum>, resolution?: Maybe<ResolutionEnum>,
/** Filter by duration (in seconds) */ /** Filter by duration (in seconds) */
@@ -1189,7 +1213,7 @@ export type SceneMarkerDataFragment = (
export type SlimSceneDataFragment = ( export type SlimSceneDataFragment = (
{ __typename?: 'Scene' } { __typename?: 'Scene' }
& Pick<Scene, 'id' | 'checksum' | 'title' | 'details' | 'url' | 'date' | 'rating' | 'path'> & Pick<Scene, 'id' | 'checksum' | 'title' | 'details' | 'url' | 'date' | 'rating' | 'o_counter' | 'path'>
& { file: ( & { file: (
{ __typename?: 'SceneFileType' } { __typename?: 'SceneFileType' }
& Pick<SceneFileType, 'size' | 'duration' | 'video_codec' | 'audio_codec' | 'width' | 'height' | 'framerate' | 'bitrate'> & Pick<SceneFileType, 'size' | 'duration' | 'video_codec' | 'audio_codec' | 'width' | 'height' | 'framerate' | 'bitrate'>
@@ -1216,7 +1240,7 @@ export type SlimSceneDataFragment = (
export type SceneDataFragment = ( export type SceneDataFragment = (
{ __typename?: 'Scene' } { __typename?: 'Scene' }
& Pick<Scene, 'id' | 'checksum' | 'title' | 'details' | 'url' | 'date' | 'rating' | 'path' | 'is_streamable'> & Pick<Scene, 'id' | 'checksum' | 'title' | 'details' | 'url' | 'date' | 'rating' | 'o_counter' | 'path' | 'is_streamable'>
& { file: ( & { file: (
{ __typename?: 'SceneFileType' } { __typename?: 'SceneFileType' }
& Pick<SceneFileType, 'size' | 'duration' | 'video_codec' | 'audio_codec' | 'width' | 'height' | 'framerate' | 'bitrate'> & Pick<SceneFileType, 'size' | 'duration' | 'video_codec' | 'audio_codec' | 'width' | 'height' | 'framerate' | 'bitrate'>
@@ -1492,6 +1516,36 @@ export type ScenesUpdateMutation = (
)>>> } )>>> }
); );
export type SceneIncrementOMutationVariables = {
id: Scalars['ID']
};
export type SceneIncrementOMutation = (
{ __typename?: 'Mutation' }
& Pick<Mutation, 'sceneIncrementO'>
);
export type SceneDecrementOMutationVariables = {
id: Scalars['ID']
};
export type SceneDecrementOMutation = (
{ __typename?: 'Mutation' }
& Pick<Mutation, 'sceneDecrementO'>
);
export type SceneResetOMutationVariables = {
id: Scalars['ID']
};
export type SceneResetOMutation = (
{ __typename?: 'Mutation' }
& Pick<Mutation, 'sceneResetO'>
);
export type SceneDestroyMutationVariables = { export type SceneDestroyMutationVariables = {
id: Scalars['ID'], id: Scalars['ID'],
delete_file?: Maybe<Scalars['Boolean']>, delete_file?: Maybe<Scalars['Boolean']>,
@@ -2226,6 +2280,7 @@ export const SlimSceneDataFragmentDoc = gql`
url url
date date
rating rating
o_counter
path path
file { file {
size size
@@ -2356,6 +2411,7 @@ export const SceneDataFragmentDoc = gql`
url url
date date
rating rating
o_counter
path path
file { file {
size size
@@ -2960,6 +3016,114 @@ export function useScenesUpdateMutation(baseOptions?: ApolloReactHooks.MutationH
export type ScenesUpdateMutationHookResult = ReturnType<typeof useScenesUpdateMutation>; export type ScenesUpdateMutationHookResult = ReturnType<typeof useScenesUpdateMutation>;
export type ScenesUpdateMutationResult = ApolloReactCommon.MutationResult<ScenesUpdateMutation>; export type ScenesUpdateMutationResult = ApolloReactCommon.MutationResult<ScenesUpdateMutation>;
export type ScenesUpdateMutationOptions = ApolloReactCommon.BaseMutationOptions<ScenesUpdateMutation, ScenesUpdateMutationVariables>; export type ScenesUpdateMutationOptions = ApolloReactCommon.BaseMutationOptions<ScenesUpdateMutation, ScenesUpdateMutationVariables>;
export const SceneIncrementODocument = gql`
mutation SceneIncrementO($id: ID!) {
sceneIncrementO(id: $id)
}
`;
export type SceneIncrementOMutationFn = ApolloReactCommon.MutationFunction<SceneIncrementOMutation, SceneIncrementOMutationVariables>;
export type SceneIncrementOComponentProps = Omit<ApolloReactComponents.MutationComponentOptions<SceneIncrementOMutation, SceneIncrementOMutationVariables>, 'mutation'>;
export const SceneIncrementOComponent = (props: SceneIncrementOComponentProps) => (
<ApolloReactComponents.Mutation<SceneIncrementOMutation, SceneIncrementOMutationVariables> mutation={SceneIncrementODocument} {...props} />
);
/**
* __useSceneIncrementOMutation__
*
* To run a mutation, you first call `useSceneIncrementOMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useSceneIncrementOMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution
*
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
*
* @example
* const [sceneIncrementOMutation, { data, loading, error }] = useSceneIncrementOMutation({
* variables: {
* id: // value for 'id'
* },
* });
*/
export function useSceneIncrementOMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<SceneIncrementOMutation, SceneIncrementOMutationVariables>) {
return ApolloReactHooks.useMutation<SceneIncrementOMutation, SceneIncrementOMutationVariables>(SceneIncrementODocument, baseOptions);
}
export type SceneIncrementOMutationHookResult = ReturnType<typeof useSceneIncrementOMutation>;
export type SceneIncrementOMutationResult = ApolloReactCommon.MutationResult<SceneIncrementOMutation>;
export type SceneIncrementOMutationOptions = ApolloReactCommon.BaseMutationOptions<SceneIncrementOMutation, SceneIncrementOMutationVariables>;
export const SceneDecrementODocument = gql`
mutation SceneDecrementO($id: ID!) {
sceneDecrementO(id: $id)
}
`;
export type SceneDecrementOMutationFn = ApolloReactCommon.MutationFunction<SceneDecrementOMutation, SceneDecrementOMutationVariables>;
export type SceneDecrementOComponentProps = Omit<ApolloReactComponents.MutationComponentOptions<SceneDecrementOMutation, SceneDecrementOMutationVariables>, 'mutation'>;
export const SceneDecrementOComponent = (props: SceneDecrementOComponentProps) => (
<ApolloReactComponents.Mutation<SceneDecrementOMutation, SceneDecrementOMutationVariables> mutation={SceneDecrementODocument} {...props} />
);
/**
* __useSceneDecrementOMutation__
*
* To run a mutation, you first call `useSceneDecrementOMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useSceneDecrementOMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution
*
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
*
* @example
* const [sceneDecrementOMutation, { data, loading, error }] = useSceneDecrementOMutation({
* variables: {
* id: // value for 'id'
* },
* });
*/
export function useSceneDecrementOMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<SceneDecrementOMutation, SceneDecrementOMutationVariables>) {
return ApolloReactHooks.useMutation<SceneDecrementOMutation, SceneDecrementOMutationVariables>(SceneDecrementODocument, baseOptions);
}
export type SceneDecrementOMutationHookResult = ReturnType<typeof useSceneDecrementOMutation>;
export type SceneDecrementOMutationResult = ApolloReactCommon.MutationResult<SceneDecrementOMutation>;
export type SceneDecrementOMutationOptions = ApolloReactCommon.BaseMutationOptions<SceneDecrementOMutation, SceneDecrementOMutationVariables>;
export const SceneResetODocument = gql`
mutation SceneResetO($id: ID!) {
sceneResetO(id: $id)
}
`;
export type SceneResetOMutationFn = ApolloReactCommon.MutationFunction<SceneResetOMutation, SceneResetOMutationVariables>;
export type SceneResetOComponentProps = Omit<ApolloReactComponents.MutationComponentOptions<SceneResetOMutation, SceneResetOMutationVariables>, 'mutation'>;
export const SceneResetOComponent = (props: SceneResetOComponentProps) => (
<ApolloReactComponents.Mutation<SceneResetOMutation, SceneResetOMutationVariables> mutation={SceneResetODocument} {...props} />
);
/**
* __useSceneResetOMutation__
*
* To run a mutation, you first call `useSceneResetOMutation` within a React component and pass it any options that fit your needs.
* When your component renders, `useSceneResetOMutation` returns a tuple that includes:
* - A mutate function that you can call at any time to execute the mutation
* - An object with fields that represent the current status of the mutation's execution
*
* @param baseOptions options that will be passed into the mutation, supported options are listed on: https://www.apollographql.com/docs/react/api/react-hooks/#options-2;
*
* @example
* const [sceneResetOMutation, { data, loading, error }] = useSceneResetOMutation({
* variables: {
* id: // value for 'id'
* },
* });
*/
export function useSceneResetOMutation(baseOptions?: ApolloReactHooks.MutationHookOptions<SceneResetOMutation, SceneResetOMutationVariables>) {
return ApolloReactHooks.useMutation<SceneResetOMutation, SceneResetOMutationVariables>(SceneResetODocument, baseOptions);
}
export type SceneResetOMutationHookResult = ReturnType<typeof useSceneResetOMutation>;
export type SceneResetOMutationResult = ApolloReactCommon.MutationResult<SceneResetOMutation>;
export type SceneResetOMutationOptions = ApolloReactCommon.BaseMutationOptions<SceneResetOMutation, SceneResetOMutationVariables>;
export const SceneDestroyDocument = gql` export const SceneDestroyDocument = gql`
mutation SceneDestroy($id: ID!, $delete_file: Boolean, $delete_generated: Boolean) { mutation SceneDestroy($id: ID!, $delete_file: Boolean, $delete_generated: Boolean) {
sceneDestroy(input: {id: $id, delete_file: $delete_file, delete_generated: $delete_generated}) sceneDestroy(input: {id: $id, delete_file: $delete_file, delete_generated: $delete_generated})

View File

@@ -7,6 +7,7 @@ import { ILabeledId, ILabeledValue } from "../types";
export type CriterionType = export type CriterionType =
| "none" | "none"
| "rating" | "rating"
| "o_counter"
| "resolution" | "resolution"
| "duration" | "duration"
| "favorite" | "favorite"
@@ -36,6 +37,8 @@ export abstract class Criterion<Option = any, Value = any> {
return "None"; return "None";
case "rating": case "rating":
return "Rating"; return "Rating";
case "o_counter":
return "O-Counter";
case "resolution": case "resolution":
return "Resolution"; return "Resolution";
case "duration": case "duration":

View File

@@ -23,6 +23,8 @@ export function makeCriteria(type: CriterionType = "none") {
return new NoneCriterion(); return new NoneCriterion();
case "rating": case "rating":
return new RatingCriterion(); return new RatingCriterion();
case "o_counter":
return new NumberCriterion(type, type);
case "resolution": case "resolution":
return new ResolutionCriterion(); return new ResolutionCriterion();
case "duration": case "duration":

View File

@@ -92,6 +92,7 @@ export class ListFilterModel {
"title", "title",
"path", "path",
"rating", "rating",
"o_counter",
"date", "date",
"filesize", "filesize",
"duration", "duration",
@@ -107,6 +108,7 @@ export class ListFilterModel {
this.criterionOptions = [ this.criterionOptions = [
new NoneCriterionOption(), new NoneCriterionOption(),
new RatingCriterionOption(), new RatingCriterionOption(),
ListFilterModel.createCriterionOption("o_counter"),
new ResolutionCriterionOption(), new ResolutionCriterionOption(),
ListFilterModel.createCriterionOption("duration"), ListFilterModel.createCriterionOption("duration"),
new HasMarkersCriterionOption(), new HasMarkersCriterionOption(),
@@ -294,7 +296,7 @@ export class ListFilterModel {
q: this.searchTerm, q: this.searchTerm,
page: this.currentPage, page: this.currentPage,
per_page: this.itemsPerPage, per_page: this.itemsPerPage,
sort: this.getSortBy(), sort: this.sortBy,
direction: this.sortDirection direction: this.sortDirection
}; };
} }
@@ -311,6 +313,11 @@ export class ListFilterModel {
}; };
break; break;
} }
case "o_counter": {
const oCounterCrit = criterion as NumberCriterion;
result.o_counter = { value: oCounterCrit.value, modifier: oCounterCrit.modifier };
break;
}
case "resolution": { case "resolution": {
switch ((criterion as ResolutionCriterion).value) { switch ((criterion as ResolutionCriterion).value) {
case "240p": case "240p":