diff --git a/packages/chat/package.json b/packages/chat/package.json index f26624fe1..285e4b8f9 100644 --- a/packages/chat/package.json +++ b/packages/chat/package.json @@ -1,6 +1,6 @@ { "name": "@nestia/chat", - "version": "0.3.2", + "version": "0.3.3", "type": "module", "main": "./lib/index.mjs", "typings": "./lib/index.d.ts", diff --git a/packages/chat/src/movies/NestiaChatMovie.tsx b/packages/chat/src/movies/NestiaChatMovie.tsx index 6674af710..4b0cc3536 100644 --- a/packages/chat/src/movies/NestiaChatMovie.tsx +++ b/packages/chat/src/movies/NestiaChatMovie.tsx @@ -1,14 +1,21 @@ import AddAPhotoIcon from "@mui/icons-material/AddAPhoto"; +import ReceiptLongIcon from "@mui/icons-material/ReceiptLong"; import SendIcon from "@mui/icons-material/Send"; import { AppBar, Button, Container, + Drawer, + IconButton, Input, + Theme, Toolbar, Typography, + useMediaQuery, + useTheme, } from "@mui/material"; import { + INestiaAgentEvent, INestiaAgentOperationSelection, INestiaAgentPrompt, INestiaAgentTokenUsage, @@ -23,13 +30,17 @@ import { NestiaChatMessageMovie } from "./messages/NestiaChatMessageMovie"; import { NestiaChatSideMovie } from "./sides/NestiaChatSideMovie"; export const NestiaChatMovie = ({ agent }: NestiaChatMovie.IProps) => { + //---- + // VARIABLES + //---- + // REFERENCES const upperDivRef = useRef(null); const middleDivRef = useRef(null); const bottomDivRef = useRef(null); const bodyContainerRef = useRef(null); - const scrollRef = useRef(null); const inputRef = useRef(null); + // STATES const [error, setError] = useState(null); const [text, setText] = useState(""); const [histories, setHistories] = useState( @@ -43,41 +54,57 @@ export const NestiaChatMovie = ({ agent }: NestiaChatMovie.IProps) => { const [selections, setSelections] = useState< INestiaAgentOperationSelection[] >([]); + const [openSide, setOpenSide] = useState(false); - useEffect(() => { - if (inputRef.current !== null) inputRef.current.select(); - agent.on("text", (evt) => { - histories.push(evt); - setHistories(histories); - }); - agent.on("describe", (evt) => { - histories.push(evt); - setHistories(histories); + //---- + // EVENT INTERACTIONS + //---- + // EVENT LISTENERS + const handleText = (evt: INestiaAgentEvent.IText) => { + histories.push(evt); + setHistories(histories); + }; + const handleDescribe = (evt: INestiaAgentEvent.IDescribe) => { + histories.push(evt); + setHistories(histories); + }; + const handleSelect = (evt: INestiaAgentEvent.ISelect) => { + histories.push({ + type: "select", + id: "something", + operations: [ + { + ...evt.operation, + reason: evt.reason, + toJSON: () => ({}) as any, + } satisfies INestiaAgentOperationSelection, + ], }); - agent.on("select", (evt) => { - histories.push({ - type: "select", - id: "something", - operations: [ - { - ...evt.operation, - reason: evt.reason, - toJSON: () => ({}) as any, - } satisfies INestiaAgentOperationSelection, - ], - }); - setHistories(histories); + setHistories(histories); - selections.push({ - ...evt.operation, - reason: evt.reason, - toJSON: () => ({}) as any, - } satisfies INestiaAgentOperationSelection); - setSelections(selections); - }); + selections.push({ + ...evt.operation, + reason: evt.reason, + toJSON: () => ({}) as any, + } satisfies INestiaAgentOperationSelection); + setSelections(selections); + }; + + // INITIALIZATION + useEffect(() => { + if (inputRef.current !== null) inputRef.current.select(); + agent.on("text", handleText); + agent.on("describe", handleDescribe); + agent.on("select", handleSelect); setTokenUsage(agent.getTokenUsage()); + return () => { + agent.off("text", handleText); + agent.off("describe", handleDescribe); + agent.off("select", handleSelect); + }; }, []); + // EVENT HANDLERS const handleKeyUp = async (event: React.KeyboardEvent) => { if (event.key === "Enter" && event.shiftKey === false) { if (enabled === false) event.preventDefault(); @@ -106,9 +133,10 @@ export const NestiaChatMovie = ({ agent }: NestiaChatMovie.IProps) => { try { await agent.conversate(text); } catch (error) { - console.log(error); - if (error instanceof Error) setError(error); - else setError(new Error("Unknown error")); + if (error instanceof Error) { + alert(error.message); + setError(error); + } else setError(new Error("Unknown error")); return; } @@ -141,7 +169,6 @@ export const NestiaChatMovie = ({ agent }: NestiaChatMovie.IProps) => { const capture = async () => { if (bodyContainerRef.current === null) return; - const canvas: HTMLCanvasElement = await html2canvas( bodyContainerRef.current, { @@ -158,6 +185,53 @@ export const NestiaChatMovie = ({ agent }: NestiaChatMovie.IProps) => { }); }; + //---- + // RENDERERS + //---- + const theme: Theme = useTheme(); + const isMobile: boolean = useMediaQuery(theme.breakpoints.down("lg")); + const bodyMovie = (): JSX.Element => ( + + {histories + .map((prompt) => ) + .filter((elem) => elem !== null)} + + ); + const sideMovie = (): JSX.Element => ( +
+ setOpenSide(false) : undefined} + > + + +
+ ); + return (
@@ -165,13 +239,24 @@ export const NestiaChatMovie = ({ agent }: NestiaChatMovie.IProps) => { Nestia A.I. Chatbot - + {isMobile ? ( + <> + + + + setOpenSide(true)}> + + + + ) : ( + + )}
{ flexDirection: "row", }} > -
- - {histories - .map((prompt) => ) - .filter((elem) => elem !== null)} - -
-
- - - -
+ {isMobile ? ( + <> + {bodyMovie()} + setOpenSide(false)} + > + {sideMovie()} + + + ) : ( + <> + {bodyMovie()} + {sideMovie()} + + )}
diff --git a/packages/chat/src/movies/messages/NestiaChatSelectMessageMovie.tsx b/packages/chat/src/movies/messages/NestiaChatSelectMessageMovie.tsx index 5e3eabf9b..1f0e94ecd 100644 --- a/packages/chat/src/movies/messages/NestiaChatSelectMessageMovie.tsx +++ b/packages/chat/src/movies/messages/NestiaChatSelectMessageMovie.tsx @@ -22,7 +22,7 @@ export const NestiaChatSelectMessageMovie = ({ style={{ marginTop: 15, marginBottom: 15, - marginRight: 200, + marginRight: "15%", }} > diff --git a/packages/chat/src/movies/messages/NestiaChatTextMessageMovie.tsx b/packages/chat/src/movies/messages/NestiaChatTextMessageMovie.tsx index 37662aefa..9f4bb755a 100644 --- a/packages/chat/src/movies/messages/NestiaChatTextMessageMovie.tsx +++ b/packages/chat/src/movies/messages/NestiaChatTextMessageMovie.tsx @@ -20,8 +20,8 @@ export const NestiaChatTextMessageMovie = ({ style={{ marginTop: 15, marginBottom: 15, - marginLeft: prompt.role === "user" ? 200 : undefined, - marginRight: prompt.role === "assistant" ? 200 : undefined, + marginLeft: prompt.role === "user" ? "15%" : undefined, + marginRight: prompt.role === "assistant" ? "15%" : undefined, textAlign: prompt.role === "user" ? "right" : "left", backgroundColor: prompt.role === "user" ? "lightyellow" : undefined, }}