Adding the ability to support different Haptic Devices (#5856)

* refactored `Interactive` class to allow more HapticDevice devices
* simplified api hooks
* update creation of `interactive` to pass `stashConfig`
* updated UIPluginApi to mention `PluginApi.InteractiveUtils`
This commit is contained in:
xtc1337
2025-09-25 00:27:58 -05:00
committed by GitHub
parent c9ca40152f
commit 15bf28d5be
6 changed files with 186 additions and 15 deletions

View File

@@ -66,7 +66,7 @@ This namespace contains all of the components available to plugins. These includ
### `utils`
This namespace provides access to the `NavUtils` and `StashService` namespaces. It also provides access to the `loadComponents` method.
This namespace provides access to the `NavUtils` , `StashService` and `InteractiveUtils` namespaces. It also provides access to the `loadComponents` method.
#### `PluginApi.utils.loadComponents`
@@ -80,6 +80,72 @@ In general, `PluginApi.hooks.useLoadComponents` hook should be used instead.
Returns a `Promise<void>` that resolves when all of the components have been loaded.
#### `PluginApi.utils.InteractiveUtils`
This namespace provides access to `interactiveClientProvider` and `getPlayer`
- `getPlayer` returns the current `videojs` player object
- `interactiveClientProvider` takes `IInteractiveClientProvider` which allows a developer to hook into the lifecycle of funscripts.
```ts
export interface IDeviceSettings {
connectionKey: string;
scriptOffset: number;
estimatedServerTimeOffset?: number;
useStashHostedFunscript?: boolean;
[key: string]: unknown;
}
export interface IInteractiveClientProviderOptions {
handyKey: string;
scriptOffset: number;
defaultClientProvider?: IInteractiveClientProvider;
stashConfig?: GQL.ConfigDataFragment;
}
export interface IInteractiveClientProvider {
(options: IInteractiveClientProviderOptions): IInteractiveClient;
}
/**
* Interface that is used for InteractiveProvider
*/
export interface IInteractiveClient {
connect(): Promise<void>;
handyKey: string;
uploadScript: (funscriptPath: string, apiKey?: string) => Promise<void>;
sync(): Promise<number>;
configure(config: Partial<IDeviceSettings>): Promise<void>;
play(position: number): Promise<void>;
pause(): Promise<void>;
ensurePlaying(position: number): Promise<void>;
setLooping(looping: boolean): Promise<void>;
readonly connected: boolean;
readonly playing: boolean;
}
```
##### Example
For instance say I wanted to add extra logging when `IInteractiveClient.connect()` is called.
In my plugin you would install your own client provider as seen below
```ts
InteractiveUtils.interactiveClientProvider = (
opts
) => {
if (!opts.defaultClientProvider) {
throw new Error('invalid setup');
}
const client = opts.defaultClientProvider(opts);
const connect = client.connect;
client.connect = async () => {
console.log('patching connect method');
return connect.call(client);
};
return client;
};
```
### `hooks`
This namespace provides access to the following core utility hooks:
@@ -251,3 +317,5 @@ Allows plugins to listen for Stash's events.
```js
PluginApi.Event.addEventListener("stash:location", (e) => console.log("Page Changed", e.detail.data.location.pathname))
```