generated from deco-sites/fashion
-
Notifications
You must be signed in to change notification settings - Fork 16
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
5987e07
commit c8cf93e
Showing
6 changed files
with
160 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,119 @@ | ||
import { useSignal } from "@preact/signals"; | ||
import { useCallback, useEffect, useRef } from "preact/hooks"; | ||
|
||
function Chat() { | ||
const messageEl = useRef<HTMLDivElement>(null); | ||
const userInput = useSignal(""); | ||
const ws = useSignal<WebSocket | null>(null); | ||
const messageList = useSignal<{ content: string; role: "user" | "bot" }[]>( | ||
[], | ||
); | ||
|
||
useEffect(() => { | ||
const host = window.location.host; | ||
const websocket = window.location.protocol === "https:" ? "wss" : "ws"; | ||
ws.value = new WebSocket( | ||
`${websocket}://${host}/live/invoke/ai-assistants/actions/chat.ts?assistant=brand`, | ||
); | ||
ws.value.onmessage = (event: MessageEvent) => { | ||
updateMessages(event.data); | ||
}; | ||
}, []); | ||
|
||
const updateMessages = useCallback((data: string) => { | ||
const newMessageObject: { content: string; role: "user" | "bot" } = { | ||
content: data, | ||
role: "user", | ||
}; | ||
messageList.value = [...messageList.value, newMessageObject]; | ||
}, []); | ||
|
||
useEffect(() => { | ||
// For automatic srolling | ||
const messageElement = messageEl.current; | ||
|
||
if (messageElement) { | ||
const observer = new MutationObserver((mutations) => { | ||
for (const mutation of mutations) { | ||
if (mutation.addedNodes.length) { | ||
messageElement.scrollTop = messageElement.scrollHeight; | ||
} | ||
} | ||
}); | ||
|
||
observer.observe(messageElement, { childList: true }); | ||
|
||
return () => observer.disconnect(); | ||
} | ||
}, []); | ||
|
||
const send = useCallback((text: string) => { | ||
if (ws.value) { | ||
ws.value.send(text); | ||
} | ||
}, []); | ||
|
||
const handleSubmit = () => { | ||
send(userInput.value); | ||
const newMessageObject: { content: string; role: "user" | "bot" } = { | ||
content: userInput.value, | ||
role: "bot", | ||
}; | ||
messageList.value = [...messageList.value, newMessageObject]; | ||
userInput.value = ""; | ||
}; | ||
|
||
const handleKeydown = (e: KeyboardEvent) => { | ||
if (e.key === "Enter" && !e.shiftKey) { | ||
e.preventDefault(); | ||
handleSubmit(); | ||
} | ||
}; | ||
|
||
return ( | ||
<> | ||
<div class="w-96 mb-4 mt-2 shadow-lg rounded-lg h-3/4 flex flex-col justify-end z-50 bg-white fixed bottom-1 right-4"> | ||
<div class="bg-blue-500 flex justify-center p-3 rounded-t-lg text-white"> | ||
DecoBot | ||
</div> | ||
<div | ||
ref={messageEl} | ||
class="h-full overflow-y-auto pt-4 flex flex-col mx-5" | ||
> | ||
{messageList.value.map((message, index) => ( | ||
<div | ||
key={index} | ||
class={`p-2 rounded-2xl mb-3 w-fit text-sm max-w-xs ${ | ||
message.role === "user" | ||
? "bg-gray-200 text-black self-start" | ||
: "bg-blue-600 text-white self-end" | ||
}`} | ||
> | ||
{message.content} | ||
</div> | ||
))} | ||
</div> | ||
<div class="flex flex-row items-center bg-gray-100 rounded-xl relative mb-4 p-4 mt-4 mx-4"> | ||
<textarea | ||
id="userInput" | ||
placeholder="Ask..." | ||
class="w-full grow h-16 outline-none relative resize-none pr-6 bg-gray-100 text-sm" | ||
value={userInput.value} | ||
onInput={(e: Event) => | ||
userInput.value = (e.target as HTMLTextAreaElement).value} | ||
onKeyDown={handleKeydown} | ||
/> | ||
<button | ||
type="button" | ||
class="bg-blue-600 hover:bg-blue-700 absolute rounder-md font-light text-white py-1 px-4 rounded-lg text-sm bottom-3 right-3" | ||
onClick={handleSubmit} | ||
> | ||
Send | ||
</button> | ||
</div> | ||
</div> | ||
</> | ||
); | ||
} | ||
|
||
export default Chat; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,8 +1,8 @@ | ||
{ | ||
"imports": { | ||
"$store/": "./", | ||
"deco/": "https://denopkg.com/deco-cx/[email protected].4/", | ||
"apps/": "https://denopkg.com/deco-cx/apps@0.23.13/", | ||
"deco/": "https://denopkg.com/deco-cx/[email protected].6/", | ||
"apps/": "https://denopkg.com/deco-cx/apps@9dd6db949718be381b9338f8167037b9edaddd63/", | ||
"$fresh/": "https://denopkg.com/denoland/fresh@7ad4610e3a42aba42638cbc1041b96ee58a9b29e/", | ||
"preact": "https://esm.sh/[email protected]", | ||
"preact/": "https://esm.sh/[email protected]/", | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
export { default } from "apps/brand-assistant/sections/Chat.tsx"; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Large diffs are not rendered by default.
Oops, something went wrong.