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

i18n

parent 4fd5e106
......@@ -34,10 +34,17 @@
"root": "",
"sourceRoot": "src",
"prefix": "app",
"i18n": {
"sourceLocale": "zh-Hans",
"locales": {
"en-US": "src/locale/messages.en-US.xlf"
}
},
"architect": {
"build": {
"builder": "@angular-builders/custom-webpack:browser",
"options": {
"localize": ["zh-Hans"],
"allowedCommonJsDependencies": [
"glob",
"aria2",
......
This diff is collapsed.
This source diff could not be displayed because it is too large. You can view the blob instead.
......@@ -13,6 +13,12 @@
"main": "main.js",
"description": "萌卡客户端",
"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": {
"@angular-builders/custom-webpack": "^12.1.1",
"@angular/animations": "~12.2.5",
......@@ -26,41 +32,93 @@
"@angular/platform-browser": "~12.2.5",
"@angular/platform-browser-dynamic": "~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",
"@types/bootstrap": "^5.1.4",
"@types/ini": "^1.3.30",
"@types/jquery": "^3.5.6",
"@types/mousetrap": "^1.6.8",
"@types/mustache": "^4.1.2",
"@types/node": "^16.4.13",
"aria2": "^3.0.1",
"bootstrap": "^5.1.0",
"candy": "https://github.com/moecube/candy/releases/download/v2.2.0/candy.tar.gz",
"candy-shop": "github:candy-chat/candy-plugins",
"electron-is-dev": "^2.0.0",
"electron-updater": "^4.3.9",
"copy-webpack-plugin": "^9.0.1",
"electron": "^14.0.0",
"electron-builder": "^22.11.7",
"electron-builder-notarize": "^1.2.0",
"exports-loader": "^3.0.0",
"imports-loader": "^3.0.0",
"ini": "^2.0.0",
"jquery": "^3.6.0",
"jquery-i18n": "github:recurser/jquery-i18n",
"mousetrap": "^1.6.5",
"mustache": "^4.2.0",
"reconnecting-websocket": "^4.4.0",
"rxjs": "^7.3.0",
"strophe.js": "^1.4.2",
"strophejs-plugin-caps": "^1.1.3",
"strophejs-plugin-disco": "^0.0.2",
"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 { InstallOption } from '../shared/install-option';
import { SettingsService } from '../settings.service';
......@@ -22,7 +22,7 @@ declare const Notification: any;
@Component({
selector: 'app-detail',
templateUrl: 'app-detail.component.html',
styleUrls: ['app-detail.component.css']
styleUrls: ['app-detail.component.css'],
})
export class AppDetailComponent implements OnInit, OnChanges {
@Input()
......@@ -44,23 +44,32 @@ export class AppDetailComponent implements OnInit, OnChanges {
payment = 'alipay';
creating_order = false;
constructor(public appsService: AppsService, private settingsService: SettingsService, private downloadService: DownloadService, private ref: ChangeDetectorRef, private el: ElementRef, private loginService: LoginService) {
this.tags = this.settingsService.getLocale().startsWith('zh') ? {
'recommend': '推荐',
'mysterious': '迷之物体',
'touhou': '东方 Project',
'touhou_pc98': '东方旧作',
'language': '语言包',
'ygopro': 'YGOPro'
} : {
'recommend': 'Recommended',
'mysterious': 'Something',
'touhou': 'Touhou Project',
'touhou_pc98': 'Touhou old series',
'language': 'Language Pack',
'ygopro': 'YGOPro'
};
constructor(
public appsService: AppsService,
private settingsService: SettingsService,
private downloadService: DownloadService,
private ref: ChangeDetectorRef,
private el: ElementRef,
private loginService: LoginService,
@Inject(LOCALE_ID) private locale: string
) {
this.tags = locale.startsWith('zh')
? {
recommend: '推荐',
mysterious: '迷之物体',
touhou: '东方 Project',
touhou_pc98: '东方旧作',
language: '语言包',
ygopro: 'YGOPro',
}
: {
recommend: 'Recommended',
mysterious: 'Something',
touhou: 'Touhou Project',
touhou_pc98: 'Touhou old series',
language: 'Language Pack',
ygopro: 'YGOPro',
};
}
async ngOnChanges(changes: SimpleChanges) {
......@@ -108,8 +117,7 @@ export class AppDetailComponent implements OnInit, OnChanges {
if (reference.isLanguage()) {
// 对于语言包,只有在语言包的locales比游戏本身的更加合适的时候才默认勾选
// 这里先偷个懒,中文环境勾选中文语言包,非中文环境勾选非中文语言包
this.referencesInstall[reference.id] =
reference.locales[0].startsWith('zh') === this.settingsService.getLocale().startsWith('zh');
this.referencesInstall[reference.id] = reference.locales[0].startsWith('zh') === this.locale.startsWith('zh');
} else {
this.referencesInstall[reference.id] = true;
}
......@@ -129,10 +137,8 @@ export class AppDetailComponent implements OnInit, OnChanges {
}
async installMod(mod: App) {
let option = new InstallOption(mod, path.dirname(mod.parent!.local!.path));
await this.install(mod, option, {});
}
async uninstall(app: App) {
......@@ -181,7 +187,7 @@ export class AppDetailComponent implements OnInit, OnChanges {
this.availableLibraries.splice(index, 1);
}
} 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 diff is collapsed.
......@@ -25,7 +25,7 @@ window['jQuery'] = $;
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 { SettingsService } from '../settings.service';
import { App } from '../shared/app';
......@@ -262,7 +262,12 @@ export class CandyComponent implements OnInit, OnChanges {
// ismax_window:Boolean=false;
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() {
this.jid = this.loginService.user.username + '@mycard.moe';
......@@ -307,7 +312,7 @@ export class CandyComponent implements OnInit, OnChanges {
},
view: {
assets: 'candy/res/', // copy-webpack-plugin
language: this.settingsService.getLocale().startsWith('zh') ? 'cn' : 'en',
language: this.locale.startsWith('zh') ? 'cn' : 'en',
enableXHTML: true,
},
});
......
/**
* 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 { LoginService } from '../login/login.service';
import { App, Category } from '../shared/app';
......@@ -16,10 +16,9 @@ const ReconnectingWebSocket = require('reconnecting-websocket');
@Component({
selector: 'lobby',
templateUrl: 'lobby.component.html',
styleUrls: ['lobby.component.css']
styleUrls: ['lobby.component.css'],
})
export class LobbyComponent implements OnInit {
currentApp: App;
resizing: HTMLElement | undefined;
offset: number;
......@@ -29,9 +28,13 @@ export class LobbyComponent implements OnInit {
//private messages: WebSocket;
constructor(private appsService: AppsService, private loginService: LoginService,
private settingsService: SettingsService, private ref: ChangeDetectorRef) {
}
constructor(
private appsService: AppsService,
private loginService: LoginService,
private settingsService: SettingsService,
private ref: ChangeDetectorRef,
@Inject(LOCALE_ID) private locale: string
) {}
get grouped_apps(): any {
// @ts-ignore
......@@ -51,7 +54,6 @@ export class LobbyComponent implements OnInit {
} else {
tags = ['runtime'];
}
}
for (const tag of tags) {
if (!result[tag]) {
......@@ -80,7 +82,7 @@ export class LobbyComponent implements OnInit {
}
}
// 特化个 YGOPRO 国际服聊天室。其他的暂时没需求。
if (!this.settingsService.getLocale().startsWith('zh')) {
if (!this.locale.startsWith('zh')) {
this.apps.get('ygopro')!.conference = 'ygopro-international';
}
this.ref.detectChanges();
......@@ -96,7 +98,6 @@ export class LobbyComponent implements OnInit {
this.currentApp = this.apps.get(this.currentApp.id)!;
}; */
// $(this.search.nativeElement).typeahead(<any>{
// minLength: 1,
// highlight: true
......
......@@ -77,9 +77,9 @@
<div class='form-group row'>
<label class='col-sm-2 col-form-label' for='locale' i18n>语言</label>
<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='zh-CN'>简体中文</option>
<option value='zh-Hans'>简体中文</option>
</select>
</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 * as remote from '@electron/remote';
import $ from 'jquery';
......@@ -32,7 +32,7 @@ export class MyCardComponent implements OnInit {
update_downloaded: ElementRef;
update_elements: Map<string, ElementRef>;
locale: string;
localeNew: string = this.locale;
resizing: HTMLElement | null;
......@@ -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) => {
// console.log(event);
// // Do something with 'event'
......@@ -98,8 +102,6 @@ export class MyCardComponent implements OnInit {
autoUpdater.on('update-downloaded', (event) => {
this.set_update_status('update-downloaded');
});
this.locale = this.settingsService.getLocale();
}
update_retry() {
......@@ -128,8 +130,8 @@ export class MyCardComponent implements OnInit {
}
submit() {
if (this.locale !== this.settingsService.getLocale()) {
localStorage.setItem(SettingsService.SETTING_LOCALE, this.locale);
if (this.localeNew !== this.locale) {
localStorage.setItem(SettingsService.SETTING_LOCALE, this.localeNew);
remote.app.relaunch();
remote.app.quit();
}
......
/**
* Created by weijian on 2016/10/24.
*/
import { Injectable } from '@angular/core';
import {Injectable} from '@angular/core';
import path from 'path';
import { app } from '@electron/remote';
import {app} from '@electron/remote';
export interface Library {
'default': boolean;
......@@ -23,12 +23,8 @@ export class SettingsService {
}
];
static SETTING_LOCALE = 'locale';
static defaultLocale = app.getLocale();
locale: string;
libraries: Library[];
getLibraries() {
if (!this.libraries) {
let data = localStorage.getItem(SettingsService.SETTING_LIBRARY);
......@@ -51,7 +47,7 @@ export class SettingsService {
l.default = false;
});
}
libraries.push({ 'default': isDefault, path: libraryPath });
libraries.push({'default': isDefault, path: libraryPath});
this.libraries = libraries;
localStorage.setItem(SettingsService.SETTING_LIBRARY, JSON.stringify(libraries));
}
......@@ -76,22 +72,4 @@ export class SettingsService {
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 {
static getQuerySuffix(platform: string, locale: string, arch: string) {
const params = new URLSearchParams();
params.set('platform', platform);
params.set('locale', locale);
params.set('locale', locale === 'zh-Hans' ? 'zh-CN' : 'zh-Hans');
params.set('arch', arch);
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