Skip to content

Commit

Permalink
feat: added translations and ui improvements
Browse files Browse the repository at this point in the history
  • Loading branch information
kangfenmao committed Oct 31, 2024
1 parent ca2a9ed commit f6aa0dc
Show file tree
Hide file tree
Showing 7 changed files with 247 additions and 144 deletions.
6 changes: 4 additions & 2 deletions src/renderer/src/i18n/locales/en-us.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
"back": "Back",
"chat": "Chat",
"close": "Close",
"cancel": "Cancel"
"cancel": "Cancel",
"download": "Download"
},
"button": {
"add": "Add",
Expand Down Expand Up @@ -351,7 +352,8 @@
"button.translate": "Translate",
"error.not_configured": "Translation model is not configured",
"input.placeholder": "Enter text to translate",
"output.placeholder": "Translation"
"output.placeholder": "Translation",
"confirm": "Original text has been copied to clipboard. Do you want to replace it with the translated text?"
},
"languages": {
"english": "English",
Expand Down
8 changes: 5 additions & 3 deletions src/renderer/src/i18n/locales/zh-cn.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
"back": "返回",
"chat": "聊天",
"close": "关闭",
"cancel": "取消"
"cancel": "取消",
"download": "下载"
},
"button": {
"add": "添加",
Expand Down Expand Up @@ -285,7 +286,7 @@
"provider.search_placeholder": "搜索模型 ID 或名称",
"provider.api.url.reset": "重置",
"provider.api.url.preview": "预览: {{url}}",
"provider.api.url.tip": "/结尾忽略v1版本,#结尾��制使用输入地址",
"provider.api.url.tip": "/结尾忽略v1版本,#结尾制使用输入地址",
"models.default_assistant_model": "默认助手模型",
"models.topic_naming_model": "话题命名模型",
"models.translate_model": "翻译模型",
Expand Down Expand Up @@ -351,7 +352,8 @@
"button.translate": "翻译",
"error.not_configured": "翻译模型未配置",
"input.placeholder": "输入文本进行翻译",
"output.placeholder": "翻译"
"output.placeholder": "翻译",
"confirm": "原文已复制到剪贴板,是否用翻译后的文本替换?"
},
"languages": {
"english": "英文",
Expand Down
6 changes: 4 additions & 2 deletions src/renderer/src/i18n/locales/zh-tw.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@
"back": "返回",
"chat": "聊天",
"close": "關閉",
"cancel": "取消"
"cancel": "取消",
"download": "下載"
},
"button": {
"add": "添加",
Expand Down Expand Up @@ -351,7 +352,8 @@
"button.translate": "翻譯",
"error.not_configured": "翻譯模型未配置",
"input.placeholder": "輸入文字進行翻譯",
"output.placeholder": "翻譯"
"output.placeholder": "翻譯",
"confirm": "原文已複製到剪貼簿,是否用翻譯後的文字替換?"
},
"languages": {
"english": "英文",
Expand Down
193 changes: 193 additions & 0 deletions src/renderer/src/pages/paintings/Artboard.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
import { CopyOutlined, DownloadOutlined } from '@ant-design/icons'
import FileManager from '@renderer/services/FileManager'
import { Painting } from '@renderer/types'
import { download } from '@renderer/utils/download'
import { Button, Dropdown, Spin } from 'antd'
import { FC } from 'react'
import { useTranslation } from 'react-i18next'
import styled from 'styled-components'

import ImagePreview from '../home/Markdown/ImagePreview'

interface ArtboardProps {
painting: Painting
isLoading: boolean
currentImageIndex: number
onPrevImage: () => void
onNextImage: () => void
onCancel: () => void
}

const Artboard: FC<ArtboardProps> = ({
painting,
isLoading,
currentImageIndex,
onPrevImage,
onNextImage,
onCancel
}) => {
const { t } = useTranslation()

const getCurrentImageUrl = () => {
const currentFile = painting.files[currentImageIndex]
return currentFile ? FileManager.getFileUrl(currentFile) : ''
}

const handleContextMenu = (e: React.MouseEvent) => {
e.preventDefault()
}

const getContextMenuItems = () => {
return [
{
key: 'copy',
label: t('common.copy'),
icon: <CopyOutlined />,
onClick: () => {
navigator.clipboard.writeText(painting.urls[currentImageIndex])
}
},
{
key: 'download',
label: t('common.download'),
icon: <DownloadOutlined />,
onClick: () => download(getCurrentImageUrl())
}
]
}

return (
<Container>
<LoadingContainer spinning={isLoading}>
{painting.files.length > 0 ? (
<ImageContainer>
{painting.files.length > 1 && (
<NavigationButton onClick={onPrevImage} style={{ left: 10 }}>
</NavigationButton>
)}
<Dropdown menu={{ items: getContextMenuItems() }} trigger={['contextMenu']}>
<ImagePreview
src={getCurrentImageUrl()}
preview={{ mask: false }}
onContextMenu={handleContextMenu}
style={{
width: '70vh',
height: '70vh',
objectFit: 'contain',
backgroundColor: 'var(--color-background-soft)',
cursor: 'pointer'
}}
/>
</Dropdown>
{painting.files.length > 1 && (
<NavigationButton onClick={onNextImage} style={{ right: 10 }}>
</NavigationButton>
)}
<ImageCounter>
{currentImageIndex + 1} / {painting.files.length}
</ImageCounter>
</ImageContainer>
) : (
<ImagePlaceholder />
)}
{isLoading && (
<LoadingOverlay>
<Spin size="large" />
<CancelButton onClick={onCancel}>{t('common.cancel')}</CancelButton>
</LoadingOverlay>
)}
</LoadingContainer>
</Container>
)
}

const Container = styled.div`
display: flex;
flex: 1;
flex-direction: row;
justify-content: center;
align-items: center;
`

const ImagePlaceholder = styled.div`
display: flex;
width: 70vh;
height: 70vh;
background-color: var(--color-background-soft);
align-items: center;
justify-content: center;
cursor: pointer;
`

const ImageContainer = styled.div`
position: relative;
display: flex;
align-items: center;
justify-content: center;
.ant-spin {
max-height: none;
}
.ant-spin-spinning {
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
z-index: 3;
}
`

const NavigationButton = styled(Button)`
position: absolute;
top: 50%;
transform: translateY(-50%);
z-index: 2;
opacity: 0.7;
&:hover {
opacity: 1;
}
`

const ImageCounter = styled.div`
position: absolute;
bottom: 10px;
left: 50%;
transform: translateX(-50%);
background-color: rgba(0, 0, 0, 0.5);
color: white;
padding: 4px 8px;
border-radius: 12px;
font-size: 12px;
`

const LoadingContainer = styled.div<{ spinning: boolean }>`
position: relative;
width: 100%;
height: 100%;
display: flex;
justify-content: center;
align-items: center;
opacity: ${(props) => (props.spinning ? 0.5 : 1)};
transition: opacity 0.3s;
`

const LoadingOverlay = styled.div`
position: absolute;
top: 50%;
left: 50%;
transform: translate(-50%, -50%);
display: flex;
flex-direction: column;
align-items: center;
gap: 20px;
`

const CancelButton = styled(Button)`
margin-top: 10px;
z-index: 1001;
`

export default Artboard
Loading

0 comments on commit f6aa0dc

Please sign in to comment.