mirror of
https://github.com/Mintplex-Labs/anything-llm.git
synced 2025-05-02 17:07:13 +00:00
[FEAT] Chat UI font size (#1172)
* WIP text font size change feature * store text size settings in localstorage and improve styles of popup menu
This commit is contained in:
parent
323c080b5e
commit
ff5d7d8372
5 changed files with 161 additions and 5 deletions
|
@ -44,7 +44,7 @@ const HistoricalMessage = ({
|
|||
</div>
|
||||
) : (
|
||||
<span
|
||||
className={`flex flex-col gap-y-1 mt-2`}
|
||||
className={`flex flex-col gap-y-1`}
|
||||
dangerouslySetInnerHTML={{
|
||||
__html: DOMPurify.sanitize(renderMarkdown(message)),
|
||||
}}
|
||||
|
|
|
@ -21,7 +21,7 @@ const PromptReply = ({
|
|||
<div
|
||||
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">
|
||||
<WorkspaceProfileImage workspace={workspace} />
|
||||
<div className="mt-3 ml-5 dot-falling"></div>
|
||||
|
@ -36,7 +36,7 @@ const PromptReply = ({
|
|||
<div
|
||||
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">
|
||||
<WorkspaceProfileImage workspace={workspace} />
|
||||
<span
|
||||
|
@ -57,7 +57,7 @@ const PromptReply = ({
|
|||
key={uuid}
|
||||
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">
|
||||
<WorkspaceProfileImage workspace={workspace} />
|
||||
<span
|
||||
|
|
|
@ -12,6 +12,36 @@ export default function ChatHistory({ history = [], workspace, sendCommand }) {
|
|||
const { showing, showModal, hideModal } = useManageWorkspaceModal();
|
||||
const [isAtBottom, setIsAtBottom] = useState(true);
|
||||
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(() => {
|
||||
if (isAtBottom) scrollToBottom();
|
||||
|
@ -91,7 +121,7 @@ export default function ChatHistory({ history = [], workspace, sendCommand }) {
|
|||
|
||||
return (
|
||||
<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"
|
||||
ref={chatHistoryRef}
|
||||
>
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
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, {
|
|||
AvailableAgents,
|
||||
useAvailableAgents,
|
||||
} from "./AgentMenu";
|
||||
import TextSizeButton from "./TextSizeMenu";
|
||||
export default function PromptInput({
|
||||
message,
|
||||
submit,
|
||||
|
@ -137,6 +138,7 @@ export default function PromptInput({
|
|||
showing={showAgents}
|
||||
setShowAgents={setShowAgents}
|
||||
/>
|
||||
<TextSizeButton />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue