diff --git a/public/locales/en/main.json b/public/locales/en/main.json index ad8ddd0..42dc454 100644 --- a/public/locales/en/main.json +++ b/public/locales/en/main.json @@ -22,5 +22,6 @@ "lightMode": "Light Mode", "darkMode": "Dark Mode", "setting": "Settings", - "image": "Image" + "image": "Image", + "autoTitle": "Auto generate title" } diff --git a/public/locales/zh-CN/main.json b/public/locales/zh-CN/main.json index a579ad9..cfa7a42 100644 --- a/public/locales/zh-CN/main.json +++ b/public/locales/zh-CN/main.json @@ -22,5 +22,6 @@ "lightMode": "亮色模式", "darkMode": "黑暗模式", "setting": "设置", - "image": "图片" + "image": "图片", + "autoTitle": "自动生成标题" } diff --git a/src/components/SettingsMenu/AutoTitleToggle.tsx b/src/components/SettingsMenu/AutoTitleToggle.tsx new file mode 100644 index 0000000..448694b --- /dev/null +++ b/src/components/SettingsMenu/AutoTitleToggle.tsx @@ -0,0 +1,28 @@ +import React, { useEffect, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import useStore from '@store/store'; +import Toggle from '@components/Toggle'; + +const AutoTitleToggle = () => { + const { t } = useTranslation(); + + const setAutoTitle = useStore((state) => state.setAutoTitle); + + const [isChecked, setIsChecked] = useState( + useStore.getState().autoTitle + ); + + useEffect(() => { + setAutoTitle(isChecked); + }, [isChecked]); + + return ( + + ); +}; + +export default AutoTitleToggle; diff --git a/src/components/SettingsMenu/SettingsMenu.tsx b/src/components/SettingsMenu/SettingsMenu.tsx index 1bd2bf3..642bddb 100644 --- a/src/components/SettingsMenu/SettingsMenu.tsx +++ b/src/components/SettingsMenu/SettingsMenu.tsx @@ -6,6 +6,7 @@ import PopupModal from '@components/PopupModal'; import SettingIcon from '@icon/SettingIcon'; import ThemeSwitcher from '@components/Menu/MenuOptions/ThemeSwitcher'; import LanguageSelector from '@components/LanguageSelector'; +import AutoTitleToggle from './AutoTitleToggle'; const SettingsMenu = () => { const { t } = useTranslation(); @@ -35,6 +36,7 @@ const SettingsMenu = () => {
+
)} diff --git a/src/components/Toggle/Toggle.tsx b/src/components/Toggle/Toggle.tsx new file mode 100644 index 0000000..d5769f6 --- /dev/null +++ b/src/components/Toggle/Toggle.tsx @@ -0,0 +1,30 @@ +import React from 'react'; + +const Toggle = ({ + label, + isChecked, + setIsChecked, +}: { + label: string; + isChecked: boolean; + setIsChecked: React.Dispatch>; +}) => { + return ( + + ); +}; + +export default Toggle; diff --git a/src/components/Toggle/index.ts b/src/components/Toggle/index.ts new file mode 100644 index 0000000..c2ec545 --- /dev/null +++ b/src/components/Toggle/index.ts @@ -0,0 +1 @@ +export { default } from './Toggle'; diff --git a/src/hooks/useSubmit.ts b/src/hooks/useSubmit.ts index b4c2ab0..28284ea 100644 --- a/src/hooks/useSubmit.ts +++ b/src/hooks/useSubmit.ts @@ -119,7 +119,11 @@ const useSubmit = () => { // generate title for new chats const currChats = useStore.getState().chats; - if (currChats && !currChats[currentChatIndex]?.titleSet) { + if ( + useStore.getState().autoTitle && + currChats && + !currChats[currentChatIndex]?.titleSet + ) { const messages_length = currChats[currentChatIndex].messages.length; const assistant_message = currChats[currentChatIndex].messages[messages_length - 1].content; diff --git a/src/store/config-slice.ts b/src/store/config-slice.ts index 18b24cc..22985a7 100644 --- a/src/store/config-slice.ts +++ b/src/store/config-slice.ts @@ -4,13 +4,16 @@ import { Theme } from '@type/theme'; export interface ConfigSlice { openConfig: boolean; theme: Theme; + autoTitle: boolean; setOpenConfig: (openConfig: boolean) => void; setTheme: (theme: Theme) => void; + setAutoTitle: (autoTitle: boolean) => void; } export const createConfigSlice: StoreSlice = (set, get) => ({ openConfig: false, theme: 'dark', + autoTitle: false, setOpenConfig: (openConfig: boolean) => { set((prev: ConfigSlice) => ({ ...prev, @@ -23,4 +26,10 @@ export const createConfigSlice: StoreSlice = (set, get) => ({ theme: theme, })); }, + setAutoTitle: (autoTitle: boolean) => { + set((prev: ConfigSlice) => ({ + ...prev, + autoTitle: autoTitle, + })); + }, }); diff --git a/src/store/migrate.ts b/src/store/migrate.ts index ff2149b..0b9abb1 100644 --- a/src/store/migrate.ts +++ b/src/store/migrate.ts @@ -1,9 +1,10 @@ import { LocalStorageInterfaceV0ToV1, LocalStorageInterfaceV1ToV2, + LocalStorageInterfaceV2ToV3, } from '@type/chat'; import { defaultChatConfig } from '@constants/chat'; -import { defaultAPIEndpoint, officialAPIEndpoint } from '@constants/auth'; +import { officialAPIEndpoint } from '@constants/auth'; export const migrateV0 = (persistedState: LocalStorageInterfaceV0ToV1) => { persistedState.chats.forEach((chat) => { @@ -20,9 +21,13 @@ export const migrateV1 = (persistedState: LocalStorageInterfaceV1ToV2) => { } }; -export const migrateV2 = (persistedState: LocalStorageInterfaceV1ToV2) => { +export const migrateV2 = (persistedState: LocalStorageInterfaceV2ToV3) => { persistedState.chats.forEach((chat) => { - chat.config.top_p = defaultChatConfig.top_p; - chat.config.frequency_penalty = defaultChatConfig.frequency_penalty; + chat.config = { + ...chat.config, + top_p: defaultChatConfig.top_p, + frequency_penalty: defaultChatConfig.frequency_penalty, + }; }); + persistedState.autoTitle = false; }; diff --git a/src/store/store.ts b/src/store/store.ts index a26aa72..d38a61e 100644 --- a/src/store/store.ts +++ b/src/store/store.ts @@ -35,6 +35,7 @@ const useStore = create()( apiFree: state.apiFree, apiEndpoint: state.apiEndpoint, theme: state.theme, + autoTitle: state.autoTitle, }), version: 3, migrate: (persistedState, version) => { diff --git a/src/types/chat.ts b/src/types/chat.ts index 4a1e2b9..157d8b7 100644 --- a/src/types/chat.ts +++ b/src/types/chat.ts @@ -49,4 +49,5 @@ export interface LocalStorageInterfaceV2ToV3 { apiFreeEndpoint: string; apiEndpoint?: string; theme: Theme; -} \ No newline at end of file + autoTitle: boolean; +}