Commit 5577fb23 authored by 神楽坂玲奈's avatar 神楽坂玲奈

i18n

parent 4fd5e106
...@@ -34,10 +34,17 @@ ...@@ -34,10 +34,17 @@
"root": "", "root": "",
"sourceRoot": "src", "sourceRoot": "src",
"prefix": "app", "prefix": "app",
"i18n": {
"sourceLocale": "zh-Hans",
"locales": {
"en-US": "src/locale/messages.en-US.xlf"
}
},
"architect": { "architect": {
"build": { "build": {
"builder": "@angular-builders/custom-webpack:browser", "builder": "@angular-builders/custom-webpack:browser",
"options": { "options": {
"localize": ["zh-Hans"],
"allowedCommonJsDependencies": [ "allowedCommonJsDependencies": [
"glob", "glob",
"aria2", "aria2",
......
...@@ -13,10 +13,12 @@ function handleElevate() { ...@@ -13,10 +13,12 @@ function handleElevate() {
require('electron').app.dock.hide(); require('electron').app.dock.hide();
} }
let elevate = JSON.parse(Buffer.from(process.argv[2], 'base64').toString()); let elevate = JSON.parse(Buffer.from(process.argv[2], 'base64').toString());
require('net').connect(elevate['ipc'], function() { require('net').connect(elevate['ipc'], function () {
process.send = (message, sendHandle, options, callback) => this.write(JSON.stringify(message) + require('os').EOL, callback); process.send = (message, sendHandle, options, callback) => this.write(JSON.stringify(message) + require('os').EOL, callback);
this.on('end', () => process.emit('disconnect')); this.on('end', () => process.emit('disconnect'));
require('readline').createInterface({ input: this }).on('line', (line) => process.emit('message', JSON.parse(line))); require('readline')
.createInterface({ input: this })
.on('line', (line) => process.emit('message', JSON.parse(line)));
process.argv = elevate['arguments'][1]; process.argv = elevate['arguments'][1];
require('./' + elevate['arguments'][0]); require('./' + elevate['arguments'][0]);
}); });
...@@ -30,6 +32,8 @@ if (handleElevate()) { ...@@ -30,6 +32,8 @@ if (handleElevate()) {
const { ipcMain, app, shell, BrowserWindow, Menu, Tray, Notification } = require('electron'); const { ipcMain, app, shell, BrowserWindow, Menu, Tray, Notification } = require('electron');
const { autoUpdater } = require('electron-updater'); const { autoUpdater } = require('electron-updater');
const { localStorage } = require('electron-browser-storage');
const isDev = require('electron-is-dev'); const isDev = require('electron-is-dev');
const child_process = require('child_process'); const child_process = require('child_process');
const path = require('path'); const path = require('path');
...@@ -102,14 +106,14 @@ autoUpdater.on('update-downloaded', (event) => { ...@@ -102,14 +106,14 @@ autoUpdater.on('update-downloaded', (event) => {
console.log('autoUpdater', 'update-downloaded', event); console.log('autoUpdater', 'update-downloaded', event);
updateWindow = new BrowserWindow({ updateWindow = new BrowserWindow({
width: 640, width: 640,
height: 360 height: 360,
}); });
updateWindow.loadURL(`file://${__dirname}/update.html`); updateWindow.loadURL(`file://${__dirname}/update.html`);
updateWindow.webContents.on('new-window', function(e, url) { updateWindow.webContents.on('new-window', function (e, url) {
e.preventDefault(); e.preventDefault();
shell.openExternal(url); shell.openExternal(url);
}); });
updateWindow.on('closed', function() { updateWindow.on('closed', function () {
updateWindow = null; updateWindow = null;
}); });
ipcMain.on('update', (event, arg) => { ipcMain.on('update', (event, arg) => {
...@@ -141,7 +145,9 @@ function createAria2c() { ...@@ -141,7 +145,9 @@ function createAria2c() {
default: default:
throw 'unsupported platform'; throw 'unsupported platform';
} }
aria2c = child_process.spawn(aria2c_path, [ aria2c = child_process.spawn(
aria2c_path,
[
'--enable-rpc', '--enable-rpc',
'--rpc-allow-origin-all', '--rpc-allow-origin-all',
'--rpc-listen-port=6800', '--rpc-listen-port=6800',
...@@ -150,12 +156,21 @@ function createAria2c() { ...@@ -150,12 +156,21 @@ function createAria2c() {
'--min-split-size=1M', '--min-split-size=1M',
'--max-connection-per-server=10', '--max-connection-per-server=10',
'--remove-control-file', '--remove-control-file',
'--allow-overwrite' '--allow-overwrite',
], { stdio: 'ignore' }); ],
{ stdio: 'ignore' }
);
}
async function getLocale() {
const store = await localStorage.getItem('locale');
if (store) return store;
return app.getLocale().startsWith('zh') ? 'zh-Hans' : 'en-US';
} }
// 主窗口 // 主窗口
function createWindow() { async function createWindow() {
// Create the browser window. // Create the browser window.
mainWindow = new BrowserWindow({ mainWindow = new BrowserWindow({
width: 1024, width: 1024,
...@@ -165,17 +180,17 @@ function createWindow() { ...@@ -165,17 +180,17 @@ function createWindow() {
frame: process.platform === 'darwin', frame: process.platform === 'darwin',
webPreferences: { nodeIntegration: true, contextIsolation: false, enableRemoteModule: true, webviewTag: true }, webPreferences: { nodeIntegration: true, contextIsolation: false, enableRemoteModule: true, webviewTag: true },
// transparent: process.platform != 'darwin', // transparent: process.platform != 'darwin',
titleBarStyle: process.platform === 'darwin' ? 'hidden' : undefined titleBarStyle: process.platform === 'darwin' ? 'hidden' : undefined,
}); });
// and load the index.html of the app. // and load the index.html of the app.
if (isDev) { if (isDev) {
mainWindow.loadURL('http://localhost:4200/'); mainWindow.loadURL('http://localhost:4200/');
} else { } else {
mainWindow.loadFile('dist/mycard/index.html'); mainWindow.loadFile(path.join('dist/mycard', await getLocale(), 'index.html'));
} }
mainWindow.webContents.on('new-window', function(e, url) { mainWindow.webContents.on('new-window', function (e, url) {
e.preventDefault(); e.preventDefault();
shell.openExternal(url); shell.openExternal(url);
}); });
...@@ -186,7 +201,7 @@ function createWindow() { ...@@ -186,7 +201,7 @@ function createWindow() {
} }
// Emitted when the window is closed. // Emitted when the window is closed.
mainWindow.on('closed', function() { mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows // Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time // in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element. // when you should delete the corresponding element.
...@@ -197,7 +212,7 @@ function createWindow() { ...@@ -197,7 +212,7 @@ function createWindow() {
let tray; let tray;
function createTray() { function createTray() {
tray = new Tray(path.join(__dirname, 'images', 'icon.ico')); tray = new Tray(path.join(__dirname, isDev ? 'src' : 'dist/mycard/zh-Hans', 'assets/icon.ico'));
tray.on('click', (event) => { tray.on('click', (event) => {
console.log(event); console.log(event);
if (event.metaKey) { if (event.metaKey) {
...@@ -211,13 +226,17 @@ function createTray() { ...@@ -211,13 +226,17 @@ function createTray() {
// {label: '社区', type: 'normal', click: (menuItem, browserWindow, event)=>{}}, // {label: '社区', type: 'normal', click: (menuItem, browserWindow, event)=>{}},
// {label: '切换账号', type: 'normal', click: (menuItem, browserWindow, event)=>{}}, // {label: '切换账号', type: 'normal', click: (menuItem, browserWindow, event)=>{}},
{ {
label: '显示主界面', type: 'normal', click: () => { label: '显示主界面',
type: 'normal',
click: () => {
mainWindow.isVisible() ? mainWindow.hide() : mainWindow.show(); mainWindow.isVisible() ? mainWindow.hide() : mainWindow.show();
} },
}, },
{ {
label: '退出', type: 'normal', click: app.quit label: '退出',
} type: 'normal',
click: app.quit,
},
]); ]);
tray.setToolTip('MyCard'); tray.setToolTip('MyCard');
tray.setContextMenu(contextMenu); tray.setContextMenu(contextMenu);
...@@ -252,7 +271,7 @@ app.on('ready', async () => { ...@@ -252,7 +271,7 @@ app.on('ready', async () => {
}); });
// Quit when all windows are closed. // Quit when all windows are closed.
app.on('window-all-closed', function() { app.on('window-all-closed', function () {
// On OS X it is common for applications and their menu bar // On OS X it is common for applications and their menu bar
// to stay active until the user quits explicitly with Cmd + Q // to stay active until the user quits explicitly with Cmd + Q
if (process.platform !== 'darwin') { if (process.platform !== 'darwin') {
...@@ -260,7 +279,7 @@ app.on('window-all-closed', function() { ...@@ -260,7 +279,7 @@ app.on('window-all-closed', function() {
} }
}); });
app.on('activate', function() { app.on('activate', function () {
// On OS X it's common to re-create a window in the app when the // On OS X it's common to re-create a window in the app when the
// dock icon is clicked and there are no other windows open. // dock icon is clicked and there are no other windows open.
if (mainWindow === null) { if (mainWindow === null) {
......
This source diff could not be displayed because it is too large. You can view the blob instead.
...@@ -13,6 +13,12 @@ ...@@ -13,6 +13,12 @@
"main": "main.js", "main": "main.js",
"description": "萌卡客户端", "description": "萌卡客户端",
"author": "zh99998 <zh99998@gmail.com>", "author": "zh99998 <zh99998@gmail.com>",
"dependencies": {
"@electron/remote": "^1.2.1",
"electron-browser-storage": "^1.0.7",
"electron-is-dev": "^2.0.0",
"electron-updater": "^4.3.9"
},
"devDependencies": { "devDependencies": {
"@angular-builders/custom-webpack": "^12.1.1", "@angular-builders/custom-webpack": "^12.1.1",
"@angular/animations": "~12.2.5", "@angular/animations": "~12.2.5",
...@@ -26,41 +32,93 @@ ...@@ -26,41 +32,93 @@
"@angular/platform-browser": "~12.2.5", "@angular/platform-browser": "~12.2.5",
"@angular/platform-browser-dynamic": "~12.2.5", "@angular/platform-browser-dynamic": "~12.2.5",
"@angular/router": "~12.2.5", "@angular/router": "~12.2.5",
"@types/bootstrap": "^5.1.4",
"@types/mousetrap": "^1.6.8",
"@types/node": "^16.4.13",
"bootstrap": "^5.1.0",
"copy-webpack-plugin": "^9.0.1",
"electron": "^13.3.0",
"electron-builder": "^22.11.7",
"mousetrap": "^1.6.5",
"rxjs": "^7.3.0",
"tslib": "^2.3.0",
"typescript": "~4.3.5",
"zone.js": "~0.11.4"
},
"dependencies": {
"@electron/remote": "^1.2.1",
"@fortawesome/fontawesome-free": "^5.15.4", "@fortawesome/fontawesome-free": "^5.15.4",
"@types/bootstrap": "^5.1.4",
"@types/ini": "^1.3.30", "@types/ini": "^1.3.30",
"@types/jquery": "^3.5.6", "@types/jquery": "^3.5.6",
"@types/mousetrap": "^1.6.8",
"@types/mustache": "^4.1.2", "@types/mustache": "^4.1.2",
"@types/node": "^16.4.13",
"aria2": "^3.0.1", "aria2": "^3.0.1",
"bootstrap": "^5.1.0",
"candy": "https://github.com/moecube/candy/releases/download/v2.2.0/candy.tar.gz", "candy": "https://github.com/moecube/candy/releases/download/v2.2.0/candy.tar.gz",
"candy-shop": "github:candy-chat/candy-plugins", "candy-shop": "github:candy-chat/candy-plugins",
"electron-is-dev": "^2.0.0", "copy-webpack-plugin": "^9.0.1",
"electron-updater": "^4.3.9", "electron": "^14.0.0",
"electron-builder": "^22.11.7",
"electron-builder-notarize": "^1.2.0",
"exports-loader": "^3.0.0", "exports-loader": "^3.0.0",
"imports-loader": "^3.0.0", "imports-loader": "^3.0.0",
"ini": "^2.0.0", "ini": "^2.0.0",
"jquery": "^3.6.0", "jquery": "^3.6.0",
"jquery-i18n": "github:recurser/jquery-i18n", "jquery-i18n": "github:recurser/jquery-i18n",
"mousetrap": "^1.6.5",
"mustache": "^4.2.0", "mustache": "^4.2.0",
"reconnecting-websocket": "^4.4.0", "reconnecting-websocket": "^4.4.0",
"rxjs": "^7.3.0",
"strophe.js": "^1.4.2", "strophe.js": "^1.4.2",
"strophejs-plugin-caps": "^1.1.3", "strophejs-plugin-caps": "^1.1.3",
"strophejs-plugin-disco": "^0.0.2", "strophejs-plugin-disco": "^0.0.2",
"strophejs-plugin-muc": "^1.1.0", "strophejs-plugin-muc": "^1.1.0",
"strophejs-plugin-roster": "^1.1.0" "strophejs-plugin-roster": "^1.1.0",
"tslib": "^2.3.0",
"typescript": "4.3",
"zone.js": "~0.11.4"
},
"build": {
"productName": "MyCard",
"appId": "com.mycard.mycard",
"publish": [
{
"provider": "generic",
"url": "https://cdn02.moecube.com:444/downloads"
}
],
"asar": false,
"files": [
"main.js",
"dist/mycard"
],
"extraResources": [
"bin"
],
"win": {
"verifyUpdateCodeSignature": false
},
"linux": {
"target": [
{
"target": "AppImage"
}
]
},
"appImage": {
"publish": [
{
"provider": "generic",
"url": "https://cdn02.moecube.com:444/downloads"
}
]
},
"afterSign": "electron-builder-notarize",
"mac": {
"hardenedRuntime": true,
"entitlements": "./node_modules/electron-builder-notarize/entitlements.mac.inherit.plist"
},
"dmg": {
"contents": [
{
"x": 448,
"y": 344,
"type": "link",
"path": "/Applications"
},
{
"x": 192,
"y": 344,
"type": "file"
}
]
}
} }
} }
import { ChangeDetectorRef, Component, ElementRef, Input, OnChanges, OnInit, SimpleChanges } from '@angular/core'; import { ChangeDetectorRef, Component, ElementRef, Inject, Input, LOCALE_ID, OnChanges, OnInit, SimpleChanges } from '@angular/core';
import { AppsService } from '../apps.service'; import { AppsService } from '../apps.service';
import { InstallOption } from '../shared/install-option'; import { InstallOption } from '../shared/install-option';
import { SettingsService } from '../settings.service'; import { SettingsService } from '../settings.service';
...@@ -22,7 +22,7 @@ declare const Notification: any; ...@@ -22,7 +22,7 @@ declare const Notification: any;
@Component({ @Component({
selector: 'app-detail', selector: 'app-detail',
templateUrl: 'app-detail.component.html', templateUrl: 'app-detail.component.html',
styleUrls: ['app-detail.component.css'] styleUrls: ['app-detail.component.css'],
}) })
export class AppDetailComponent implements OnInit, OnChanges { export class AppDetailComponent implements OnInit, OnChanges {
@Input() @Input()
...@@ -44,22 +44,31 @@ export class AppDetailComponent implements OnInit, OnChanges { ...@@ -44,22 +44,31 @@ export class AppDetailComponent implements OnInit, OnChanges {
payment = 'alipay'; payment = 'alipay';
creating_order = false; creating_order = false;
constructor(public appsService: AppsService, private settingsService: SettingsService, private downloadService: DownloadService, private ref: ChangeDetectorRef, private el: ElementRef, private loginService: LoginService) { constructor(
public appsService: AppsService,
this.tags = this.settingsService.getLocale().startsWith('zh') ? { private settingsService: SettingsService,
'recommend': '推荐', private downloadService: DownloadService,
'mysterious': '迷之物体', private ref: ChangeDetectorRef,
'touhou': '东方 Project', private el: ElementRef,
'touhou_pc98': '东方旧作', private loginService: LoginService,
'language': '语言包', @Inject(LOCALE_ID) private locale: string
'ygopro': 'YGOPro' ) {
} : { this.tags = locale.startsWith('zh')
'recommend': 'Recommended', ? {
'mysterious': 'Something', recommend: '推荐',
'touhou': 'Touhou Project', mysterious: '迷之物体',
'touhou_pc98': 'Touhou old series', touhou: '东方 Project',
'language': 'Language Pack', touhou_pc98: '东方旧作',
'ygopro': 'YGOPro' language: '语言包',
ygopro: 'YGOPro',
}
: {
recommend: 'Recommended',
mysterious: 'Something',
touhou: 'Touhou Project',
touhou_pc98: 'Touhou old series',
language: 'Language Pack',
ygopro: 'YGOPro',
}; };
} }
...@@ -108,8 +117,7 @@ export class AppDetailComponent implements OnInit, OnChanges { ...@@ -108,8 +117,7 @@ export class AppDetailComponent implements OnInit, OnChanges {
if (reference.isLanguage()) { if (reference.isLanguage()) {
// 对于语言包,只有在语言包的locales比游戏本身的更加合适的时候才默认勾选 // 对于语言包,只有在语言包的locales比游戏本身的更加合适的时候才默认勾选
// 这里先偷个懒,中文环境勾选中文语言包,非中文环境勾选非中文语言包 // 这里先偷个懒,中文环境勾选中文语言包,非中文环境勾选非中文语言包
this.referencesInstall[reference.id] = this.referencesInstall[reference.id] = reference.locales[0].startsWith('zh') === this.locale.startsWith('zh');
reference.locales[0].startsWith('zh') === this.settingsService.getLocale().startsWith('zh');
} else { } else {
this.referencesInstall[reference.id] = true; this.referencesInstall[reference.id] = true;
} }
...@@ -129,10 +137,8 @@ export class AppDetailComponent implements OnInit, OnChanges { ...@@ -129,10 +137,8 @@ export class AppDetailComponent implements OnInit, OnChanges {
} }
async installMod(mod: App) { async installMod(mod: App) {
let option = new InstallOption(mod, path.dirname(mod.parent!.local!.path)); let option = new InstallOption(mod, path.dirname(mod.parent!.local!.path));
await this.install(mod, option, {}); await this.install(mod, option, {});
} }
async uninstall(app: App) { async uninstall(app: App) {
...@@ -181,7 +187,7 @@ export class AppDetailComponent implements OnInit, OnChanges { ...@@ -181,7 +187,7 @@ export class AppDetailComponent implements OnInit, OnChanges {
this.availableLibraries.splice(index, 1); this.availableLibraries.splice(index, 1);
} }
} else { } else {
this.settingsService.setDefaultLibrary({ path: this.installOption.installLibrary, 'default': true }); this.settingsService.setDefaultLibrary({ path: this.installOption.installLibrary, default: true });
} }
this.installOption.installLibrary = this.settingsService.getDefaultLibrary().path; this.installOption.installLibrary = this.settingsService.getDefaultLibrary().path;
} }
......
This diff is collapsed.
...@@ -25,7 +25,7 @@ window['jQuery'] = $; ...@@ -25,7 +25,7 @@ window['jQuery'] = $;
import Mustache from 'mustache'; import Mustache from 'mustache';
import { Component, ElementRef, Input, OnChanges, OnInit, SimpleChanges, ViewEncapsulation } from '@angular/core'; import { Component, ElementRef, Inject, Input, LOCALE_ID, OnChanges, OnInit, SimpleChanges, ViewEncapsulation } from '@angular/core';
import { LoginService } from '../login/login.service'; import { LoginService } from '../login/login.service';
import { SettingsService } from '../settings.service'; import { SettingsService } from '../settings.service';
import { App } from '../shared/app'; import { App } from '../shared/app';
...@@ -262,7 +262,12 @@ export class CandyComponent implements OnInit, OnChanges { ...@@ -262,7 +262,12 @@ export class CandyComponent implements OnInit, OnChanges {
// ismax_window:Boolean=false; // ismax_window:Boolean=false;
height_default_window: string = '230px'; height_default_window: string = '230px';
constructor(private loginService: LoginService, private settingsService: SettingsService, private element: ElementRef) {} constructor(
private loginService: LoginService,
private settingsService: SettingsService,
private element: ElementRef,
@Inject(LOCALE_ID) private locale: string
) {}
ngOnInit() { ngOnInit() {
this.jid = this.loginService.user.username + '@mycard.moe'; this.jid = this.loginService.user.username + '@mycard.moe';
...@@ -307,7 +312,7 @@ export class CandyComponent implements OnInit, OnChanges { ...@@ -307,7 +312,7 @@ export class CandyComponent implements OnInit, OnChanges {
}, },
view: { view: {
assets: 'candy/res/', // copy-webpack-plugin assets: 'candy/res/', // copy-webpack-plugin
language: this.settingsService.getLocale().startsWith('zh') ? 'cn' : 'en', language: this.locale.startsWith('zh') ? 'cn' : 'en',
enableXHTML: true, enableXHTML: true,
}, },
}); });
......
/** /**
* Created by zh99998 on 16/9/2. * Created by zh99998 on 16/9/2.
*/ */
import { ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild } from '@angular/core'; import { ChangeDetectorRef, Component, ElementRef, Inject, LOCALE_ID, OnInit, ViewChild } from '@angular/core';
import { AppsService } from '../apps.service'; import { AppsService } from '../apps.service';
import { LoginService } from '../login/login.service'; import { LoginService } from '../login/login.service';
import { App, Category } from '../shared/app'; import { App, Category } from '../shared/app';
...@@ -16,10 +16,9 @@ const ReconnectingWebSocket = require('reconnecting-websocket'); ...@@ -16,10 +16,9 @@ const ReconnectingWebSocket = require('reconnecting-websocket');
@Component({ @Component({
selector: 'lobby', selector: 'lobby',
templateUrl: 'lobby.component.html', templateUrl: 'lobby.component.html',
styleUrls: ['lobby.component.css'] styleUrls: ['lobby.component.css'],
}) })
export class LobbyComponent implements OnInit { export class LobbyComponent implements OnInit {
currentApp: App; currentApp: App;
resizing: HTMLElement | undefined; resizing: HTMLElement | undefined;
offset: number; offset: number;
...@@ -29,9 +28,13 @@ export class LobbyComponent implements OnInit { ...@@ -29,9 +28,13 @@ export class LobbyComponent implements OnInit {
//private messages: WebSocket; //private messages: WebSocket;
constructor(private appsService: AppsService, private loginService: LoginService, constructor(
private settingsService: SettingsService, private ref: ChangeDetectorRef) { private appsService: AppsService,
} private loginService: LoginService,
private settingsService: SettingsService,
private ref: ChangeDetectorRef,
@Inject(LOCALE_ID) private locale: string
) {}
get grouped_apps(): any { get grouped_apps(): any {
// @ts-ignore // @ts-ignore
...@@ -51,7 +54,6 @@ export class LobbyComponent implements OnInit { ...@@ -51,7 +54,6 @@ export class LobbyComponent implements OnInit {
} else { } else {
tags = ['runtime']; tags = ['runtime'];
} }
} }
for (const tag of tags) { for (const tag of tags) {
if (!result[tag]) { if (!result[tag]) {
...@@ -80,7 +82,7 @@ export class LobbyComponent implements OnInit { ...@@ -80,7 +82,7 @@ export class LobbyComponent implements OnInit {
} }
} }
// 特化个 YGOPRO 国际服聊天室。其他的暂时没需求。 // 特化个 YGOPRO 国际服聊天室。其他的暂时没需求。
if (!this.settingsService.getLocale().startsWith('zh')) { if (!this.locale.startsWith('zh')) {
this.apps.get('ygopro')!.conference = 'ygopro-international'; this.apps.get('ygopro')!.conference = 'ygopro-international';
} }
this.ref.detectChanges(); this.ref.detectChanges();
...@@ -96,7 +98,6 @@ export class LobbyComponent implements OnInit { ...@@ -96,7 +98,6 @@ export class LobbyComponent implements OnInit {
this.currentApp = this.apps.get(this.currentApp.id)!; this.currentApp = this.apps.get(this.currentApp.id)!;
}; */ }; */
// $(this.search.nativeElement).typeahead(<any>{ // $(this.search.nativeElement).typeahead(<any>{
// minLength: 1, // minLength: 1,
// highlight: true // highlight: true
......
...@@ -77,9 +77,9 @@ ...@@ -77,9 +77,9 @@
<div class='form-group row'> <div class='form-group row'>
<label class='col-sm-2 col-form-label' for='locale' i18n>语言</label> <label class='col-sm-2 col-form-label' for='locale' i18n>语言</label>
<div class='col-sm-10'> <div class='col-sm-10'>
<select [(ngModel)]='locale' class='form-control' id='locale' name='locale'> <select [(ngModel)]='localeNew' class='form-control' id='locale' name='locale'>
<option value='en-US'>English</option> <option value='en-US'>English</option>
<option value='zh-CN'>简体中文</option> <option value='zh-Hans'>简体中文</option>
</select> </select>
</div> </div>
</div> </div>
......
import { ChangeDetectorRef, Component, ElementRef, OnInit, ViewChild } from '@angular/core'; import { ChangeDetectorRef, Component, ElementRef, Inject, LOCALE_ID, OnInit, ViewChild } from '@angular/core';
import { shell } from 'electron'; import { shell } from 'electron';
import * as remote from '@electron/remote'; import * as remote from '@electron/remote';
import $ from 'jquery'; import $ from 'jquery';
...@@ -32,7 +32,7 @@ export class MyCardComponent implements OnInit { ...@@ -32,7 +32,7 @@ export class MyCardComponent implements OnInit {
update_downloaded: ElementRef; update_downloaded: ElementRef;
update_elements: Map<string, ElementRef>; update_elements: Map<string, ElementRef>;
locale: string; localeNew: string = this.locale;
resizing: HTMLElement | null; resizing: HTMLElement | null;
...@@ -73,7 +73,11 @@ export class MyCardComponent implements OnInit { ...@@ -73,7 +73,11 @@ export class MyCardComponent implements OnInit {
// }); // });
} }
constructor(public loginService: LoginService, private ref: ChangeDetectorRef, private settingsService: SettingsService) { constructor(
public loginService: LoginService,
private ref: ChangeDetectorRef,
@Inject(LOCALE_ID) public locale: string
) {
// renderer.listenGlobal('window', 'message', (event) => { // renderer.listenGlobal('window', 'message', (event) => {
// console.log(event); // console.log(event);
// // Do something with 'event' // // Do something with 'event'
...@@ -98,8 +102,6 @@ export class MyCardComponent implements OnInit { ...@@ -98,8 +102,6 @@ export class MyCardComponent implements OnInit {
autoUpdater.on('update-downloaded', (event) => { autoUpdater.on('update-downloaded', (event) => {
this.set_update_status('update-downloaded'); this.set_update_status('update-downloaded');
}); });
this.locale = this.settingsService.getLocale();
} }
update_retry() { update_retry() {
...@@ -128,8 +130,8 @@ export class MyCardComponent implements OnInit { ...@@ -128,8 +130,8 @@ export class MyCardComponent implements OnInit {
} }
submit() { submit() {
if (this.locale !== this.settingsService.getLocale()) { if (this.localeNew !== this.locale) {
localStorage.setItem(SettingsService.SETTING_LOCALE, this.locale); localStorage.setItem(SettingsService.SETTING_LOCALE, this.localeNew);
remote.app.relaunch(); remote.app.relaunch();
remote.app.quit(); remote.app.quit();
} }
......
/** /**
* Created by weijian on 2016/10/24. * Created by weijian on 2016/10/24.
*/ */
import { Injectable } from '@angular/core'; import {Injectable} from '@angular/core';
import path from 'path'; import path from 'path';
import { app } from '@electron/remote'; import {app} from '@electron/remote';
export interface Library { export interface Library {
'default': boolean; 'default': boolean;
...@@ -23,12 +23,8 @@ export class SettingsService { ...@@ -23,12 +23,8 @@ export class SettingsService {
} }
]; ];
static SETTING_LOCALE = 'locale'; static SETTING_LOCALE = 'locale';
static defaultLocale = app.getLocale();
locale: string;
libraries: Library[]; libraries: Library[];
getLibraries() { getLibraries() {
if (!this.libraries) { if (!this.libraries) {
let data = localStorage.getItem(SettingsService.SETTING_LIBRARY); let data = localStorage.getItem(SettingsService.SETTING_LIBRARY);
...@@ -51,7 +47,7 @@ export class SettingsService { ...@@ -51,7 +47,7 @@ export class SettingsService {
l.default = false; l.default = false;
}); });
} }
libraries.push({ 'default': isDefault, path: libraryPath }); libraries.push({'default': isDefault, path: libraryPath});
this.libraries = libraries; this.libraries = libraries;
localStorage.setItem(SettingsService.SETTING_LIBRARY, JSON.stringify(libraries)); localStorage.setItem(SettingsService.SETTING_LIBRARY, JSON.stringify(libraries));
} }
...@@ -76,22 +72,4 @@ export class SettingsService { ...@@ -76,22 +72,4 @@ export class SettingsService {
throw('no default library found'); throw('no default library found');
} }
} }
getLocale(): string {
if (!this.locale) {
let locale = localStorage.getItem(SettingsService.SETTING_LOCALE);
if (!locale) {
this.locale = SettingsService.defaultLocale;
localStorage.setItem(SettingsService.SETTING_LOCALE, SettingsService.defaultLocale);
} else {
this.locale = locale;
}
}
return this.locale;
}
setLocale(locale: string) {
this.locale = locale;
localStorage.setItem(SettingsService.SETTING_LOCALE, locale);
}
} }
...@@ -108,7 +108,7 @@ export class App { ...@@ -108,7 +108,7 @@ export class App {
static getQuerySuffix(platform: string, locale: string, arch: string) { static getQuerySuffix(platform: string, locale: string, arch: string) {
const params = new URLSearchParams(); const params = new URLSearchParams();
params.set('platform', platform); params.set('platform', platform);
params.set('locale', locale); params.set('locale', locale === 'zh-Hans' ? 'zh-CN' : 'zh-Hans');
params.set('arch', arch); params.set('arch', arch);
return params.toString(); return params.toString();
} }
......
import {LOCALE_ID, TRANSLATIONS, TRANSLATIONS_FORMAT} from '@angular/core';
import * as remote from '@electron/remote';
export async function getTranslationProviders (): Promise<Object[]> {
let locale = localStorage.getItem('locale');
if (!locale) {
locale = remote.app.getLocale();
localStorage.setItem('locale', locale);
}
const noProviders: Object[] = [];
if (!locale || locale === 'zh-CN') {
return noProviders;
}
const translationFile = `./locale/messages.${locale}.xlf`;
try {
let translations = await getTranslationsWithSystemJs(translationFile);
return [
{provide: TRANSLATIONS, useValue: translations},
{provide: TRANSLATIONS_FORMAT, useValue: 'xlf'},
{provide: LOCALE_ID, useValue: locale}
];
} catch (error) {
return noProviders;
}
}
declare const System: any;
function getTranslationsWithSystemJs (file: string) {
return System.import(file + '!text'); // relies on text plugin
}
This diff is collapsed.
This diff is collapsed.
This diff is collapsed.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment