diff --git a/frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/index.jsx b/frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/index.jsx index 8a5697f94..458af8590 100644 --- a/frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/index.jsx +++ b/frontend/src/components/WorkspaceChat/ChatContainer/ChatHistory/index.jsx @@ -1,6 +1,6 @@ +import React, { useEffect, useRef, useState } from "react"; import HistoricalMessage from "./HistoricalMessage"; import PromptReply from "./PromptReply"; -import { useEffect, useRef, useState } from "react"; import { useManageWorkspaceModal } from "../../../Modals/ManageWorkspace"; import ManageWorkspace from "../../../Modals/ManageWorkspace"; import { ArrowDown } from "@phosphor-icons/react"; @@ -10,6 +10,7 @@ import Chartable from "./Chartable"; import Workspace from "@/models/workspace"; import { useParams } from "react-router-dom"; import paths from "@/utils/paths"; +import Appearance from "@/models/appearance"; export default function ChatHistory({ history = [], @@ -25,6 +26,7 @@ export default function ChatHistory({ const [isAtBottom, setIsAtBottom] = useState(true); const chatHistoryRef = useRef(null); const [textSize, setTextSize] = useState("normal"); + const showScrollbar = Appearance.getSettings()?.showScrollbar || false; const getTextSizeClass = (size) => { switch (size) { @@ -190,7 +192,9 @@ export default function ChatHistory({ return ( <div - 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`} + 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 ${ + showScrollbar ? "" : "no-scroll" + }`} id="chat-history" ref={chatHistoryRef} > diff --git a/frontend/src/models/appearance.js b/frontend/src/models/appearance.js new file mode 100644 index 000000000..7914da00a --- /dev/null +++ b/frontend/src/models/appearance.js @@ -0,0 +1,25 @@ +import { APPEARANCE_SETTINGS } from "@/utils/constants"; + +const Appearance = { + /** + * Fetches any locally storage settings for the user + * @returns {{showScrollbar: boolean}} + */ + getSettings: () => { + const settings = localStorage.getItem(APPEARANCE_SETTINGS); + return settings ? JSON.parse(settings) : { showScrollbar: false }; + }, + + /** + * Updates locally stored user settings + * @param {object} newSettings - new settings to update. + * @returns {object} + */ + updateSettings: (newSettings) => { + const updatedSettings = { ...Appearance.getSettings(), ...newSettings }; + localStorage.setItem(APPEARANCE_SETTINGS, JSON.stringify(updatedSettings)); + return updatedSettings; + }, +}; + +export default Appearance; diff --git a/frontend/src/pages/GeneralSettings/Appearance/ShowScrollbar/index.jsx b/frontend/src/pages/GeneralSettings/Appearance/ShowScrollbar/index.jsx new file mode 100644 index 000000000..eb8c63378 --- /dev/null +++ b/frontend/src/pages/GeneralSettings/Appearance/ShowScrollbar/index.jsx @@ -0,0 +1,56 @@ +import React, { useState, useEffect } from "react"; +import Appearance from "@/models/appearance"; + +export default function ShowScrollbar() { + const [saving, setSaving] = useState(false); + const [showScrollbar, setShowScrollbar] = useState(false); + + const handleChange = async (e) => { + const newValue = e.target.checked; + setShowScrollbar(newValue); + setSaving(true); + try { + Appearance.updateSettings({ showScrollbar: newValue }); + } catch (error) { + console.error("Failed to update appearance settings:", error); + setShowScrollbar(!newValue); + } + setSaving(false); + }; + + useEffect(() => { + function fetchSettings() { + const settings = Appearance.getSettings(); + setShowScrollbar(settings.showScrollbar); + } + fetchSettings(); + }, []); + + return ( + <div className="flex flex-col w-full gap-y-4 mt-6"> + <div className="flex flex-col gap-y-1"> + <h2 className="text-base leading-6 font-bold text-white"> + Show chat window scrollbar + </h2> + <p className="text-xs leading-[18px] font-base text-white/60"> + Enable or disable the scrollbar in the chat window + </p> + <div className="mt-2"> + <label className="relative inline-flex cursor-pointer items-center"> + <input + id="show_scrollbar" + type="checkbox" + name="show_scrollbar" + value="yes" + checked={showScrollbar} + onChange={handleChange} + disabled={saving} + className="peer sr-only" + /> + <div className="pointer-events-none peer h-6 w-11 rounded-full bg-stone-400 after:absolute after:left-[2px] after:top-[2px] after:h-5 after:w-5 after:rounded-full after:shadow-xl after:border after:border-gray-600 after:bg-white after:box-shadow-md after:transition-all after:content-[''] peer-checked:bg-lime-300 peer-checked:after:translate-x-full peer-checked:after:border-white peer-focus:outline-none peer-focus:ring-4 peer-focus:ring-blue-800"></div> + </label> + </div> + </div> + </div> + ); +} diff --git a/frontend/src/pages/GeneralSettings/Appearance/index.jsx b/frontend/src/pages/GeneralSettings/Appearance/index.jsx index ec3ff2672..afb244395 100644 --- a/frontend/src/pages/GeneralSettings/Appearance/index.jsx +++ b/frontend/src/pages/GeneralSettings/Appearance/index.jsx @@ -8,6 +8,7 @@ import { useTranslation } from "react-i18next"; import CustomAppName from "./CustomAppName"; import LanguagePreference from "./LanguagePreference"; import CustomSiteSettings from "./CustomSiteSettings"; +import ShowScrollbar from "./ShowScrollbar"; export default function Appearance() { const { t } = useTranslation(); @@ -30,6 +31,7 @@ export default function Appearance() { </p> </div> <LanguagePreference /> + <ShowScrollbar /> <CustomLogo /> <CustomAppName /> <CustomMessages /> diff --git a/frontend/src/utils/constants.js b/frontend/src/utils/constants.js index 1fad7389f..8b9c75629 100644 --- a/frontend/src/utils/constants.js +++ b/frontend/src/utils/constants.js @@ -9,6 +9,7 @@ export const SEEN_WATCH_ALERT = "anythingllm_watched_document_alert"; export const USER_BACKGROUND_COLOR = "bg-historical-msg-user"; export const AI_BACKGROUND_COLOR = "bg-historical-msg-system"; +export const APPEARANCE_SETTINGS = "anythingllm_appearance_settings"; export const OLLAMA_COMMON_URLS = [ "http://127.0.0.1:11434",