import { useEffect, useState } from "react"; import { toast } from "react-hot-toast"; import { useTranslation } from "react-i18next"; import { Button, Divider, Input, Switch, Textarea } from "@mui/joy"; import { formatBytes } from "@/helpers/utils"; import { useGlobalStore } from "@/store/module"; import * as api from "@/helpers/api"; import HelpButton from "../kit/HelpButton"; import showUpdateCustomizedProfileDialog from "../UpdateCustomizedProfileDialog"; import "@/less/settings/system-section.less"; interface State { dbSize: number; allowSignUp: boolean; ignoreUpgrade: boolean; disablePublicMemos: boolean; additionalStyle: string; additionalScript: string; maxUploadSizeMiB: number; memoDisplayWithUpdatedTs: boolean; } const SystemSection = () => { const { t } = useTranslation(); const globalStore = useGlobalStore(); const systemStatus = globalStore.state.systemStatus; const [state, setState] = useState({ dbSize: systemStatus.dbSize, allowSignUp: systemStatus.allowSignUp, ignoreUpgrade: systemStatus.ignoreUpgrade, additionalStyle: systemStatus.additionalStyle, additionalScript: systemStatus.additionalScript, disablePublicMemos: systemStatus.disablePublicMemos, maxUploadSizeMiB: systemStatus.maxUploadSizeMiB, memoDisplayWithUpdatedTs: systemStatus.memoDisplayWithUpdatedTs, }); const [telegramBotToken, setTelegramBotToken] = useState(""); const [openAIConfig, setOpenAIConfig] = useState({ key: "", host: "", }); useEffect(() => { globalStore.fetchSystemStatus(); }, []); useEffect(() => { api.getSystemSetting().then(({ data: { data: systemSettings } }) => { const openAIConfigSetting = systemSettings.find((setting) => setting.name === "openai-config"); if (openAIConfigSetting) { setOpenAIConfig(JSON.parse(openAIConfigSetting.value)); } const telegramBotSetting = systemSettings.find((setting) => setting.name === "telegram-bot-token"); if (telegramBotSetting) { setTelegramBotToken(telegramBotSetting.value); } }); }, []); useEffect(() => { setState({ ...state, dbSize: systemStatus.dbSize, allowSignUp: systemStatus.allowSignUp, additionalStyle: systemStatus.additionalStyle, additionalScript: systemStatus.additionalScript, disablePublicMemos: systemStatus.disablePublicMemos, maxUploadSizeMiB: systemStatus.maxUploadSizeMiB, memoDisplayWithUpdatedTs: systemStatus.memoDisplayWithUpdatedTs, }); }, [systemStatus]); const handleAllowSignUpChanged = async (value: boolean) => { setState({ ...state, allowSignUp: value, }); await api.upsertSystemSetting({ name: "allow-signup", value: JSON.stringify(value), }); }; const handleIgnoreUpgradeChanged = async (value: boolean) => { setState({ ...state, ignoreUpgrade: value, }); await api.upsertSystemSetting({ name: "ignore-upgrade", value: JSON.stringify(value), }); }; const handleUpdateCustomizedProfileButtonClick = () => { showUpdateCustomizedProfileDialog(); }; const handleVacuumBtnClick = async () => { try { await api.vacuumDatabase(); await globalStore.fetchSystemStatus(); } catch (error) { console.error(error); return; } toast.success(t("message.succeed-vacuum-database")); }; const handleOpenAIConfigKeyChanged = (value: string) => { setOpenAIConfig({ ...openAIConfig, key: value, }); }; const handleOpenAIConfigHostChanged = (value: string) => { setOpenAIConfig({ ...openAIConfig, host: value, }); }; const handleSaveOpenAIConfig = async () => { try { await api.upsertSystemSetting({ name: "openai-config", value: JSON.stringify(openAIConfig), }); } catch (error) { console.error(error); return; } toast.success("OpenAI Config updated"); }; const handleTelegramBotTokenChanged = (value: string) => { setTelegramBotToken(value); }; const handleSaveTelegramBotToken = async () => { try { await api.upsertSystemSetting({ name: "telegram-bot-token", value: telegramBotToken, }); } catch (error: any) { console.error(error); toast.error(error.response.data.message); return; } toast.success("Telegram Bot Token updated"); }; const handleAdditionalStyleChanged = (value: string) => { setState({ ...state, additionalStyle: value, }); }; const handleSaveAdditionalStyle = async () => { try { await api.upsertSystemSetting({ name: "additional-style", value: JSON.stringify(state.additionalStyle), }); } catch (error) { console.error(error); return; } toast.success(t("message.succeed-update-additional-style")); }; const handleAdditionalScriptChanged = (value: string) => { setState({ ...state, additionalScript: value, }); }; const handleSaveAdditionalScript = async () => { try { await api.upsertSystemSetting({ name: "additional-script", value: JSON.stringify(state.additionalScript), }); } catch (error) { console.error(error); return; } toast.success(t("message.succeed-update-additional-script")); }; const handleDisablePublicMemosChanged = async (value: boolean) => { setState({ ...state, disablePublicMemos: value, }); globalStore.setSystemStatus({ disablePublicMemos: value }); await api.upsertSystemSetting({ name: "disable-public-memos", value: JSON.stringify(value), }); }; const handleMemoDisplayWithUpdatedTs = async (value: boolean) => { setState({ ...state, memoDisplayWithUpdatedTs: value, }); globalStore.setSystemStatus({ disablePublicMemos: value }); await api.upsertSystemSetting({ name: "memo-display-with-updated-ts", value: JSON.stringify(value), }); }; const handleMaxUploadSizeChanged = async (event: React.FocusEvent) => { // fixes cursor skipping position on mobile event.target.selectionEnd = event.target.value.length; let num = parseInt(event.target.value); if (Number.isNaN(num)) { num = 0; } setState({ ...state, maxUploadSizeMiB: num, }); event.target.value = num.toString(); globalStore.setSystemStatus({ maxUploadSizeMiB: num }); await api.upsertSystemSetting({ name: "max-upload-size-mib", value: JSON.stringify(num), }); }; const handleMaxUploadSizeFocus = (event: React.FocusEvent) => { event.target.select(); }; return (

{t("common.basic")}

{t("setting.system-section.server-name")}: {systemStatus.customizedProfile.name}
{t("setting.system-section.database-file-size")}: {formatBytes(state.dbSize)}

{t("common.settings")}

{t("setting.system-section.allow-user-signup")} handleAllowSignUpChanged(event.target.checked)} />
{t("setting.system-section.ignore-version-upgrade")} handleIgnoreUpgradeChanged(event.target.checked)} />
{t("setting.system-section.disable-public-memos")} handleDisablePublicMemosChanged(event.target.checked)} />
Display with updated time handleMemoDisplayWithUpdatedTs(event.target.checked)} />
{t("setting.system-section.max-upload-size")}
{t("setting.system-section.telegram-bot-token")}
handleTelegramBotTokenChanged(event.target.value)} />
{t("setting.system-section.openai-api-key")}
handleOpenAIConfigKeyChanged(event.target.value)} />
{t("setting.system-section.openai-api-host")}
handleOpenAIConfigHostChanged(event.target.value)} />
{t("setting.system-section.additional-style")}