feat: new about page
This commit is contained in:
parent
ac3cfe2878
commit
40d687104e
@ -97,11 +97,11 @@ const resources = {
|
|||||||
},
|
},
|
||||||
settings: {
|
settings: {
|
||||||
title: 'Settings',
|
title: 'Settings',
|
||||||
general: 'General',
|
general: 'General Settings',
|
||||||
provider: 'Model Provider',
|
provider: 'Model Provider',
|
||||||
model: 'Model Settings',
|
model: 'Model Settings',
|
||||||
assistant: 'Default Assistant',
|
assistant: 'Default Assistant',
|
||||||
about: 'About',
|
about: 'About & Feedback',
|
||||||
'general.title': 'General Settings',
|
'general.title': 'General Settings',
|
||||||
'provider.api_key': 'API Key',
|
'provider.api_key': 'API Key',
|
||||||
'provider.check': 'Check',
|
'provider.check': 'Check',
|
||||||
@ -133,7 +133,16 @@ const resources = {
|
|||||||
'provider.delete.title': 'Delete Provider',
|
'provider.delete.title': 'Delete Provider',
|
||||||
'provider.delete.content': 'Are you sure you want to delete this provider?',
|
'provider.delete.content': 'Are you sure you want to delete this provider?',
|
||||||
'provider.edit.name': 'Provider Name',
|
'provider.edit.name': 'Provider Name',
|
||||||
'provider.edit.name.placeholder': 'Example: OpenAI'
|
'provider.edit.name.placeholder': 'Example: OpenAI',
|
||||||
|
'about.title': 'About',
|
||||||
|
'about.releases.title': 'Release Notes',
|
||||||
|
'about.releases.button': 'Releases',
|
||||||
|
'about.website.title': 'Official Website',
|
||||||
|
'about.website.button': 'Website',
|
||||||
|
'about.feedback.title': 'Feedback',
|
||||||
|
'about.feedback.button': 'Feedback',
|
||||||
|
'about.contact.title': 'Contact',
|
||||||
|
'about.contact.button': 'Email'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -236,7 +245,7 @@ const resources = {
|
|||||||
provider: '模型提供商',
|
provider: '模型提供商',
|
||||||
model: '模型设置',
|
model: '模型设置',
|
||||||
assistant: '默认助手',
|
assistant: '默认助手',
|
||||||
about: '关于',
|
about: '关于我们',
|
||||||
'general.title': '常规设置',
|
'general.title': '常规设置',
|
||||||
'provider.api_key': 'API 密钥',
|
'provider.api_key': 'API 密钥',
|
||||||
'provider.check': '检查',
|
'provider.check': '检查',
|
||||||
@ -259,7 +268,7 @@ const resources = {
|
|||||||
'models.empty': '没有模型',
|
'models.empty': '没有模型',
|
||||||
'assistant.title': '默认助手',
|
'assistant.title': '默认助手',
|
||||||
'assistant.model_params': '模型参数',
|
'assistant.model_params': '模型参数',
|
||||||
'about.description': '一个为创造者而生的 AI 助手',
|
'about.description': '一款为创造者而生的 AI 助手',
|
||||||
'about.updateNotAvailable': '你的软件已是最新版本',
|
'about.updateNotAvailable': '你的软件已是最新版本',
|
||||||
'about.checkingUpdate': '正在检查更新...',
|
'about.checkingUpdate': '正在检查更新...',
|
||||||
'about.updateError': '更新出错',
|
'about.updateError': '更新出错',
|
||||||
@ -268,7 +277,16 @@ const resources = {
|
|||||||
'provider.delete.title': '删除提供商',
|
'provider.delete.title': '删除提供商',
|
||||||
'provider.delete.content': '确定要删除此模型提供商吗?',
|
'provider.delete.content': '确定要删除此模型提供商吗?',
|
||||||
'provider.edit.name': '模型提供商名称',
|
'provider.edit.name': '模型提供商名称',
|
||||||
'provider.edit.name.placeholder': '例如 OpenAI'
|
'provider.edit.name.placeholder': '例如 OpenAI',
|
||||||
|
'about.title': '关于我们',
|
||||||
|
'about.releases.title': '📔 更新日志',
|
||||||
|
'about.releases.button': '查看',
|
||||||
|
'about.website.title': '🌐 官方网站',
|
||||||
|
'about.website.button': '查看',
|
||||||
|
'about.feedback.title': '📝 意见反馈',
|
||||||
|
'about.feedback.button': '反馈',
|
||||||
|
'about.contact.title': '📧 邮件联系',
|
||||||
|
'about.contact.button': '邮件'
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -1,12 +1,12 @@
|
|||||||
import { Avatar, Button, Progress } from 'antd'
|
import { Avatar, Button, Progress, Row, Tag } from 'antd'
|
||||||
import { FC, useEffect, useState } from 'react'
|
import { FC, useEffect, useState } from 'react'
|
||||||
import styled from 'styled-components'
|
import styled from 'styled-components'
|
||||||
import Logo from '@renderer/assets/images/logo.png'
|
import Logo from '@renderer/assets/images/logo.png'
|
||||||
import { runAsyncFunction } from '@renderer/utils'
|
import { runAsyncFunction } from '@renderer/utils'
|
||||||
import { useTranslation } from 'react-i18next'
|
import { useTranslation } from 'react-i18next'
|
||||||
import Changelog from './components/Changelog'
|
|
||||||
import { debounce } from 'lodash'
|
import { debounce } from 'lodash'
|
||||||
import { ProgressInfo } from 'electron-updater'
|
import { ProgressInfo } from 'electron-updater'
|
||||||
|
import { SettingContainer, SettingDivider, SettingRow, SettingRowTitle, SettingTitle } from './components'
|
||||||
|
|
||||||
const AboutSettings: FC = () => {
|
const AboutSettings: FC = () => {
|
||||||
const [version, setVersion] = useState('')
|
const [version, setVersion] = useState('')
|
||||||
@ -26,8 +26,17 @@ const AboutSettings: FC = () => {
|
|||||||
{ leading: true, trailing: false }
|
{ leading: true, trailing: false }
|
||||||
)
|
)
|
||||||
|
|
||||||
const onOpenWebsite = (suffix = '') => {
|
const onOpenWebsite = (url: string) => {
|
||||||
window.api.openWebsite('https://github.com/kangfenmao/cherry-studio' + suffix)
|
window.api.openWebsite(url)
|
||||||
|
}
|
||||||
|
|
||||||
|
const mailto = async () => {
|
||||||
|
const email = 'kangfenmao@qq.com'
|
||||||
|
const subject = 'Cherry Studio Feedback'
|
||||||
|
const version = (await window.api.getAppInfo()).version
|
||||||
|
const platform = window.electron.process.platform
|
||||||
|
const url = `mailto:${email}?subject=${subject}&body=%0A%0AVersion: ${version} | Platform: ${platform}`
|
||||||
|
onOpenWebsite(url)
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
@ -69,57 +78,92 @@ const AboutSettings: FC = () => {
|
|||||||
}, [t])
|
}, [t])
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Container>
|
<SettingContainer>
|
||||||
<AvatarWrapper onClick={() => onOpenWebsite()}>
|
<SettingTitle>{t('settings.about.title')}</SettingTitle>
|
||||||
{percent > 0 && (
|
<SettingDivider />
|
||||||
<ProgressCircle
|
<AboutHeader>
|
||||||
type="circle"
|
<Row align="middle">
|
||||||
size={104}
|
<AvatarWrapper onClick={() => onOpenWebsite('https://github.com/kangfenmao/cherry-studio')}>
|
||||||
percent={percent}
|
{percent > 0 && (
|
||||||
showInfo={false}
|
<ProgressCircle
|
||||||
strokeLinecap="butt"
|
type="circle"
|
||||||
strokeColor="#67ad5b"
|
size={84}
|
||||||
/>
|
percent={percent}
|
||||||
)}
|
showInfo={false}
|
||||||
<Avatar src={Logo} size={100} style={{ marginTop: 50, minHeight: 100 }} />
|
strokeLinecap="butt"
|
||||||
</AvatarWrapper>
|
strokeColor="#67ad5b"
|
||||||
<Title>
|
/>
|
||||||
Cherry Studio <Version onClick={() => onOpenWebsite('/releases')}>(v{version})</Version>
|
)}
|
||||||
</Title>
|
<Avatar src={Logo} size={80} style={{ minHeight: 80 }} />
|
||||||
<Description>{t('settings.about.description')}</Description>
|
</AvatarWrapper>
|
||||||
<CheckUpdateButton onClick={onCheckUpdate} loading={checkUpdateLoading}>
|
<VersionWrapper>
|
||||||
{downloading ? t('settings.about.downloading') : t('settings.about.checkUpdate')}
|
<Title>Cherry Studio</Title>
|
||||||
</CheckUpdateButton>
|
<Description>{t('settings.about.description')}</Description>
|
||||||
<Changelog />
|
<Tag
|
||||||
</Container>
|
onClick={() => onOpenWebsite('https://github.com/kangfenmao/cherry-studio/releases')}
|
||||||
|
color="cyan"
|
||||||
|
style={{ marginTop: 8, cursor: 'pointer' }}>
|
||||||
|
v{version}
|
||||||
|
</Tag>
|
||||||
|
</VersionWrapper>
|
||||||
|
</Row>
|
||||||
|
<CheckUpdateButton onClick={onCheckUpdate} loading={checkUpdateLoading}>
|
||||||
|
{downloading ? t('settings.about.downloading') : t('settings.about.checkUpdate')}
|
||||||
|
</CheckUpdateButton>
|
||||||
|
</AboutHeader>
|
||||||
|
<SettingDivider />
|
||||||
|
<SettingRow>
|
||||||
|
<SettingRowTitle>{t('settings.about.releases.title')}</SettingRowTitle>
|
||||||
|
<Button onClick={() => onOpenWebsite('https://github.com/kangfenmao/cherry-studio/releases')}>
|
||||||
|
{t('settings.about.releases.button')}
|
||||||
|
</Button>
|
||||||
|
</SettingRow>
|
||||||
|
<SettingDivider />
|
||||||
|
<SettingRow>
|
||||||
|
<SettingRowTitle>{t('settings.about.website.title')}</SettingRowTitle>
|
||||||
|
<Button onClick={() => onOpenWebsite('https://easys.run/cherry-studio')}>
|
||||||
|
{t('settings.about.website.button')}
|
||||||
|
</Button>
|
||||||
|
</SettingRow>
|
||||||
|
<SettingDivider />
|
||||||
|
<SettingRow>
|
||||||
|
<SettingRowTitle>{t('settings.about.feedback.title')}</SettingRowTitle>
|
||||||
|
<Button onClick={() => onOpenWebsite('https://github.com/kangfenmao/cherry-studio/issues')}>
|
||||||
|
{t('settings.about.feedback.button')}
|
||||||
|
</Button>
|
||||||
|
</SettingRow>
|
||||||
|
<SettingDivider />
|
||||||
|
<SettingRow>
|
||||||
|
<SettingRowTitle>{t('settings.about.contact.title')}</SettingRowTitle>
|
||||||
|
<Button onClick={mailto}>{t('settings.about.contact.button')}</Button>
|
||||||
|
</SettingRow>
|
||||||
|
<SettingDivider />
|
||||||
|
</SettingContainer>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const Container = styled.div`
|
const AboutHeader = styled.div`
|
||||||
display: flex;
|
display: flex;
|
||||||
flex: 1;
|
flex-direction: row;
|
||||||
flex-direction: column;
|
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: flex-start;
|
justify-content: space-between;
|
||||||
height: calc(100vh - var(--navbar-height));
|
width: 100%;
|
||||||
overflow-y: scroll;
|
padding: 5px 0;
|
||||||
padding: 0;
|
`
|
||||||
padding-bottom: 50px;
|
|
||||||
|
const VersionWrapper = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
min-height: 80px;
|
||||||
|
justify-content: center;
|
||||||
|
align-items: flex-start;
|
||||||
`
|
`
|
||||||
|
|
||||||
const Title = styled.div`
|
const Title = styled.div`
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
color: var(--color-text-1);
|
color: var(--color-text-1);
|
||||||
margin: 10px 0;
|
margin-bottom: 5px;
|
||||||
`
|
|
||||||
|
|
||||||
const Version = styled.span`
|
|
||||||
font-size: 14px;
|
|
||||||
color: var(--color-text-2);
|
|
||||||
margin: 10px 0;
|
|
||||||
text-align: center;
|
|
||||||
cursor: pointer;
|
|
||||||
`
|
`
|
||||||
|
|
||||||
const Description = styled.div`
|
const Description = styled.div`
|
||||||
@ -128,18 +172,17 @@ const Description = styled.div`
|
|||||||
text-align: center;
|
text-align: center;
|
||||||
`
|
`
|
||||||
|
|
||||||
const CheckUpdateButton = styled(Button)`
|
const CheckUpdateButton = styled(Button)``
|
||||||
margin-top: 10px;
|
|
||||||
`
|
|
||||||
|
|
||||||
const AvatarWrapper = styled.div`
|
const AvatarWrapper = styled.div`
|
||||||
position: relative;
|
position: relative;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
|
margin-right: 15px;
|
||||||
`
|
`
|
||||||
|
|
||||||
const ProgressCircle = styled(Progress)`
|
const ProgressCircle = styled(Progress)`
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 48px;
|
top: -2px;
|
||||||
left: -2px;
|
left: -2px;
|
||||||
`
|
`
|
||||||
|
|
||||||
|
|||||||
@ -18,12 +18,13 @@ const Changelog: FC = () => {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const Container = styled.div`
|
const Container = styled.div`
|
||||||
|
display: flex;
|
||||||
|
flex: 1;
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
background-color: var(--color-background-soft);
|
|
||||||
margin-top: 40px;
|
|
||||||
padding: 20px;
|
padding: 20px;
|
||||||
border-radius: 5px;
|
width: 100%;
|
||||||
width: 650px;
|
overflow-y: scroll;
|
||||||
|
border-left: 0.5px solid var(--color-border);
|
||||||
`
|
`
|
||||||
|
|
||||||
export default Changelog
|
export default Changelog
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user