Commit 0b8fbac9 authored by 神楽坂玲奈's avatar 神楽坂玲奈

YGOPro 匹配显示时间,优化聊天室性能,去除圆角窗口,3.0.18

parent 5ece2fe2
...@@ -4,15 +4,15 @@ ...@@ -4,15 +4,15 @@
let shadow: ShadowRoot; let shadow: ShadowRoot;
const jQueryShadow = require('../jquery-shadow.js'); const $ = require('../jquery-shadow.js');
jQueryShadow.fn.init = new Proxy(jQueryShadow.fn.init, { $.fn.init = new Proxy($.fn.init, {
construct(target, argumentsList, newTarget) { construct(target, argumentsList, newTarget) {
let [selector, context, root] = argumentsList; let [selector, context, root] = argumentsList;
if (shadow) { if (shadow) {
if (selector === 'body') { if (selector === 'body') {
selector = shadow; selector = shadow;
} else if (selector === document) { } else if (selector === document) {
selector = shadow.querySelector('#candy'); selector = $('#candy');
} else if (!context) { } else if (!context) {
context = shadow; context = shadow;
} }
...@@ -21,7 +21,7 @@ jQueryShadow.fn.init = new Proxy(jQueryShadow.fn.init, { ...@@ -21,7 +21,7 @@ jQueryShadow.fn.init = new Proxy(jQueryShadow.fn.init, {
} }
}); });
window['jQuery'] = jQueryShadow; window['jQuery'] = $;
import {Component, ViewEncapsulation, OnInit, Input, OnChanges, SimpleChanges, ElementRef} from '@angular/core'; import {Component, ViewEncapsulation, OnInit, Input, OnChanges, SimpleChanges, ElementRef} from '@angular/core';
import {LoginService} from './login.service'; import {LoginService} from './login.service';
...@@ -57,6 +57,31 @@ Candy.Util.getPosTopAccordingToWindowBounds = new Proxy(Candy.Util.getPosTopAcco ...@@ -57,6 +57,31 @@ Candy.Util.getPosTopAccordingToWindowBounds = new Proxy(Candy.Util.getPosTopAcco
return target.apply(thisArg, argumentsList); return target.apply(thisArg, argumentsList);
} }
}); });
Candy.View.Pane.Roster.joinAnimation = function (elementId: string) {
$("#" + elementId).show().css({opacity: 'initial'});
};
declare const Mustache: any;
Candy.View.Pane.Roster._insertUser = function (roomJid: string, roomId: string, user: any, userId: string, currentUser: any) {
let contact = user.getContact();
let html = Mustache.to_html(Candy.View.Template.Roster.user, {
roomId: roomId,
userId: userId,
userJid: user.getJid(),
realJid: user.getRealJid(),
status: user.getStatus(),
contact_status: contact ? contact.getStatus() : "unavailable",
nick: user.getNick(),
displayNick: Candy.Util.crop(user.getNick(), Candy.View.getOptions().crop.roster.nickname),
role: user.getRole(),
affiliation: user.getAffiliation(),
me: currentUser !== undefined && user.getNick() === currentUser.getNick(),
tooltipRole: $.i18n._("tooltipRole"),
tooltipIgnored: $.i18n._("tooltipIgnored")
});
let rosterPane = Candy.View.Pane.Room.getPane(roomJid, ".roster-pane");
rosterPane.append(html);
};
document['__defineGetter__']('cookie', () => 'candy-nostatusmessages'); document['__defineGetter__']('cookie', () => 'candy-nostatusmessages');
document['__defineSetter__']('cookie', () => true); document['__defineSetter__']('cookie', () => true);
...@@ -75,10 +100,10 @@ export class CandyComponent implements OnInit, OnChanges { ...@@ -75,10 +100,10 @@ export class CandyComponent implements OnInit, OnChanges {
password: string; password: string;
nickname: string; nickname: string;
constructor(private loginService: LoginService, private settingsService: SettingsService, private element: ElementRef) { constructor (private loginService: LoginService, private settingsService: SettingsService, private element: ElementRef) {
} }
ngOnInit() { ngOnInit () {
this.jid = this.loginService.user.username + '@mycard.moe'; this.jid = this.loginService.user.username + '@mycard.moe';
this.password = this.loginService.user.external_id.toString(); this.password = this.loginService.user.external_id.toString();
...@@ -136,7 +161,7 @@ export class CandyComponent implements OnInit, OnChanges { ...@@ -136,7 +161,7 @@ export class CandyComponent implements OnInit, OnChanges {
Candy.Core.connect(this.jid, this.password, this.nickname); Candy.Core.connect(this.jid, this.password, this.nickname);
} }
ngOnChanges(changes: SimpleChanges): void { ngOnChanges (changes: SimpleChanges): void {
if (!Candy.Core.getConnection()) { if (!Candy.Core.getConnection()) {
return; return;
} }
......
...@@ -7,7 +7,7 @@ import {LoginService} from './login.service'; ...@@ -7,7 +7,7 @@ import {LoginService} from './login.service';
import {App, Category} from './app'; import {App, Category} from './app';
import {shell} from 'electron'; import {shell} from 'electron';
import {SettingsService} from './settings.sevices'; import {SettingsService} from './settings.sevices';
import 'typeahead.js'; // import 'typeahead.js';
// import Options = Twitter.Typeahead.Options; // import Options = Twitter.Typeahead.Options;
@Component({ @Component({
......
:host { /*:host {*/
background-color: white; /*background-color: white;*/
} /*}*/
.page { .page {
flex-grow: 1; flex-grow: 1;
/*margin-bottom: 60px;*/ /*margin-bottom: 60px;*/
...@@ -54,9 +54,9 @@ lobby[hidden], webview[hidden] { ...@@ -54,9 +54,9 @@ lobby[hidden], webview[hidden] {
/* 不加这个切到有 Webview 的页面,上面的圆角会消失 */ /* 不加这个切到有 Webview 的页面,上面的圆角会消失 */
/* 即使加了这个,下面的圆角也会消失 */ /* 即使加了这个,下面的圆角也会消失 */
webview { /*webview {*/
overflow: hidden; /*overflow: hidden;*/
} /*}*/
#navbar { #navbar {
background-color: #f7f7f9!important; background-color: #f7f7f9!important;
......
#game-list-modal tbody { /*#game-list-modal tbody {*/
display: block; /*display: block;*/
overflow-y: auto; /*overflow-y: auto;*/
height: 21.5rem; /*height: 21.5rem;*/
} /*}*/
/*#game-list-modal thead {*/
/*position: relative;*/
/*display: block;*/
/*}*/
/*#game-list-modal tr {*/
/*width: 100%;*/
/*display: table;*/
/*}*/
/*#game-list-modal .table {*/
/*margin-bottom: 0;*/
/*}*/
/*#game-list-modal .close {*/
/*position: absolute;*/
/*top: 15px;*/
/*right: 15px;*/
/*}*/
/*#game-list-modal .modal-header {*/
/*padding-left: 0;*/
/*padding-right: 0;*/
/*}*/
/*#game-list-modal .modal-header th {*/
/*line-height: 36px;*/
/*padding-top: 0;*/
/*padding-bottom: 0;*/
/*border: none;*/
/*}*/
/*#game-list-modal .modal-body {*/
/*padding: 0;*/
/*height: 21.4rem;*/
/*}*/
/*#game-list-modal .modal-body tr:first-child td {*/
/*border-top: none;*/
/*}*/
/*#game-list-modal .modal-body tr:last-child td {*/
/*border-bottom: none;*/
/*}*/
/*!*fixme: auto width*!*/
/*#game-list-modal .title {*/
/*width: 25%;*/
/*}*/
/*#game-list-modal .users {*/
/*width: 20%;*/
/*}*/
/*#game-list-modal .mode {*/
/*width: 20%;*/
/*}*/
/*#game-list-modal .extra {*/
/*width: 35%;*/
/*}*/
/*.float-left {*/
/*float: left;*/
/*}*/
/*.actions {*/
/*margin-bottom: 1em;*/
/*}*/
#game-list-modal thead { dl {
position: relative; margin-bottom: 0;
display: block;
} }
#game-list-modal tr { /*.modal-dialog {*/
width: 100%; /*max-width: 600px;*/
display: table; /*}*/
/*label {*/
/*font-size: 15px;*/
/*}*/
form {
padding-bottom: .75rem;
} }
#game-list-modal .table { .btn-primary {
margin-bottom: 0; background-color: #00a4d9;
border-color: #008dbb;
} }
#game-list-modal .avatar { #action, #match-time {
width: 25px; margin-bottom: .5rem;
height: 25px;
border-radius: 50%;
} }
#game-list-modal .close { #match-time .input-group-addon {
position: absolute; display: block;
top: 15px;
right: 15px;
} }
#game-list-modal .modal-header { #game-list-modal .modal-content {
padding-left: 0; flex-direction: row;
padding-right: 0;
} }
#game-list-modal .modal-header th { #game-list-modal .table {
line-height: 36px; font-size: 14px;
padding-top: 0; }
padding-bottom: 0;
border: none;
#game-list-modal .avatar {
width: 18px;
height: 18px;
} }
#game-list-modal .modal-body { #game-list-modal form {
padding: 0; position: relative;
height: 21.4rem; background-color: #f7f7f7;
border-left: 1px solid #eee;
width: 200px;
flex-shrink: 0;
} }
#game-list-modal .modal-body tr:first-child td { #game-list-modal .modal-content {
border-top: none; overflow: hidden;
} }
#game-list-modal .modal-body tr:last-child td { #game-list-modal #game-create-actions {
border-bottom: none; position: absolute;
right: 0;
bottom: .75rem;
} }
/*fixme: auto width*/ #game-list-modal fieldset label:last-child {
#game-list-modal .title { margin-bottom: 0;
width: 25%;
} }
#game-list-modal .users { #game-list {
width: 20%; position: relative;
flex-grow: 1;
} }
#game-list-modal .mode { #game-list-modal h3 {
width: 20%; border-bottom: 2px solid #eceeef;
padding: .75rem;
vertical-align: top;
font-size: 15px;
font-weight: bold;
line-height: 1.5;
} }
#game-list-modal .extra { #game-list-modal form > div, #game-list-modal form > fieldset {
width: 35%; padding: 0 .75rem;
font-size: 14px;
} }
.float-left { #game-list-close {
float: left; position: absolute;
right: .75rem;
top: .5rem;
} }
.actions { #game-list-modal th {
margin-bottom: 1em; white-space: nowrap
} }
dl { #game-list-modal legend {
margin-bottom: 0; font-size: 14px;
} }
.modal-dialog { #game-list-modal fieldset label {
max-width: 600px; padding-right: 0;
} }
label { #game-replay-modal .nav-tabs .nav-item {
font-size: 15px; font-size: 15px;
} }
#game-replay-bilibili webview {
form { height: 440px;
margin-bottom: 0;
} }
.btn-primary { #game-replay-watch table {
background-color: #00a4d9; font-size: 14px;
border-color: #008dbb;
} }
#action, #match-time { #game-replay-watch .avatar {
margin-bottom: .5rem; width: 18px;
height: 18px;
} }
#match-time .input-group-addon {
display: block;
}
\ No newline at end of file
...@@ -4,6 +4,7 @@ ...@@ -4,6 +4,7 @@
<button i18n [disabled]="!appsService.allReady(app)" (click)="request_match('entertain')" type="button" class="btn btn-secondary btn-sm">娱乐匹配</button> <button i18n [disabled]="!appsService.allReady(app)" (click)="request_match('entertain')" type="button" class="btn btn-secondary btn-sm">娱乐匹配</button>
<button i18n [disabled]="!appsService.allReady(app)" type="button" class="btn btn-secondary btn-sm" data-toggle="modal" data-target="#game-list-modal">自定义游戏</button> <button i18n [disabled]="!appsService.allReady(app)" type="button" class="btn btn-secondary btn-sm" data-toggle="modal" data-target="#game-list-modal">自定义游戏</button>
<button i18n [disabled]="!appsService.allReady(app)" type="button" class="btn btn-secondary btn-sm" data-toggle="modal" data-target="#game-create-windbot">单人模式</button> <button i18n [disabled]="!appsService.allReady(app)" type="button" class="btn btn-secondary btn-sm" data-toggle="modal" data-target="#game-create-windbot">单人模式</button>
<button i18n [disabled]="!appsService.allReady(app)" type="button" class="btn btn-secondary btn-sm" data-toggle="modal" data-target="#game-replay-modal">观战和录像</button>
</div> </div>
<!-- 匹配中 --> <!-- 匹配中 -->
...@@ -48,141 +49,208 @@ ...@@ -48,141 +49,208 @@
</div> </div>
</div> </div>
<div class="modal fade" id="game-create-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true"> <div class="modal fade" id="game-list-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document"> <div class="modal-dialog modal-lg" role="document">
<div class="modal-content"> <div class="modal-content flex-row">
<div class="modal-header">
<h5 class="modal-title" i18n id="myModalLabel">创建房间</h5> <div id="game-list">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"> <table class="table table-striped table-hover">
<span aria-hidden="true">&times;</span> <thead>
</button> <tr>
<th i18n class="title">游戏标题</th>
<th i18n class="users">玩家</th>
<th i18n class="mode">决斗模式</th>
<th i18n class="extra">额外选项</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let room of rooms" class="room" (click)="join_room(room)">
<td class="title">{{room.title}}</td>
<td class="users">
<img *ngFor="let user of room.users" class="avatar rounded" [src]="'https://ygobbs.com/user_avatar/ygobbs.com/' + user.username + '/25/1.png'" data-toggle="tooltip" data-placement="bottom" [title]="user.username">
</td>
<td class="mode">
<span i18n *ngIf="room.options.mode === 0">单局模式</span>
<span i18n *ngIf="room.options.mode === 1">比赛模式</span>
<span i18n *ngIf="room.options.mode === 2">TAG</span>
</td>
<td class="extra">
<span *ngIf="room.options.rule != default_options.rule">{{{'0': 'OCG', '1': 'TCG', '2': 'O/T', '3': '专有卡禁止'}[room.options.rule]}}</span>
<span i18n *ngIf="room.options.start_lp != default_options.start_lp">{{room.options.start_lp}} LP</span>
<span i18n *ngIf="room.options.start_hand != default_options.start_hand">{{room.options.start_hand}} 初始</span>
<span i18n *ngIf="room.options.draw_count != default_options.draw_count">{{room.options.draw_count}} 抽卡</span>
<span i18n *ngIf="room.options.enable_priority != default_options.enable_priority">旧规则</span>
<span i18n *ngIf="room.options.no_check_deck != default_options.no_check_deck">不检查</span>
<span i18n *ngIf="room.options.no_shuffle_deck != default_options.no_shuffle_deck">不洗卡</span>
</td>
</tr>
</tbody>
</table>
</div> </div>
<form id="game-create" (submit)="create_room(room)">
<div class="modal-body">
<div class="form-group row"> <form (submit)="create_room(room)">
<label for="game-create-title" i18n class="col-sm-2 form-control-label">游戏标题</label> <h3 i18n>创建房间</h3>
<div class="col-sm-10"> <div class="form-group">
<input type="text" class="form-control" id="game-create-title" name="title" [(ngModel)]="room.title"> <label i18n for="game-create-title">游戏标题</label>
<input type="text" maxlength="12" class="form-control form-control-sm" id="game-create-title" name="title" [(ngModel)]="room.title" required>
<small id="emailHelp" class="form-text text-muted">最多 12 个字</small>
</div>
<div class="form-group">
<label i18n for="game-create-rule">卡片允许</label>
<select class="form-control form-control-sm" id="game-create-rule" name="rule" [(ngModel)]="room.options.rule">
<option i18n value="0">OCG</option>
<option i18n value="1">TCG</option>
<option i18n value="2">OCG & TCG</option>
<option i18n value="3">专有卡禁止</option>
</select>
</div>
<div class="form-group">
<label i18n for="game-create-rule">决斗模式</label>
<select class="form-control form-control-sm" id="game-create-mode" name="mode" [(ngModel)]="room.options.mode">
<option i18n value="0">单局模式</option>
<option i18n value="1">比赛模式</option>
<option i18n value="2">TAG</option>
</select>
</div>
<fieldset>
<legend i18n class="col-form-legend">额外选项</legend>
<div class="row">
<label i18n for="game-create-start-lp" class="col-sm-6 col-form-label">初始 LP</label>
<div class="col-sm-6">
<input type="number" value="8000" min="1" max="65536" class="form-control form-control-sm" id="game-create-start-lp" name="start_lp" [(ngModel)]="room.options.start_lp">
</div> </div>
</div> </div>
<div class="form-group row"> <div class="row">
<label i18n for="game-create-rule" class="col-sm-2 form-control-label">卡片允许</label> <label i18n for="game-create-start-hand" class="col-sm-6 col-form-label">初始手牌数</label>
<div class="col-sm-10"> <div class="col-sm-6">
<select class="form-control" id="game-create-rule" name="rule" [(ngModel)]="room.options.rule"> <input type="number" value="5" min="0" max="16" class="form-control form-control-sm" id="game-create-start-hand" name="start_hand" [(ngModel)]="room.options.start_hand">
<option i18n value="0">OCG</option>
<option i18n value="1">TCG</option>
<option i18n value="2">OCG & TCG</option>
<option i18n value="3">专有卡禁止</option>
</select>
</div> </div>
</div> </div>
<div class="form-group row"> <div class="row">
<label for="game-create-mode" i18n class="col-sm-2 form-control-label">决斗模式</label> <label i18n for="game-create-draw-count" class="col-sm-6 col-form-label">每回合抽卡</label>
<div class="col-sm-10"> <div class="col-sm-6">
<select class="form-control" id="game-create-mode" name="mode" [(ngModel)]="room.options.mode"> <input type="number" value="1" min="0" max="16" class="form-control form-control-sm" id="game-create-draw-count" name="draw_count" [(ngModel)]="room.options.draw_count">
<option i18n value="0">单局模式</option>
<option i18n value="1">比赛模式</option>
<option i18n value="2">TAG</option>
</select>
</div> </div>
</div> </div>
<div class="form-group row"> <div>
<label i18n class="col-sm-2 form-control-label">额外选项</label> <input id="enable_priority" name="enable_priority" [(ngModel)]="room.options.enable_priority" type="checkbox">
<div class="col-sm-5"> <label i18n for="enable_priority">旧规则</label>
<div class="row"> </div>
<label i18n for="game-create-start-lp" class="col-sm-6 form-control-label">初始 LP</label> <div>
<div class="col-sm-6"> <input id="no_check_deck" name="no_check_deck" [(ngModel)]="room.options.no_check_deck" type="checkbox">
<input name="start_lp" type="number" value="8000" min="1" max="65536" class="form-control form-control-sm game-create-extra" id="game-create-start-lp" [(ngModel)]="room.options.start_lp"> <label i18n for="no_check_deck">不检查卡组</label>
</div>
</div>
<div class="row">
<label i18n for="game-create-start-hand" class="col-sm-6 form-control-label">初始手牌数</label>
<div class="col-sm-6">
<input name="start_hand" type="number" value="5" min="0" max="16" class="form-control form-control-sm game-create-extra" id="game-create-start-hand" [(ngModel)]="room.options.start_hand">
</div>
</div>
<div class="row">
<label i18n for="game-create-draw-count" class="col-sm-6 form-control-label">每回合抽卡</label>
<div class="col-sm-6">
<input name="draw_count" type="number" value="1" min="0" max="16" class="form-control form-control-sm game-create-extra" id="game-create-draw-count" [(ngModel)]="room.options.draw_count">
</div>
</div>
</div>
<div class="col-sm-5">
<div class="checkbox">
<input id="enable_priority" name="enable_priority" type="checkbox" [(ngModel)]="room.options.enable_priority">
<label i18n for="enable_priority">允许启动效果优先权</label>
</div>
<div class="checkbox">
<input id="no_check_deck" name="no_check_deck" type="checkbox" [(ngModel)]="room.options.no_check_deck">
<label i18n for="no_check_deck">不检查卡组</label>
</div>
<div class="checkbox">
<input id="no_shuffle_deck" name="no_shuffle_deck" type="checkbox" [(ngModel)]="room.options.no_shuffle_deck">
<label for="no_shuffle_deck" i18n>开局不洗卡组</label>
</div>
</div>
</div> </div>
<!--<div class="form-group row">
<label class="col-sm-2">私密房间</label>
<div class="col-sm-10">
<div class="checkbox">
<label>
<input name="private" type="checkbox">不在房间列表中显示 (约战功能还没做好,不要勾
</label>
</div>
</div>
</div>-->
</div>
<div class="modal-footer justify-content-between">
<button i18n type="button" class="btn btn-secondary" data-dismiss="modal" data-toggle="modal" data-target="#game-list-modal">查看房间</button>
<div> <div>
<button i18n type="button" class="btn btn-secondary" data-dismiss="modal">取消</button> <input id="no_shuffle_deck" name="no_shuffle_deck" type="checkbox" [(ngModel)]="room.options.no_shuffle_deck">
<button i18n type="submit" class="btn btn-primary">创建</button> <label i18n for="no_shuffle_deck">不洗切卡组</label>
</div> </div>
</fieldset>
<div id="game-create-actions">
<button i18n type="submit" class="btn btn-sm btn-primary">创建房间</button>
</div> </div>
</form> </form>
<button id="game-list-close" type="button" class="close" data-dismiss="modal" aria-label="Close">
<span aria-hidden="true">&times;</span>
</button>
</div> </div>
</div> </div>
</div><!-- Modal --> </div>
<div class="modal fade" id="game-list-modal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog" role="document">
<div class="modal-content">
<table class="table table-striped table-hover">
<thead class="modal-header">
<tr>
<th i18n class="title">游戏标题</th>
<th i18n class="users">玩家</th>
<th i18n class="mode">决斗模式</th>
<th i18n class="extra">额外选项</th>
</tr>
</thead>
<tbody class="modal-body">
<tr *ngFor="let room of rooms" class="room" (click)="join_room(room)">
<td class="title">{{room.title}}</td> <div class="modal fade" id="game-replay-modal" tabindex="-1" role="dialog" aria-labelledby="exampleModalLabel" aria-hidden="true">
<td class="users"> <div class="modal-dialog modal-lg" role="document">
<img *ngFor="let user of room.users" class="avatar" [src]="'https://ygobbs.com/user_avatar/ygobbs.com/' + user.username + '/25/1.png'" data-toggle="tooltip" data-placement="bottom" [title]="user.username"> <div class="modal-content">
</td> <!--<div class="modal-header">-->
<td class="mode">{{{'0': '单局模式', '1': '比赛模式', '2': 'TAG'}[room.options.mode]}}</td> <!--<h5 class="modal-title" id="exampleModalLabel">Modal title</h5>-->
<td class="extra"> <!--<button type="button" class="close" data-dismiss="modal" aria-label="Close">-->
<span *ngIf="room.options.rule != default_options.rule">{{{'0': 'OCG', '1': 'TCG', '2': 'O/T', '3': '专有卡禁止'}[room.options.rule]}}</span> <!--<span aria-hidden="true">&times;</span>-->
<span i18n *ngIf="room.options.start_lp != default_options.start_lp">{{room.options.start_lp}} LP</span> <!--</button>-->
<span i18n *ngIf="room.options.start_hand != default_options.start_hand">{{room.options.start_hand}} 初始</span> <!--</div>-->
<span i18n *ngIf="room.options.draw_count != default_options.draw_count">{{room.options.draw_count}} 抽卡</span> <div class="modal-body">
<span i18n *ngIf="room.options.enable_priority != default_options.enable_priority">优先权</span> <button type="button" class="close" data-dismiss="modal" aria-label="Close">
<span i18n *ngIf="room.options.no_check_deck != default_options.no_check_deck">不检查</span> <span aria-hidden="true">&times;</span>
<span i18n *ngIf="room.options.no_shuffle_deck != default_options.no_shuffle_deck">不洗卡</span> </button>
</td> <ul class="nav nav-tabs" role="tablist">
</tbody> <!--<li class="nav-item">-->
</table> <!--<a class="nav-link" data-toggle="tab" href="#home" role="tab">推荐</a>-->
<button type="button" class="close" data-dismiss="modal" aria-label="Close"> <!--</li>-->
<span aria-hidden="true">&times;</span> <li class="nav-item">
</button> <a i18n class="nav-link active" data-toggle="tab" href="#game-replay-watch" role="tab">观战</a>
<div class="modal-footer justify-content-between"> </li>
<button i18n type="button" class="btn btn-secondary" data-dismiss="modal" data-toggle="modal" data-target="#game-create-modal">创建房间</button> <!--<li class="nav-item">-->
<button i18n type="button" class="btn btn-secondary" data-dismiss="modal">取消</button> <!--<a class="nav-link" data-toggle="tab" href="#home" role="tab">收藏的录像</a>-->
<!--</li>-->
<li class="nav-item">
<a i18n class="nav-link" data-toggle="tab" href="#game-replay-local" role="tab">本地录像</a>
</li>
<li *ngIf="settingsService.getLocale().startsWith('zh')" class="nav-item">
<a class="nav-link" data-toggle="tab" href="#game-replay-bilibili" role="tab">哔哩哔哩</a>
</li>
<!--<li class="nav-item">-->
<!--<a class="nav-link" data-toggle="tab" href="#game-replay-youtube" role="tab">YouTube</a>-->
<!--</li>-->
</ul>
<div class="tab-content">
<div class="tab-pane active" id="game-replay-watch" role="tabpanel">
<table class="table table-striped table-hover">
<thead>
<tr>
<th i18n class="title">游戏模式</th>
<th i18n class="users">游戏标题</th>
<th i18n class="mode">玩家</th>
<th i18n class="extra">详情</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let room of replay_rooms" class="room" (click)="join_room(room)">
<td class="mode">
<span i18n *ngIf="room.arena === 'athletic'">竞技匹配</span>
<span i18n *ngIf="room.arena === 'entertain'">娱乐匹配</span>
<span i18n *ngIf="!room.arena && room.options.mode === 0">单局模式</span>
<span i18n *ngIf="!room.arena && room.options.mode === 1">比赛模式</span>
<span i18n *ngIf="!room.arena && room.options.mode === 2">TAG</span>
</td>
<td class="title">
<span i18n *ngIf="room.arena">{{room.users[0] && room.users[0].username}} 跟 {{room.users[1] && room.users[1].username}} 的决斗</span>
<span *ngIf="!room.arena">{{room.title}}</span>
</td>
<td class="users">
<img *ngFor="let user of room.users" class="avatar rounded" [src]="'https://ygobbs.com/user_avatar/ygobbs.com/' + user.username + '/25/1.png'" data-toggle="tooltip" data-placement="bottom" [title]="user.username">
</td>
<td class="extra">
<span *ngIf="room.options.rule != default_options.rule">{{{'0': 'OCG', '1': 'TCG', '2': 'O/T', '3': '专有卡禁止'}[room.options.rule]}}</span>
<span i18n *ngIf="room.options.start_lp != default_options.start_lp">{{room.options.start_lp}} LP</span>
<span i18n *ngIf="room.options.start_hand != default_options.start_hand">{{room.options.start_hand}} 初始</span>
<span i18n *ngIf="room.options.draw_count != default_options.draw_count">{{room.options.draw_count}} 抽卡</span>
<span i18n *ngIf="room.options.enable_priority != default_options.enable_priority">旧规则</span>
<span i18n *ngIf="room.options.no_check_deck != default_options.no_check_deck">不检查</span>
<span i18n *ngIf="room.options.no_shuffle_deck != default_options.no_shuffle_deck">不洗卡</span>
</td>
</tr>
</tbody>
</table>
</div>
<div class="tab-pane" id="game-replay-local" role="tabpanel">
<div class="list-group">
<a *ngFor="let replay of replays" class="list-group-item list-group-item-action" (click)="watch_replay(replay)">{{replay}}</a>
</div>
</div>
<div *ngIf="settingsService.getLocale().startsWith('zh')" class="tab-pane" id="game-replay-bilibili" role="tabpanel">
<webview #bilibili src="http://m.bilibili.com/search.html?keyword=YGOPro" (did-finish-load)="bilibili_loaded()" (will-navigate)="bilibili_navigate($event)"></webview>
</div>
<!--<div class="tab-pane" id="game-replay-youtube" role="tabpanel">-->
<!--<webview #youtube src="https://m.youtube.com/results?search_query=YGOPro" (did-finish-load)="youtube_loaded()" (will-navigate)="youtube_navigate($event)"></webview>-->
<!--</div>-->
</div>
</div> </div>
<!--<div class="modal-footer">-->
<!--<button type="button" class="btn btn-secondary" data-dismiss="modal">Close</button>-->
<!--&lt;!&ndash;<button type="button" class="btn btn-primary">Save changes</button>&ndash;&gt;-->
<!--</div>-->
</div> </div>
</div> </div>
</div> </div>
\ No newline at end of file
/** /**
* Created by zh99998 on 16/9/2. * Created by zh99998 on 16/9/2.
*/ */
import {Component, OnInit, ChangeDetectorRef, Input, EventEmitter, Output, OnDestroy} from '@angular/core'; import {
Component,
OnInit,
ChangeDetectorRef,
Input,
EventEmitter,
Output,
OnDestroy,
ViewChild,
ElementRef
} from '@angular/core';
import * as fs from 'fs'; import * as fs from 'fs';
import * as path from 'path'; import * as path from 'path';
import * as child_process from 'child_process'; import * as child_process from 'child_process';
import {remote} from 'electron'; import {remote, shell} from 'electron';
import * as ini from 'ini'; import * as ini from 'ini';
import {EncodeOptions} from 'ini'; import {EncodeOptions} from 'ini';
import {LoginService} from './login.service'; import {LoginService} from './login.service';
...@@ -17,6 +27,7 @@ import {AppsService} from './apps.service'; ...@@ -17,6 +27,7 @@ import {AppsService} from './apps.service';
import {SettingsService} from './settings.sevices'; import {SettingsService} from './settings.sevices';
import * as $ from 'jquery'; import * as $ from 'jquery';
import Timer = NodeJS.Timer; import Timer = NodeJS.Timer;
import WillNavigateEvent = Electron.WebViewElement.WillNavigateEvent;
interface SystemConf { interface SystemConf {
use_d3d: string; use_d3d: string;
...@@ -50,6 +61,8 @@ interface Server { ...@@ -50,6 +61,8 @@ interface Server {
url?: string; url?: string;
address: string; address: string;
port: number; port: number;
custom?: boolean;
replay?: boolean;
} }
interface Room { interface Room {
...@@ -58,6 +71,8 @@ interface Room { ...@@ -58,6 +71,8 @@ interface Room {
server?: Server; server?: Server;
private?: boolean; private?: boolean;
options: Options; options: Options;
arena?: string;
users?: {username: string, position: number}[];
} }
interface Options { interface Options {
...@@ -108,10 +123,17 @@ export class YGOProComponent implements OnInit, OnDestroy { ...@@ -108,10 +123,17 @@ export class YGOProComponent implements OnInit, OnDestroy {
@Output() @Output()
points: EventEmitter<Points> = new EventEmitter(); points: EventEmitter<Points> = new EventEmitter();
decks: string[] = []; decks: string[] = [];
replays: string[] = [];
current_deck: string; current_deck: string;
system_conf: string; system_conf: string;
numfont: string[]; numfont: string[];
textfont: string[]; textfont: string[];
@ViewChild('bilibili')
bilibili: ElementRef;
@ViewChild('youtube')
youtube: ElementRef;
// points: Points; // points: Points;
windbot: string[]; // ["琪露诺", "谜之剑士LV4", "复制植物", "尼亚"]; windbot: string[]; // ["琪露诺", "谜之剑士LV4", "复制植物", "尼亚"];
...@@ -137,6 +159,8 @@ export class YGOProComponent implements OnInit, OnDestroy { ...@@ -137,6 +159,8 @@ export class YGOProComponent implements OnInit, OnDestroy {
rooms: Room[] = []; rooms: Room[] = [];
connections: WebSocket[] = []; connections: WebSocket[] = [];
replay_connections: WebSocket[] = [];
replay_rooms: Room[] = [];
matching: ISubscription | undefined; matching: ISubscription | undefined;
matching_arena: string | undefined; matching_arena: string | undefined;
...@@ -145,7 +169,7 @@ export class YGOProComponent implements OnInit, OnDestroy { ...@@ -145,7 +169,7 @@ export class YGOProComponent implements OnInit, OnDestroy {
match_interval: Timer | undefined; match_interval: Timer | undefined;
constructor (private http: Http, private appsService: AppsService, private loginService: LoginService, constructor (private http: Http, private appsService: AppsService, private loginService: LoginService,
private settingsService: SettingsService, private ref: ChangeDetectorRef) { public settingsService: SettingsService, private ref: ChangeDetectorRef) {
switch (process.platform) { switch (process.platform) {
case 'darwin': case 'darwin':
this.numfont = ['/System/Library/Fonts/SFNSTextCondensed-Bold.otf']; this.numfont = ['/System/Library/Fonts/SFNSTextCondensed-Bold.otf'];
...@@ -175,17 +199,34 @@ export class YGOProComponent implements OnInit, OnDestroy { ...@@ -175,17 +199,34 @@ export class YGOProComponent implements OnInit, OnDestroy {
id: 'tiramisu', id: 'tiramisu',
url: 'wss://tiramisu.mycard.moe:7923', url: 'wss://tiramisu.mycard.moe:7923',
address: '112.124.105.11', address: '112.124.105.11',
port: 7911 port: 7911,
custom: true,
replay: true
}, {
id: 'tiramisu-athletic',
url: 'wss://tiramisu.mycard.moe:8923',
address: '112.124.105.11',
port: 8911,
custom: false,
replay: true
}); });
} else { } else {
this.servers.push({ this.servers.push({
id: 'mercury-us-1-athletic',
url: 'wss://mercury-us-1.mycard.moe:7923',
address: '104.237.154.173',
port: 7911,
custom: true,
replay: true
}, {
id: 'mercury-us-1', id: 'mercury-us-1',
url: 'wss://mercury-us-1.mycard.moe:7923', url: 'wss://mercury-us-1.mycard.moe:7923',
address: '104.237.154.173', address: '104.237.154.173',
port: 7911 port: 8911,
custom: false,
replay: true
}); });
} }
} }
async ngOnInit () { async ngOnInit () {
...@@ -204,8 +245,10 @@ export class YGOProComponent implements OnInit, OnDestroy { ...@@ -204,8 +245,10 @@ export class YGOProComponent implements OnInit, OnDestroy {
let modal = $('#game-list-modal'); let modal = $('#game-list-modal');
modal.on('show.bs.modal', () => { modal.on('show.bs.modal', () => {
this.connections = this.servers.map((server) => { this.connections = this.servers.filter(server => server.custom).map((server) => {
let connection = new WebSocket(server.url!); let url = new URL(server.url!);
url['searchParams'].set('filter', 'waiting');
let connection = new WebSocket(url.toString());
connection.onclose = () => { connection.onclose = () => {
this.rooms = this.rooms.filter(room => room.server !== server); this.rooms = this.rooms.filter(room => room.server !== server);
}; };
...@@ -232,30 +275,67 @@ export class YGOProComponent implements OnInit, OnDestroy { ...@@ -232,30 +275,67 @@ export class YGOProComponent implements OnInit, OnDestroy {
}); });
}); });
modal.on('shown.bs.modal', () => { modal.on('hide.bs.modal', () => {
$('td.users').tooltip({ for (let connection of this.connections) {
selector: '[data-toggle=tooltip]' connection.close();
}
this.connections = [];
});
// TODO: 跟上面的逻辑合并
let replay_modal = $('#game-replay-modal');
replay_modal.on('show.bs.modal', () => {
this.replay_connections = this.servers.filter(server => server.replay).map((server) => {
let url = new URL(server.url!);
url['searchParams'].set('filter', 'started');
let connection = new WebSocket(url.toString());
connection.onclose = () => {
this.replay_rooms = this.replay_rooms.filter(room => room.server !== server);
};
connection.onmessage = (event) => {
let message = JSON.parse(event.data);
switch (message.event) {
case 'init':
this.replay_rooms = this.replay_rooms.filter(room => room.server !== server).concat(
message.data.map((room: Room) => Object.assign({server: server}, room))
);
break;
case 'create':
this.replay_rooms.push(Object.assign({server: server}, message.data));
break;
// case 'update':
// Object.assign(this.replay_rooms.find(room => room.server === server && room.id === message.data.id), message.data);
// break;
case 'delete':
this.replay_rooms.splice(this.replay_rooms.findIndex(room => room.server === server && room.id === message.data), 1);
}
this.ref.detectChanges();
};
return connection;
}); });
}); });
modal.on('hide.bs.modal', () => { modal.on('hide.bs.modal', () => {
for (let connection of this.connections) { for (let connection of this.replay_connections) {
connection.close(); connection.close();
} }
this.connections = []; this.replay_connections = [];
}); });
} }
async refresh () { async refresh () {
let decks = await this.get_decks(); this.decks = await this.get_decks();
this.decks = decks;
let system_conf = await this.load_system_conf(); let system_conf = await this.load_system_conf();
if (this.decks.includes(system_conf.lastdeck)) { if (this.decks.includes(system_conf.lastdeck)) {
this.current_deck = system_conf.lastdeck; this.current_deck = system_conf.lastdeck;
} else { } else {
this.current_deck = decks[0]; this.current_deck = this.decks[0];
} }
this.replays = await this.get_replays();
// https://mycard.moe/ygopro/api/user?username=ozxdno // https://mycard.moe/ygopro/api/user?username=ozxdno
let params = new URLSearchParams(); let params = new URLSearchParams();
params.set('username', this.loginService.user.username); params.set('username', this.loginService.user.username);
...@@ -281,6 +361,18 @@ export class YGOProComponent implements OnInit, OnDestroy { ...@@ -281,6 +361,18 @@ export class YGOProComponent implements OnInit, OnDestroy {
}); });
} }
get_replays (): Promise<string[]> {
return new Promise((resolve, reject) => {
fs.readdir(path.join(this.app.local!.path, 'replay'), (error, files) => {
if (error) {
resolve([]);
} else {
resolve(files.filter(file => path.extname(file) === '.yrp').map(file => path.basename(file, '.yrp')));
}
});
});
}
async get_font (files: string[]): Promise<string | undefined> { async get_font (files: string[]): Promise<string | undefined> {
for (let file of files) { for (let file of files) {
let found = await new Promise((resolve) => fs.access(file, fs.constants.R_OK, error => resolve(!error))); let found = await new Promise((resolve) => fs.access(file, fs.constants.R_OK, error => resolve(!error)));
...@@ -356,6 +448,13 @@ export class YGOProComponent implements OnInit, OnDestroy { ...@@ -356,6 +448,13 @@ export class YGOProComponent implements OnInit, OnDestroy {
return this.start_game(['-d']); return this.start_game(['-d']);
} }
async watch_replay (replay: string) {
let system_conf = await this.load_system_conf();
await this.fix_fonts(system_conf);
await this.save_system_conf(system_conf);
return this.start_game(['-r', path.join('replay', replay + '.yrp')]);
}
join_windbot (name: string) { join_windbot (name: string) {
return this.join('AI#' + name, this.servers[0]); return this.join('AI#' + name, this.servers[0]);
} }
...@@ -485,4 +584,38 @@ export class YGOProComponent implements OnInit, OnDestroy { ...@@ -485,4 +584,38 @@ export class YGOProComponent implements OnInit, OnDestroy {
this.match_time = new Date().getTime() - match_started_at.getTime(); this.match_time = new Date().getTime() - match_started_at.getTime();
this.match_cancelable = this.match_time <= 5000 || this.match_time >= 180000; this.match_cancelable = this.match_time <= 5000 || this.match_time >= 180000;
} }
bilibili_loaded () {
this.bilibili.nativeElement.insertCSS(`
#b_app_link {
visibility: hidden;
}
.wrapper {
padding-top: 0 !important;
overflow-y: hidden;
}
.nav-bar, .top-title, .roll-bar, footer {
display: none !important;
}
html, body {
background-color: initial !important;
}
`);
}
bilibili_navigate (event: WillNavigateEvent) {
// event.preventDefault();
// https://github.com/electron/electron/issues/1378
this.bilibili.nativeElement.src = 'http://m.bilibili.com/search.html?keyword=YGOPro';
shell.openExternal(event.url);
}
// youtube_loaded () {
//
// }
//
// youtube_navigate (event: WillNavigateEvent) {
// this.youtube.nativeElement.src = 'https://m.youtube.com/results?search_query=YGOPro';
// shell.openExternal(event.url);
// }
} }
...@@ -143,7 +143,7 @@ function createWindow() { ...@@ -143,7 +143,7 @@ function createWindow() {
minWidth: 1024, minWidth: 1024,
minHeight: 640, minHeight: 640,
frame: process.platform == 'darwin', frame: process.platform == 'darwin',
transparent: process.platform != 'darwin', // transparent: process.platform != 'darwin',
titleBarStyle: process.platform == 'darwin' ? 'hidden' : null titleBarStyle: process.platform == 'darwin' ? 'hidden' : null
}); });
......
...@@ -5,11 +5,6 @@ ...@@ -5,11 +5,6 @@
<source>竞技匹配</source> <source>竞技匹配</source>
<target>Ranked Match</target> <target>Ranked Match</target>
</trans-unit>
<trans-unit datatype="html" id="37869c115276c5df476f1f5aae75c099ffb35b59">
<source>取消等待</source>
<target>Cancel</target>
</trans-unit> </trans-unit>
<trans-unit datatype="html" id="0bf938a69dc640aba46428d1cbbd2fef34c88daa"> <trans-unit datatype="html" id="0bf938a69dc640aba46428d1cbbd2fef34c88daa">
<source>娱乐匹配</source> <source>娱乐匹配</source>
...@@ -24,8 +19,23 @@ ...@@ -24,8 +19,23 @@
<trans-unit datatype="html" id="3768b60a7e2625bb1fc2db37eb8c6b8e4bd99101"> <trans-unit datatype="html" id="3768b60a7e2625bb1fc2db37eb8c6b8e4bd99101">
<source>单人模式</source> <source>单人模式</source>
<target>Single Mode</target> <target>Single Mode</target>
</trans-unit> </trans-unit>
<trans-unit datatype="html" id="4115bf4e35def25bcfa6d4e649f5e006225c691a">
<source>观战和录像</source>
<target>Watch Replay</target>
</trans-unit>
<trans-unit datatype="html" id="157bc28ebe7ecf3f455852f64687ea580dfe23dc">
<source>预计时间</source>
<target>Estimated Wait</target>
</trans-unit>
<trans-unit datatype="html" id="6968a638448b1f36c52a3b306541214acbf9d567">
<source>实际时间</source>
<target>Actual Wait</target>
</trans-unit>
<trans-unit datatype="html" id="def237147323023c1f5ce0579345da19d4707fdb"> <trans-unit datatype="html" id="def237147323023c1f5ce0579345da19d4707fdb">
<source>卡组</source> <source>卡组</source>
<target>Deck</target> <target>Deck</target>
...@@ -45,46 +55,26 @@ ...@@ -45,46 +55,26 @@
<source>取消</source> <source>取消</source>
<target>Cancel</target> <target>Cancel</target>
</trans-unit>
<trans-unit datatype="html" id="19923836b1ae79614782426a7a001d8ccfa27b5c">
<source>创建房间</source>
<target>Custom Game</target>
</trans-unit> </trans-unit>
<trans-unit datatype="html" id="e35d1bf7c735e8df55a62046cd2d9f820bf5bffd"> <trans-unit datatype="html" id="e35d1bf7c735e8df55a62046cd2d9f820bf5bffd">
<source>游戏标题</source> <source>游戏标题</source>
<target>Title</target> <target>Title</target>
</trans-unit> </trans-unit>
<trans-unit datatype="html" id="4b911deaa4defd0803635012281f3dd1112aabd1"> <trans-unit datatype="html" id="3872a823a98042e4730861ab6f9344239d9deeb6">
<source>卡片允许</source> <source>玩家</source>
<target>Rule</target> <target>Player</target>
</trans-unit>
<trans-unit datatype="html" id="93d3b6bb4f3a66efd8c49f9063f6c8d6a9e959bf">
<source>OCG</source>
<target>OCG</target>
</trans-unit>
<trans-unit datatype="html" id="150cb34526cf737163beb63ab76e4809ac1367dd">
<source>TCG</source>
<target>TCG</target>
</trans-unit>
<trans-unit datatype="html" id="be6d109c359b1d11b261280915e6b1706ca3ed9b">
<source>OCG &amp; TCG</source>
<target>TCG/OCG</target>
</trans-unit>
<trans-unit datatype="html" id="2a3f48f9ea5e6aae92e249ac2b279dbc07a6127d">
<source>专有卡禁止</source>
<target>Unspecified</target>
</trans-unit> </trans-unit>
<trans-unit datatype="html" id="d62a2717a0381d996785271c61177711777ba63c"> <trans-unit datatype="html" id="d62a2717a0381d996785271c61177711777ba63c">
<source>决斗模式</source> <source>决斗模式</source>
<target>Duel mode</target> <target>Duel mode</target>
</trans-unit>
<trans-unit datatype="html" id="d4038dd5d0e9d5139d425fc7bea40e40d965cc5b">
<source>额外选项</source>
<target>Additional Options</target>
</trans-unit> </trans-unit>
<trans-unit datatype="html" id="e436a4a0da03320dc61ba35bfab390ab85a23d0c"> <trans-unit datatype="html" id="e436a4a0da03320dc61ba35bfab390ab85a23d0c">
<source>单局模式</source> <source>单局模式</source>
...@@ -100,56 +90,6 @@ ...@@ -100,56 +90,6 @@
<source>TAG</source> <source>TAG</source>
<target>TAG</target> <target>TAG</target>
</trans-unit>
<trans-unit datatype="html" id="d4038dd5d0e9d5139d425fc7bea40e40d965cc5b">
<source>额外选项</source>
<target>Additional Options</target>
</trans-unit>
<trans-unit datatype="html" id="01cfbee3f1d69f5adae299b7b8c8d75034aef53b">
<source>初始 LP</source>
<target>Starting LP</target>
</trans-unit>
<trans-unit datatype="html" id="0d72e50857f1d2504e08f7886d4c9d35a46e3ed9">
<source>初始手牌数</source>
<target>Starting Hand</target>
</trans-unit>
<trans-unit datatype="html" id="88cc5676c5322fd55c1df94ab487359100e6f9dd">
<source>每回合抽卡</source>
<target>Draw per Turn</target>
</trans-unit>
<trans-unit datatype="html" id="e405d8c7feb2bed82f3f0667657fa4ab668ae015">
<source>允许启动效果优先权</source>
<target>Ignition Priority</target>
</trans-unit>
<trans-unit datatype="html" id="6e7470ddf4c35f6fab39b6ebeadb1780701a5469">
<source>不检查卡组</source>
<target>Don't check</target>
</trans-unit>
<trans-unit datatype="html" id="0320acff078b039f2220bb385586cd2e24392bbb">
<source>开局不洗卡组</source>
<target>Don't shuffle</target>
</trans-unit>
<trans-unit datatype="html" id="c17e9385db80e1881f37dda25d109b115a2843b3">
<source>查看房间</source>
<target>View rooms</target>
</trans-unit>
<trans-unit datatype="html" id="f8ae23b4314929573cf0e815ccc12d70486dd74f">
<source>创建</source>
<target>Create</target>
</trans-unit>
<trans-unit datatype="html" id="3872a823a98042e4730861ab6f9344239d9deeb6">
<source>玩家</source>
<target>Player</target>
</trans-unit> </trans-unit>
<trans-unit datatype="html" id="8514a93609dc67a44e5b198b53e42fe468f8a81a"> <trans-unit datatype="html" id="8514a93609dc67a44e5b198b53e42fe468f8a81a">
<source> <source>
...@@ -184,9 +124,9 @@ ...@@ -184,9 +124,9 @@
</target> </target>
</trans-unit> </trans-unit>
<trans-unit datatype="html" id="be32d8fb22f36c3b2c1530e91f2ca07d108c8abe"> <trans-unit datatype="html" id="785cc65c8db99887484b3b1067c45b32810c7c2a">
<source>优先权</source> <source>旧规则</source>
<target>Priority</target> <target>Old rules</target>
</trans-unit> </trans-unit>
<trans-unit datatype="html" id="b5be173f96718dfa737f1da31d9ffab5b803561e"> <trans-unit datatype="html" id="b5be173f96718dfa737f1da31d9ffab5b803561e">
...@@ -197,6 +137,95 @@ ...@@ -197,6 +137,95 @@
<trans-unit datatype="html" id="517c8b6e5361bc32d7458a1e8b2bdbf09abb6f01"> <trans-unit datatype="html" id="517c8b6e5361bc32d7458a1e8b2bdbf09abb6f01">
<source>不洗卡</source> <source>不洗卡</source>
<target>Don't shuffle</target> <target>Don't shuffle</target>
</trans-unit>
<trans-unit datatype="html" id="19923836b1ae79614782426a7a001d8ccfa27b5c">
<source>创建房间</source>
<target>Create</target>
</trans-unit>
<trans-unit datatype="html" id="4b911deaa4defd0803635012281f3dd1112aabd1">
<source>卡片允许</source>
<target>Rule</target>
</trans-unit>
<trans-unit datatype="html" id="93d3b6bb4f3a66efd8c49f9063f6c8d6a9e959bf">
<source>OCG</source>
<target>OCG</target>
</trans-unit>
<trans-unit datatype="html" id="150cb34526cf737163beb63ab76e4809ac1367dd">
<source>TCG</source>
<target>TCG</target>
</trans-unit>
<trans-unit datatype="html" id="be6d109c359b1d11b261280915e6b1706ca3ed9b">
<source>OCG &amp; TCG</source>
<target>TCG/OCG</target>
</trans-unit>
<trans-unit datatype="html" id="2a3f48f9ea5e6aae92e249ac2b279dbc07a6127d">
<source>专有卡禁止</source>
<target>Unspecified</target>
</trans-unit>
<trans-unit datatype="html" id="01cfbee3f1d69f5adae299b7b8c8d75034aef53b">
<source>初始 LP</source>
<target>Starting LP</target>
</trans-unit>
<trans-unit datatype="html" id="0d72e50857f1d2504e08f7886d4c9d35a46e3ed9">
<source>初始手牌数</source>
<target>Starting Hand</target>
</trans-unit>
<trans-unit datatype="html" id="88cc5676c5322fd55c1df94ab487359100e6f9dd">
<source>每回合抽卡</source>
<target>Draw / Turn</target>
</trans-unit>
<trans-unit datatype="html" id="6e7470ddf4c35f6fab39b6ebeadb1780701a5469">
<source>不检查卡组</source>
<target>Don't check</target>
</trans-unit>
<trans-unit datatype="html" id="4f104c680937cb724b069f62ab1ff60651c5bb06">
<source>不洗切卡组</source>
<target>Don't shuffle</target>
</trans-unit>
<trans-unit datatype="html" id="84276d07f694b80bd5ea94d28283b6530248d02e">
<source>观战</source>
<target>Live</target>
</trans-unit>
<trans-unit datatype="html" id="d516b78557483a84288359494abde950d3887518">
<source>本地录像</source>
<target>Local</target>
</trans-unit>
<trans-unit datatype="html" id="7047116f06b2fcb5e7f8e8589d1ef31628aff0fa">
<source>游戏模式</source>
<target>Game Mode</target>
</trans-unit>
<trans-unit datatype="html" id="08afd8197e09842de9d76741588c6c1bcd3e2605">
<source>详情</source>
<target>Detail</target>
</trans-unit>
<trans-unit datatype="html" id="5136f852d874c46bf808987470980a0f2560487e">
<source>
<x id="INTERPOLATION"/>
<x id="INTERPOLATION_1"/>
的决斗
</source>
<target>
<x id="INTERPOLATION"/>
Vs.
<x id="INTERPOLATION_1"/>
</target>
</trans-unit> </trans-unit>
<trans-unit datatype="html" id="a8cae935472a05e1c8c9be436bb7b1bdea96a54a"> <trans-unit datatype="html" id="a8cae935472a05e1c8c9be436bb7b1bdea96a54a">
...@@ -416,7 +445,7 @@ ...@@ -416,7 +445,7 @@
</trans-unit> </trans-unit>
<trans-unit datatype="html" id="69f3fab778e92fcec3a8c38d53d771a36e6d5230"> <trans-unit datatype="html" id="69f3fab778e92fcec3a8c38d53d771a36e6d5230">
<source>推荐</source> <source>推荐</source>
<target>Recommend</target> <target>Recommended</target>
</trans-unit> </trans-unit>
<trans-unit datatype="html" id="fc570ecca13755cb4a92e7513fbd55c2d412f23c"> <trans-unit datatype="html" id="fc570ecca13755cb4a92e7513fbd55c2d412f23c">
......
{ {
"name": "mycard", "name": "mycard",
"version": "3.0.17", "version": "3.0.18",
"description": "mycard", "description": "mycard",
"keywords": [], "keywords": [],
"author": "zh99998 <zh99998@gmail.com>", "author": "zh99998 <zh99998@gmail.com>",
......
html, body { html, body {
height: 100%; height: 100%;
overflow: hidden; /*overflow: hidden;*/
} }
body { body {
...@@ -8,12 +8,12 @@ body { ...@@ -8,12 +8,12 @@ body {
-webkit-user-select: none; -webkit-user-select: none;
} }
body.win32 { /*body.win32 {*/
background: transparent; /*background: transparent;*/
border-radius: 5px; /*border-radius: 5px;*/
border: 1px solid #eee; /*border: 1px solid #eee;*/
padding-right: 0 !important; /*padding-right: 0 !important;*/
} /*}*/
mycard { mycard {
height: 100%; height: 100%;
...@@ -94,6 +94,10 @@ body.resizing /deep/ * { ...@@ -94,6 +94,10 @@ body.resizing /deep/ * {
-webkit-user-select: none; -webkit-user-select: none;
} }
mycard { /*mycard {*/
background-color: white; /*background-color: white;*/
} /*}*/
\ No newline at end of file
/*button, input, optgroup, select, textarea {*/
/*font-family: inherit;*/
/*}*/
\ No newline at end of file
...@@ -77,7 +77,7 @@ System.config({ ...@@ -77,7 +77,7 @@ System.config({
'jquery': 'npm:jquery/dist/jquery.min.js', 'jquery': 'npm:jquery/dist/jquery.min.js',
'tether': 'npm:tether/dist/js/tether.min.js', 'tether': 'npm:tether/dist/js/tether.min.js',
'bootstrap': 'npm:bootstrap/dist/js/bootstrap.min.js', 'bootstrap': 'npm:bootstrap/dist/js/bootstrap.min.js',
'typeahead.js': '@node/typeahead.js' // 'typeahead.js': '@node/typeahead.js'
}, },
// packages tells the System loader how to load when no filename and/or no extension // packages tells the System loader how to load when no filename and/or no extension
packages: { packages: {
......
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