Commit 96e5b306 authored by 神楽坂玲奈's avatar 神楽坂玲奈

loading, 更新进度

parent 0ec68e54
<h1>{{currentApp.name}}</h1> <h1>{{currentApp.name}}</h1>
<div *ngIf="currentApp.status.status === 'init'"> <div class="actions" *ngIf="currentApp.status.status === 'init'">
<button i18n type="button" class="btn btn-primary" data-toggle="modal" (click)="updateInstallConfig(currentApp)" data-target="#install-modal">安装</button> <button i18n type="button" class="btn btn-primary" data-toggle="modal" (click)="updateInstallConfig(currentApp)" data-target="#install-modal">安装</button>
<button i18n type="button" class="btn btn-secondary">导入</button> <button i18n type="button" class="btn btn-secondary">导入</button>
</div> </div>
...@@ -29,7 +29,7 @@ ...@@ -29,7 +29,7 @@
<div id="news" *ngFor="let item of news"> <div id="news" *ngFor="let item of news">
<h3>{{item.title}}</h3> <h3>{{item.title}}</h3>
<p>{{item.text}}</p> <p>{{item.text}}</p>
<a i18n *ngIf="item.url" [href]="item.url">了解更多</a> <a i18n *ngIf="item.url" [href]="item.url" target="_blank">了解更多</a>
</div> </div>
<div *ngIf="currentApp.isInstalled()"> <div *ngIf="currentApp.isInstalled()">
<div *ngIf="mods && mods.length"> <div *ngIf="mods && mods.length">
......
...@@ -28,6 +28,10 @@ a { ...@@ -28,6 +28,10 @@ a {
padding: 10px 20px 10px 20px; padding: 10px 20px 10px 20px;
} }
a:focus, a:hover {
text-decoration: none;
}
.active { .active {
background-color: #428bca; background-color: #428bca;
} }
......
...@@ -7,9 +7,15 @@ ...@@ -7,9 +7,15 @@
<a (click)="chooseApp(app)" href="#">{{app.name}}</a> <a (click)="chooseApp(app)" href="#">{{app.name}}</a>
</li> </li>
</ul> </ul>
<span *ngIf="grouped_apps.yugioh">游戏王</span> <span *ngIf="grouped_apps.recommend">推荐</span>
<ul *ngIf="grouped_apps.yugioh" class="nav nav-sidebar"> <ul *ngIf="grouped_apps.recommend" class="nav nav-sidebar">
<li *ngFor="let app of grouped_apps.yugioh" [class.active]="app===currentApp"> <li *ngFor="let app of grouped_apps.recommend" [class.active]="app===currentApp">
<a (click)="chooseApp(app)" href="#">{{app.name}}</a>
</li>
</ul>
<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> <a (click)="chooseApp(app)" href="#">{{app.name}}</a>
</li> </li>
</ul> </ul>
......
: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 { .page {
flex-grow: 1; flex-grow: 1;
/*margin-bottom: 60px;*/ /*margin-bottom: 60px;*/
...@@ -50,25 +21,19 @@ nav.darwin { ...@@ -50,25 +21,19 @@ nav.darwin {
text-decoration: none; text-decoration: none;
} }
.item:hover { #update-status > i {
color: #fff; line-height: 1.5;
} color: #eceeef;
padding-top: .425rem;
a { padding-bottom: .425rem;
cursor: default;
}
#window-buttons > i {
color: rgba(255, 255, 255, .75);
margin: .5rem;
} }
li > a:hover, #window-buttons > i:hover { .item:hover, li > a:hover {
color: #fff; color: #fff;
} }
.navbar { a {
border-radius: initial; cursor: default;
} }
/* https://github.com/electron/electron/issues/7661#event-827104990 */ /* 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> <a class="navbar-brand" href="#">MyCard</a>
<ul class="nav navbar-nav"> <ul class="nav navbar-nav">
<li *ngIf="!loginService.logged_in" class="nav-item active"> <li *ngIf="!loginService.logged_in" class="nav-item active">
...@@ -17,12 +17,18 @@ ...@@ -17,12 +17,18 @@
</li> </li>
</ul> </ul>
<div class="navbar-right"> <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"> <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"><img id="avatar" [src]="loginService.user.avatar_url" alt="image"></a>
<a href="#" class="profile item" id="username">{{loginService.user.username}}</a> <a href="#" class="profile item" id="username">{{loginService.user.username}}</a>
<a i18n href="#" (click)="loginService.logout()" class="item">切换账号</a> <a i18n href="#" (click)="loginService.logout()" class="item">切换账号</a>
</div> </div>
<div id="window-buttons" *ngIf="platform != 'darwin'"> <div id="window-buttons">
<i (click)="currentWindow.minimize()" class="fa fa-minus"></i> <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.maximize()" class="fa fa-expand"></i>
<i *ngIf="currentWindow.isMaximized()" (click)="currentWindow.unmaximize()" class="fa fa-clone"></i> <i *ngIf="currentWindow.isMaximized()" (click)="currentWindow.unmaximize()" class="fa fa-clone"></i>
...@@ -33,4 +39,4 @@ ...@@ -33,4 +39,4 @@
<login class="page" *ngIf="!loginService.logged_in"></login> <login class="page" *ngIf="!loginService.logged_in"></login>
<store class="page" *ngIf="loginService.logged_in" [hidden]="currentPage != 'store'"></store> <store class="page" *ngIf="loginService.logged_in" [hidden]="currentPage != 'store'"></store>
<lobby class="page" *ngIf="loginService.logged_in" [hidden]="currentPage != 'lobby'"></lobby> <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> <webview class="page" *ngIf="loginService.logged_in" [hidden]="currentPage != 'community'" src="https://ygobbs.com"></webview>
\ No newline at end of file
import {Component, Renderer, ChangeDetectorRef, OnInit} from "@angular/core"; import {Component, Renderer, ChangeDetectorRef, OnInit, ElementRef, ViewChild} from "@angular/core";
import {remote} from "electron"; import {remote} from "electron";
import {LoginService} from "./login.service"; import {LoginService} from "./login.service";
const autoUpdater: Electron.AutoUpdater = remote.getGlobal('autoUpdater'); const autoUpdater: Electron.AutoUpdater = remote.getGlobal('autoUpdater');
declare const $: any;
@Component({ @Component({
moduleId: module.id, moduleId: module.id,
...@@ -11,16 +11,31 @@ const autoUpdater: Electron.AutoUpdater = remote.getGlobal('autoUpdater'); ...@@ -11,16 +11,31 @@ const autoUpdater: Electron.AutoUpdater = remote.getGlobal('autoUpdater');
styleUrls: ['mycard.component.css'], styleUrls: ['mycard.component.css'],
}) })
export class MyCardComponent implements OnInit { export class MyCardComponent implements OnInit {
currentPage: string = "lobby"; currentPage: string = "lobby";
platform = process.platform; update_status: string | undefined;
update_error: string | undefined;
currentWindow = remote.getCurrentWindow(); currentWindow = remote.getCurrentWindow();
window = window; 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) { constructor(private renderer: Renderer, private loginService: LoginService, private ref: ChangeDetectorRef) {
...@@ -29,23 +44,49 @@ export class MyCardComponent implements OnInit { ...@@ -29,23 +44,49 @@ export class MyCardComponent implements OnInit {
// // Do something with 'event' // // Do something with 'event'
// }); // });
this.currentWindow.on('maximize', () => ref.detectChanges()); this.currentWindow.on('maximize', () => this.ref.detectChanges());
this.currentWindow.on('unmaximize', () => ref.detectChanges()); this.currentWindow.on('unmaximize', () => this.ref.detectChanges());
autoUpdater.on('error', (error) => { autoUpdater.on('error', (error) => {
console.log('autoUpdater', 'error', error.message) this.set_update_status('error');
}); });
autoUpdater.on('checking-for-update', () => { autoUpdater.on('checking-for-update', () => {
console.log('autoUpdater', 'checking-for-update') this.set_update_status('checking-for-update');
}); });
autoUpdater.on('update-available', () => { autoUpdater.on('update-available', () => {
console.log('autoUpdater', 'update-available') this.set_update_status('update-available');
}); });
autoUpdater.on('update-not-available', () => { autoUpdater.on('update-not-available', () => {
console.log('autoUpdater', 'update-not-available') this.set_update_status('update-not-available');
}); });
autoUpdater.on('update-downloaded', (event) => { 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'})
}
} }
} }
...@@ -2039,7 +2039,7 @@ ...@@ -2039,7 +2039,7 @@
}, },
"category": "game", "category": "game",
"tags": [ "tags": [
"yugioh" "recommend"
], ],
"dependencies": { "dependencies": {
"win32": [], "win32": [],
...@@ -2075,7 +2075,7 @@ ...@@ -2075,7 +2075,7 @@
}, },
"news": [ "news": [
{ {
"url": "#", "url": "https://ygobbs.com",
"image": "http://pic.4j4j.cn/upload/pic/20140327/af650cf463.jpg", "image": "http://pic.4j4j.cn/upload/pic/20140327/af650cf463.jpg",
"title": "News Title", "title": "News Title",
"text": "喵喵喵喵" "text": "喵喵喵喵"
...@@ -2145,7 +2145,7 @@ ...@@ -2145,7 +2145,7 @@
}, },
"category": "game", "category": "game",
"tags": [ "tags": [
"yugioh" "mysterious"
], ],
"dependencies": { "dependencies": {
"win32": [ "win32": [
......
...@@ -7,6 +7,11 @@ ...@@ -7,6 +7,11 @@
<link rel="shortcut icon" href="res/img/favicon.png" type="image/gif"/> <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="libs.min.css"/>
<link rel="stylesheet" type="text/css" href="res/default.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>delete module.exports</script>
<script type="text/javascript" src="../node_modules/jquery/dist/jquery.min.js"></script> <script type="text/javascript" src="../node_modules/jquery/dist/jquery.min.js"></script>
......
...@@ -23,11 +23,32 @@ ...@@ -23,11 +23,32 @@
<script src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script> <script src="node_modules/bootstrap/dist/js/bootstrap.min.js"></script>
<script> <script>
System.import('app') System.import('app').catch((error) => {
$('#loading').hide();
$('#failed').removeAttr('hidden');
$('#error').removeAttr('hidden').text(error);
});
</script> </script>
</head> </head>
<body> <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> </body>
</html> </html>
'use strict'; 'use strict';
const {ipcMain, app, BrowserWindow} = require('electron'); const {ipcMain, app, shell, BrowserWindow} = require('electron');
const {autoUpdater} = require("electron-auto-updater"); const {autoUpdater} = require("electron-auto-updater");
const isDev = require('electron-is-dev'); const isDev = require('electron-is-dev');
const child_process = require('child_process'); const child_process = require('child_process');
...@@ -35,6 +35,14 @@ global.autoUpdater = autoUpdater; ...@@ -35,6 +35,14 @@ global.autoUpdater = autoUpdater;
if (process.env['NODE_ENV'] == 'production' && process.platform == 'darwin') { if (process.env['NODE_ENV'] == 'production' && process.platform == 'darwin') {
autoUpdater.setFeedURL("https://wudizhanche.mycard.moe/update/darwin/" + app.getVersion()); 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) => { autoUpdater.on('error', (event) => {
console.log('autoUpdater', 'error', event); console.log('autoUpdater', 'error', event);
}); });
...@@ -131,6 +139,11 @@ function createWindow() { ...@@ -131,6 +139,11 @@ function createWindow() {
// and load the index.html of the app. // and load the index.html of the app.
mainWindow.loadURL(`file://${__dirname}/index.html`); mainWindow.loadURL(`file://${__dirname}/index.html`);
mainWindow.webContents.on('new-window', function(e, url) {
e.preventDefault();
shell.openExternal(url);
});
// Open the DevTools. // Open the DevTools.
if (process.env['NODE_ENV'] == 'development') { if (process.env['NODE_ENV'] == 'development') {
mainWindow.webContents.openDevTools(); mainWindow.webContents.openDevTools();
......
...@@ -5,3 +5,46 @@ html, body { ...@@ -5,3 +5,46 @@ html, body {
body { body {
font-family: -apple-system, Arial, 'Source Sans Pro', "Microsoft YaHei", 'Microsoft JhengHei', "WenQuanYi Micro Hei", sans-serif; 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
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