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

@@ -2,6 +2,10 @@ import React, { useCallback, useContext, useEffect, useState } from "react";
import { ConfigurationContext } from "../Config";
import { useLocalForage } from "../LocalForage";
import { Interactive as InteractiveAPI } from "./interactive";
import InteractiveUtils, {
IInteractiveClient,
IInteractiveClientProvider,
} from "./utils";
export enum ConnectionState {
Missing,
@@ -34,7 +38,7 @@ export function connectionStateLabel(s: ConnectionState) {
}
export interface IState {
interactive: InteractiveAPI;
interactive: IInteractiveClient;
state: ConnectionState;
serverOffset: number;
initialised: boolean;
@@ -69,6 +73,13 @@ interface IInteractiveState {
lastSyncTime: number;
}
export const defaultInteractiveClientProvider: IInteractiveClientProvider = ({
handyKey,
scriptOffset,
}): IInteractiveClient => {
return new InteractiveAPI(handyKey, scriptOffset);
};
export const InteractiveProvider: React.FC = ({ children }) => {
const [{ data: config }, setConfig] = useLocalForage<IInteractiveState>(
LOCAL_FORAGE_KEY,
@@ -85,7 +96,22 @@ export const InteractiveProvider: React.FC = ({ children }) => {
const [scriptOffset, setScriptOffset] = useState<number>(0);
const [useStashHostedFunscript, setUseStashHostedFunscript] =
useState<boolean>(false);
const [interactive] = useState<InteractiveAPI>(new InteractiveAPI("", 0));
const resolveInteractiveClient = useCallback(() => {
const interactiveClientProvider =
InteractiveUtils.interactiveClientProvider ??
defaultInteractiveClientProvider;
return interactiveClientProvider({
handyKey: "",
scriptOffset: 0,
defaultClientProvider: defaultInteractiveClientProvider,
stashConfig,
});
}, [stashConfig]);
// fetch client provider from PluginApi if not found use default provider
const [interactive] = useState(resolveInteractiveClient);
const [initialised, setInitialised] = useState(false);
const [error, setError] = useState<string | undefined>();
@@ -104,7 +130,9 @@ export const InteractiveProvider: React.FC = ({ children }) => {
}
if (config?.serverOffset) {
interactive.setServerTimeOffset(config.serverOffset);
await interactive.configure({
estimatedServerTimeOffset: config.serverOffset,
});
setState(ConnectionState.Connecting);
try {
await interactive.connect();
@@ -138,13 +166,17 @@ export const InteractiveProvider: React.FC = ({ children }) => {
const oldKey = interactive.handyKey;
interactive.handyKey = handyKey ?? "";
interactive.scriptOffset = scriptOffset;
interactive.useStashHostedFunscript = useStashHostedFunscript;
if (oldKey !== interactive.handyKey && interactive.handyKey) {
initialise();
}
interactive
.configure({
connectionKey: handyKey ?? "",
offset: scriptOffset,
useStashHostedFunscript,
})
.then(() => {
if (oldKey !== interactive.handyKey && interactive.handyKey) {
initialise();
}
});
}, [
handyKey,
scriptOffset,
@@ -171,7 +203,7 @@ export const InteractiveProvider: React.FC = ({ children }) => {
const uploadScript = useCallback(
async (funscriptPath: string) => {
interactive.pause();
await interactive.pause();
if (
!interactive.handyKey ||
!funscriptPath ||