[FEAT] Implement width and height resizing options for embed chat widget (#1278)

* WIP embed app window size

* fix UI when resizing window and add text size customization option

* update stylying for dims

* publish new embed

---------

Co-authored-by: timothycarambat <rambat1010@gmail.com>
This commit is contained in:
Sean Hatfield 2024-05-08 14:11:55 -07:00 committed by GitHub
parent 977a07db86
commit b2b41db110
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
10 changed files with 46 additions and 17 deletions

View File

@ -87,6 +87,12 @@ REQUIRED data attributes:
- `data-assistant-icon` - Set the icon of the chat assistant. - `data-assistant-icon` - Set the icon of the chat assistant.
- `data-window-height` - Set the chat window height. **must include CSS suffix:** `px`,`%`,`rem`
- `data-window-width` - Set the chat window width. **must include CSS suffix:** `px`,`%`,`rem`
- `data-text-size` - Set the text size of the chats in pixels.
**Behavior Overrides** **Behavior Overrides**
- `data-open-on-load` — Once loaded, open the chat as default. It can still be closed by the user. - `data-open-on-load` — Once loaded, open the chat as default. It can still be closed by the user.

View File

@ -1,5 +1,6 @@
<!doctype html> <!doctype html>
<html lang="en"> <html lang="en">
<body> <body>
<h1>This is an example testing page for embedded AnythingLLM.</h1> <h1>This is an example testing page for embedded AnythingLLM.</h1>
<!-- <!--
@ -8,4 +9,5 @@
</script> </script>
--> -->
</body> </body>
</html>
</html>

View File

@ -27,13 +27,19 @@ export default function App() {
}; };
const position = embedSettings.position || "bottom-right"; const position = embedSettings.position || "bottom-right";
const windowWidth = embedSettings.windowWidth
? `md:max-w-[${embedSettings.windowWidth}]`
: "md:max-w-[400px]";
const windowHeight = embedSettings.windowHeight
? `md:max-h-[${embedSettings.windowHeight}]`
: "md:max-h-[700px]";
return ( return (
<> <>
<Head /> <Head />
<div className={`fixed inset-0 z-50 ${isChatOpen ? "block" : "hidden"}`}> <div className={`fixed inset-0 z-50 ${isChatOpen ? "block" : "hidden"}`}>
<div <div
className={`w-full h-full bg-white md:max-w-[400px] md:max-h-[700px] md:fixed md:bottom-0 md:right-0 md:mb-4 md:mr-4 md:rounded-2xl md:border md:border-gray-300 md:shadow-[0_4px_14px_rgba(0,0,0,0.25)] ${positionClasses[position]}`} className={`${windowHeight} ${windowWidth} h-full w-full bg-white md:fixed md:bottom-0 md:right-0 md:mb-4 md:mr-4 md:rounded-2xl md:border md:border-gray-300 md:shadow-[0_4px_14px_rgba(0,0,0,0.25)] ${positionClasses[position]}`}
id="anything-llm-chat" id="anything-llm-chat"
> >
{isChatOpen && ( {isChatOpen && (

View File

@ -13,6 +13,10 @@ const HistoricalMessage = forwardRef(
{ uuid = v4(), message, role, sources = [], error = false, sentAt }, { uuid = v4(), message, role, sources = [], error = false, sentAt },
ref ref
) => { ) => {
const textSize = !!embedderSettings.settings.textSize
? `text-[${embedderSettings.settings.textSize}px]`
: "text-sm";
return ( return (
<div className="py-[5px]"> <div className="py-[5px]">
{role === "assistant" && ( {role === "assistant" && (
@ -61,7 +65,7 @@ const HistoricalMessage = forwardRef(
</div> </div>
) : ( ) : (
<span <span
className={`whitespace-pre-line font-medium flex flex-col gap-y-1 text-sm leading-[20px]`} className={`whitespace-pre-line font-medium flex flex-col gap-y-1 ${textSize} leading-[20px]`}
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(renderMarkdown(message)), __html: DOMPurify.sanitize(renderMarkdown(message)),
}} }}

View File

@ -58,7 +58,7 @@ export default function ChatHistory({ settings = {}, history = [] }) {
return ( return (
<div <div
className="pb-[30px] pt-[5px] rounded-lg px-2 h-full gap-y-2 overflow-y-scroll flex flex-col justify-start no-scroll md:max-h-[500px] max-h-[calc(100vh-200px)]" className="pb-[30px] pt-[5px] rounded-lg px-2 h-full gap-y-2 overflow-y-scroll flex flex-col justify-start no-scroll md:max-h-[500px]"
id="chat-history" id="chat-history"
ref={chatHistoryRef} ref={chatHistoryRef}
> >

View File

@ -46,7 +46,7 @@ export default function PromptInput({
}; };
return ( return (
<div className="w-full absolute left-0 bottom-[25px] z-10 flex justify-center items-center px-5"> <div className="w-full sticky bottom-0 z-10 flex justify-center items-center px-5 bg-white">
<form <form
onSubmit={handleSubmit} onSubmit={handleSubmit}
className="flex flex-col gap-y-1 rounded-t-lg w-full items-center justify-center" className="flex flex-col gap-y-1 rounded-t-lg w-full items-center justify-center"

View File

@ -26,6 +26,7 @@ export default function ChatContainer({
const handleSubmit = async (event) => { const handleSubmit = async (event) => {
event.preventDefault(); event.preventDefault();
if (!message || message === "") return false; if (!message || message === "") return false;
const prevChatHistory = [ const prevChatHistory = [
@ -39,7 +40,6 @@ export default function ChatContainer({
animate: true, animate: true,
}, },
]; ];
setChatHistory(prevChatHistory); setChatHistory(prevChatHistory);
setMessage(""); setMessage("");
setLoadingResponse(true); setLoadingResponse(true);
@ -72,12 +72,15 @@ export default function ChatContainer({
); );
return; return;
} }
loadingResponse === true && fetchReply(); loadingResponse === true && fetchReply();
}, [loadingResponse, chatHistory]); }, [loadingResponse, chatHistory]);
return ( return (
<div className="h-full w-full relative"> <div className="h-full w-full flex flex-col">
<ChatHistory settings={settings} history={chatHistory} /> <div className="flex-grow overflow-y-auto">
<ChatHistory settings={settings} history={chatHistory} />
</div>
<PromptInput <PromptInput
message={message} message={message}
submit={handleSubmit} submit={handleSubmit}

View File

@ -32,6 +32,7 @@ export default function ChatWindow({ closeChat, settings, sessionId }) {
} }
setEventDelegatorForCodeSnippets(); setEventDelegatorForCodeSnippets();
return ( return (
<div className="flex flex-col h-full"> <div className="flex flex-col h-full">
<ChatWindowHeader <ChatWindowHeader
@ -41,12 +42,14 @@ export default function ChatWindow({ closeChat, settings, sessionId }) {
closeChat={closeChat} closeChat={closeChat}
setChatHistory={setChatHistory} setChatHistory={setChatHistory}
/> />
<ChatContainer <div className="flex-grow overflow-y-auto">
sessionId={sessionId} <ChatContainer
settings={settings} sessionId={sessionId}
knownHistory={chatHistory} settings={settings}
/> knownHistory={chatHistory}
<div className="-mt-2 pb-6 h-fit gap-y-2 z-10"> />
</div>
<div className="mt-4 pb-4 h-fit gap-y-2 z-10">
<Sponsor settings={settings} /> <Sponsor settings={settings} />
<ResetChat <ResetChat
setChatHistory={setChatHistory} setChatHistory={setChatHistory}
@ -64,6 +67,7 @@ export default function ChatWindow({ closeChat, settings, sessionId }) {
function copyCodeSnippet(uuid) { function copyCodeSnippet(uuid) {
const target = document.querySelector(`[data-code="${uuid}"]`); const target = document.querySelector(`[data-code="${uuid}"]`);
if (!target) return false; if (!target) return false;
const markdown = const markdown =
target.parentElement?.parentElement?.querySelector( target.parentElement?.parentElement?.querySelector(
"pre:first-of-type" "pre:first-of-type"
@ -71,6 +75,7 @@ function copyCodeSnippet(uuid) {
if (!markdown) return false; if (!markdown) return false;
window.navigator.clipboard.writeText(markdown); window.navigator.clipboard.writeText(markdown);
target.classList.add("text-green-500"); target.classList.add("text-green-500");
const originalText = target.innerHTML; const originalText = target.innerHTML;
target.innerText = "Copied!"; target.innerText = "Copied!";

View File

@ -23,6 +23,9 @@ const DEFAULT_SETTINGS = {
position: "bottom-right", // position of chat button/window position: "bottom-right", // position of chat button/window
assistantName: "AnythingLLM Chat Assistant", // default assistant name assistantName: "AnythingLLM Chat Assistant", // default assistant name
assistantIcon: null, // default assistant icon assistantIcon: null, // default assistant icon
windowHeight: null, // height of chat window in number:css-prefix
windowWidth: null, // width of chat window in number:css-prefix
textSize: null, // text size in px (number only)
// behaviors // behaviors
openOnLoad: "off", // or "on" openOnLoad: "off", // or "on"

File diff suppressed because one or more lines are too long