Appearance setting for show/hide scroll bar on chat window (#2187)

* implement appearance setting for show/hide scrollbar

* put back comments

* revert backend for show_scrollbar

* show scrollbar save to localstorage

* old model function

* lint

* edit

---------

Co-authored-by: Timothy Carambat <rambat1010@gmail.com>
This commit is contained in:
Sean Hatfield 2024-09-16 16:09:54 -07:00 committed by GitHub
parent a30fa9b2ed
commit fb191d8ba7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 90 additions and 2 deletions

View File

@ -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}
>

View File

@ -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;

View File

@ -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>
);
}

View File

@ -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 />

View File

@ -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",