feat: new inputbar style

This commit is contained in:
kangfenmao 2024-08-09 18:56:45 +08:00
parent 34d99b711c
commit 4fc53d7c19
19 changed files with 218 additions and 206 deletions

View File

@ -20,12 +20,12 @@ Cherry Studio is a desktop client that supports for multiple LLM providers, avai
6. Code highlighting.
7. Mermaid chart
# 👥 Community
Join our Telegram group to discuss Cherry Studio's latest developments and features! [Telegram community](https://t.me/CherryStudioAI)
# 🖥️ Develop
## Recommended IDE Setup
- [VSCode](https://code.visualstudio.com/) + [ESLint](https://marketplace.visualstudio.com/items?itemName=dbaeumer.vscode-eslint) + [Prettier](https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode)
## Project Setup
### Install

View File

@ -1,8 +1,8 @@
@font-face {
font-family: "iconfont"; /* Project id 4563475 */
src: url('iconfont.woff2?t=1722242729348') format('woff2'),
url('iconfont.woff?t=1722242729348') format('woff'),
url('iconfont.ttf?t=1722242729348') format('truetype');
src: url('iconfont.woff2?t=1723186111414') format('woff2'),
url('iconfont.woff?t=1723186111414') format('woff'),
url('iconfont.ttf?t=1723186111414') format('truetype');
}
.iconfont {
@ -13,6 +13,14 @@
-moz-osx-font-smoothing: grayscale;
}
.icon-copy:before {
content: "\e6ae";
}
.icon-ic_send:before {
content: "\e795";
}
.icon-dark1:before {
content: "\e72f";
}

View File

@ -40,6 +40,7 @@
--navbar-background: rgba(0, 0, 0, 0.8);
--sidebar-background: rgba(0, 0, 0, 0.8);
--input-bar-background: rgba(255, 255, 255, 0.02);
--navbar-height: 42px;
--sidebar-width: 55px;
@ -47,7 +48,7 @@
--topic-list-width: 260px;
--settings-width: var(--assistants-width);
--status-bar-height: 40px;
--input-bar-height: 115px;
--input-bar-height: 85px;
}
body[theme-mode='light'] {
@ -87,6 +88,7 @@ body[theme-mode='light'] {
--navbar-background: rgba(255, 255, 255, 0.8);
--sidebar-background: rgba(255, 255, 255, 0.8);
--input-bar-background: rgba(0, 0, 0, 0.02);
}
*,
@ -155,3 +157,7 @@ body,
position: relative;
animation: flash 0.5s ease-out infinite alternate;
}
.ant-segmented-group {
gap: 4px;
}

View File

@ -3,6 +3,7 @@
font-size: 15px;
line-height: 1.6;
user-select: text;
word-break: break-word;
h1:first-child,
h2:first-child,
@ -72,6 +73,9 @@
li {
margin-bottom: 0.5em;
&::marker {
color: var(--color-text-3);
}
}
li > ul,
@ -103,7 +107,7 @@
pre {
white-space: pre-wrap !important;
padding: 1em;
padding: 1em 0;
border-radius: 5px;
overflow-x: auto;
font-family: 'Fira Code', 'Courier New', Courier, monospace;

View File

@ -0,0 +1,24 @@
import { getModelLogo } from '@renderer/config/provider'
import { Model } from '@renderer/types'
import { Avatar, AvatarProps } from 'antd'
import { first } from 'lodash'
import { FC } from 'react'
interface Props {
model: Model
size: number
props?: AvatarProps
}
const ModelAvatar: FC<Props> = ({ model, size, props }) => {
return (
<Avatar
src={getModelLogo(model?.id || '')}
style={{ width: size, height: size, display: 'flex', alignItems: 'center', justifyContent: 'center' }}
{...props}>
{first(model?.name)}
</Avatar>
)
}
export default ModelAvatar

View File

@ -39,7 +39,6 @@ const TopViewContainer: React.FC<Props> = ({ children }) => {
}, [messageApi, modal])
onPop = () => {
console.debug('[TopView] onPop')
const views = [...elementsRef.current]
views.pop()
elementsRef.current = views
@ -47,8 +46,6 @@ const TopViewContainer: React.FC<Props> = ({ children }) => {
}
onShow = ({ element, id }: ElementItem) => {
console.debug('[TopView] onShow', id)
if (!elementsRef.current.find((el) => el.id === id)) {
elementsRef.current = elementsRef.current.concat([{ element, id }])
setElements(elementsRef.current)
@ -56,13 +53,11 @@ const TopViewContainer: React.FC<Props> = ({ children }) => {
}
onHide = (id: string) => {
console.debug('[TopView] onHide', id, elementsRef.current)
elementsRef.current = elementsRef.current.filter((el) => el.id !== id)
setElements(elementsRef.current)
}
onHideAll = () => {
console.debug('[TopView] onHideAll')
setElements([])
elementsRef.current = []
}
@ -76,11 +71,6 @@ const TopViewContainer: React.FC<Props> = ({ children }) => {
)
}, [])
console.debug(
'[TopView]',
elements.map((el) => [el.id, el.element])
)
return (
<>
{children}

View File

@ -131,6 +131,7 @@ const resources = {
'messages.use_serif_font': 'Use serif font',
'messages.input.title': 'Input Settings',
'messages.input.show_estimated_tokens': 'Show estimated input tokens',
'messages.input.send_shortcuts': 'Send shortcuts',
'general.title': 'General Settings',
'general.user_name': 'User Name',
'general.user_name.placeholder': 'Enter your name',
@ -345,6 +346,7 @@ const resources = {
'messages.use_serif_font': '使用衬线字体',
'messages.input.title': '输入设置',
'messages.input.show_estimated_tokens': '状态显示',
'messages.input.send_shortcuts': '发送快捷键',
'general.title': '常规设置',
'general.user_name': '用户名',
'general.user_name.placeholder': '请输入用户名',

View File

@ -1,6 +1,5 @@
import {
CheckOutlined,
CopyOutlined,
DeleteOutlined,
EditOutlined,
MenuOutlined,
@ -47,6 +46,7 @@ const MessageItem: FC<Props> = ({ message, index, showMenu, onDeleteMessage }) =
const isUserMessage = message.role === 'user'
const isAssistantMessage = message.role === 'assistant'
const canRegenerate = isLastMessage && isAssistantMessage
const showMetadata = Boolean(message.usage) && !generating
const onCopy = useCallback(() => {
navigator.clipboard.writeText(message.content)
@ -119,15 +119,15 @@ const MessageItem: FC<Props> = ({ message, index, showMenu, onDeleteMessage }) =
}, [message])
return (
<MessageContainer key={message.id} className="message" style={{ border: messageBorder }}>
<MessageContainer key={message.id} className="message">
<MessageHeader>
<AvatarWrapper>
{isAssistantMessage ? (
<Avatar src={avatarSource} size={35}>
<Avatar src={avatarSource} size={35} style={{ borderRadius: '20%' }}>
{avatarName}
</Avatar>
) : (
<Avatar src={avatar} size={35} />
<Avatar src={avatar} size={35} style={{ borderRadius: '20%' }} />
)}
<UserWrap>
<UserName>{username}</UserName>
@ -137,11 +137,7 @@ const MessageItem: FC<Props> = ({ message, index, showMenu, onDeleteMessage }) =
</MessageHeader>
<MessageContent style={{ fontFamily }}>
<MessageItem />
{message.usage && !generating && (
<MessageMetadata>
Tokens: {message.usage.total_tokens} | {message.usage.prompt_tokens}{message.usage.completion_tokens}
</MessageMetadata>
)}
<MessageFooter style={{ border: messageBorder }}>
{showMenu && (
<MenusBar className={`menubar ${isLastMessage && 'show'} ${(!isLastMessage || isUserMessage) && 'user'}`}>
{message.role === 'user' && (
@ -153,7 +149,7 @@ const MessageItem: FC<Props> = ({ message, index, showMenu, onDeleteMessage }) =
)}
<Tooltip title={t('common.copy')} mouseEnterDelay={0.8}>
<ActionButton onClick={onCopy}>
{!copied && <CopyOutlined />}
{!copied && <i className="iconfont icon-copy"></i>}
{copied && <CheckOutlined style={{ color: 'var(--color-primary)' }} />}
</ActionButton>
</Tooltip>
@ -186,6 +182,13 @@ const MessageItem: FC<Props> = ({ message, index, showMenu, onDeleteMessage }) =
)}
</MenusBar>
)}
{showMetadata && (
<MessageMetadata>
Tokens: {message?.usage?.total_tokens} | {message?.usage?.prompt_tokens} |
{message?.usage?.completion_tokens}
</MessageMetadata>
)}
</MessageFooter>
</MessageContent>
</MessageContainer>
)
@ -194,9 +197,8 @@ const MessageItem: FC<Props> = ({ message, index, showMenu, onDeleteMessage }) =
const MessageContainer = styled.div`
display: flex;
flex-direction: column;
padding: 10px 20px;
padding: 0 20px;
position: relative;
border-bottom: 0.5px dotted var(--color-border);
.menubar {
opacity: 0;
transition: opacity 0.2s ease;
@ -205,7 +207,7 @@ const MessageContainer = styled.div`
}
&.user {
position: absolute;
top: 15px;
top: 10px;
right: 10px;
}
}
@ -257,6 +259,16 @@ const MessageContent = styled.div`
margin-top: 5px;
`
const MessageFooter = styled.div`
display: flex;
flex-direction: row;
justify-content: space-between;
align-items: center;
padding: 2px 0;
margin: 2px 0 8px 0;
border-top: 0.5px dashed var(--color-border);
`
const MessageContentLoading = styled.div`
display: flex;
flex-direction: row;
@ -270,17 +282,18 @@ const MenusBar = styled.div`
justify-content: flex-end;
align-items: center;
gap: 6px;
margin-left: -5px;
`
const MessageMetadata = styled.div`
font-size: 12px;
color: var(--color-text-2);
user-select: text;
margin: 2px 0;
`
const ActionButton = styled.div`
cursor: pointer;
border: 1px solid var(--color-border);
border-radius: 8px;
display: flex;
flex-direction: row;
@ -288,7 +301,15 @@ const ActionButton = styled.div`
align-items: center;
width: 30px;
height: 30px;
transition: all 0.3s ease;
&:hover {
background-color: var(--color-background-mute);
.anticon {
color: var(--color-text-1);
}
}
.anticon,
.iconfont {
cursor: pointer;
font-size: 14px;
color: var(--color-icon);

View File

@ -1,7 +1,7 @@
import { getModelLogo } from '@renderer/config/provider'
import ModelAvatar from '@renderer/components/Avatar/ModelAvatar'
import { useAssistant } from '@renderer/hooks/useAssistant'
import { Assistant } from '@renderer/types'
import { Avatar, Button } from 'antd'
import { Button } from 'antd'
import { upperFirst } from 'lodash'
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
@ -20,7 +20,7 @@ const SelectModelButton: FC<Props> = ({ assistant }) => {
return (
<SelectModelDropdown model={model} onSelect={setModel}>
<DropdownButton size="small" type="default">
<Avatar src={getModelLogo(model?.id || '')} style={{ width: 20, height: 20 }} />
<ModelAvatar model={model} size={20} />
<ModelName>{model ? upperFirst(model.name) : t('button.select_model')}</ModelName>
</DropdownButton>
</SelectModelDropdown>

View File

@ -2,7 +2,7 @@ import { getModelLogo } from '@renderer/config/provider'
import { useProviders } from '@renderer/hooks/useProvider'
import { Model } from '@renderer/types'
import { Avatar, Dropdown, DropdownProps, MenuProps } from 'antd'
import { first, upperFirst } from 'lodash'
import { first, sortBy, upperFirst } from 'lodash'
import { FC, PropsWithChildren } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
@ -22,7 +22,7 @@ const SelectModelDropdown: FC<Props & PropsWithChildren> = ({ children, model, o
key: p.id,
label: p.isSystem ? t(`provider.${p.id}`) : p.name,
type: 'group',
children: p.models.map((m) => ({
children: sortBy(p.models, 'name').map((m) => ({
key: m?.id,
label: upperFirst(m?.name),
defaultSelectedKeys: [model?.id],

View File

@ -18,7 +18,7 @@ import store, { useAppSelector } from '@renderer/store'
import { setGenerating } from '@renderer/store/runtime'
import { Assistant, Message, Topic } from '@renderer/types'
import { uuid } from '@renderer/utils'
import { Button, Popconfirm, Tag, Tooltip } from 'antd'
import { Button, Divider, Popconfirm, Tag, Tooltip } from 'antd'
import TextArea, { TextAreaRef } from 'antd/es/input/TextArea'
import dayjs from 'dayjs'
import { debounce, isEmpty } from 'lodash'
@ -37,6 +37,7 @@ let _text = ''
const Inputbar: FC<Props> = ({ assistant, setActiveTopic }) => {
const [text, setText] = useState(_text)
const [inputFocus, setInputFocus] = useState(false)
const { addTopic } = useAssistant(assistant.id)
const { sendMessageShortcut, showInputEstimatedTokens } = useSettings()
const [expended, setExpend] = useState(false)
@ -141,7 +142,10 @@ const Inputbar: FC<Props> = ({ assistant, setActiveTopic }) => {
}, [assistant])
return (
<Container id="inputbar" style={{ minHeight: expended ? '80%' : 'var(--input-bar-height)' }}>
<Container
id="inputbar"
style={{ minHeight: expended ? '60%' : 'var(--input-bar-height)' }}
className={inputFocus ? 'focus' : ''}>
<Toolbar>
<ToolbarMenu>
<Tooltip placement="top" title={t('chat.input.new_topic')} arrow>
@ -179,11 +183,20 @@ const Inputbar: FC<Props> = ({ assistant, setActiveTopic }) => {
</Tooltip>
{showInputEstimatedTokens && (
<TextCount>
<Tooltip title={t('chat.input.context_count.tip')}>
<Tag style={{ cursor: 'pointer' }}>{assistant?.settings?.contextCount ?? DEFAULT_CONEXTCOUNT}</Tag>
</Tooltip>
<Tooltip title={t('chat.input.estimated_tokens.tip')}>
<Tag style={{ cursor: 'pointer' }}> {`${inputTokenCount} / ${estimateTokenCount}`}</Tag>
<Tooltip title={t('chat.input.context_count.tip') + ' | ' + t('chat.input.estimated_tokens.tip')}>
<Tag
style={{
cursor: 'pointer',
borderRadius: '20px',
display: 'flex',
alignItems: 'center',
padding: '2px 8px'
}}>
<i className="iconfont icon-history" style={{ marginRight: '3px' }} />
{assistant?.settings?.contextCount ?? DEFAULT_CONEXTCOUNT}
<Divider type="vertical" style={{ marginTop: 2, marginLeft: 5, marginRight: 5 }} />
{`${inputTokenCount} / ${estimateTokenCount}`}
</Tag>
</Tooltip>
</TextCount>
)}
@ -196,7 +209,7 @@ const Inputbar: FC<Props> = ({ assistant, setActiveTopic }) => {
</ToolbarButton>
</Tooltip>
)}
<SendMessageButton sendMessage={sendMessage} />
<SendMessageButton sendMessage={sendMessage} disabled={generating || !text} />
</ToolbarMenu>
</Toolbar>
<Textarea
@ -209,6 +222,8 @@ const Inputbar: FC<Props> = ({ assistant, setActiveTopic }) => {
variant="borderless"
ref={inputRef}
styles={{ textarea: { paddingLeft: 0 } }}
onFocus={() => setInputFocus(true)}
onBlur={() => setInputFocus(false)}
/>
</Container>
)
@ -217,10 +232,14 @@ const Inputbar: FC<Props> = ({ assistant, setActiveTopic }) => {
const Container = styled.div`
display: flex;
flex-direction: column;
width: 100%;
border-top: 0.5px solid var(--color-border);
height: var(--input-bar-height);
border: 1px solid var(--color-border);
transition: all 0.3s ease;
position: relative;
margin: 0 20px 15px 20px;
border-radius: 10px;
&.focus {
}
`
const Textarea = styled(TextArea)`
@ -229,13 +248,16 @@ const Textarea = styled(TextArea)`
display: flex;
flex: 1;
margin: 0 15px 5px 15px;
font-family: Ubuntu;
resize: vertical;
overflow: auto;
`
const Toolbar = styled.div`
display: flex;
flex-direction: row;
justify-content: space-between;
padding: 3px 10px;
padding: 0 10px;
`
const ToolbarMenu = styled.div`

View File

@ -1,44 +1,22 @@
import { ArrowUpOutlined, EnterOutlined } from '@ant-design/icons'
import { SendOutlined } from '@ant-design/icons'
import { useSettings } from '@renderer/hooks/useSettings'
import { Dropdown, MenuProps } from 'antd'
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
interface Props {
disabled: boolean
sendMessage: () => void
}
const SendMessageButton: FC<Props> = ({ sendMessage }) => {
const { sendMessageShortcut, setSendMessageShortcut } = useSettings()
const { t } = useTranslation()
const sendSettingItems: MenuProps['items'] = [
{
label: `Enter ${t('chat.input.send')}`,
key: 'Enter',
icon: <EnterOutlined />,
onClick: () => setSendMessageShortcut('Enter')
},
{
label: `Shift+Enter ${t('chat.input.send')}`,
key: 'Shift+Enter',
icon: <ArrowUpOutlined />,
onClick: () => setSendMessageShortcut('Shift+Enter')
}
]
const SendMessageButton: FC<Props> = ({ disabled, sendMessage }) => {
return (
<Dropdown.Button
size="small"
<i
className="iconfont icon-ic_send"
onClick={sendMessage}
trigger={['click']}
arrow
menu={{ items: sendSettingItems, selectable: true, defaultSelectedKeys: [sendMessageShortcut] }}
style={{ width: 'auto' }}>
{t('chat.input.send')}
<SendOutlined />
</Dropdown.Button>
style={{
cursor: disabled ? 'not-allowed' : 'pointer',
color: disabled ? 'var(--color-text-3)' : 'var(--color-primary)',
fontSize: 22,
transition: 'all 0.2s'
}}
/>
)
}

View File

@ -1,6 +1,8 @@
import { BarsOutlined, SettingOutlined } from '@ant-design/icons'
import { useShowRightSidebar } from '@renderer/hooks/useStore'
import { EVENT_NAMES, EventEmitter } from '@renderer/services/event'
import { Assistant, Topic } from '@renderer/types'
import { Segmented } from 'antd'
import { FC, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'
@ -54,14 +56,16 @@ const RightSidebar: FC<Props> = (props) => {
return (
<Container>
<Tabs>
<Tab className={tab === 'topic' ? 'active' : ''} onClick={() => setTab('topic')}>
{t('common.topics')}
</Tab>
<Tab className={tab === 'settings' ? 'active' : ''} onClick={() => setTab('settings')}>
{t('settings.title')}
</Tab>
</Tabs>
<Segmented
value={tab}
style={{ borderRadius: 0, padding: '10px', gap: 5, borderBottom: '0.5px solid var(--color-border)' }}
options={[
{ label: t('common.topics'), value: 'topic', icon: <BarsOutlined /> },
{ label: t('settings.title'), value: 'settings', icon: <SettingOutlined /> }
]}
block
onChange={(value) => setTab(value as 'topic' | 'settings')}
/>
<TabContent>
{tab === 'topic' && <TopicsTab {...props} />}
{tab === 'settings' && <SettingsTab assistant={props.assistant} />}
@ -82,29 +86,6 @@ const Container = styled.div`
}
`
const Tabs = styled.div`
display: flex;
flex-direction: row;
border-bottom: 0.5px solid var(--color-border);
padding: 0 10px;
`
const Tab = styled.div`
padding: 8px 0;
font-weight: 500;
display: flex;
flex: 1;
justify-content: center;
align-items: center;
font-size: 13px;
cursor: pointer;
color: var(--color-text-3);
&.active {
color: var(--color-text-2);
font-weight: 600;
}
`
const TabContent = styled.div`
display: flex;
flex: 1;

View File

@ -1,4 +1,4 @@
import { QuestionCircleOutlined, ReloadOutlined } from '@ant-design/icons'
import { CheckOutlined, QuestionCircleOutlined, ReloadOutlined } from '@ant-design/icons'
import { HStack } from '@renderer/components/Layout'
import { DEFAULT_CONEXTCOUNT, DEFAULT_MAX_TOKENS, DEFAULT_TEMPERATURE } from '@renderer/config/constant'
import { useAssistant } from '@renderer/hooks/useAssistant'
@ -7,7 +7,7 @@ import { SettingDivider, SettingRow, SettingRowTitle, SettingSubtitle } from '@r
import { useAppDispatch } from '@renderer/store'
import { setMessageFont, setShowInputEstimatedTokens, setShowMessageDivider } from '@renderer/store/settings'
import { Assistant, AssistantSettings } from '@renderer/types'
import { Col, InputNumber, Row, Slider, Switch, Tooltip } from 'antd'
import { Col, Row, Select, Slider, Switch, Tooltip } from 'antd'
import { debounce } from 'lodash'
import { FC, useCallback, useEffect, useState } from 'react'
import { useTranslation } from 'react-i18next'
@ -27,7 +27,8 @@ const SettingsTab: FC<Props> = (props) => {
const dispatch = useAppDispatch()
const { showMessageDivider, messageFont, showInputEstimatedTokens } = useSettings()
const { showMessageDivider, messageFont, showInputEstimatedTokens, sendMessageShortcut, setSendMessageShortcut } =
useSettings()
const onUpdateAssistantSettings = useCallback(
debounce(
@ -104,27 +105,15 @@ const SettingsTab: FC<Props> = (props) => {
</Tooltip>
</Row>
<Row align="middle" gutter={10}>
<Col span={18}>
<Col span={24}>
<Slider
min={0}
max={1.2}
onChange={onTemperatureChange}
value={typeof temperature === 'number' ? temperature : 0}
marks={{ 0: '0', 0.7: '0.7', 1.2: '1.2' }}
step={0.1}
/>
</Col>
<Col span={6}>
<InputNumberic
min={0}
max={1.2}
step={0.1}
value={temperature}
onChange={onTemperatureChange}
controls={false}
size="small"
/>
</Col>
</Row>
<Row align="middle">
<Label>{t('chat.settings.conext_count')}</Label>
@ -133,27 +122,15 @@ const SettingsTab: FC<Props> = (props) => {
</Tooltip>
</Row>
<Row align="middle" gutter={10}>
<Col span={18}>
<Col span={24}>
<Slider
min={0}
max={20}
marks={{ 0: '0', 10: '10', 20: t('chat.settings.max') }}
onChange={onConextCountChange}
value={typeof contextCount === 'number' ? contextCount : 0}
step={1}
/>
</Col>
<Col span={6}>
<InputNumberic
min={0}
max={20}
step={1}
value={contextCount}
onChange={onConextCountChange}
controls={false}
size="small"
/>
</Col>
</Row>
<Row align="middle" justify="space-between" style={{ marginBottom: 8 }}>
<HStack alignItems="center">
@ -173,7 +150,7 @@ const SettingsTab: FC<Props> = (props) => {
</Row>
{enableMaxTokens && (
<Row align="middle" gutter={10}>
<Col span={16}>
<Col span={24}>
<Slider
min={0}
max={32000}
@ -182,18 +159,6 @@ const SettingsTab: FC<Props> = (props) => {
step={100}
/>
</Col>
<Col span={8}>
<InputNumberic
min={0}
max={32000}
step={100}
value={maxTokens}
onChange={onMaxTokensChange}
controls={true}
style={{ width: '100%' }}
size="small"
/>
</Col>
</Row>
)}
<SettingSubtitle>{t('settings.messages.title')}</SettingSubtitle>
@ -227,6 +192,19 @@ const SettingsTab: FC<Props> = (props) => {
/>
</SettingRow>
<SettingDivider />
<SettingRow>
<SettingRowTitleSmall>{t('settings.messages.input.send_shortcuts')}</SettingRowTitleSmall>
</SettingRow>
<Select
value={sendMessageShortcut}
menuItemSelectedIcon={<CheckOutlined />}
options={[
{ value: 'Enter', label: `Enter ${t('chat.input.send')}` },
{ value: 'Shift+Enter', label: `Shift + Enter ${t('chat.input.send')}` }
]}
onChange={(value) => setSendMessageShortcut(value)}
style={{ width: '100%', marginTop: 10 }}
/>
</Container>
)
}
@ -238,16 +216,6 @@ const Container = styled.div`
padding: 0 15px;
`
const InputNumberic = styled(InputNumber)`
width: 45px;
padding: 0;
margin-left: 5px;
text-align: center;
.ant-input-number-input {
text-align: center;
}
`
const Label = styled.p`
margin: 0;
font-size: 12px;

View File

@ -136,7 +136,7 @@ const Container = styled.div`
display: flex;
flex: 1;
flex-direction: column;
padding: 15px 10px;
padding: 10px 10px;
`
const TopicListItem = styled.div`

View File

@ -8,12 +8,20 @@ import { useTheme } from './ThemeProvider'
const AntdProvider: FC<PropsWithChildren> = ({ children }) => {
const { language } = useSettings()
const { theme: _theme } = useTheme()
const isDarkTheme = _theme === 'dark'
return (
<ConfigProvider
locale={getAntdLocale(language)}
theme={{
algorithm: [_theme === 'dark' ? theme.darkAlgorithm : theme.defaultAlgorithm],
components: {
Segmented: {
trackBg: 'transparent',
itemSelectedBg: isDarkTheme ? 'rgba(255, 255, 255, 0.05)' : 'rgba(0, 0, 0, 0.05)',
boxShadowTertiary: undefined
}
},
token: {
colorPrimary: '#00b96b',
borderRadius: 8