import { useState, useEffect, useRef, useMemo } from "react";
import EmojiPicker, { Theme as EmojiTheme } from "emoji-picker-react";
import styles from "./settings.module.scss";
import ResetIcon from "../icons/reload.svg";
import CloseIcon from "../icons/close.svg";
import ClearIcon from "../icons/clear.svg";
import EditIcon from "../icons/edit.svg";
import { List, ListItem, Popover, showToast } from "./ui-lib";
import { IconButton } from "./button";
import {
SubmitKey,
useChatStore,
Theme,
ALL_MODELS,
useUpdateStore,
useAccessStore,
} from "../store";
import { Avatar } from "./chat";
import Locale, { AllLangs, changeLang, getLang } from "../locales";
import { getCurrentVersion } from "../utils";
import Link from "next/link";
import { UPDATE_URL } from "../constant";
import { SearchService, usePromptStore } from "../store/prompt";
import { requestUsage } from "../requests";
function SettingItem(props: {
title: string;
subTitle?: string;
children: JSX.Element;
}) {
return (
{props.title}
{props.subTitle && (
{props.subTitle}
)}
{props.children}
);
}
export function Settings(props: { closeSettings: () => void }) {
const [showEmojiPicker, setShowEmojiPicker] = useState(false);
const [config, updateConfig, resetConfig, clearAllData, clearSessions] =
useChatStore((state) => [
state.config,
state.updateConfig,
state.resetConfig,
state.clearAllData,
state.clearSessions,
]);
const updateStore = useUpdateStore();
const [checkingUpdate, setCheckingUpdate] = useState(false);
const currentId = getCurrentVersion();
const remoteId = updateStore.remoteId;
const hasNewVersion = currentId !== remoteId;
function checkUpdate(force = false) {
setCheckingUpdate(true);
updateStore.getLatestCommitId(force).then(() => {
setCheckingUpdate(false);
});
}
const [usage, setUsage] = useState<{
used?: number;
}>();
const [loadingUsage, setLoadingUsage] = useState(false);
function checkUsage() {
setLoadingUsage(true);
requestUsage()
.then((res) =>
setUsage({
used: res,
}),
)
.finally(() => {
setLoadingUsage(false);
});
}
useEffect(() => {
checkUpdate();
checkUsage();
}, []);
const accessStore = useAccessStore();
const enabledAccessControl = useMemo(
() => accessStore.enabledAccessControl(),
[],
);
const promptStore = usePromptStore();
const builtinCount = SearchService.count.builtin;
const customCount = promptStore.prompts.size ?? 0;
return (
<>
{Locale.Settings.Title}
{Locale.Settings.SubTitle}
}
onClick={clearSessions}
bordered
title={Locale.Settings.Actions.ClearAll}
/>
}
onClick={resetConfig}
bordered
title={Locale.Settings.Actions.ResetAll}
/>
}
onClick={props.closeSettings}
bordered
title={Locale.Settings.Actions.Close}
/>
setShowEmojiPicker(false)}
content={
{
updateConfig((config) => (config.avatar = e.unified));
setShowEmojiPicker(false);
}}
/>
}
open={showEmojiPicker}
>
setShowEmojiPicker(true)}
>
{checkingUpdate ? (
) : hasNewVersion ? (
{Locale.Settings.Update.GoToUpdate}
) : (
}
text={Locale.Settings.Update.CheckUpdate}
onClick={() => checkUpdate(true)}
/>
)}
{Locale.Settings.Theme}
updateConfig(
(config) =>
(config.fontSize = Number.parseInt(e.currentTarget.value)),
)
}
>
updateConfig(
(config) => (config.tightBorder = e.currentTarget.checked),
)
}
>
updateConfig(
(config) =>
(config.sendPreviewBubble = e.currentTarget.checked),
)
}
>
updateConfig(
(config) =>
(config.disablePromptHint = e.currentTarget.checked),
)
}
>
}
text={Locale.Settings.Prompt.Edit}
onClick={() => showToast(Locale.WIP)}
/>
{enabledAccessControl ? (
{
accessStore.updateCode(e.currentTarget.value);
}}
>
) : (
<>>
)}
{
accessStore.updateToken(e.currentTarget.value);
}}
>
{loadingUsage ? (
) : (
}
text={Locale.Settings.Usage.Check}
onClick={checkUsage}
/>
)}
updateConfig(
(config) =>
(config.historyMessageCount = e.target.valueAsNumber),
)
}
>
updateConfig(
(config) =>
(config.compressMessageLengthThreshold =
e.currentTarget.valueAsNumber),
)
}
>
{
updateConfig(
(config) =>
(config.modelConfig.temperature =
e.currentTarget.valueAsNumber),
);
}}
>
updateConfig(
(config) =>
(config.modelConfig.max_tokens =
e.currentTarget.valueAsNumber),
)
}
>
{
updateConfig(
(config) =>
(config.modelConfig.presence_penalty =
e.currentTarget.valueAsNumber),
);
}}
>
>
);
}