diff --git a/ui/v2.5/src/components/Scenes/SceneDetails/SceneFileInfoPanel.tsx b/ui/v2.5/src/components/Scenes/SceneDetails/SceneFileInfoPanel.tsx index de65f7ed0..8db3f9388 100644 --- a/ui/v2.5/src/components/Scenes/SceneDetails/SceneFileInfoPanel.tsx +++ b/ui/v2.5/src/components/Scenes/SceneDetails/SceneFileInfoPanel.tsx @@ -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 = ( +const _SceneFileInfoPanel: React.FC = ( props: ISceneFileInfoPanelProps ) => { const Toast = useToast(); @@ -315,4 +316,8 @@ export const SceneFileInfoPanel: React.FC = ( ); }; +export const SceneFileInfoPanel = PatchComponent( + "SceneFileInfoPanel", + _SceneFileInfoPanel +); export default SceneFileInfoPanel; diff --git a/ui/v2.5/src/hooks/Interactive/context.tsx b/ui/v2.5/src/hooks/Interactive/context.tsx index 487fa8468..04c2548ab 100644 --- a/ui/v2.5/src/hooks/Interactive/context.tsx +++ b/ui/v2.5/src/hooks/Interactive/context.tsx @@ -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; diff --git a/ui/v2.5/src/pluginApi.d.ts b/ui/v2.5/src/pluginApi.d.ts index bbdc9fcff..21629dda5 100644 --- a/ui/v2.5/src/pluginApi.d.ts +++ b/ui/v2.5/src/pluginApi.d.ts @@ -687,7 +687,9 @@ declare namespace PluginApi { NumberSetting: React.FC; StringListSetting: React.FC; ConstantSetting: React.FC; + SceneFileInfoPanel: React.FC; }; + 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; + set handyKey(key: string); + get handyKey(): string; + set useStashHostedFunscript(useStashHostedFunscript: boolean); + get useStashHostedFunscript(): boolean; + set scriptOffset(offset: number); + uploadScript(funscriptPath: string, apiKey?: string): Promise; + sync(): Promise; + setServerTimeOffset(offset: number): void; + play(position: number): Promise; + pause(): Promise; + ensurePlaying(position: number): Promise; + setLooping(looping: boolean): Promise; + }; + + function useInteractive(): { + interactive: InteractiveAPI; + state: ConnectionState; + serverOffset: number; + initialised: boolean; + currentScript?: string; + error?: string; + initialise: () => Promise; + uploadScript: (funscriptPath: string) => Promise; + sync: () => Promise; + }; } 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): void; diff --git a/ui/v2.5/src/pluginApi.tsx b/ui/v2.5/src/pluginApi.tsx index f35fb0fe6..ac8fcf840 100644 --- a/ui/v2.5/src/pluginApi.tsx +++ b/ui/v2.5/src/pluginApi.tsx @@ -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