Skip to content

Commit

Permalink
feat: 修改默认hash读取来源为defaults.json,防止导出的数据无法覆盖英文内容的问题
Browse files Browse the repository at this point in the history
  • Loading branch information
erguotou520 committed Apr 19, 2021
1 parent 797fcf9 commit 74d2936
Show file tree
Hide file tree
Showing 9 changed files with 81 additions and 56 deletions.
1 change: 0 additions & 1 deletion .eslintcache

This file was deleted.

1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
.env.development.local
.env.test.local
.env.production.local
.eslintcache

npm-debug.log*
yarn-debug.log*
Expand Down
8 changes: 5 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
# 在线国际化翻译小助手

该项目可以帮助我们对`react-intl`生成的国际化配置做辅助在线翻译的功能。

## 使用方法
1. 编译`react-intl`项目以便生成包含国际化`json`数据的`lang`目录

1. 编译`react-intl`项目以便生成包含国际化`json`数据的`lang`目录,要求生成一份最新翻译抽取出的`defaults.json`文件,其余的为各语言的 json 文件
2. 压缩`lang`目录,生成`lang.zip`
3. 打开[https://turing-fe.github.io/translate-app/](https://turing-fe.github.io/translate-app/),点击下方`选择zip文件上传`按钮上传打包的zip文件
4. 在页面填写未翻译的空白项,完成后点击`导出`按钮下载zip包,解压缩后替换代码中的`lang`目录
3. 打开[https://turing-fe.github.io/translate-app/](https://turing-fe.github.io/translate-app/),点击下方`选择zip文件上传`按钮上传打包的 zip 文件
4. 在页面填写未翻译的空白项,完成后点击`导出`按钮下载 zip 包,解压缩后替换代码中的`lang`目录中的文件
4 changes: 2 additions & 2 deletions src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { useGlobalData } from './provider/data'

const TranslatePage: React.FC = () => {
const mainContentRef = useRef<MainContentAction>()
const { noEnLangs } = useGlobalData()
const { langs } = useGlobalData()
// 导出
const doExport = () => {
mainContentRef.current.exportZip()
Expand All @@ -14,7 +14,7 @@ const TranslatePage: React.FC = () => {
return (
<div style={{ minHeight: 'calc(100vh - 64px)', paddingBottom: '84px' }}>
<MainContent actionRef={mainContentRef} />
<FixedFooter langs={noEnLangs} onExport={doExport} />
<FixedFooter langs={langs} onExport={doExport} />
</div>
)
}
Expand Down
1 change: 0 additions & 1 deletion src/components/FixedFooter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ const FixedFooter: React.FC<Props> = ({ langs, onExport }) => {
const onSelectZipFile = useCallback(
async ({ file }) => {
const locales = await parseZip(file)
console.log(locales.length)
setConfig('locales', locales)
},
[setConfig]
Expand Down
75 changes: 43 additions & 32 deletions src/components/MainContent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { Collapse } from 'antd'
import EditableTranslate from './EditableTranslate'
import { useGlobalData } from '../provider/data'
import { LocaleTranslateItem } from '../types'
import { EN_LANG } from '../configs/constants'
import { DEFAULT_LANG } from '../configs/constants'
import { downloadZip } from 'src/utils/zip'

const { Panel } = Collapse
Expand Down Expand Up @@ -38,14 +38,15 @@ function shouldPanelDefaultCollapsed(
)
}

const MainContent: React.FC<{ actionRef: React.MutableRefObject<MainContentAction>}> = ({ actionRef }) => {
const MainContent: React.FC<{
actionRef: React.MutableRefObject<MainContentAction>
}> = ({ actionRef }) => {
const {
hideTranslatedPanel,
hideTranslatedLocales,
visibleLang,
locales,
langs,
// noEnLangs
langs
} = useGlobalData()

console.log('locales', locales)
Expand All @@ -58,17 +59,18 @@ const MainContent: React.FC<{ actionRef: React.MutableRefObject<MainContentActio
</p>
)
}
// 读取英文翻译
const enLocale = locales.find(locale => locale.filename === EN_LANG)
// 解析英文中的所有hash数据
let enJson: LocaleTranslates = {}
// 读取默认翻译
const defaultLocale = locales.find(locale => locale.filename === DEFAULT_LANG)

// 解析默认翻译中的所有hash数据
let defaultJson: LocaleTranslates = {}
try {
enJson = JSON.parse(enLocale.content) as LocaleTranslates
defaultJson = JSON.parse(defaultLocale.content) as LocaleTranslates
} catch (error) {
console.error(error)
return (
<p className="text-red-600 empty-content">
解析英文源文件失败,请检查上传的zip文件是否正确!
解析源文件失败,请检查上传的zip文件是否正确!
</p>
)
}
Expand All @@ -78,30 +80,37 @@ const MainContent: React.FC<{ actionRef: React.MutableRefObject<MainContentActio
const localeJsons = locales.reduce<{
[key: string]: LocaleTranslates
}>((obj, locale) => {
obj[locale.filename] = JSON.parse(locale.content) as LocaleTranslates
// 默认翻译不展示
if (locale.filename !== DEFAULT_LANG) {
obj[locale.filename] = JSON.parse(locale.content) as LocaleTranslates
}
return obj
}, {})

// 面板数据
const panels = Object.keys(enJson).reduce<LangPanelProps[]>((arr, hash) => {
const panel = {
description: enJson[hash].description,
hash,
langs,
locales: langs.reduce<{ [key: string]: string }>((obj, lang) => {
obj[lang] = localeJsons[lang][hash]?.defaultMessage
return obj
}, {})
}
if (
!(
hideTranslatedPanel && shouldPanelDefaultCollapsed(panel, visibleLang)
)
) {
arr.push(panel)
}
return arr
}, [])
const panels = Object.keys(defaultJson).reduce<LangPanelProps[]>(
(arr, hash) => {
const panel = {
description: defaultJson[hash].description,
hash,
langs,
locales: langs.reduce<{ [key: string]: string }>((obj, lang) => {
obj[lang] = localeJsons[lang][hash]?.defaultMessage
return obj
}, {})
}
if (
!(
hideTranslatedPanel &&
shouldPanelDefaultCollapsed(panel, visibleLang)
)
) {
arr.push(panel)
}
return arr
},
[]
)

// 如果所有语言都有翻译,则默认收起
const defaultActiveKeys = panels.reduce<string[]>((arr, panel) => {
Expand Down Expand Up @@ -132,7 +141,7 @@ const MainContent: React.FC<{ actionRef: React.MutableRefObject<MainContentActio
if (!localeJsons[key.lang][key.hash]) {
localeJsons[key.lang][key.hash] = {
defaultMessage: '',
description: enJson[key.hash].description
description: defaultJson[key.hash].description
}
}
localeJsons[key.lang][key.hash].defaultMessage = value
Expand All @@ -147,7 +156,9 @@ const MainContent: React.FC<{ actionRef: React.MutableRefObject<MainContentActio
{panels.map(panel => (
<Panel
header={
panel.description ? `描述:${panel.description}` : (
panel.description ? (
`描述:${panel.description}`
) : (
<span className="text-red-600 empty-content">未提供描述</span>
)
}
Expand Down
2 changes: 1 addition & 1 deletion src/configs/constants.ts
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export const EN_LANG = 'en-US'
export const DEFAULT_LANG = 'defaults'
12 changes: 6 additions & 6 deletions src/provider/data.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { createContext, useContext, useState } from 'react'
import { EN_LANG } from 'src/configs/constants'
import { DEFAULT_LANG } from 'src/configs/constants'
import { LocaleFileContent } from '../types'

interface GlobalData {
Expand All @@ -15,8 +15,10 @@ interface GlobalData {

interface GlobalDataWithAction extends GlobalData {
langs: string[]
noEnLangs: string[]
setConfig: (key: keyof GlobalData, value: boolean | string | LocaleFileContent[]) => void
setConfig: (
key: keyof GlobalData,
value: boolean | string | LocaleFileContent[]
) => void
}

const defaultGlobalData = {
Expand All @@ -29,7 +31,6 @@ const defaultGlobalData = {
const GlobalDataContext = createContext<GlobalDataWithAction>({
...defaultGlobalData,
langs: [],
noEnLangs: [],
// eslint-disable-next-line @typescript-eslint/no-empty-function
setConfig: () => {}
})
Expand All @@ -41,8 +42,7 @@ const GlobalDataProvider: React.FC = props => {
<GlobalDataContext.Provider
value={{
...globalData,
langs,
noEnLangs: langs.filter(lang => lang !== EN_LANG),
langs: langs.filter(lang => lang !== DEFAULT_LANG),
setConfig: (key, value) => {
setGlobalData({
...globalData,
Expand Down
33 changes: 23 additions & 10 deletions src/utils/zip.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,23 @@ export async function parseZip(file: File): Promise<LocaleFileContent[]> {
const ret: LocaleFileContent[] = []
for (const fileKey of Object.keys(zip.files)) {
const localeFile = zip.files[fileKey]
// 目录跳过
// 目录跳过,非json跳过
if (!localeFile.dir && localeFile.name.endsWith('.json')) {
const localeContent = await localeFile.async('string')
ret.push({
filename: localeFile.name.split('/').pop().replace(/\.json/, ''),
content: localeContent
})
const filename = localeFile.name
.split('/')
.pop()
.replace(/\.json/, '')
// 非法文件跳过
if (filename.match(/^[a-zA-Z-]+$/)) {
ret.push({
filename: localeFile.name
.split('/')
.pop()
.replace(/\.json/, ''),
content: localeContent
})
}
}
}
return ret
Expand All @@ -25,12 +35,15 @@ export async function parseZip(file: File): Promise<LocaleFileContent[]> {
return []
}

export function downloadZip(noEnLangs: string[], localeJsons: {
[key: string]: LocaleTranslates
}) {
export function downloadZip(
langs: string[],
localeJsons: {
[key: string]: LocaleTranslates
}
) {
const zip = new JsZip()
const langFolder = zip.folder('lang')
noEnLangs.forEach(lang => {
langs.forEach(lang => {
// json重新排序
const newJson = Object.keys(localeJsons[lang])
.sort((a, b) => (a < b ? -1 : 1))
Expand All @@ -56,4 +69,4 @@ export function downloadZip(noEnLangs: string[], localeJsons: {
// 然后移除
document.body.removeChild(eleLink)
})
}
}

0 comments on commit 74d2936

Please sign in to comment.