@charisma-ai/react
Version:
Charisma.ai chat component for React
68 lines (67 loc) • 2.7 kB
JavaScript
import React, { createContext, useContext, useEffect, useState } from "react";
import { Playthrough as PlaythroughClass, setGlobalBaseUrl } from "@charisma-ai/sdk";
import useChangeableRef from "./useChangeableRef.js";
// Preserve equality across renders by defining this function outside the component.
const noOp = ()=>undefined;
export const usePlaythrough = ({ playthroughToken, charismaUrl, autoconnect = false, onConnectionStatus = noOp, onError = noOp, onProblem = noOp })=>{
const [playthrough, setPlaythrough] = useState();
const [connectionStatus, setConnectionStatus] = useState("disconnected");
const [playerSessionId, setPlayerSessionId] = useState();
const onConnectionStatusRef = useChangeableRef(onConnectionStatus);
const onErrorRef = useChangeableRef(onError);
const onProblemRef = useChangeableRef(onProblem);
useEffect(()=>{
if (charismaUrl) {
setGlobalBaseUrl(charismaUrl);
}
}, [
charismaUrl
]);
useEffect(()=>{
if (playthroughToken) {
const newPlaythrough = new PlaythroughClass(playthroughToken);
newPlaythrough.on("connection-status", (newConnectionStatus)=>{
setConnectionStatus(newConnectionStatus);
onConnectionStatusRef.current(newConnectionStatus);
}).on("error", (...args)=>onErrorRef.current(...args)).on("problem", (...args)=>onProblemRef.current(...args));
setPlaythrough(newPlaythrough);
return ()=>{
newPlaythrough.disconnect();
};
}
// Without this, TypeScript complains that not all code paths return a value.
return undefined;
}, [
playthroughToken,
// All the below refs never change, this is to satisfy the linter.
onConnectionStatusRef,
onErrorRef,
onProblemRef
]);
useEffect(()=>{
const connect = async ()=>{
if (playthrough && autoconnect) {
const connection = await playthrough.connect();
setPlayerSessionId(connection.playerSessionId);
}
};
connect();
}, [
playthrough,
autoconnect
]);
return {
connectionStatus,
playthrough,
playthroughToken,
playerSessionId
};
};
const PlaythroughContext = /*#__PURE__*/ createContext(undefined);
export const Playthrough = ({ children, ...props })=>{
const playthrough = usePlaythrough(props);
return /*#__PURE__*/ React.createElement(PlaythroughContext.Provider, {
value: playthrough
}, children);
};
export const usePlaythroughContext = ()=>useContext(PlaythroughContext);