Commit 8ad7dc2b authored by wudizhanche1000's avatar wudizhanche1000

Merge remote-tracking branch 'origin/v3' into v3

# Conflicts:
#	app/app-detail.component.html
#	app/install.service.ts
parents e001cc3e 5b048477
......@@ -10,3 +10,5 @@
/.idea/
.DS_Store
Thumbs.db
messages.xlf
messages.xlf.bak
\ No newline at end of file
......@@ -8,7 +8,7 @@ dist: trusty
sudo: required
env:
npm_config_target: 1.4.5
npm_config_target: '$(npm show electron version)'
npm_config_arch: x64
npm_config_target_arch: x64
npm_config_disturl: https://atom.io/download/atom-shell
......@@ -29,11 +29,12 @@ cache:
- $HOME/.cache
before_install:
- env
- openssl aes-256-cbc -K $encrypted_9f35b7f09ebe_key -iv $encrypted_9f35b7f09ebe_iv -in ssh-key.enc -out $HOME/.ssh/id_ecdsa -d
- chmod 600 $HOME/.ssh/id_ecdsa
install:
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then mkdir -p bin; curl -L https://github.com/aria2/aria2/releases/download/release-1.27.1/aria2-1.27.1-osx-darwin.tar.bz2 | tar --strip-components=2 -C bin -jxf - aria2-1.27.1/bin/aria2c; fi
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then mkdir -p bin; curl --location --retry 5 https://github.com/aria2/aria2/releases/download/release-1.27.1/aria2-1.27.1-osx-darwin.tar.bz2 | tar --strip-components=2 -C bin -jxf - aria2-1.27.1/bin/aria2c; fi
- npm install
- npm prune
......
......@@ -70,7 +70,23 @@ export class App {
conference: string | undefined;
isInstalled(): boolean {
return !!this.local;
return this.status.status != 'init';
}
isReady(): boolean {
return this.status.status == 'ready';
}
isInstalling(): boolean {
return this.status.status == 'installing';
}
isWaiting(): boolean {
return this.status.status == 'waiting';
}
isDownloading(): boolean {
return this.status.status === "downloading";
}
runable() {
......
......@@ -146,6 +146,7 @@ export class AppsService {
let apps: App[] = [];
let dependencies = app.findDependencies();
apps.push(...dependencies, app);
console.log(apps);
let downloadPath = path.join(option.installLibrary, 'downloading');
let tasks: Promise<any>[] = [];
for (let a of apps) {
......
......@@ -28,6 +28,10 @@ a {
padding: 10px 20px 10px 20px;
}
a:focus, a:hover {
text-decoration: none;
}
.active {
background-color: #428bca;
}
......@@ -42,4 +46,69 @@ span {
.actions {
margin-bottom: 1em;
}
.progress {
height: 1em;
width: 1em;
float: right;
margin: 14px;
position: relative;
}
.pie {
height: 100%;
width: 100%;
clip: rect(0, 1em, 1em, 0.5em);
left: 0;
position: absolute;
top: 0;
}
.half-circle {
height: 100%;
width: 100%;
border: 0.2em solid #3498db;
border-radius: 50%;
clip: rect(0, 0.5em, 1em, 0);
left: 0;
position: absolute;
top: 0;
}
.shadow {
height: 100%;
width: 100%;
border: 0.2em solid #bdc3c7;
border-radius: 50%;
}
.right-side {
display: none;
}
.half-circle {
/*border-color: #e74c3c;*/
border-color: rgb(0, 116, 217);
}
.left-side {
/*transform: rotate(1turn);*/
/*在前台用Angular填写*/
}
.second-half {
clip: rect(auto, auto, auto, auto);
}
.second-half > .right-side {
display: inherit;
transform: rotate(0.5turn);
}
.fa-spin {
margin: 14px;
color: #0275d8;
font-weight: bold;
float: right;
}
\ No newline at end of file
<!-- Begin page content -->
<div id="main">
<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">
<i *ngIf="!app.isReady() && !app.status.total" class="spin fa fa-circle-o-notch fa-spin fa-fw"></i>
<div *ngIf="!app.isReady() && app.status.total" class="progress">
<div class="pie" [class.second-half]="app.status.progress/app.status.total>0.5">
<div class="left-side half-circle" [style.transform]="'rotate('+(app.status.progress/app.status.total).toString()+'turn)'"></div>
<div class="right-side half-circle"></div>
</div>
<div class="shadow"></div>
</div>
<a (click)="chooseApp(app)" href="#">{{app.name}}</a>
</li>
</ul>
<span *ngIf="grouped_apps.recommend">推荐</span>
<ul *ngIf="grouped_apps.recommend" class="nav nav-sidebar">
<li *ngFor="let app of grouped_apps.recommend" [class.active]="app===currentApp">
<a (click)="chooseApp(app)" href="#">{{app.name}}</a>
<progress *ngIf="app.status.status === 'downloading'"
class="progress progress-striped progress-animated"
value="{{app.status.progress}}"
max="{{app.status.total}}"></progress>
</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">
<span *ngIf="grouped_apps.mysterious">迷之物体</span>
<ul *ngIf="grouped_apps.mysterious" class="nav nav-sidebar">
<li *ngFor="let app of grouped_apps.mysterious" [class.active]="app===currentApp">
<a (click)="chooseApp(app)" href="#">{{app.name}}</a>
<progress *ngIf="app.status.status === 'downloading'"
class="progress progress-striped progress-animated"
......@@ -47,4 +59,5 @@
<app-detail *ngIf="currentApp" [currentApp]="currentApp"></app-detail>
<roster></roster>
</div>
<webview *ngIf="currentApp" #candy id="candy" [src]="candy_url" nodeintegration></webview>
:host {
height: 100%;
display: flex;
flex-direction: column;
}
nav {
-webkit-app-region: drag;
padding-right: 0;
flex-shrink: 0;
}
nav a, nav i, nav img {
-webkit-app-region: no-drag;
}
nav.darwin {
padding-left: 80px;
}
.navbar-right {
float: right
}
.navbar-right > div, #user > .item {
float: left;
margin: 0 0.5rem;
}
.page {
flex-grow: 1;
/*margin-bottom: 60px;*/
......@@ -50,25 +21,19 @@ nav.darwin {
text-decoration: none;
}
.item:hover {
color: #fff;
}
a {
cursor: default;
}
#window-buttons > i {
color: rgba(255, 255, 255, .75);
margin: .5rem;
#update-status > i {
line-height: 1.5;
color: #eceeef;
padding-top: .425rem;
padding-bottom: .425rem;
}
li > a:hover, #window-buttons > i:hover {
.item:hover, li > a:hover {
color: #fff;
}
.navbar {
border-radius: initial;
a {
cursor: default;
}
/* https://github.com/electron/electron/issues/7661#event-827104990 */
......
<nav class="navbar navbar-dark bg-inverse" [class.darwin]="platform == 'darwin'">
<nav id="navbar" class="navbar navbar-dark bg-inverse">
<a class="navbar-brand" href="#">MyCard</a>
<ul class="nav navbar-nav">
<li *ngIf="!loginService.logged_in" class="nav-item active">
......@@ -17,12 +17,18 @@
</li>
</ul>
<div class="navbar-right">
<div id="update-status">
<i #error [hidden]="update_status != 'error'" (click)="update_retry()" class="fa fa-exclamation-circle" data-toggle="tooltip" title="更新出错,点击重试"></i>
<i #checking_for_update [hidden]="update_status != 'checking-for-update'" class="fa fa-spinner fa-pulse fa-spin" data-toggle="tooltip" title="正在检查更新"></i>
<i #update_available [hidden]="update_status != 'update-available'" class="fa fa-refresh fa-spin" data-toggle="tooltip" title="正在下载更新"></i>
<i #update_downloaded [hidden]="update_status != 'update-downloaded'" (click)="update_install()" class="fa fa-angle-double-up" data-toggle="tooltip" title="下载更新完成,点击安装"></i>
</div>
<div id="user" *ngIf="loginService.logged_in">
<a href="#" class="profile"><img id="avatar" [src]="loginService.user.avatar_url" alt="image"></a>
<a href="#" class="profile item" id="username">{{loginService.user.username}}</a>
<a i18n href="#" (click)="loginService.logout()" class="item">切换账号</a>
</div>
<div id="window-buttons" *ngIf="platform != 'darwin'">
<div id="window-buttons">
<i (click)="currentWindow.minimize()" class="fa fa-minus"></i>
<i *ngIf="!currentWindow.isMaximized()" (click)="currentWindow.maximize()" class="fa fa-expand"></i>
<i *ngIf="currentWindow.isMaximized()" (click)="currentWindow.unmaximize()" class="fa fa-clone"></i>
......@@ -33,4 +39,4 @@
<login class="page" *ngIf="!loginService.logged_in"></login>
<store class="page" *ngIf="loginService.logged_in" [hidden]="currentPage != 'store'"></store>
<lobby class="page" *ngIf="loginService.logged_in" [hidden]="currentPage != 'lobby'"></lobby>
<webview class="page" *ngIf="loginService.logged_in" [hidden]="currentPage != 'community'" src="https://ygobbs.com"></webview>
\ No newline at end of file
<webview class="page" *ngIf="loginService.logged_in" [hidden]="currentPage != 'community'" src="https://ygobbs.com"></webview>
import {Component, Renderer, ChangeDetectorRef, OnInit} from "@angular/core";
import {Component, Renderer, ChangeDetectorRef, OnInit, ElementRef, ViewChild} from "@angular/core";
import {remote} from "electron";
import {LoginService} from "./login.service";
const autoUpdater: Electron.AutoUpdater = remote.getGlobal('autoUpdater');
declare const $: any;
@Component({
moduleId: module.id,
......@@ -11,16 +11,31 @@ const autoUpdater: Electron.AutoUpdater = remote.getGlobal('autoUpdater');
styleUrls: ['mycard.component.css'],
})
export class MyCardComponent implements OnInit {
currentPage: string = "lobby";
platform = process.platform;
update_status: string | undefined;
update_error: string | undefined;
currentWindow = remote.getCurrentWindow();
window = window;
ngOnInit() {
@ViewChild('error')
error: ElementRef;
@ViewChild('checking_for_update')
checking_for_update: ElementRef;
@ViewChild('update_available')
update_available: ElementRef;
@ViewChild('update_downloaded')
update_downloaded: ElementRef;
update_elements: Map<string, ElementRef>;
ngOnInit() {
this.update_elements = new Map(Object.entries({
'error': this.error,
'checking-for-update': this.checking_for_update,
'update-available': this.update_available,
'update-downloaded': this.update_downloaded
}));
}
constructor(private renderer: Renderer, private loginService: LoginService, private ref: ChangeDetectorRef) {
......@@ -29,23 +44,49 @@ export class MyCardComponent implements OnInit {
// // Do something with 'event'
// });
this.currentWindow.on('maximize', () => ref.detectChanges());
this.currentWindow.on('unmaximize', () => ref.detectChanges());
this.currentWindow.on('maximize', () => this.ref.detectChanges());
this.currentWindow.on('unmaximize', () => this.ref.detectChanges());
autoUpdater.on('error', (error) => {
console.log('autoUpdater', 'error', error.message)
this.set_update_status('error');
});
autoUpdater.on('checking-for-update', () => {
console.log('autoUpdater', 'checking-for-update')
this.set_update_status('checking-for-update');
});
autoUpdater.on('update-available', () => {
console.log('autoUpdater', 'update-available')
this.set_update_status('update-available');
});
autoUpdater.on('update-not-available', () => {
console.log('autoUpdater', 'update-not-available')
this.set_update_status('update-not-available');
});
autoUpdater.on('update-downloaded', (event) => {
console.log('autoUpdater', 'update-downloaded')
this.set_update_status('update-downloaded');
});
}
update_retry() {
autoUpdater.checkForUpdates()
}
update_install() {
autoUpdater.quitAndInstall()
}
set_update_status(status: string) {
console.log('autoUpdater', status);
if (this.update_status) {
let element = this.update_elements.get(this.update_status);
if (element) {
$(element.nativeElement).tooltip('dispose')
}
}
this.update_status = status;
this.ref.detectChanges();
let element = this.update_elements.get(this.update_status);
if (element) {
$(element.nativeElement).tooltip({placement: 'bottom', container: 'body'})
}
}
}
This diff is collapsed.
......@@ -2039,7 +2039,7 @@
},
"category": "game",
"tags": [
"yugioh"
"recommend"
],
"dependencies": {
"win32": [],
......@@ -2075,7 +2075,7 @@
},
"news": [
{
"url": "#",
"url": "https://ygobbs.com",
"image": "http://pic.4j4j.cn/upload/pic/20140327/af650cf463.jpg",
"title": "News Title",
"text": "喵喵喵喵"
......@@ -2145,7 +2145,7 @@
},
"category": "game",
"tags": [
"yugioh"
"mysterious"
],
"dependencies": {
"win32": [
......
......@@ -11,7 +11,7 @@ environment:
secure: itZ9Z1dxEpfPJLdTs/PiY98pVZ3GCLNWfid7eAu7SL88Jl9AIrf/3rviKFEbsnoY
CSC_LINK:
secure: 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
npm_config_target: 1.4.5
# npm_config_target: 1.4.10 # 在下面 install 里动态获取
npm_config_arch: ia32
npm_config_target_arch: ia32
npm_config_disturl: https://atom.io/download/atom-shell
......@@ -19,9 +19,9 @@ environment:
npm_config_build_from_source: true
cache:
- node_modules
- '%APPDATA%\npm-cache'
- '%USERPROFILE%\.electron'
- node_modules -> package.json
- '%APPDATA%\npm-cache -> package.json'
- '%USERPROFILE%\.electron -> package.json'
shallow_clone: true
......@@ -34,14 +34,16 @@ init:
install:
- set PATH=%PATH%;C:\MinGW\msys\1.0\bin # tar xz
- mkdir -p bin
- curl -L -o aria2-1.28.0-win-32bit-build1.zip https://github.com/aria2/aria2/releases/download/release-1.28.0/aria2-1.28.0-win-32bit-build1.zip
- curl --location --retry 5 --output aria2-1.28.0-win-32bit-build1.zip https://github.com/aria2/aria2/releases/download/release-1.28.0/aria2-1.28.0-win-32bit-build1.zip
- unzip -o aria2-1.28.0-win-32bit-build1.zip aria2-1.28.0-win-32bit-build1/aria2c.exe
- mv aria2-1.28.0-win-32bit-build1/aria2c.exe bin
- rm -rf aria2-1.28.0-win-32bit-build1 aria2-1.27.1-win-32bit-build1.zip
- curl -L 'http://downloads.sourceforge.net/project/msys2/REPOS/MSYS2/i686/bsdtar-3.2.1-1-i686.pkg.tar.xz' | tar --strip-components=2 -C bin -Jxf - usr/bin/bsdtar.exe
- curl -L 'http://downloads.sourceforge.net/project/msys2/Base/i686/msys2-base-i686-20161025.tar.xz' | tar --strip-components=3 -C bin -Jxf - msys32/usr/bin/msys-2.0.dll msys32/usr/bin/msys-bz2-1.dll msys32/usr/bin/msys-gcc_s-1.dll msys32/usr/bin/msys-iconv-2.dll msys32/usr/bin/msys-lzma-5.dll msys32/usr/bin/msys-lzo2-2.dll msys32/usr/bin/msys-nettle-6.dll msys32/usr/bin/msys-xml2-2.dll msys32/usr/bin/msys-z.dll msys32/usr/bin/sha256sum.exe msys32/usr/bin/msys-intl-8.dll
- curl --location --retry 5 'http://downloads.sourceforge.net/project/msys2/REPOS/MSYS2/i686/bsdtar-3.2.1-1-i686.pkg.tar.xz' | tar --strip-components=2 -C bin -Jxf - usr/bin/bsdtar.exe
- curl --location --retry 5 'http://downloads.sourceforge.net/project/msys2/Base/i686/msys2-base-i686-20161025.tar.xz' | tar --strip-components=3 -C bin -Jxf - msys32/usr/bin/msys-2.0.dll msys32/usr/bin/msys-bz2-1.dll msys32/usr/bin/msys-gcc_s-1.dll msys32/usr/bin/msys-iconv-2.dll msys32/usr/bin/msys-lzma-5.dll msys32/usr/bin/msys-lzo2-2.dll msys32/usr/bin/msys-nettle-6.dll msys32/usr/bin/msys-xml2-2.dll msys32/usr/bin/msys-z.dll msys32/usr/bin/sha256sum.exe msys32/usr/bin/msys-intl-8.dll
- ps: Install-Product node
- npm show electron version > %temp%\electron-version.txt
- set /p npm_config_target= < %temp%\electron-version.txt
- npm install
- npm prune
......
......@@ -7,6 +7,11 @@
<link rel="shortcut icon" href="res/img/favicon.png" type="image/gif"/>
<link rel="stylesheet" type="text/css" href="libs.min.css"/>
<link rel="stylesheet" type="text/css" href="res/default.css"/>
<style>
body {
font-family: -apple-system, Arial, 'Source Sans Pro', "Microsoft YaHei", 'Microsoft JhengHei', "WenQuanYi Micro Hei", sans-serif;
}
</style>
<script>delete module.exports</script>
<script type="text/javascript" src="../node_modules/jquery/dist/jquery.min.js"></script>
......
......@@ -23,11 +23,32 @@
<script src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<script>
System.import('app')
System.import('app').catch((error) => {
$('#loading').hide();
$('#failed').removeAttr('hidden');
$('#error').removeAttr('hidden').text(error);
});
</script>
</head>
<body>
<mycard>Loading...</mycard>
<mycard>
<nav id="navbar" class="navbar navbar-dark bg-inverse">
<a class="navbar-brand" href="#">MyCard</a>
<div class="navbar-right">
<div id="window-buttons">
<i onclick="window.close()" class="fa fa-times"></i>
</div>
</div>
</nav>
<div id="loading">MyCard <span id="version"></span> Loading...</div>
<div id="failed" hidden>发生了错误,请复制以下错误信息并联系 support@mycard.moe</div>
<pre id="error" hidden></pre>
</mycard>
<script>
document.body.classList.add(process.platform);
document.getElementById('version').innerHTML = require('electron').remote.app.getVersion();
</script>
</body>
</html>
'use strict';
const {ipcMain, app, BrowserWindow} = require('electron');
const {ipcMain, app, shell, BrowserWindow} = require('electron');
const {autoUpdater} = require("electron-auto-updater");
const isDev = require('electron-is-dev');
const child_process = require('child_process');
const path = require('path');
if (process.platform == 'darwin') {
try {
autoUpdater.setFeedURL("https://wudizhanche.mycard.moe/update/darwin/" + app.getVersion());
} catch (err) {
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow;
// 单实例
const shouldQuit = app.makeSingleInstance((commandLine, workingDirectory) => {
// Someone tried to run a second instance, we should focus our window.
if (mainWindow) {
if (mainWindow.isMinimized()) {
mainWindow.restore()
}
mainWindow.focus()
}
})
if (shouldQuit) {
app.quit()
}
global.autoUpdater = autoUpdater;
// 调试模式
if (!process.env['NODE_ENV']) {
process.env['NODE_ENV'] = isDev ? 'development' : 'production'
}
// 自动更新
let updateWindow;
global.autoUpdater = autoUpdater;
if (process.env['NODE_ENV'] == 'production' && process.platform == 'darwin') {
autoUpdater.setFeedURL("https://wudizhanche.mycard.moe/update/darwin/" + app.getVersion());
}
// else{
// setTimeout(()=>{
// autoUpdater.emit('checking-for-update')
// }, 5000)
// setTimeout(()=>{
// autoUpdater.emit('error', '1')
// }, 6000)
// }
autoUpdater.on('error', (event) => {
console.log('autoUpdater', 'error', event);
});
......@@ -26,27 +55,22 @@ autoUpdater.on('update-available', () => {
autoUpdater.on('update-not-available', () => {
console.log('autoUpdater', 'update-not-available');
});
let updateWindow;
autoUpdater.on('update-downloaded', (event) => {
console.log('autoUpdater', 'update-downloaded', event);
updateWindow = new BrowserWindow({
width: 640,
height: 480,
});
updateWindow.loadURL(`file://${__dirname}/update.html`);
updateWindow.on('closed', function () {
updateWindow = null
});
ipcMain.on('update', (event, arg) => {
autoUpdater.quitAndInstall()
})
});
// 处理提权
function handleElevate() {
// for debug
......@@ -73,32 +97,36 @@ function handleElevate() {
return true;
}
}
if (handleElevate()) {
return;
}
// Aria2c
function createAria2c() {
let aria2c_path;
switch (process.platform) {
case 'win32':
aria2c_path = path.join(process.resourcesPath, 'bin', 'aria2c.exe');
if (process.env['NODE_ENV'] == 'production') {
aria2c_path = path.join(process.resourcesPath, 'bin', 'aria2c.exe');
} else {
aria2c_path = path.join('bin', 'aria2c.exe');
}
break;
case 'darwin':
aria2c_path = path.join(process.resourcesPath, 'bin', 'aria2c');
if (process.env['NODE_ENV'] == 'production') {
aria2c_path = path.join(process.resourcesPath, 'bin', 'aria2c');
} else {
aria2c_path = path.join('bin', 'aria2c');
}
break;
default:
throw 'unsupported platform';
}
return 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'});
}
const aria2c = createAria2c();
// Keep a global reference of the window object, if you don't, the window will
// be closed automatically when the JavaScript object is garbage collected.
let mainWindow;
// 主窗口
function createWindow() {
// Create the browser window.
mainWindow = new BrowserWindow({
......@@ -111,8 +139,15 @@ function createWindow() {
// and load the index.html of the app.
mainWindow.loadURL(`file://${__dirname}/index.html`);
mainWindow.webContents.on('new-window', function(e, url) {
e.preventDefault();
shell.openExternal(url);
});
// Open the DevTools.
mainWindow.webContents.openDevTools();
if (process.env['NODE_ENV'] == 'development') {
mainWindow.webContents.openDevTools();
}
// Emitted when the window is closed.
mainWindow.on('closed', function () {
......@@ -128,7 +163,9 @@ function createWindow() {
// Some APIs can only be used after this event occurs.
app.on('ready', () => {
createWindow();
setTimeout(autoUpdater.checkForUpdates, 2000);
if (process.env['NODE_ENV'] == 'production') {
setTimeout(autoUpdater.checkForUpdates, 2000);
}
});
// Quit when all windows are closed.
......
This diff is collapsed.
{
"name": "mycard",
"version": "3.0.0-dev.10",
"version": "3.0.0-dev.12",
"description": "mycard",
"keywords": [],
"author": "zh99998 <zh99998@gmail.com>",
......@@ -12,7 +12,7 @@
"pack": "tsc && build --dir",
"dist": "tsc && build",
"tsc": "tsc",
"i18n": "ng-xi18n"
"i18n": "ng-xi18n && sed -i.bak 's/source-language=\"en\"/source-language=\"zh-CN\"/' messages.xlf"
},
"dependencies": {
"@angular/common": "latest",
......@@ -24,22 +24,24 @@
"@angular/platform-browser-dynamic": "latest",
"@angular/router": "latest",
"angular-in-memory-web-api": "latest",
"systemjs": "latest",
"aria2": "latest",
"bootstrap": "next",
"core-js": "latest",
"reflect-metadata": "latest",
"rxjs": "5.0.0-beta.12",
"zone.js": "^0.6.26",
"electron-auto-updater": "latest",
"electron-cookies": "latest",
"electron-is-dev": "latest",
"electron-sudo": "mycard/electron-sudo#mycard",
"jquery": "latest",
"tether": "latest",
"bootstrap": "next",
"font-awesome": "latest",
"aria2": "latest",
"ini": "latest",
"jquery": "latest",
"mkdirp": "latest",
"raw-socket": "latest"
"raw-socket": "latest",
"reflect-metadata": "latest",
"rxjs": "5.0.0-beta.12",
"systemjs": "mycard/systemjs#mycard",
"systemjs-plugin-text": "latest",
"tether": "latest",
"zone.js": "^0.6.26"
},
"devDependencies": {
"@angular/compiler-cli": "latest",
......@@ -75,6 +77,7 @@
]
},
"dmg": {
"format": "ULFO",
"contents": [
{
"x": 448,
......
......@@ -5,3 +5,46 @@ html, body {
body {
font-family: -apple-system, Arial, 'Source Sans Pro', "Microsoft YaHei", 'Microsoft JhengHei', "WenQuanYi Micro Hei", sans-serif;
}
mycard {
height: 100%;
display: flex;
flex-direction: column;
}
.darwin #window-buttons {
display: none;
}
#window-buttons > i {
color: rgba(255, 255, 255, .75);
margin: .5rem;
}
#window-buttons > i:hover {
color: #fff;
}
#navbar {
-webkit-app-region: drag;
padding-right: 0;
flex-shrink: 0;
border-radius: initial;
}
#navbar a, #navbar i, #navbar img {
-webkit-app-region: no-drag;
}
#navbar .navbar-right {
float: right
}
#navbar .navbar-right > div, #user > .item {
float: left;
margin: 0 0.5rem;
}
.darwin #navbar {
padding-left: 80px;
}
\ No newline at end of file
/*
SystemJS Text plugin from
https://github.com/systemjs/plugin-text/blob/master/text.js
*/
exports.translate = function(load) {
if (this.builder && this.transpiler) {
load.metadata.format = 'esm';
return 'exp' + 'ort var __useDefault = true; exp' + 'ort default ' + JSON.stringify(load.source) + ';';
}
load.metadata.format = 'amd';
return 'def' + 'ine(function() {\nreturn ' + JSON.stringify(load.source) + ';\n});';
}
......@@ -13,7 +13,7 @@ System.config({
app: 'app',
// systemjs plugins
'text': 'systemjs-text-plugin.js',
'text': 'npm:systemjs-plugin-text/text.js',
// angular bundles
'@angular/core': 'npm:@angular/core/bundles/core.umd.js',
......
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