Commit fc860a13 authored by 神楽坂玲奈's avatar 神楽坂玲奈

Merge branch 'v3' of github.com:mycard/mycard into v3

parents 57e1550b 0ae6f4c3
This diff is collapsed.
import {Component, OnInit} from "@angular/core";
import {Component, OnInit, Input, ChangeDetectorRef} from "@angular/core";
import {AppsService} from "./apps.service";
import {InstallConfig} from "./install-config";
import {SettingsService} from "./settings.sevices";
import {App} from "./app";
import {DownloadService} from "./download.service";
import {clipboard, remote} from "electron";
import {clipboard, remote, ipcRenderer} from "electron";
import * as path from "path";
import * as child_process from "child_process";
import {InstallService} from "./install.service";
declare var Notification;
declare var $;
@Component({
selector: 'app-detail',
templateUrl: 'app/app-detail.component.html',
styleUrls: ['app/app-detail.component.css'],
providers: [DownloadService]
})
export class AppDetailComponent implements OnInit {
@Input()
currentApp: App;
platform = process.platform;
installConfig: InstallConfig;
constructor(private appsService: AppsService, private settingsService: SettingsService, private downloadService: DownloadService) {
constructor(private appsService: AppsService, private settingsService: SettingsService,
private downloadService: DownloadService, private installService: InstallService,
private ref: ChangeDetectorRef) {
}
ngOnInit() {
this.updateInstallConfig();
// this.updateInstallConfig();
ipcRenderer.on('download-message-reply', (event, arg)=> {
console.log(arg);
});
ipcRenderer.send("download-message", "ping")
}
updateInstallConfig() {
this.installConfig = this.appsService.getInstallConfig(this.appsService.currentApp);
this.installConfig.installPath = this.settingsService.getDefaultLibrary().path;
}
get name() {
let currentApp = this.appsService.currentApp;
if (currentApp) {
return currentApp.name[this.settingsService.getLocale()];
this.installConfig = new InstallConfig(this.currentApp);
this.installConfig.installLibrary = this.settingsService.getDefaultLibrary().path;
this.installConfig.references = [];
for (let reference of this.currentApp.references.values()) {
this.installConfig.references.push(new InstallConfig(reference))
}
return "Loading";
};
get isInstalled() {
let currentApp = this.appsService.currentApp;
return !!(currentApp.local && currentApp.local.path);
}
get libraries(): string[] {
return this.settingsService.getLibraries().map((item)=>item.path);
}
get news() {
let currentApp = this.appsService.currentApp;
if (currentApp) {
return currentApp.news;
}
return this.currentApp.news;
}
get friends() {
......@@ -63,35 +63,36 @@ export class AppDetailComponent implements OnInit {
}
get mods() {
let contains = ["optional", "language", "emulator"];
let currentApp = this.appsService.currentApp;
if (currentApp) {
if (currentApp.references[process.platform] && currentApp.references[process.platform].length > 0) {
let refs = currentApp.references[process.platform];
refs = refs.filter((ref)=> {
return contains.includes(ref.type);
});
refs = refs.map((ref)=> {
let tmp = Object.create(ref);
switch (tmp.type) {
case "optional":
tmp.type = "选项";
break;
case "language":
tmp.type = "语言";
break;
default:
break;
}
//console.log(tmp.type);
return tmp;
});
return refs;
//return this.currentApp.references[process.platform];
}
}
// let contains = ["optional", "language", "emulator"];
//
// let currentApp = this.appsService.currentApp;
// if (currentApp) {
// if (currentApp.references[process.platform] && currentApp.references[process.platform].length > 0) {
// let refs = currentApp.references[process.platform];
// refs = refs.filter((ref)=> {
// return contains.includes(ref.type);
// });
// refs = refs.map((ref)=> {
// let tmp = Object.create(ref);
// switch (tmp.type) {
// case "optional":
// tmp.type = "选项";
// break;
// case "language":
// tmp.type = "语言";
// break;
// default:
// break;
// }
// //console.log(tmp.type);
// return tmp;
// });
// return refs;
//return this.currentApp.references[process.platform];
// }
// }
return [];
}
uninstalling: boolean;
......@@ -99,23 +100,64 @@ export class AppDetailComponent implements OnInit {
uninstall(id: string) {
if (confirm("确认删除?")) {
this.uninstalling = true;
this.appsService.uninstall(id).then(()=> {
this.uninstalling = false;
}
);
// this.appsService.uninstall(id).then(()=> {
// this.uninstalling = false;
// }
// );
}
}
install() {
async install() {
$('#install-modal').modal('hide');
this.appsService.download();
let currentApp = this.currentApp;
let options = this.installConfig;
let dependencies = currentApp.findDependencies();
let apps = dependencies.concat(currentApp).filter((app)=>!app.isInstalled());
for (let reference of options.references) {
if (reference.install) {
apps.push(reference.app);
apps.push(...reference.app.findDependencies())
}
}
let downloadPath = path.join(this.installConfig.installLibrary, "downloading");
try {
let downloadApps = await this.downloadService.addUris(apps, downloadPath);
this.downloadService.getProgress(currentApp)
.subscribe((progress)=> {
currentApp.status.status = "downloading";
currentApp.status.progress = progress.progress;
currentApp.status.total = progress.total;
this.ref.detectChanges();
},
(error)=> {
},
()=> {
currentApp.status.status = "waiting";
this.ref.detectChanges();
});
await Promise.all(downloadApps.map((app)=> {
return this.downloadService.getComplete(app)
.then((completeApp: App)=> {
return this.installService.add(completeApp, options);
});
}));
currentApp.status.status = "ready";
} catch (e) {
new Notification(currentApp.name, {body: "下载失败"});
}
}
selectDir() {
let dir = remote.dialog.showOpenDialog({properties: ['openFile', 'openDirectory']});
console.log(dir);
this.appsService.installConfig.installDir = dir[0];
// this.appsService.installConfig.installDir = dir[0];
return dir[0];
}
......@@ -131,12 +173,8 @@ export class AppDetailComponent implements OnInit {
let open = '';
let openApp = app.actions.get("main").open;
if (openApp) {
if (this.isInstalled) {
open = path.join(openApp.local.path, openApp.actions.get("main").execute);
args.push(execute);
} else {
console.error('open app not found');
}
open = path.join(openApp.local.path, openApp.actions.get("main").execute);
args.push(execute);
} else {
//没有需要通过open启动依赖,直接启动程序
open = execute;
......
......@@ -4,5 +4,24 @@
export class AppLocal {
path: string;
version: string;
files: string[];
files: Map<string,string>;
update(local) {
this.path = local.path;
this.version = local.version;
let files = new Map<string,string>();
for (let filename of Object.keys(local.files)) {
files.set(filename, local.files[filename]);
}
this.files = files;
}
toJSON() {
let t = {};
for (let [k,v] of this.files) {
t[k] = v;
}
return {path: this.path, version: this.version, files: t};
}
}
import {AppLocal} from "./app-local";
/*
export enum Reference_Type {
runtime, // directx
emulator, // wine, np2
dependency, //
optional, // fxtz
language,
host
}
*/
/*
export enum App_Category {
game,
music,
book,
runtime, // directx
emulator, // wine, np2
language
}
*/
export enum Category {
game, // 游戏
music, // 音乐
book, // 图书
runtime, // 运行库
emulator, // 模拟器
language, // 语言包
expansion, // 资料片
module, // 创意工坊
}
// export enum Status{
// downloading,
// init,
// installing,
// ready,
// updating,
// uninstalling,
// waiting,
// }
export class AppStatus {
progress: number;
total: number;
status: string;
}
export class App {
id: string;
name: string; // i18n
_name: string; // i18n
get name() {
return this._name;
}
set name(a) {
this._name = a;
}
description: string; //i18n
author: string; // English Only
homepage: string;
category: string;
category: Category;
parent: App;
actions: Map<string,{execute: string, args: string[], env: {}, open: App}>;
references: Map<string,App>;
dependencies: Map<string,App>;
locales: string[];
download: {[platform: string]: string}; // meta4 url
download: string; // meta4 url
news: {title: string, url: string, image: string}[];
network: any;
tags: string[];
version: {[platform: string]: string};
version: string;
local: AppLocal;
status: AppStatus;
isInstalled(): boolean {
return this.local !== undefined;
}
constructor(app) {
this.id = app.id;
......@@ -46,7 +64,7 @@ export class App {
this.description = app.description;
this.author = app.author;
this.homepage = app.homepage;
this.category = app.category;
this.category = Category[app.category as string];
this.actions = app.actions;
this.dependencies = app.dependencies;
this.parent = app.parent;
......@@ -57,8 +75,20 @@ export class App {
this.network = app.network;
this.tags = app.tags;
this.version = app.version;
this.local = app.local;
}
findDependencies(): App[] {
if (this.dependencies && this.dependencies.size > 0) {
let set = new Set();
for (let dependency of this.dependencies.values()) {
dependency.findDependencies()
.forEach((value)=> {
set.add(value);
});
set.add(dependency);
}
return Array.from(set);
}
return [];
}
}
:host {
/*background-color: darkslategray;*/
width: 280px;
flex-shrink: 0;
overflow-y: auto;
background-color: #f5f5f5;
border-right: 1px solid #eee;
}
a {
display: block;
padding: 10px 20px 10px 20px;
}
.active {
background-color: #428bca;
}
.active > a {
color: #fff;
}
span {
margin-left: 8px;
}
\ No newline at end of file
<span *ngIf="grouped_apps.installed">已安装</span>
<ul *ngIf="grouped_apps.installed" class="nav nav-sidebar">
<li *ngFor="let app of grouped_apps.installed" [class.active]="app===appsService.currentApp">
<a (click)="chooseApp(app)" href="#">{{app.name}}</a>
</li>
</ul><span *ngIf="grouped_apps.yugioh">游戏王</span>
<ul *ngIf="grouped_apps.yugioh" class="nav nav-sidebar">
<li *ngFor="let app of grouped_apps.yugioh" [class.active]="app===appsService.currentApp">
<a (click)="chooseApp(app)" href="#">{{app.name}}</a>
</li>
</ul><span *ngIf="grouped_apps.touhou">东方 Project</span>
<ul *ngIf="grouped_apps.touhou" class="nav nav-sidebar">
<li *ngFor="let app of grouped_apps.touhou" [class.active]="app===appsService.currentApp">
<a (click)="chooseApp(app)" href="#">{{app.name}}</a>
</li>
</ul><span *ngIf="grouped_apps.touhou_pc98">东方旧作</span>
<ul *ngIf="grouped_apps.touhou_pc98" class="nav nav-sidebar">
<li *ngFor="let app of grouped_apps.touhou_pc98" [class.active]="app===appsService.currentApp">
<a (click)="chooseApp(app)" href="#">{{app.name}}</a>
</li>
</ul>
\ No newline at end of file
import {Component, OnInit} from "@angular/core";
import {AppsService} from "./apps.service";
import {App} from "./app";
@Component({
selector: 'apps',
templateUrl: 'app/apps.component.html',
styleUrls: ['app/apps.component.css'],
})
export class AppsComponent implements OnInit {
constructor(private appsService: AppsService) {
}
ngOnInit() {
}
chooseApp(app: App) {
this.appsService.currentApp = app;
}
get grouped_apps() {
let contains = ["game", "music", "book"];
let apps = Array.from(this.appsService.allApps.values());
let result = {};
for (let app of apps) {
if (contains.includes(app.category)) {
let tag;
if (app.local) {
tag = 'installed';
} else {
tag = app.tags[0];
}
if (!result[tag]) {
result[tag] = []
}
result[tag].push(app)
}
}
//console.log(result)
return result
}
}
\ No newline at end of file
This diff is collapsed.
......@@ -2,24 +2,90 @@
* Created by weijian on 2016/10/26.
*/
import {Injectable} from "@angular/core";
import {SettingsService} from "./settings.sevices";
import {ipcRenderer} from "electron";
import {Injectable, NgZone} from "@angular/core";
import {Http} from "@angular/http";
import {Observable} from "rxjs/Observable";
import {EventEmitter} from "events";
import {App} from "./app";
const Aria2 = require('aria2');
@Injectable()
export class DownloadService {
aria2 = new Aria2();
baseURL = 'http://thief.mycard.moe/metalinks/'
appGidMap = new Map<App,string>();
gidAppMap = new Map<string,App>();
eventEmitter = new EventEmitter();
open = this.aria2.open();
constructor(private settingsService: SettingsService) {
ipcRenderer.send("download-message", "123");
constructor(private ngZone: NgZone, private http: Http) {
this.aria2.onDownloadComplete = (gid)=> {
let app = this.gidAppMap.get(gid.gid);
if (app) {
this.appGidMap.delete(app);
this.gidAppMap.delete(gid.gid);
this.eventEmitter.emit(app.id, 'complete');
}
}
}
sendEvent(event, args) {
ipcRenderer.send('')
getComplete(app: App): Promise<App> {
if (this.appGidMap.has(app)) {
return new Promise((resolve, reject)=> {
this.eventEmitter.once(app.id, (event)=> {
resolve(app);
})
});
}
}
listenEvent() {
console.log(ipcRenderer);
getProgress(app: App): Observable<any> {
let gid = this.appGidMap.get(app);
return Observable.create((observer)=> {
let interval;
this.ngZone.runOutsideAngular(()=> {
interval = setInterval(()=> {
this.aria2.tellStatus(gid).then((status: any)=> {
if (status.status === 'complete') {
observer.complete();
} else if (status.status === "active") {
observer.next({total: status.totalLength, progress: status.completedLength})
} else if (status.status === "error") {
observer.error(status.errorCode)
}
});
}, 1000);
});
return ()=> {
clearInterval(interval);
}
});
}
async addUris(apps: App[], path: string): Promise<App[]> {
let tasks = [];
for (let app of apps) {
let task = await this.addUri(app, path);
tasks.push(task);
}
return tasks;
}
async addUri(app: App, path: string): Promise<App> {
let id = app.id;
await this.open;
if (this.appGidMap.has(app)) {
return app;
} else {
let meta4link = `${this.baseURL}${id}.meta4`;
let response = await this.http.get(meta4link).toPromise();
let meta4 = btoa(response.text());
let gid = (await this.aria2.addMetalink(meta4, {dir: path}))[0];
this.appGidMap.set(app, gid);
this.gidAppMap.set(gid, app);
return app;
}
}
}
......@@ -6,21 +6,18 @@ import {App} from "./app";
export class InstallConfig {
app: App;
install: boolean;
installPath: string;
installLibrary: string;
installDir: string;
createShortcut: boolean;
createDesktopShortcut: boolean;
references: InstallConfig[];
constructor(app: App, installPath = ".", installDir = "", install = true, shortcut = false, desktopShortcut = false) {
constructor(app: App, installLibrary = "", installDir = "", install = true, shortcut = false, desktopShortcut = false) {
this.app = app;
this.createShortcut = shortcut;
this.createDesktopShortcut = desktopShortcut;
this.install = install;
this.installDir = installDir;
}
updateChecked() {
this.installLibrary = installLibrary;
}
}
\ No newline at end of file
/**
* Created by weijian on 2016/11/2.
*/
import {Injectable} from "@angular/core";
import {App} from "./app";
import {InstallConfig} from "./install-config";
import * as path from "path";
import * as child_process from "child_process";
import * as mkdirp from "mkdirp";
import * as readline from "readline";
import * as fs from 'fs';
import {EventEmitter} from "events";
import {AppLocal} from "./app-local";
import {Http} from "@angular/http";
import ReadableStream = NodeJS.ReadableStream;
@Injectable()
export class InstallService {
tarPath: string;
installQueue: Map<App,InstallConfig> = new Map();
eventEmitter: EventEmitter = new EventEmitter();
installingQueue: Set<App> = new Set();
checksumUri = "http://thief.mycard.moe/checksums/";
constructor(private http: Http) {
if (process.platform === "win32") {
this.tarPath = path.join(process.resourcesPath, 'bin/tar.exe');
} else {
this.tarPath = "tar"
}
}
createDirectory(dir: string) {
return new Promise((resolve, reject)=> {
mkdirp(dir, resolve);
})
}
getComplete(app: App): Promise<App> {
return null;
}
extract(file: string, destPath: string) {
return new Promise((resolve, reject)=> {
let tarProcess = child_process.spawn(this.tarPath, ['xvf', file, '-C', destPath]);
let rl = readline.createInterface({
input: <ReadableStream>tarProcess.stderr,
});
rl.on('line', (input)=> {
});
tarProcess.on('exit', (code)=> {
if (code === 0) {
resolve();
} else {
reject(code);
}
})
});
}
async postInstall(app: App, appPath: string) {
let action = app.actions.get('install');
if (action) {
let env = Object.assign({}, action.env);
let command = [];
command.push(path.join(appPath, action.execute));
command.push(...action.args);
let open = action.open;
if (open) {
let openAction = open.actions.get("main");
env = Object.assign(env, openAction.env);
command.unshift(...openAction.args);
command.unshift(path.join(open.local.path, openAction.execute));
}
return new Promise((resolve, reject)=> {
let child = child_process.spawn(command.shift(), command, {
env: env,
stdio: 'inherit',
shell: true,
});
child.on('error', (error)=> {
console.log(error);
});
child.on('exit', (code)=> {
if (code === 0) {
resolve();
} else {
reject();
}
})
})
}
}
saveAppLocal(app: App) {
if (app.local) {
let a = JSON.stringify(app.local)
console.log(a);
localStorage.setItem(app.id, a);
}
}
async backupFiles(app: App, files: Iterable<string>) {
let backupPath = path.join(app.local.path, "backup");
await this.createDirectory(backupPath);
for (let file of files) {
await new Promise((resolve, reject)=> {
let oldPath = path.join(app.local.path, file);
let newPath = path.join(backupPath, file);
fs.rename(oldPath, newPath, resolve);
});
}
}
async doInstall() {
for (let app of this.installQueue.keys()) {
let depInstalled = app.findDependencies()
.every((dependency)=>dependency.isInstalled());
if (depInstalled && !this.installingQueue.has(app)) {
this.installingQueue.add(app);
let options = this.installQueue.get(app);
let checksumMap: Map<string,string> = await this.http.get(`${this.checksumUri}${app.id}`)
.map((response)=> {
let map = new Map<string,string>();
for (let line of response.text().split('\n')) {
if (line !== "") {
let [checksum,filename]=line.split(' ', 2);
map.set(filename, checksum);
}
}
return map;
}).toPromise();
let packagePath = path.join(options.installLibrary, 'downloading', `${app.id}.tar.xz`);
let destPath: string;
if (app.parent) {
let differenceSet = new Set<string>();
let parentFilesMap = app.parent.local.files;
for (let key of checksumMap.keys()) {
if (parentFilesMap.has(key)) {
differenceSet.add(key);
}
}
await this.backupFiles(app.parent, differenceSet);
destPath = app.parent.local.path;
} else {
destPath = path.join(options.installLibrary, app.id);
await this.createDirectory(destPath);
}
this.installQueue.delete(app);
await this.extract(packagePath, destPath);
await this.postInstall(app, destPath);
let local = new AppLocal();
local.path = destPath;
local.files = checksumMap;
local.version = app.version;
app.local = local;
this.saveAppLocal(app);
this.installingQueue.delete(app);
if (this.installQueue.size > 0) {
await this.doInstall()
}
}
}
}
add(app: App, options: InstallConfig) {
if (!this.installQueue.has(app)) {
this.installQueue.set(app, options);
if (!app.isInstalled()) {
this.doInstall()
}
}
}
}
\ No newline at end of file
......@@ -12,4 +12,30 @@
background-color: #336699;
height: 236px;
flex-shrink: 0;
}
#apps{
/*background-color: darkslategray;*/
width: 280px;
flex-shrink: 0;
overflow-y: auto;
background-color: #f5f5f5;
border-right: 1px solid #eee;
}
a {
display: block;
padding: 10px 20px 10px 20px;
}
.active {
background-color: #428bca;
}
.active > a {
color: #fff;
}
span {
margin-left: 8px;
}
\ No newline at end of file
<!-- Begin page content -->
<div id="main">
<apps *ngIf="appsService.allApps"></apps>
<app-detail *ngIf="appsService._currentApp"></app-detail>
<div id="apps" *ngIf="apps">
<span *ngIf="grouped_apps.installed">已安装</span>
<ul *ngIf="grouped_apps.installed" class="nav nav-sidebar">
<li *ngFor="let app of grouped_apps.installed" [class.active]="app===currentApp">
<a (click)="chooseApp(app)" href="#">{{app.name}}</a>
</li>
</ul>
<span *ngIf="grouped_apps.yugioh">游戏王</span>
<ul *ngIf="grouped_apps.yugioh" class="nav nav-sidebar">
<li *ngFor="let app of grouped_apps.yugioh" [class.active]="app===currentApp">
<a (click)="chooseApp(app)" href="#">{{app.name}}</a>
</li>
</ul>
<span *ngIf="grouped_apps.touhou">东方 Project</span>
<ul *ngIf="grouped_apps.touhou" class="nav nav-sidebar">
<li *ngFor="let app of grouped_apps.touhou" [class.active]="app===currentApp">
<a (click)="chooseApp(app)" href="#">{{app.name}}</a>
</li>
</ul>
<span *ngIf="grouped_apps.touhou_pc98">东方旧作</span>
<ul *ngIf="grouped_apps.touhou_pc98" class="nav nav-sidebar">
<li *ngFor="let app of grouped_apps.touhou_pc98" [class.active]="app===currentApp">
<a (click)="chooseApp(app)" href="#">{{app.name}}</a>
</li>
</ul>
</div>
<app-detail *ngIf="currentApp" [currentApp]="currentApp"></app-detail>
<roster></roster>
</div>
<webview id="candy" [src]="candy_url" nodeintegration></webview>
\ No newline at end of file
/**
* Created by zh99998 on 16/9/2.
*/
import {Component} from "@angular/core";
import {Component, OnInit} from "@angular/core";
import {AppsService} from "./apps.service";
import {LoginService} from "./login.service";
import {App, Category} from "./app";
import {DownloadService} from "./download.service";
@Component({
selector: 'lobby',
templateUrl: 'app/lobby.component.html',
styleUrls: ['app/lobby.component.css'],
})
export class LobbyComponent {
candy_url;
export class LobbyComponent implements OnInit {
candy_url: string;
currentApp: App;
private apps: Map<string,App>;
constructor(private appsService: AppsService, private loginService: LoginService) {
constructor(private appsService: AppsService, private loginService: LoginService,private downloadService:DownloadService) {
this.candy_url = './candy/index.html?jid=' + this.loginService.user.username + '@mycard.moe&password=' + this.loginService.user.external_id + '&nickname=' + this.loginService.user.username + '&autojoin=ygopro_china_north@conference.mycard.moe'
}
ngOnInit() {
this.appsService.loadApps()
.then((apps)=> {
this.apps = apps;
this.currentApp = this.apps.get("th06");
})
}
chooseApp(app: App) {
this.currentApp = app;
}
get grouped_apps() {
let contains = ["game", "music", "book"].map((value)=>Category[value]);
let result = {};
for (let app of this.apps.values()) {
if (contains.includes(app.category)) {
let tag;
if (app.isInstalled()) {
tag = 'installed';
} else {
tag = app.tags[0];
}
if (!result[tag]) {
result[tag] = []
}
result[tag].push(app)
}
}
return result
}
}
......@@ -6,7 +6,6 @@ import {MyCardComponent} from "./mycard.component";
import {LoginComponent} from "./login.component";
import {StoreComponent} from "./store.component";
import {LobbyComponent} from "./lobby.component";
import {AppsComponent} from "./apps.component";
import {AppDetailComponent} from "./app-detail.component";
import {RosterComponent} from "./roster.component";
import {CommunityComponent} from "./community.component";
......@@ -15,12 +14,20 @@ import {AppsService} from "./apps.service";
import {TranslateModule} from "ng2-translate";
import {SettingsService} from "./settings.sevices";
import {LoginService} from "./login.service";
import {DownloadService} from "./download.service";
import {InstallService} from "./install.service";
@NgModule({
imports: [BrowserModule, FormsModule, ReactiveFormsModule, HttpModule, TranslateModule.forRoot()],
declarations: [MyCardComponent, LoginComponent, StoreComponent, LobbyComponent, CommunityComponent, AppsComponent, AppDetailComponent, RosterComponent, YGOProComponent],
declarations: [
MyCardComponent, LoginComponent, StoreComponent, LobbyComponent,
CommunityComponent, AppDetailComponent, RosterComponent, YGOProComponent,
],
bootstrap: [MyCardComponent],
providers: [AppsService, SettingsService, LoginService],
providers: [
AppsService, SettingsService, LoginService, DownloadService,
InstallService
],
schemas: [NO_ERRORS_SCHEMA]
})
export class MyCard {
......
......@@ -3,16 +3,32 @@
*/
import {Injectable} from "@angular/core";
import {remote} from "electron";
import * as path from "path";
@Injectable()
export class SettingsService {
static SETTING_LIBRARY = "library";
libraries: [{"default": boolean,path: string}];
static defaultLibraries = [
{
"default": true,
path: path.join(remote.app.getPath("appData"), "library")
},
];
libraries: {"default": boolean,path: string}[];
getLibraries() {
if (!this.libraries) {
let data = localStorage.getItem(SettingsService.SETTING_LIBRARY);
this.libraries = JSON.parse(data);
if (!data) {
this.libraries = SettingsService.defaultLibraries;
localStorage.setItem(SettingsService.SETTING_LIBRARY,
JSON.stringify(SettingsService.defaultLibraries));
} else {
this.libraries = JSON.parse(data);
}
}
return this.libraries;
}
......@@ -25,16 +41,23 @@ export class SettingsService {
}
static SETTING_LOCALE = "locale";
static defaultLocale = remote.app.getLocale();
locale: string;
getLocale(): string {
if (!this.locale) {
this.locale = localStorage.getItem(SettingsService.SETTING_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;
}
setLocal(locale: string) {
setLocale(locale: string) {
this.locale = locale;
localStorage.setItem(SettingsService.SETTING_LOCALE, locale);
}
......
/**
* Created by zh99998 on 16/9/2.
*/
import {Component, OnInit, ChangeDetectorRef} from "@angular/core";
import {Component, OnInit, ChangeDetectorRef, Input} from "@angular/core";
import {AppsService} from "./apps.service";
import * as fs from "fs";
import * as path from "path";
......@@ -11,6 +11,7 @@ import {remote} from "electron";
import * as ini from "ini";
import {EncodeOptions} from "ini";
import {LoginService} from "./login.service";
import {App} from "./app";
import {Http, Headers, URLSearchParams} from "@angular/http";
import "rxjs/Rx";
import {ISubscription} from "rxjs/Subscription";
......@@ -70,7 +71,8 @@ interface Room {
styleUrls: ['app/ygopro.component.css'],
})
export class YGOProComponent implements OnInit {
app = this.appsService.searchApp('ygopro');
@Input()
app: App;
decks: string[] = [];
current_deck: string;
......
......@@ -94,8 +94,11 @@
"language"
],
"dependencies": {
"win32": [],
"win32": [
"th06"
],
"darwin": [
"th06",
"wine"
]
},
......@@ -1384,6 +1387,7 @@
}
},
"version": {
"win32": "1.06",
"darwin": "1.06"
},
"download": {
......@@ -2188,6 +2192,7 @@
}
},
"version": {
"win32": "1.06",
"darwin": "1.06"
},
"download": {
......
......@@ -132,7 +132,9 @@ function createAria2c() {
throw 'unsupported platform';
}
//--split=10 --min-split-size=1M --max-connection-per-server=10
let aria2c = child_process.spawn(aria2c_path, ['--enable-rpc', '--rpc-allow-origin-all', "--continue", "--split=10", "--min-split-size=1M", "--max-connection-per-server=10"]);
let aria2c = child_process.spawn(aria2c_path,
['--enable-rpc', '--rpc-allow-origin-all', "--continue", "--split=10", "--min-split-size=1M", "--max-connection-per-server=10"],
{stdio: 'ignore'});
aria2c.on('data', (data)=> {
console.log(data);
});
......
......@@ -66,6 +66,18 @@
"provider": "github"
}
],
"extraResources": [
"bin"
],
"publish": [
{
"provider": "generic",
"url": "https://wudizhanche.mycard.moe/downloads"
},
{
"provider": "github"
}
],
"win": {
"target": [
"nsis"
......
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