Skip to content
Snippets Groups Projects
Unverified Commit ff5d7d83 authored by Sean Hatfield's avatar Sean Hatfield Committed by GitHub
Browse files

[FEAT] Chat UI font size (#1172)

* WIP text font size change feature

* store text size settings in localstorage and improve styles of popup menu
parent 323c080b
No related branches found
No related tags found
No related merge requests found
...@@ -44,7 +44,7 @@ const HistoricalMessage = ({ ...@@ -44,7 +44,7 @@ const HistoricalMessage = ({
</div> </div>
) : ( ) : (
<span <span
className={`flex flex-col gap-y-1 mt-2`} className={`flex flex-col gap-y-1`}
dangerouslySetInnerHTML={{ dangerouslySetInnerHTML={{
__html: DOMPurify.sanitize(renderMarkdown(message)), __html: DOMPurify.sanitize(renderMarkdown(message)),
}} }}
......
...@@ -21,7 +21,7 @@ const PromptReply = ({ ...@@ -21,7 +21,7 @@ const PromptReply = ({
<div <div
className={`flex justify-center items-end w-full ${assistantBackgroundColor}`} className={`flex justify-center items-end w-full ${assistantBackgroundColor}`}
> >
<div className="py-8 px-4 w-full flex gap-x-5 md:max-w-[800px] flex-col"> <div className="py-6 px-4 w-full flex gap-x-5 md:max-w-[800px] flex-col">
<div className="flex gap-x-5"> <div className="flex gap-x-5">
<WorkspaceProfileImage workspace={workspace} /> <WorkspaceProfileImage workspace={workspace} />
<div className="mt-3 ml-5 dot-falling"></div> <div className="mt-3 ml-5 dot-falling"></div>
...@@ -36,7 +36,7 @@ const PromptReply = ({ ...@@ -36,7 +36,7 @@ const PromptReply = ({
<div <div
className={`flex justify-center items-end w-full ${assistantBackgroundColor}`} className={`flex justify-center items-end w-full ${assistantBackgroundColor}`}
> >
<div className="py-8 px-4 w-full flex gap-x-5 md:max-w-[800px] flex-col"> <div className="py-6 px-4 w-full flex gap-x-5 md:max-w-[800px] flex-col">
<div className="flex gap-x-5"> <div className="flex gap-x-5">
<WorkspaceProfileImage workspace={workspace} /> <WorkspaceProfileImage workspace={workspace} />
<span <span
...@@ -57,7 +57,7 @@ const PromptReply = ({ ...@@ -57,7 +57,7 @@ const PromptReply = ({
key={uuid} key={uuid}
className={`flex justify-center items-end w-full ${assistantBackgroundColor}`} className={`flex justify-center items-end w-full ${assistantBackgroundColor}`}
> >
<div className="py-8 px-4 w-full flex gap-x-5 md:max-w-[800px] flex-col"> <div className="py-6 px-4 w-full flex gap-x-5 md:max-w-[800px] flex-col">
<div className="flex gap-x-5"> <div className="flex gap-x-5">
<WorkspaceProfileImage workspace={workspace} /> <WorkspaceProfileImage workspace={workspace} />
<span <span
......
...@@ -12,6 +12,36 @@ export default function ChatHistory({ history = [], workspace, sendCommand }) { ...@@ -12,6 +12,36 @@ export default function ChatHistory({ history = [], workspace, sendCommand }) {
const { showing, showModal, hideModal } = useManageWorkspaceModal(); const { showing, showModal, hideModal } = useManageWorkspaceModal();
const [isAtBottom, setIsAtBottom] = useState(true); const [isAtBottom, setIsAtBottom] = useState(true);
const chatHistoryRef = useRef(null); const chatHistoryRef = useRef(null);
const [textSize, setTextSize] = useState("normal");
const getTextSizeClass = (size) => {
switch (size) {
case "small":
return "text-[12px]";
case "large":
return "text-[18px]";
default:
return "text-[14px]";
}
};
useEffect(() => {
const storedTextSize = window.localStorage.getItem("anythingllm_text_size");
if (storedTextSize) {
setTextSize(getTextSizeClass(storedTextSize));
}
const handleTextSizeChange = (event) => {
const size = event.detail;
setTextSize(getTextSizeClass(size));
};
window.addEventListener("textSizeChange", handleTextSizeChange);
return () => {
window.removeEventListener("textSizeChange", handleTextSizeChange);
};
}, []);
useEffect(() => { useEffect(() => {
if (isAtBottom) scrollToBottom(); if (isAtBottom) scrollToBottom();
...@@ -91,7 +121,7 @@ export default function ChatHistory({ history = [], workspace, sendCommand }) { ...@@ -91,7 +121,7 @@ export default function ChatHistory({ history = [], workspace, sendCommand }) {
return ( return (
<div <div
className="markdown text-white/80 font-light text-sm h-full md:h-[83%] pb-[100px] pt-6 md:pt-0 md:pb-20 md:mx-0 overflow-y-scroll flex flex-col justify-start no-scroll" className={`markdown text-white/80 font-light ${textSize} h-full md:h-[83%] pb-[100px] pt-6 md:pt-0 md:pb-20 md:mx-0 overflow-y-scroll flex flex-col justify-start no-scroll`}
id="chat-history" id="chat-history"
ref={chatHistoryRef} ref={chatHistoryRef}
> >
......
import { useState, useRef, useEffect } from "react";
import { TextT } from "@phosphor-icons/react";
import { Tooltip } from "react-tooltip";
export default function TextSizeButton() {
const [showTextSizeMenu, setShowTextSizeMenu] = useState(false);
const buttonRef = useRef(null);
return (
<>
<div
ref={buttonRef}
id="text-size-btn"
data-tooltip-id="tooltip-text-size-btn"
data-tooltip-content="Change text size"
aria-label="Change text size"
onClick={() => setShowTextSizeMenu(!showTextSizeMenu)}
className={`relative flex justify-center items-center opacity-60 hover:opacity-100 cursor-pointer ${
showTextSizeMenu ? "!opacity-100" : ""
}`}
>
<TextT
weight="fill"
className="w-6 h-6 pointer-events-none text-white"
/>
<Tooltip
id="tooltip-text-size-btn"
place="top"
delayShow={300}
className="tooltip !text-xs z-99"
/>
</div>
<TextSizeMenu
showing={showTextSizeMenu}
setShowing={setShowTextSizeMenu}
buttonRef={buttonRef}
/>
</>
);
}
function TextSizeMenu({ showing, setShowing, buttonRef }) {
const formRef = useRef(null);
const [selectedSize, setSelectedSize] = useState(
window.localStorage.getItem("anythingllm_text_size") || "normal"
);
useEffect(() => {
function listenForOutsideClick() {
if (!showing || !formRef.current) return false;
document.addEventListener("click", closeIfOutside);
}
listenForOutsideClick();
}, [showing, formRef.current]);
const closeIfOutside = ({ target }) => {
if (target.id === "text-size-btn") return;
const isOutside = !formRef?.current?.contains(target);
if (!isOutside) return;
setShowing(false);
};
const handleTextSizeChange = (size) => {
setSelectedSize(size);
window.localStorage.setItem("anythingllm_text_size", size);
window.dispatchEvent(new CustomEvent("textSizeChange", { detail: size }));
};
if (!buttonRef.current) return null;
return (
<div hidden={!showing}>
<div
ref={formRef}
className="absolute bottom-16 -ml-8 w-[140px] p-2 bg-zinc-800 rounded-lg shadow-md flex flex-col justify-center items-start gap-2 z-50"
>
<button
onClick={(e) => {
e.preventDefault();
setShowing(false);
handleTextSizeChange("small");
}}
className={`w-full hover:cursor-pointer px-2 py-1 rounded-md flex flex-col justify-start group ${
selectedSize === "small" ? "bg-zinc-700" : "hover:bg-zinc-700"
}`}
>
<div className="w-full flex-col text-left flex pointer-events-none">
<div className="text-white text-xs">Small</div>
</div>
</button>
<button
onClick={(e) => {
e.preventDefault();
setShowing(false);
handleTextSizeChange("normal");
}}
className={`w-full hover:cursor-pointer px-2 py-1 rounded-md flex flex-col justify-start group ${
selectedSize === "normal" ? "bg-zinc-700" : "hover:bg-zinc-700"
}`}
>
<div className="w-full flex-col text-left flex pointer-events-none">
<div className="text-white text-sm">Normal</div>
</div>
</button>
<button
onClick={(e) => {
e.preventDefault();
setShowing(false);
handleTextSizeChange("large");
}}
className={`w-full hover:cursor-pointer px-2 py-1 rounded-md flex flex-col justify-start group ${
selectedSize === "large" ? "bg-zinc-700" : "hover:bg-zinc-700"
}`}
>
<div className="w-full flex-col text-left flex pointer-events-none">
<div className="text-white text-[16px]">Large</div>
</div>
</button>
</div>
</div>
);
}
...@@ -11,6 +11,7 @@ import AvailableAgentsButton, { ...@@ -11,6 +11,7 @@ import AvailableAgentsButton, {
AvailableAgents, AvailableAgents,
useAvailableAgents, useAvailableAgents,
} from "./AgentMenu"; } from "./AgentMenu";
import TextSizeButton from "./TextSizeMenu";
export default function PromptInput({ export default function PromptInput({
message, message,
submit, submit,
...@@ -137,6 +138,7 @@ export default function PromptInput({ ...@@ -137,6 +138,7 @@ export default function PromptInput({
showing={showAgents} showing={showAgents}
setShowAgents={setShowAgents} setShowAgents={setShowAgents}
/> />
<TextSizeButton />
</div> </div>
</div> </div>
</div> </div>
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment