From ab0e7e1e076d3a4d6964f425795e0a8a189b04d0 Mon Sep 17 00:00:00 2001 From: kangfenmao Date: Thu, 5 Sep 2024 22:53:52 +0800 Subject: [PATCH] feat: change topics position --- src/renderer/src/hooks/useSettings.ts | 4 +++ src/renderer/src/hooks/useStore.ts | 20 +---------- src/renderer/src/i18n/index.ts | 10 ++++-- src/renderer/src/pages/home/Chat.tsx | 17 +++++----- src/renderer/src/pages/home/Navbar.tsx | 13 ++++++-- src/renderer/src/pages/home/RightSidebar.tsx | 24 +++++++------- src/renderer/src/pages/home/Topics.tsx | 33 ++++++++++++------- .../src/pages/settings/GeneralSettings.tsx | 25 +++++++++++++- src/renderer/src/services/assistant.ts | 2 ++ src/renderer/src/store/migrate.ts | 4 +++ src/renderer/src/store/settings.ts | 20 +++++------ 11 files changed, 103 insertions(+), 69 deletions(-) diff --git a/src/renderer/src/hooks/useSettings.ts b/src/renderer/src/hooks/useSettings.ts index 700ed6b0..57d08ee1 100644 --- a/src/renderer/src/hooks/useSettings.ts +++ b/src/renderer/src/hooks/useSettings.ts @@ -3,6 +3,7 @@ import { SendMessageShortcut, setSendMessageShortcut as _setSendMessageShortcut, setTheme, + setTopicPosition, setWindowStyle, ThemeMode } from '@renderer/store/settings' @@ -21,6 +22,9 @@ export function useSettings() { }, setWindowStyle(windowStyle: 'transparent' | 'opaque') { dispatch(setWindowStyle(windowStyle)) + }, + setTopicPosition(topicPosition: 'left' | 'right') { + dispatch(setTopicPosition(topicPosition)) } } } diff --git a/src/renderer/src/hooks/useStore.ts b/src/renderer/src/hooks/useStore.ts index c1f24fcc..6b148e3e 100644 --- a/src/renderer/src/hooks/useStore.ts +++ b/src/renderer/src/hooks/useStore.ts @@ -1,23 +1,5 @@ import { useAppDispatch, useAppSelector } from '@renderer/store' -import { - setShowRightSidebar, - setShowTopics, - toggleRightSidebar, - toggleShowAssistants, - toggleShowTopics -} from '@renderer/store/settings' - -export function useShowRightSidebar() { - const showRightSidebar = useAppSelector((state) => state.settings.showRightSidebar) - const dispatch = useAppDispatch() - - return { - rightSidebarShown: showRightSidebar, - toggleRightSidebar: () => dispatch(toggleRightSidebar()), - showRightSidebar: () => dispatch(setShowRightSidebar(true)), - hideRightSidebar: () => dispatch(setShowRightSidebar(false)) - } -} +import { setShowTopics, toggleShowAssistants, toggleShowTopics } from '@renderer/store/settings' export function useShowAssistants() { const showAssistants = useAppSelector((state) => state.settings.showAssistants) diff --git a/src/renderer/src/i18n/index.ts b/src/renderer/src/i18n/index.ts index 39e0718d..0b084cef 100644 --- a/src/renderer/src/i18n/index.ts +++ b/src/renderer/src/i18n/index.ts @@ -207,7 +207,10 @@ const resources = { 'theme.window.style.title': 'Window Style', 'theme.window.style.transparent': 'Transparent Window', 'theme.window.style.opaque': 'Opaque Window', - 'font_size.title': 'Message Font Size' + 'font_size.title': 'Message Font Size', + 'topic.position': 'Topic Position', + 'topic.position.left': 'Left', + 'topic.position.right': 'Right' }, translate: { title: 'Translation', @@ -454,7 +457,10 @@ const resources = { 'theme.window.style.title': '窗口样式', 'theme.window.style.transparent': '透明窗口', 'theme.window.style.opaque': '不透明窗口', - 'font_size.title': '消息字体大小' + 'font_size.title': '消息字体大小', + 'topic.position': '话题位置', + 'topic.position.left': '左侧', + 'topic.position.right': '右侧' }, translate: { title: '翻译', diff --git a/src/renderer/src/pages/home/Chat.tsx b/src/renderer/src/pages/home/Chat.tsx index 88fc937f..9f901317 100644 --- a/src/renderer/src/pages/home/Chat.tsx +++ b/src/renderer/src/pages/home/Chat.tsx @@ -1,8 +1,9 @@ import { useAssistant } from '@renderer/hooks/useAssistant' -import { useShowRightSidebar, useShowTopics } from '@renderer/hooks/useStore' +import { useSettings } from '@renderer/hooks/useSettings' +import { useShowTopics } from '@renderer/hooks/useStore' import { Assistant, Topic } from '@renderer/types' import { Flex } from 'antd' -import { FC, useEffect, useState } from 'react' +import { FC } from 'react' import styled from 'styled-components' import Inputbar from './Inputbar/Inputbar' @@ -17,23 +18,21 @@ interface Props { const Chat: FC = (props) => { const { assistant } = useAssistant(props.assistant.id) - const [showSetting, setShowSetting] = useState(false) - const { rightSidebarShown } = useShowRightSidebar() const { showTopics } = useShowTopics() - - useEffect(() => { - !rightSidebarShown && showSetting && setShowSetting(false) - }, [rightSidebarShown, showSetting]) + const { topicPosition } = useSettings() return ( - {showTopics && ( + {showTopics && topicPosition === 'left' && ( )}
+ {showTopics && topicPosition === 'right' && ( + + )}
) } diff --git a/src/renderer/src/pages/home/Navbar.tsx b/src/renderer/src/pages/home/Navbar.tsx index d79f9a9a..119887b1 100644 --- a/src/renderer/src/pages/home/Navbar.tsx +++ b/src/renderer/src/pages/home/Navbar.tsx @@ -6,6 +6,7 @@ import AssistantSettingPopup from '@renderer/components/Popups/AssistantSettingP import { isMac, isWindows } from '@renderer/config/constant' import { useTheme } from '@renderer/context/ThemeProvider' import { useAssistant } from '@renderer/hooks/useAssistant' +import { useSettings } from '@renderer/hooks/useSettings' import { useShowAssistants, useShowTopics } from '@renderer/hooks/useStore' import { getDefaultTopic } from '@renderer/services/assistant' import { Assistant, Topic } from '@renderer/types' @@ -27,8 +28,9 @@ const HeaderNavbar: FC = ({ activeAssistant, setActiveAssistant, setActiv const { assistant, addTopic } = useAssistant(activeAssistant.id) const { t } = useTranslation() const { showAssistants, toggleShowAssistants } = useShowAssistants() - const { showTopics } = useShowTopics() + const { showTopics, toggleShowTopics } = useShowTopics() const { theme, toggleTheme } = useTheme() + const { topicPosition } = useSettings() const onCreateAssistant = async () => { const assistant = await AddAssistantPopup.show() @@ -53,7 +55,7 @@ const HeaderNavbar: FC = ({ activeAssistant, setActiveAssistant, setActiv )} - {showTopics && ( + {showTopics && topicPosition === 'left' && ( = ({ activeAssistant, setActiveAssistant, setActiv )} - {!showAssistants && !showTopics && ( + {!showAssistants && (topicPosition === 'left' ? !showTopics : true) && ( toggleShowAssistants()} style={{ marginRight: isMac ? 8 : 25, marginLeft: isMac ? 8 : 0 }}> @@ -102,6 +104,11 @@ const HeaderNavbar: FC = ({ activeAssistant, setActiveAssistant, setActiv checked={theme === 'dark'} onChange={toggleTheme} /> + {topicPosition === 'right' && ( + + + + )} diff --git a/src/renderer/src/pages/home/RightSidebar.tsx b/src/renderer/src/pages/home/RightSidebar.tsx index 6b636fc8..4b4b3ce8 100644 --- a/src/renderer/src/pages/home/RightSidebar.tsx +++ b/src/renderer/src/pages/home/RightSidebar.tsx @@ -1,5 +1,5 @@ import { BarsOutlined, SettingOutlined } from '@ant-design/icons' -import { useShowRightSidebar } from '@renderer/hooks/useStore' +import { useShowTopics } from '@renderer/hooks/useStore' import { EVENT_NAMES, EventEmitter } from '@renderer/services/event' import { Assistant, Topic } from '@renderer/types' import { Segmented } from 'antd' @@ -18,7 +18,7 @@ interface Props { const RightSidebar: FC = (props) => { const [tab, setTab] = useState<'topic' | 'settings'>('topic') - const { rightSidebarShown, showRightSidebar, hideRightSidebar } = useShowRightSidebar() + const { showTopics, setShowTopics } = useShowTopics() const { t } = useTranslation() const isTopicTab = tab === 'topic' const isSettingsTab = tab === 'settings' @@ -26,31 +26,31 @@ const RightSidebar: FC = (props) => { useEffect(() => { const unsubscribes = [ EventEmitter.on(EVENT_NAMES.SHOW_TOPIC_SIDEBAR, (): any => { - if (rightSidebarShown && isTopicTab) { - return hideRightSidebar() + if (showTopics && isTopicTab) { + return setShowTopics(false) } - if (rightSidebarShown) { + if (showTopics) { return setTab('topic') } - showRightSidebar() + setShowTopics(true) setTab('topic') }), EventEmitter.on(EVENT_NAMES.SHOW_CHAT_SETTINGS, (): any => { - if (rightSidebarShown && isSettingsTab) { - return hideRightSidebar() + if (showTopics && isSettingsTab) { + return setShowTopics(false) } - if (rightSidebarShown) { + if (showTopics) { return setTab('settings') } - showRightSidebar() + setShowTopics(true) setTab('settings') }), EventEmitter.on(EVENT_NAMES.SWITCH_TOPIC_SIDEBAR, () => setTab('topic')) ] return () => unsubscribes.forEach((unsub) => unsub()) - }, [hideRightSidebar, isSettingsTab, isTopicTab, rightSidebarShown, showRightSidebar]) + }, [isSettingsTab, isTopicTab, showTopics, setShowTopics]) - if (!rightSidebarShown) { + if (!showTopics) { return null } diff --git a/src/renderer/src/pages/home/Topics.tsx b/src/renderer/src/pages/home/Topics.tsx index c56e4dd0..3d7df3b5 100644 --- a/src/renderer/src/pages/home/Topics.tsx +++ b/src/renderer/src/pages/home/Topics.tsx @@ -2,6 +2,7 @@ import { DeleteOutlined, EditOutlined, OpenAIOutlined } from '@ant-design/icons' import DragableList from '@renderer/components/DragableList' import PromptPopup from '@renderer/components/Popups/PromptPopup' import { useAssistant } from '@renderer/hooks/useAssistant' +import { useSettings } from '@renderer/hooks/useSettings' import { fetchMessagesSummary } from '@renderer/services/api' import LocalStorage from '@renderer/services/storage' import { useAppSelector } from '@renderer/store' @@ -21,6 +22,9 @@ const Topics: FC = ({ assistant: _assistant, activeTopic, setActiveTopic const { assistant, removeTopic, updateTopic, updateTopics } = useAssistant(_assistant.id) const { t } = useTranslation() const generating = useAppSelector((state) => state.runtime.generating) + const { topicPosition } = useSettings() + + const borderStyle = '0.5px solid var(--color-border)' const getTopicMenuItems = useCallback( (topic: Topic) => { @@ -88,17 +92,19 @@ const Topics: FC = ({ assistant: _assistant, activeTopic, setActiveTopic ) return ( - + - {(topic) => ( - - onSwitchTopic(topic)}> - {topic.name} - - - )} + {(topic) => { + const isActive = topic.id === activeTopic?.id + const activeClass = topicPosition === 'left' ? 'active-left' : 'active-right' + return ( + + onSwitchTopic(topic)}> + {topic.name} + + + ) + }} ) @@ -112,6 +118,7 @@ const Container = styled.div` min-width: var(--topic-list-width); max-width: var(--topic-list-width); border-right: 0.5px solid var(--color-border); + border-left: 0.5px solid var(--color-border); overflow-y: scroll; height: calc(100vh - var(--navbar-height)); ` @@ -129,11 +136,15 @@ const TopicListItem = styled.div` &:hover { background-color: var(--color-background-soft); } - &.active { + &.active-left { background-color: var(--color-primary); color: white; font-weight: 500; } + &.active-right { + background-color: var(--color-background-mute); + font-weight: 500; + } ` export default Topics diff --git a/src/renderer/src/pages/settings/GeneralSettings.tsx b/src/renderer/src/pages/settings/GeneralSettings.tsx index 7b57fb99..635fe54a 100644 --- a/src/renderer/src/pages/settings/GeneralSettings.tsx +++ b/src/renderer/src/pages/settings/GeneralSettings.tsx @@ -14,7 +14,17 @@ import { useTranslation } from 'react-i18next' import { SettingContainer, SettingDivider, SettingRow, SettingRowTitle, SettingTitle } from '.' const GeneralSettings: FC = () => { - const { language, proxyUrl: storeProxyUrl, userName, theme, windowStyle, setTheme, setWindowStyle } = useSettings() + const { + language, + proxyUrl: storeProxyUrl, + userName, + theme, + windowStyle, + topicPosition, + setTheme, + setWindowStyle, + setTopicPosition + } = useSettings() const [proxyUrl, setProxyUrl] = useState(storeProxyUrl) const dispatch = useAppDispatch() const { t } = useTranslation() @@ -79,6 +89,19 @@ const GeneralSettings: FC = () => { /> + + {t('settings.topic.position')} + { - state.showRightSidebar = !state.showRightSidebar - }, - setShowRightSidebar: (state, action: PayloadAction) => { - state.showRightSidebar = action.payload - }, setShowAssistants: (state, action: PayloadAction) => { state.showAssistants = action.payload }, @@ -92,13 +86,14 @@ const settingsSlice = createSlice({ setWindowStyle: (state, action: PayloadAction<'transparent' | 'opaque'>) => { state.windowStyle = action.payload console.log(state.windowStyle) + }, + setTopicPosition: (state, action: PayloadAction<'left' | 'right'>) => { + state.topicPosition = action.payload } } }) export const { - setShowRightSidebar, - toggleRightSidebar, setShowAssistants, toggleShowAssistants, setShowTopics, @@ -112,7 +107,8 @@ export const { setShowInputEstimatedTokens, setTheme, setFontSize, - setWindowStyle + setWindowStyle, + setTopicPosition } = settingsSlice.actions export default settingsSlice.reducer