Skip to content

Commit

Permalink
✨ Feature(i18n): add i18n for picgo
Browse files Browse the repository at this point in the history
  • Loading branch information
Molunerfinn committed Jan 31, 2022
1 parent 443bd2e commit 4b93a76
Show file tree
Hide file tree
Showing 7 changed files with 172 additions and 21 deletions.
12 changes: 4 additions & 8 deletions src/core/PicGo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { IBuildInEvent, IBusEvent } from '../utils/enum'
import { eventBus } from '../utils/eventBus'
import { RequestPromiseAPI } from 'request-promise-native'
import { isConfigKeyInBlackList, isInputConfigValid } from '../utils/common'
import { i18nManager } from '../i18n'
import { I18nManager } from '../i18n'

export class PicGo extends EventEmitter implements IPicGo {
private _config!: IConfig
Expand All @@ -40,7 +40,7 @@ export class PicGo extends EventEmitter implements IPicGo {
* use request instead
*/
Request!: Request
i18n: II18nManager = i18nManager
i18n!: II18nManager
VERSION: string = process.env.PICGO_VERSION
GUI_VERSION?: string

Expand Down Expand Up @@ -90,6 +90,8 @@ export class PicGo extends EventEmitter implements IPicGo {

private init (): void {
try {
// init 18n at first
this.i18n = new I18nManager(this)
this.Request = new Request(this)
this._pluginLoader = new PluginLoader(this)
// load self plugins
Expand All @@ -100,19 +102,13 @@ export class PicGo extends EventEmitter implements IPicGo {
// load third-party plugins
this._pluginLoader.load()
this.lifecycle = new Lifecycle(this)
this.initI18n()
} catch (e: any) {
this.emit(IBuildInEvent.UPLOAD_PROGRESS, -1)
this.log.error(e)
throw e
}
}

private initI18n (): void {
const language = this.getConfig<string>('settings.language') || 'zh-CN'
this.i18n.setLanguage(language)
}

registerCommands (): void {
if (this.configPath !== '') {
this.cmd.init()
Expand Down
82 changes: 82 additions & 0 deletions src/i18n/en.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import { ILocales } from './zh-CN'

/* eslint-disable no-template-curly-in-string */
export const EN: ILocales = {
UPLOAD_FAILED: 'Upload failed',
CHECK_SETTINGS: 'Please check your settings',
CHECK_SETTINGS_AND_NETWORK: 'Please check your settings and network',
UPLOAD_FAILED_REASON: 'Error code: ${code}, please open the browser and paste the address to see the reason',
SERVER_ERROR: 'Server error, please try again later',
AUTH_FAILED: 'Authentication failed',

// smms
PICBED_SMMS: 'SM.MS',
PICBED_SMMS_TOKEN: 'Set Token',

// Ali-cloud
PICBED_ALICLOUD: 'Ali Cloud',
PICBED_ALICLOUD_ACCESSKEYID: 'Set KeyId',
PICBED_ALICLOUD_ACCESSKEYSECRET: 'Set KeySecret',
PICBED_ALICLOUD_BUCKET: 'Set Bucket',
PICBED_ALICLOUD_AREA: 'Set Area',
PICBED_ALICLOUD_PATH: 'Set Path',
PICBED_ALICLOUD_CUSTOMURL: 'Set Custom URL',
PICBED_ALICLOUD_OPTIONS: 'Set URL Suffix',

// Tencent-cloud
PICBED_TENCENTCLOUD: 'Tencent Cloud',
PICBED_TENCENTCLOUD_VERSION: 'Choose COS version',
PICBED_TENCENTCLOUD_SECRETID: 'Set SecretId',
PICBED_TENCENTCLOUD_SECRETKEY: 'Set SecretKey',
PICBED_TENCENTCLOUD_APPID: 'Set AppId',
PICBED_TENCENTCLOUD_BUCKET: 'Set Bucket',
PICBED_TENCENTCLOUD_AREA: 'Set Area',
PICBED_TENCENTCLOUD_PATH: 'Set Path',
PICBED_TENCENTCLOUD_CUSTOMURL: 'Set Custom URL',

// GitHub
PICBED_GITHUB: 'GitHub',
PICBED_GITHUB_TOKEN: 'Set Token',
PICBED_GITHUB_REPO: 'Set Repo Name',
PICBED_GITHUB_PATH: 'Set Path',
PICBED_GITHUB_BRANCH: 'Set Branch',
PICBED_GITHUB_CUSTOMURL: 'Set Custom URL',

// qiniu
PICBED_QINIU: 'Qiniu',
PICBED_QINIU_ACCESSKEY: 'Set AccessKey',
PICBED_QINIU_SECRETKEY: 'Set SecretKey',
PICBED_QINIU_BUCKET: 'Set Bucket',
PICBED_QINIU_PATH: 'Set Path',
PICBED_QINIU_URL: 'Set URL',
PICBED_QINIU_OPTIONS: 'Set URL Suffix',
PICBED_QINIU_AREA: 'Set Area',

// imgur
PICBED_IMGUR: 'Imgur',
PICBED_IMGUR_CLIENTID: 'Set ClientId',
PICBED_IMGUR_PROXY: 'Set Proxy',

// upyun
PICBED_UPYUN: 'Upyun',
PICBED_UPYUN_BUCKET: 'Set Bucket',
PICBED_UPYUN_OPERATOR: 'Set Operator',
PICBED_UPYUN_PASSWORD: 'Set Operator Password',
PICBED_UPYUN_PATH: 'Set Path',
PICBED_UPYUN_URL: 'Set URL',
PICBED_UPYUN_OPTIONS: 'Set URL Suffix',

// Plugin Handler
PLUGIN_HANDLER_PLUGIN_INSTALL_SUCCESS: 'Plugin installed successfully',
PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED: 'Plugin installation failed',
PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED_REASON: 'Plugin installation failed, error code is ${code}, error log is \n ${data}',
PLUGIN_HANDLER_PLUGIN_INSTALL_FAILED_PATH: 'Plugin installation failed, please enter a valid plugin name or valid installation path',
PLUGIN_HANDLER_PLUGIN_UNINSTALL_SUCCESS: 'Plugin uninstalled successfully',
PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED: 'Plugin uninstall failed',
PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_REASON: 'Plugin uninstall failed, error code is ${code}, error log is \n ${data}',
PLUGIN_HANDLER_PLUGIN_UNINSTALL_FAILED_VALID: 'Plugin uninstall failed, please enter a valid plugin name',
PLUGIN_HANDLER_PLUGIN_UPDATE_SUCCESS: 'Plugin updated successfully',
PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED: 'Plugin update failed',
PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_REASON: 'Plugin update failed, error code is ${code}, error log is \n ${data}',
PLUGIN_HANDLER_PLUGIN_UPDATE_FAILED_VALID: 'Plugin update failed, please enter a valid plugin name'
}
41 changes: 28 additions & 13 deletions src/i18n/index.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,28 @@
import { ZH_CN, ILocalesKey } from './zh-CN'
import { merge } from 'lodash'
import { IPicGo } from '../types'

import { ObjectAdapter, I18n } from '@picgo/i18n'
import { IStringKeyMap, II18nManager } from '../types/index'
import { ILocale } from '@picgo/i18n/dist/types'
import { EN } from './en'

const languageList = {
'zh-CN': ZH_CN
const languageList: IStringKeyMap<IStringKeyMap<string>> = {
'zh-CN': ZH_CN,
en: EN
}

class I18nManager implements II18nManager {
private readonly i18n: I18n
private readonly objectAdapter: ObjectAdapter
constructor () {
private readonly ctx: IPicGo
constructor (ctx: IPicGo) {
this.ctx = ctx
this.objectAdapter = new ObjectAdapter(languageList)
const language = this.ctx.getConfig<string>('settings.language') || 'zh-CN'
this.i18n = new I18n({
adapter: this.objectAdapter,
defaultLanguage: 'zh-CN'
defaultLanguage: language
})
}

Expand All @@ -26,14 +32,11 @@ class I18nManager implements II18nManager {

setLanguage (language: string): void {
this.i18n.setLanguage(language)
this.ctx.saveConfig({
'settings.language': language
})
}

/**
* add locale to current i18n language
* default locale list
* - zh-CN
* - en
*/
addLocale (language: string, locales: ILocale): boolean {
const originLocales = this.objectAdapter.getLocale(language)
if (!originLocales) {
Expand All @@ -43,10 +46,22 @@ class I18nManager implements II18nManager {
this.objectAdapter.setLocale(language, newLocales)
return true
}
}

const i18nManager = new I18nManager()
addLanguage (language: string, locales: ILocale): boolean {
const originLocales = this.objectAdapter.getLocale(language)
if (originLocales) {
return false
}
this.objectAdapter.setLocale(language, locales)
languageList[language] = locales
return true
}

getLanguageList (): string[] {
return Object.keys(languageList)
}
}

export {
i18nManager
I18nManager
}
1 change: 1 addition & 0 deletions src/i18n/zh-CN.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,3 +80,4 @@ export const ZH_CN = {
}

export type ILocalesKey = keyof typeof ZH_CN
export type ILocales = typeof ZH_CN
35 changes: 35 additions & 0 deletions src/plugins/commander/i18n.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { IPlugin, IPicGo, IStringKeyMap } from '../../types'

const i18n: IPlugin = {
handle: (ctx: IPicGo) => {
const cmd = ctx.cmd
cmd.program
.command('i18n')
.arguments('[lang]')
.action(async (lang: string = '') => {
const list = ctx.i18n.getLanguageList()
if (!lang) {
const prompts = [
{
type: 'list',
name: 'i18n',
choices: list,
message: 'Choose a language',
default: ctx.getConfig('settings.language') || 'zh-CN'
}
]
const answer = await ctx.cmd.inquirer.prompt<IStringKeyMap<string>>(prompts)
ctx.i18n.setLanguage(answer.i18n)
ctx.log.success(`Language set to ${answer.i18n}`)
return
}
if (!list.includes(lang)) {
return ctx.log.warn('No such language')
}
ctx.i18n.setLanguage(lang)
ctx.log.success(`Language set to ${lang}`)
})
}
}

export default i18n
2 changes: 2 additions & 0 deletions src/plugins/commander/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import setting from './setting'
import use from './use'
import proxy from './proxy'
import init from './init'
import i18n from './i18n'
import { IPicGo } from '../../types'

export default (ctx: IPicGo): void => {
Expand All @@ -15,4 +16,5 @@ export default (ctx: IPicGo): void => {
ctx.cmd.register('use', use)
ctx.cmd.register('proxy', proxy)
ctx.cmd.register('init', init)
ctx.cmd.register('i18n', i18n)
}
20 changes: 20 additions & 0 deletions src/types/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -478,7 +478,27 @@ export interface IConfigChangePayload<T> {
}

export interface II18nManager {
/**
* translate text
*/
translate: <T extends string>(key: T, args?: IStringKeyMap<string>) => string
/**
* add locale to current i18n language
* default locale list
* - zh-CN
* - en
*/
addLocale: (language: string, locales: ILocale) => boolean
/**
* set current language
*/
setLanguage: (language: string) => void
/**
* dynamic add new language & locales
*/
addLanguage: (language: string, locales: ILocale) => boolean
/**
* get language list
*/
getLanguageList: () => string[]
}

0 comments on commit 4b93a76

Please sign in to comment.