anything-llm/server/utils/files/logo.js
Sean Hatfield 727d802779
Light/dark mode UI overhaul (#2629)
* Refactor workspace sidebar component styles (#2380)

rely on css for conditional styles

* New sidebar colors (#2381)

new sidebar colors

* Main container color update (#2382)

* Dark mode setup themes (#2411)

* setup generic tailwind theme + ability to add new themes

* add theme context

* use correct colors from design for sidebar + fix padding

* Settings sidebar UI updates (#2416)

settings sidebar ui updates

* fix sidebar resizing/truncate issue on hover

* 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>

* Dark mode welcome page (#2444)

* dark mode welcome page styles + refactor

* remove AI_BACKGROUND_COLOR and USER_BACKGROUND_COLOR constants

* Dark mode UI for admin and tools pages + mobile view improvements (#2454)

* dark mode ui for admin and tools pages + mobile view improvements

* lint

* ai provider pages + options darkmode ui

* placeholder generic class

* appearance settings styles

* ai providers mobile margin

* dark mode styles for agent skills + experimental features

* mobile styles on security settings

* fine tune flow ui dark mode

* workspace settings page

* lint

* Dark mode onboarding (#2461)

dark mode onboarding

* update all modals + normalize styles (#2471)

* lint

* Dark mode privacy & experimental pages (#2479)

* document watch + privacy pages ui + mobile modal darkmode

* lint

* Dark mode login screens (#2483)

* multi-user auth screen ui update

* dark mode login screen + recovery key modals

* remove unneeded import

* Workspace preset commands modals dark mode (#2484)

update workspace preset dark mode modal

* Document pinning modal ui update (#2490)

document pinning modal ui update

* Experimental agreement modal dark mode (#2491)

experimental agreement modal dark mode

* Serp options dark mode (#2492)

serp options dark mode

* field fixes

* attempt light mode wip

* setting sidebar

* Toasts and threads

* main page content and privacy page

* force rewrite for light

* add border for light mode rightside content

* more fixes

* wip

* wip

* wip light mode implementation

* wip dark light mode file picker

* document picker light mode ui

* slight ui tweaks

* light mode fine tuning flow

* light mode tweaks + qa fixes

* fix md rendering of light mode + tooltip fixes

* lint

* qa bug fixes

* Add developer hook for theme
move provider to outmost layer

* qa light mode bug fixes

* Linting and hotfixes for UI

* Light mode to dev

* accept invite light mode ui fix

* Fix onboarding inputs in dark mode

* fix close icons
last minute items

* patch z-index on tooltips

* patch light mode citations

---------

Co-authored-by: timothycarambat <rambat1010@gmail.com>
2024-11-18 15:40:18 -08:00

115 lines
3.6 KiB
JavaScript

const path = require("path");
const fs = require("fs");
const { getType } = require("mime");
const { v4 } = require("uuid");
const { SystemSettings } = require("../../models/systemSettings");
const { normalizePath, isWithin } = require(".");
const LOGO_FILENAME = "anything-llm.png";
const LOGO_FILENAME_DARK = "anything-llm-dark.png";
/**
* Checks if the filename is the default logo filename for dark or light mode.
* @param {string} filename - The filename to check.
* @returns {boolean} Whether the filename is the default logo filename.
*/
function isDefaultFilename(filename) {
return [LOGO_FILENAME, LOGO_FILENAME_DARK].includes(filename);
}
function validFilename(newFilename = "") {
return !isDefaultFilename(newFilename);
}
/**
* Shows the logo for the current theme. In dark mode, it shows the light logo
* and vice versa.
* @param {boolean} darkMode - Whether the logo should be for dark mode.
* @returns {string} The filename of the logo.
*/
function getDefaultFilename(darkMode = true) {
return darkMode ? LOGO_FILENAME : LOGO_FILENAME_DARK;
}
async function determineLogoFilepath(defaultFilename = LOGO_FILENAME) {
const currentLogoFilename = await SystemSettings.currentLogoFilename();
const basePath = process.env.STORAGE_DIR
? path.join(process.env.STORAGE_DIR, "assets")
: path.join(__dirname, "../../storage/assets");
const defaultFilepath = path.join(basePath, defaultFilename);
if (currentLogoFilename && validFilename(currentLogoFilename)) {
customLogoPath = path.join(basePath, normalizePath(currentLogoFilename));
if (!isWithin(path.resolve(basePath), path.resolve(customLogoPath)))
return defaultFilepath;
return fs.existsSync(customLogoPath) ? customLogoPath : defaultFilepath;
}
return defaultFilepath;
}
function fetchLogo(logoPath) {
if (!fs.existsSync(logoPath)) {
return {
found: false,
buffer: null,
size: 0,
mime: "none/none",
};
}
const mime = getType(logoPath);
const buffer = fs.readFileSync(logoPath);
return {
found: true,
buffer,
size: buffer.length,
mime,
};
}
async function renameLogoFile(originalFilename = null) {
const extname = path.extname(originalFilename) || ".png";
const newFilename = `${v4()}${extname}`;
const assetsDirectory = process.env.STORAGE_DIR
? path.join(process.env.STORAGE_DIR, "assets")
: path.join(__dirname, `../../storage/assets`);
const originalFilepath = path.join(
assetsDirectory,
normalizePath(originalFilename)
);
if (!isWithin(path.resolve(assetsDirectory), path.resolve(originalFilepath)))
throw new Error("Invalid file path.");
// The output always uses a random filename.
const outputFilepath = process.env.STORAGE_DIR
? path.join(process.env.STORAGE_DIR, "assets", normalizePath(newFilename))
: path.join(__dirname, `../../storage/assets`, normalizePath(newFilename));
fs.renameSync(originalFilepath, outputFilepath);
return newFilename;
}
async function removeCustomLogo(logoFilename = LOGO_FILENAME) {
if (!logoFilename || !validFilename(logoFilename)) return false;
const assetsDirectory = process.env.STORAGE_DIR
? path.join(process.env.STORAGE_DIR, "assets")
: path.join(__dirname, `../../storage/assets`);
const logoPath = path.join(assetsDirectory, normalizePath(logoFilename));
if (!isWithin(path.resolve(assetsDirectory), path.resolve(logoPath)))
throw new Error("Invalid file path.");
if (fs.existsSync(logoPath)) fs.unlinkSync(logoPath);
return true;
}
module.exports = {
fetchLogo,
renameLogoFile,
removeCustomLogo,
validFilename,
getDefaultFilename,
determineLogoFilepath,
isDefaultFilename,
LOGO_FILENAME,
};