mirror of
https://github.com/Mintplex-Labs/anything-llm.git
synced 2024-11-19 04:30:10 +01:00
Dark mode chat window (#2443)
* Support XLSX files (#2403) * support xlsx files * lint * create seperate docs for each xlsx sheet * lint * use node-xlsx pkg for parsing xslx files * lint * update error handling --------- Co-authored-by: timothycarambat <rambat1010@gmail.com> * wip chat window * ux+ux improvements and update new colors * chat window dark mode * remove comment --------- Co-authored-by: timothycarambat <rambat1010@gmail.com>
This commit is contained in:
parent
88f5bb5ce1
commit
29eff8a27f
@ -33,6 +33,7 @@
|
|||||||
"mime": "^3.0.0",
|
"mime": "^3.0.0",
|
||||||
"moment": "^2.29.4",
|
"moment": "^2.29.4",
|
||||||
"node-html-parser": "^6.1.13",
|
"node-html-parser": "^6.1.13",
|
||||||
|
"node-xlsx": "^0.24.0",
|
||||||
"officeparser": "^4.0.5",
|
"officeparser": "^4.0.5",
|
||||||
"openai": "4.38.5",
|
"openai": "4.38.5",
|
||||||
"pdf-parse": "^1.1.1",
|
"pdf-parse": "^1.1.1",
|
||||||
@ -48,4 +49,4 @@
|
|||||||
"nodemon": "^2.0.22",
|
"nodemon": "^2.0.22",
|
||||||
"prettier": "^2.4.1"
|
"prettier": "^2.4.1"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
113
collector/processSingleFile/convert/asXlsx.js
Normal file
113
collector/processSingleFile/convert/asXlsx.js
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
const { v4 } = require("uuid");
|
||||||
|
const xlsx = require("node-xlsx").default;
|
||||||
|
const path = require("path");
|
||||||
|
const fs = require("fs");
|
||||||
|
const {
|
||||||
|
createdDate,
|
||||||
|
trashFile,
|
||||||
|
writeToServerDocuments,
|
||||||
|
} = require("../../utils/files");
|
||||||
|
const { tokenizeString } = require("../../utils/tokenizer");
|
||||||
|
const { default: slugify } = require("slugify");
|
||||||
|
|
||||||
|
function convertToCSV(data) {
|
||||||
|
return data
|
||||||
|
.map((row) =>
|
||||||
|
row
|
||||||
|
.map((cell) => {
|
||||||
|
if (cell === null || cell === undefined) return "";
|
||||||
|
if (typeof cell === "string" && cell.includes(","))
|
||||||
|
return `"${cell}"`;
|
||||||
|
return cell;
|
||||||
|
})
|
||||||
|
.join(",")
|
||||||
|
)
|
||||||
|
.join("\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
async function asXlsx({ fullFilePath = "", filename = "" }) {
|
||||||
|
const documents = [];
|
||||||
|
const folderName = slugify(`${path.basename(filename)}-${v4().slice(0, 4)}`, {
|
||||||
|
lower: true,
|
||||||
|
trim: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
const outFolderPath =
|
||||||
|
process.env.NODE_ENV === "development"
|
||||||
|
? path.resolve(
|
||||||
|
__dirname,
|
||||||
|
`../../../server/storage/documents/${folderName}`
|
||||||
|
)
|
||||||
|
: path.resolve(process.env.STORAGE_DIR, `documents/${folderName}`);
|
||||||
|
|
||||||
|
try {
|
||||||
|
const workSheetsFromFile = xlsx.parse(fullFilePath);
|
||||||
|
if (!fs.existsSync(outFolderPath))
|
||||||
|
fs.mkdirSync(outFolderPath, { recursive: true });
|
||||||
|
|
||||||
|
for (const sheet of workSheetsFromFile) {
|
||||||
|
try {
|
||||||
|
const { name, data } = sheet;
|
||||||
|
const content = convertToCSV(data);
|
||||||
|
|
||||||
|
if (!content?.length) {
|
||||||
|
console.warn(`Sheet "${name}" is empty. Skipping.`);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(`-- Processing sheet: ${name} --`);
|
||||||
|
const sheetData = {
|
||||||
|
id: v4(),
|
||||||
|
url: `file://${path.join(outFolderPath, `${slugify(name)}.csv`)}`,
|
||||||
|
title: `${filename} - Sheet:${name}`,
|
||||||
|
docAuthor: "Unknown",
|
||||||
|
description: `Spreadsheet data from sheet: ${name}`,
|
||||||
|
docSource: "an xlsx file uploaded by the user.",
|
||||||
|
chunkSource: "",
|
||||||
|
published: createdDate(fullFilePath),
|
||||||
|
wordCount: content.split(/\s+/).length,
|
||||||
|
pageContent: content,
|
||||||
|
token_count_estimate: tokenizeString(content).length,
|
||||||
|
};
|
||||||
|
|
||||||
|
const document = writeToServerDocuments(
|
||||||
|
sheetData,
|
||||||
|
`sheet-${slugify(name)}`,
|
||||||
|
outFolderPath
|
||||||
|
);
|
||||||
|
documents.push(document);
|
||||||
|
console.log(
|
||||||
|
`[SUCCESS]: Sheet "${name}" converted & ready for embedding.`
|
||||||
|
);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(`Error processing sheet "${name}":`, err);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
console.error("Could not process xlsx file!", err);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
reason: `Error processing ${filename}: ${err.message}`,
|
||||||
|
documents: [],
|
||||||
|
};
|
||||||
|
} finally {
|
||||||
|
trashFile(fullFilePath);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (documents.length === 0) {
|
||||||
|
console.error(`No valid sheets found in ${filename}.`);
|
||||||
|
return {
|
||||||
|
success: false,
|
||||||
|
reason: `No valid sheets found in ${filename}.`,
|
||||||
|
documents: [],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
console.log(
|
||||||
|
`[SUCCESS]: ${filename} fully processed. Created ${documents.length} document(s).\n`
|
||||||
|
);
|
||||||
|
return { success: true, reason: null, documents };
|
||||||
|
}
|
||||||
|
|
||||||
|
module.exports = asXlsx;
|
@ -11,6 +11,10 @@ const ACCEPTED_MIMES = {
|
|||||||
".pptx",
|
".pptx",
|
||||||
],
|
],
|
||||||
|
|
||||||
|
"application/vnd.openxmlformats-officedocument.spreadsheetml.sheet": [
|
||||||
|
".xlsx",
|
||||||
|
],
|
||||||
|
|
||||||
"application/vnd.oasis.opendocument.text": [".odt"],
|
"application/vnd.oasis.opendocument.text": [".odt"],
|
||||||
"application/vnd.oasis.opendocument.presentation": [".odp"],
|
"application/vnd.oasis.opendocument.presentation": [".odp"],
|
||||||
|
|
||||||
@ -41,6 +45,8 @@ const SUPPORTED_FILETYPE_CONVERTERS = {
|
|||||||
".odt": "./convert/asOfficeMime.js",
|
".odt": "./convert/asOfficeMime.js",
|
||||||
".odp": "./convert/asOfficeMime.js",
|
".odp": "./convert/asOfficeMime.js",
|
||||||
|
|
||||||
|
".xlsx": "./convert/asXlsx.js",
|
||||||
|
|
||||||
".mbox": "./convert/asMbox.js",
|
".mbox": "./convert/asMbox.js",
|
||||||
|
|
||||||
".epub": "./convert/asEPub.js",
|
".epub": "./convert/asEPub.js",
|
||||||
|
@ -2326,6 +2326,13 @@ node-html-parser@^6.1.13:
|
|||||||
css-select "^5.1.0"
|
css-select "^5.1.0"
|
||||||
he "1.2.0"
|
he "1.2.0"
|
||||||
|
|
||||||
|
node-xlsx@^0.24.0:
|
||||||
|
version "0.24.0"
|
||||||
|
resolved "https://registry.yarnpkg.com/node-xlsx/-/node-xlsx-0.24.0.tgz#a6a365acb18ad37c66c2b254b6ebe0c22dc9dc6f"
|
||||||
|
integrity sha512-1olwK48XK9nXZsyH/FCltvGrQYvXXZuxVitxXXv2GIuRm51aBi1+5KwR4rWM4KeO61sFU+00913WLZTD+AcXEg==
|
||||||
|
dependencies:
|
||||||
|
xlsx "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz"
|
||||||
|
|
||||||
nodemailer@6.9.13:
|
nodemailer@6.9.13:
|
||||||
version "6.9.13"
|
version "6.9.13"
|
||||||
resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.9.13.tgz#5b292bf1e92645f4852ca872c56a6ba6c4a3d3d6"
|
resolved "https://registry.yarnpkg.com/nodemailer/-/nodemailer-6.9.13.tgz#5b292bf1e92645f4852ca872c56a6ba6c4a3d3d6"
|
||||||
@ -3528,6 +3535,10 @@ ws@8.14.2:
|
|||||||
resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f"
|
resolved "https://registry.yarnpkg.com/ws/-/ws-8.14.2.tgz#6c249a806eb2db7a20d26d51e7709eab7b2e6c7f"
|
||||||
integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==
|
integrity sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==
|
||||||
|
|
||||||
|
"xlsx@https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz":
|
||||||
|
version "0.20.2"
|
||||||
|
resolved "https://cdn.sheetjs.com/xlsx-0.20.2/xlsx-0.20.2.tgz#0f64eeed3f1a46e64724620c3553f2dbd3cd2d7d"
|
||||||
|
|
||||||
xml2js@^0.6.2:
|
xml2js@^0.6.2:
|
||||||
version "0.6.2"
|
version "0.6.2"
|
||||||
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.6.2.tgz#dd0b630083aa09c161e25a4d0901e2b2a929b499"
|
resolved "https://registry.yarnpkg.com/xml2js/-/xml2js-0.6.2.tgz#dd0b630083aa09c161e25a4d0901e2b2a929b499"
|
||||||
|
@ -53,17 +53,17 @@ function ActionMenu({ chatId, forkThread, isEditing, role }) {
|
|||||||
<DotsThreeVertical size={24} weight="bold" />
|
<DotsThreeVertical size={24} weight="bold" />
|
||||||
</button>
|
</button>
|
||||||
{open && (
|
{open && (
|
||||||
<div className="absolute -top-1 left-7 mt-1 border-[1.5px] border-white/40 rounded-lg bg-[#41454B] bg-opacity-100 flex flex-col shadow-[0_4px_14px_rgba(0,0,0,0.25)] text-white z-99 md:z-10">
|
<div className="absolute -top-1 left-7 mt-1 border-[1.5px] border-white/40 rounded-lg bg-theme-action-menu-bg flex flex-col shadow-[0_4px_14px_rgba(0,0,0,0.25)] text-white z-99 md:z-10">
|
||||||
<button
|
<button
|
||||||
onClick={handleFork}
|
onClick={handleFork}
|
||||||
className="border-none flex items-center gap-x-2 hover:bg-white/10 py-1.5 px-2 transition-colors duration-200 w-full text-left"
|
className="border-none flex items-center gap-x-2 hover:bg-theme-action-menu-item-hover py-1.5 px-2 transition-colors duration-200 w-full text-left"
|
||||||
>
|
>
|
||||||
<TreeView size={18} />
|
<TreeView size={18} />
|
||||||
<span className="text-sm">Fork</span>
|
<span className="text-sm">Fork</span>
|
||||||
</button>
|
</button>
|
||||||
<button
|
<button
|
||||||
onClick={handleDelete}
|
onClick={handleDelete}
|
||||||
className="border-none flex items-center gap-x-2 hover:bg-white/10 py-1.5 px-2 transition-colors duration-200 w-full text-left"
|
className="border-none flex items-center gap-x-2 hover:bg-theme-action-menu-item-hover py-1.5 px-2 transition-colors duration-200 w-full text-left"
|
||||||
>
|
>
|
||||||
<Trash size={18} />
|
<Trash size={18} />
|
||||||
<span className="text-sm">Delete</span>
|
<span className="text-sm">Delete</span>
|
||||||
|
@ -5,7 +5,6 @@ import Actions from "./Actions";
|
|||||||
import renderMarkdown from "@/utils/chat/markdown";
|
import renderMarkdown from "@/utils/chat/markdown";
|
||||||
import { userFromStorage } from "@/utils/request";
|
import { userFromStorage } from "@/utils/request";
|
||||||
import Citations from "../Citation";
|
import Citations from "../Citation";
|
||||||
import { AI_BACKGROUND_COLOR, USER_BACKGROUND_COLOR } from "@/utils/constants";
|
|
||||||
import { v4 } from "uuid";
|
import { v4 } from "uuid";
|
||||||
import createDOMPurify from "dompurify";
|
import createDOMPurify from "dompurify";
|
||||||
import { EditMessageForm, useEditMessage } from "./Actions/EditMessage";
|
import { EditMessageForm, useEditMessage } from "./Actions/EditMessage";
|
||||||
@ -43,9 +42,7 @@ const HistoricalMessage = ({
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={uuid}
|
key={uuid}
|
||||||
className={`flex justify-center items-end w-full ${
|
className={`flex justify-center items-end w-full bg-theme-bg-chat`}
|
||||||
role === "user" ? USER_BACKGROUND_COLOR : AI_BACKGROUND_COLOR
|
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
<div className="py-8 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col">
|
<div className="py-8 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col">
|
||||||
<div className="flex gap-x-5">
|
<div className="flex gap-x-5">
|
||||||
@ -68,14 +65,12 @@ const HistoricalMessage = ({
|
|||||||
if (completeDelete) return null;
|
if (completeDelete) return null;
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
key={uuid}
|
key={uuid}
|
||||||
onAnimationEnd={onEndAnimation}
|
onAnimationEnd={onEndAnimation}
|
||||||
className={`${
|
className={`${
|
||||||
isDeleted ? "animate-remove" : ""
|
isDeleted ? "animate-remove" : ""
|
||||||
} flex justify-center items-end w-full group ${
|
} flex justify-center items-end w-full group bg-theme-bg-chat`}
|
||||||
role === "user" ? USER_BACKGROUND_COLOR : AI_BACKGROUND_COLOR
|
>
|
||||||
}`}
|
|
||||||
>
|
|
||||||
<div className="py-8 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col">
|
<div className="py-8 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col">
|
||||||
<div className="flex gap-x-5">
|
<div className="flex gap-x-5">
|
||||||
<div className="flex flex-col items-center">
|
<div className="flex flex-col items-center">
|
||||||
|
@ -13,7 +13,8 @@ const PromptReply = ({
|
|||||||
sources = [],
|
sources = [],
|
||||||
closed = true,
|
closed = true,
|
||||||
}) => {
|
}) => {
|
||||||
const assistantBackgroundColor = "bg-historical-msg-system";
|
const assistantBackgroundColor = "bg-theme-bg-chat";
|
||||||
|
|
||||||
if (!reply && sources.length === 0 && !pending && !error) return null;
|
if (!reply && sources.length === 0 && !pending && !error) return null;
|
||||||
|
|
||||||
if (pending) {
|
if (pending) {
|
||||||
@ -57,11 +58,11 @@ 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-6 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col">
|
<div className="py-8 px-4 w-full flex gap-x-5 md:max-w-[80%] flex-col">
|
||||||
<div className="flex gap-x-5">
|
<div className="flex gap-x-5">
|
||||||
<WorkspaceProfileImage workspace={workspace} />
|
<WorkspaceProfileImage workspace={workspace} />
|
||||||
<span
|
<span
|
||||||
className={`reply flex flex-col gap-y-1 mt-2`}
|
className={`overflow-x-scroll break-words no-scroll`}
|
||||||
dangerouslySetInnerHTML={{ __html: renderMarkdown(reply) }}
|
dangerouslySetInnerHTML={{ __html: renderMarkdown(reply) }}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
|
@ -17,7 +17,7 @@ export default function AvailableAgentsButton({ showing, setShowAgents }) {
|
|||||||
showing ? "!opacity-100" : ""
|
showing ? "!opacity-100" : ""
|
||||||
}`}
|
}`}
|
||||||
>
|
>
|
||||||
<At className="w-6 h-6 pointer-events-none text-white" />
|
<At className="w-[22px] h-[22px] pointer-events-none text-white" />
|
||||||
<Tooltip
|
<Tooltip
|
||||||
id="tooltip-agent-list-btn"
|
id="tooltip-agent-list-btn"
|
||||||
place="top"
|
place="top"
|
||||||
|
@ -25,7 +25,7 @@ export default function AttachItem() {
|
|||||||
}}
|
}}
|
||||||
className={`border-none relative flex justify-center items-center opacity-60 hover:opacity-100 cursor-pointer`}
|
className={`border-none relative flex justify-center items-center opacity-60 hover:opacity-100 cursor-pointer`}
|
||||||
>
|
>
|
||||||
<PaperclipHorizontal className="w-6 h-6 pointer-events-none text-white rotate-90 -scale-y-100" />
|
<PaperclipHorizontal className="w-[22px] h-[22px] pointer-events-none text-white rotate-90 -scale-y-100" />
|
||||||
<Tooltip
|
<Tooltip
|
||||||
id="attach-item-btn"
|
id="attach-item-btn"
|
||||||
place="top"
|
place="top"
|
||||||
|
@ -18,7 +18,7 @@ export default function SlashCommandsButton({ showing, setShowSlashCommand }) {
|
|||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
src={SlashCommandIcon}
|
src={SlashCommandIcon}
|
||||||
className="w-6 h-6 pointer-events-none"
|
className="w-[20px] h-[20px] pointer-events-none"
|
||||||
alt="Slash commands button"
|
alt="Slash commands button"
|
||||||
/>
|
/>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
|
@ -104,7 +104,7 @@ export default function SpeechToText({ sendCommand }) {
|
|||||||
>
|
>
|
||||||
<Microphone
|
<Microphone
|
||||||
weight="fill"
|
weight="fill"
|
||||||
className={`w-6 h-6 pointer-events-none text-white overflow-hidden rounded-full ${
|
className={`w-[22px] h-[21px] pointer-events-none text-white overflow-hidden rounded-full ${
|
||||||
listening ? "animate-pulse-glow" : ""
|
listening ? "animate-pulse-glow" : ""
|
||||||
}`}
|
}`}
|
||||||
/>
|
/>
|
||||||
|
@ -21,7 +21,7 @@ export default function TextSizeButton() {
|
|||||||
>
|
>
|
||||||
<TextT
|
<TextT
|
||||||
weight="fill"
|
weight="fill"
|
||||||
className="w-6 h-6 pointer-events-none text-white"
|
className="w-[22px] h-[22px] pointer-events-none text-white"
|
||||||
/>
|
/>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
id="tooltip-text-size-btn"
|
id="tooltip-text-size-btn"
|
||||||
|
@ -89,7 +89,7 @@ export default function PromptInput({
|
|||||||
const adjustTextArea = (event) => {
|
const adjustTextArea = (event) => {
|
||||||
const element = event.target;
|
const element = event.target;
|
||||||
element.style.height = "auto";
|
element.style.height = "auto";
|
||||||
element.style.height = `${element.scrollHeight}px`;
|
element.style.height = `${element.scrollHeight + 12}px`;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handlePasteEvent = (e) => {
|
const handlePasteEvent = (e) => {
|
||||||
@ -150,9 +150,9 @@ export default function PromptInput({
|
|||||||
className="flex flex-col gap-y-1 rounded-t-lg md:w-3/4 w-full mx-auto max-w-xl items-center"
|
className="flex flex-col gap-y-1 rounded-t-lg md:w-3/4 w-full mx-auto max-w-xl items-center"
|
||||||
>
|
>
|
||||||
<div className="flex items-center rounded-lg md:mb-4">
|
<div className="flex items-center rounded-lg md:mb-4">
|
||||||
<div className="w-[95vw] md:w-[635px] bg-main-gradient shadow-2xl border border-white/50 rounded-2xl flex flex-col px-4 overflow-hidden">
|
<div className="w-[95vw] md:w-[635px] bg-theme-bg-chat-input shadow-sm rounded-2xl flex flex-col px-4 overflow-hidden">
|
||||||
<AttachmentManager attachments={attachments} />
|
<AttachmentManager attachments={attachments} />
|
||||||
<div className="flex items-center w-full border-b-2 border-gray-500/50">
|
<div className="flex items-center w-full border-b-2 border-theme-chat-input-border">
|
||||||
<textarea
|
<textarea
|
||||||
ref={textareaRef}
|
ref={textareaRef}
|
||||||
onChange={(e) => {
|
onChange={(e) => {
|
||||||
@ -172,7 +172,7 @@ export default function PromptInput({
|
|||||||
adjustTextArea(e);
|
adjustTextArea(e);
|
||||||
}}
|
}}
|
||||||
value={promptInput}
|
value={promptInput}
|
||||||
className="cursor-text max-h-[50vh] md:max-h-[350px] md:min-h-[40px] mx-2 md:mx-0 py-2 w-full text-[16px] md:text-md text-white bg-transparent placeholder:text-white/60 resize-none active:outline-none focus:outline-none flex-grow"
|
className="cursor-text max-h-[50vh] md:max-h-[350px] md:min-h-[40px] mx-2 md:mx-0 pt-[12px] w-full text-[14px] leading-5 md:text-md text-white bg-transparent placeholder:text-white/60 resize-none active:outline-none focus:outline-none flex-grow"
|
||||||
placeholder={"Send a message"}
|
placeholder={"Send a message"}
|
||||||
/>
|
/>
|
||||||
{buttonDisabled ? (
|
{buttonDisabled ? (
|
||||||
@ -187,7 +187,7 @@ export default function PromptInput({
|
|||||||
data-tooltip-content="Send prompt message to workspace"
|
data-tooltip-content="Send prompt message to workspace"
|
||||||
aria-label="Send prompt message to workspace"
|
aria-label="Send prompt message to workspace"
|
||||||
>
|
>
|
||||||
<PaperPlaneRight className="w-7 h-7 my-3" weight="fill" />
|
<PaperPlaneRight className="w-[21px] h-[24px]" weight="fill" />
|
||||||
<span className="sr-only">Send message</span>
|
<span className="sr-only">Send message</span>
|
||||||
</button>
|
</button>
|
||||||
<Tooltip
|
<Tooltip
|
||||||
|
@ -263,7 +263,7 @@ export default function ChatContainer({ workspace, knownHistory = [] }) {
|
|||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{ height: isMobile ? "100%" : "calc(100% - 32px)" }}
|
style={{ height: isMobile ? "100%" : "calc(100% - 32px)" }}
|
||||||
className="transition-all duration-500 relative md:ml-[2px] md:mr-[16px] md:my-[16px] md:rounded-[16px] bg-main-gradient w-full h-full overflow-y-scroll border-2 border-outline no-scroll"
|
className="transition-all duration-500 relative md:ml-[2px] md:mr-[16px] md:my-[16px] md:rounded-[16px] bg-theme-bg-secondary w-full h-full overflow-y-scroll no-scroll"
|
||||||
>
|
>
|
||||||
{isMobile && <SidebarMobileHeader />}
|
{isMobile && <SidebarMobileHeader />}
|
||||||
<DnDFileUploaderWrapper>
|
<DnDFileUploaderWrapper>
|
||||||
|
@ -3,12 +3,12 @@ import * as Skeleton from "react-loading-skeleton";
|
|||||||
import "react-loading-skeleton/dist/skeleton.css";
|
import "react-loading-skeleton/dist/skeleton.css";
|
||||||
|
|
||||||
export default function LoadingChat() {
|
export default function LoadingChat() {
|
||||||
const highlightColor = "#3D4147";
|
const highlightColor = "var(--theme-bg-primary)";
|
||||||
const baseColor = "#2C2F35";
|
const baseColor = "var(--theme-bg-secondary)";
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
style={{ height: isMobile ? "100%" : "calc(100% - 32px)" }}
|
className="transition-all duration-500 relative md:ml-[2px] md:mr-[16px] md:my-[16px] md:rounded-[16px] bg-theme-bg-secondary w-full h-full overflow-y-scroll no-scroll p-4"
|
||||||
className="p-4 transition-all duration-500 relative md:ml-[2px] md:mr-[8px] md:my-[16px] md:rounded-[26px] bg-main-gradient w-full h-full overflow-y-scroll"
|
style={{ height: "calc(100% - 32px)" }}
|
||||||
>
|
>
|
||||||
<Skeleton.default
|
<Skeleton.default
|
||||||
height="100px"
|
height="100px"
|
||||||
|
@ -5,9 +5,11 @@
|
|||||||
:root {
|
:root {
|
||||||
/* Default theme */
|
/* Default theme */
|
||||||
--theme-bg-primary: #0e0f0f;
|
--theme-bg-primary: #0e0f0f;
|
||||||
--theme-bg-secondary: rgba(255, 255, 255, 0.05);
|
--theme-bg-secondary: #1B1B1E;
|
||||||
--theme-bg-sidebar: #0e0f0f;
|
--theme-bg-sidebar: #0e0f0f;
|
||||||
--theme-bg-container: #0e0f0f;
|
--theme-bg-container: #0e0f0f;
|
||||||
|
--theme-bg-chat: #1B1B1E;
|
||||||
|
--theme-bg-chat-input: #27282A;
|
||||||
--theme-text-primary: #ffffff;
|
--theme-text-primary: #ffffff;
|
||||||
--theme-text-secondary: rgba(255, 255, 255, 0.6);
|
--theme-text-secondary: rgba(255, 255, 255, 0.6);
|
||||||
--theme-sidebar-item-default: rgba(255, 255, 255, 0.1);
|
--theme-sidebar-item-default: rgba(255, 255, 255, 0.1);
|
||||||
@ -19,6 +21,9 @@
|
|||||||
--theme-sidebar-footer-icon: rgba(255, 255, 255, 0.1);
|
--theme-sidebar-footer-icon: rgba(255, 255, 255, 0.1);
|
||||||
--theme-sidebar-footer-icon-hover: rgba(255, 255, 255, 0.2);
|
--theme-sidebar-footer-icon-hover: rgba(255, 255, 255, 0.2);
|
||||||
--theme-sidebar-border: rgba(255, 255, 255, 0.1);
|
--theme-sidebar-border: rgba(255, 255, 255, 0.1);
|
||||||
|
--theme-chat-input-border: #525355;
|
||||||
|
--theme-action-menu-bg: #27282A;
|
||||||
|
--theme-action-menu-item-hover: rgba(255, 255, 255, 0.1);
|
||||||
}
|
}
|
||||||
|
|
||||||
[data-theme="light"] {
|
[data-theme="light"] {
|
||||||
|
@ -52,6 +52,8 @@ export default {
|
|||||||
secondary: 'var(--theme-bg-secondary)',
|
secondary: 'var(--theme-bg-secondary)',
|
||||||
sidebar: 'var(--theme-bg-sidebar)',
|
sidebar: 'var(--theme-bg-sidebar)',
|
||||||
container: 'var(--theme-bg-container)',
|
container: 'var(--theme-bg-container)',
|
||||||
|
chat: 'var(--theme-bg-chat)',
|
||||||
|
"chat-input": 'var(--theme-bg-chat-input)',
|
||||||
},
|
},
|
||||||
text: {
|
text: {
|
||||||
primary: 'var(--theme-text-primary)',
|
primary: 'var(--theme-text-primary)',
|
||||||
@ -74,6 +76,13 @@ export default {
|
|||||||
},
|
},
|
||||||
border: 'var(--theme-sidebar-border)',
|
border: 'var(--theme-sidebar-border)',
|
||||||
},
|
},
|
||||||
|
"chat-input": {
|
||||||
|
border: 'var(--theme-chat-input-border)',
|
||||||
|
},
|
||||||
|
"action-menu": {
|
||||||
|
bg: 'var(--theme-action-menu-bg)',
|
||||||
|
"item-hover": 'var(--theme-action-menu-item-hover)',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
backgroundImage: {
|
backgroundImage: {
|
||||||
|
Loading…
Reference in New Issue
Block a user