Interactive Tools Enhancements Support (#5115)

* added `useInteractive` hook and exposed to `PluginApi`
* made `SceneFileInfoPanel` patchable
This commit is contained in:
blackx69 2024-08-05 19:34:27 -05:00 committed by GitHub
parent c79f299d1a
commit c8d4dacffd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 60 additions and 5 deletions

View File

@ -17,6 +17,7 @@ import NavUtils from "src/utils/navigation";
import TextUtils from "src/utils/text";
import { TextField, URLField, URLsField } from "src/utils/field";
import { StashIDPill } from "src/components/Shared/StashID";
import { PatchComponent } from "../../../patch";
interface IFileInfoPanelProps {
sceneID: string;
@ -174,7 +175,7 @@ interface ISceneFileInfoPanelProps {
scene: GQL.SceneDataFragment;
}
export const SceneFileInfoPanel: React.FC<ISceneFileInfoPanelProps> = (
const _SceneFileInfoPanel: React.FC<ISceneFileInfoPanelProps> = (
props: ISceneFileInfoPanelProps
) => {
const Toast = useToast();
@ -315,4 +316,8 @@ export const SceneFileInfoPanel: React.FC<ISceneFileInfoPanelProps> = (
);
};
export const SceneFileInfoPanel = PatchComponent(
"SceneFileInfoPanel",
_SceneFileInfoPanel
);
export default SceneFileInfoPanel;

View File

@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useState } from "react";
import React, { useCallback, useContext, useEffect, useState } from "react";
import { ConfigurationContext } from "../Config";
import { useLocalForage } from "../LocalForage";
import { Interactive as InteractiveAPI } from "./interactive";
@ -208,4 +208,7 @@ export const InteractiveProvider: React.FC = ({ children }) => {
);
};
export const useInteractive = () => {
return useContext(InteractiveContext);
};
export default InteractiveProvider;

View File

@ -687,7 +687,9 @@ declare namespace PluginApi {
NumberSetting: React.FC<any>;
StringListSetting: React.FC<any>;
ConstantSetting: React.FC<any>;
SceneFileInfoPanel: React.FC<any>;
};
type PatchableComponentNames = keyof typeof components | string;
namespace utils {
namespace NavUtils {
function makePerformerScenesUrl(...args: any[]): any;
@ -955,11 +957,54 @@ declare namespace PluginApi {
refetch: () => void;
};
export enum ConnectionState {
Missing,
Disconnected,
Error,
Connecting,
Syncing,
Uploading,
Ready,
}
type Handy = typeof import("thehandy").default;
export type InteractiveAPI = {
readonly _connected: boolean;
readonly _playing: boolean;
readonly _scriptOffset: number;
readonly _handy: Handy;
readonly _useStashHostedFunscript: boolean;
connect(): Promise<void>;
set handyKey(key: string);
get handyKey(): string;
set useStashHostedFunscript(useStashHostedFunscript: boolean);
get useStashHostedFunscript(): boolean;
set scriptOffset(offset: number);
uploadScript(funscriptPath: string, apiKey?: string): Promise<void>;
sync(): Promise<number>;
setServerTimeOffset(offset: number): void;
play(position: number): Promise<void>;
pause(): Promise<void>;
ensurePlaying(position: number): Promise<void>;
setLooping(looping: boolean): Promise<void>;
};
function useInteractive(): {
interactive: InteractiveAPI;
state: ConnectionState;
serverOffset: number;
initialised: boolean;
currentScript?: string;
error?: string;
initialise: () => Promise<void>;
uploadScript: (funscriptPath: string) => Promise<void>;
sync: () => Promise<void>;
};
}
namespace patch {
function before(target: string, fn: Function): void;
function instead(target: string, fn: Function): void;
function after(target: string, fn: Function): void;
function before(target: PatchableComponentNames, fn: Function): void;
function instead(target: PatchableComponentNames, fn: Function): void;
function after(target: PatchableComponentNames, fn: Function): void;
}
namespace register {
function route(path: string, component: React.FC<any>): void;

View File

@ -16,6 +16,7 @@ import { useToast } from "./hooks/Toast";
import Event from "./hooks/event";
import { before, instead, after, components, RegisterComponent } from "./patch";
import { useSettings } from "./components/Settings/context";
import { useInteractive } from "./hooks/Interactive/context";
// due to code splitting, some components may not have been loaded when a plugin
// page is loaded. This function will load all components passed to it.
@ -94,6 +95,7 @@ export const PluginApi = {
useSpriteInfo,
useToast,
useSettings,
useInteractive,
},
patch: {
// intercept the arguments of supported functions