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

观战筛选和排序

parent f4c56ba2
......@@ -15,4 +15,5 @@
.DS_Store
Thumbs.db
messages.xlf
messages.xlf.bak
\ No newline at end of file
messages.xlf.bak
locale/*.xlf.bak
\ No newline at end of file
......@@ -185,7 +185,7 @@ form {
}
#game-replay-watch {
max-height: 500px;
height: 500px;
}
#game-replay-watch table {
......@@ -196,3 +196,13 @@ form {
width: 18px;
height: 18px;
}
#watch-filter {
display: inline-block;
}
#watch-filter .dropdown-item {
font-size: .875rem;
}
#watch-filter .form-check-input {
margin-left: inherit;
}
\ No newline at end of file
......@@ -200,36 +200,75 @@
<table class="table table-striped table-hover">
<thead>
<tr>
<th i18n class="title">游戏模式</th>
<th class="title">
<span i18n>游戏模式</span>
<div id="watch-filter" class="dropdown">
<button class="btn btn-secondary dropdown-toggle btn-sm" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
筛选
</button>
<div class="dropdown-menu">
<h6 i18n class="dropdown-header">匹配</h6>
<div class="form-check dropdown-item">
<input id="filter-athletic" type="checkbox" class="form-check-input" [(ngModel)]="replay_rooms_filter.athletic" (change)="refresh_replay_rooms()">
<label i18n for="filter-athletic" class="form-check-label">竞技匹配</label>
</div>
<div class="form-check dropdown-item">
<input id="filter-entertain" type="checkbox" class="form-check-input" [(ngModel)]="replay_rooms_filter.entertain" (change)="refresh_replay_rooms()">
<label i18n for="filter-entertain" class="form-check-label">娱乐匹配</label>
</div>
<h6 i18n class="dropdown-header">自定义游戏</h6>
<div class="form-check dropdown-item">
<input id="filter-single" type="checkbox" class="form-check-input" [(ngModel)]="replay_rooms_filter.single" (change)="refresh_replay_rooms()">
<label i18n for="filter-single" class="form-check-label">单局模式</label>
</div>
<div class="form-check dropdown-item">
<input id="filter-match" type="checkbox" class="form-check-input" [(ngModel)]="replay_rooms_filter.match" (change)="refresh_replay_rooms()">
<label i18n for="filter-match" class="form-check-label">比赛模式</label>
</div>
<div class="form-check dropdown-item">
<input id="filter-tag" type="checkbox" class="form-check-input" [(ngModel)]="replay_rooms_filter.tag" (change)="refresh_replay_rooms()">
<label i18n for="filter-tag" class="form-check-label">TAG</label>
</div>
<h6 i18n class="dropdown-header">单人模式</h6>
<div class="form-check dropdown-item">
<input id="filter-windbot" type="checkbox" class="form-check-input" [(ngModel)]="replay_rooms_filter.windbot" (change)="refresh_replay_rooms()">
<label i18n for="filter-windbot" class="form-check-label">单人模式</label>
</div>
</div>
</div>
</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)">
<tr *ngFor="let room of replay_rooms_show" class="room" (click)="join_room(room)">
<td class="mode">
<span i18n *ngIf="room.id.startsWith('AI#')">单人模式</span>
<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>
<span i18n *ngIf="!(room.arena || room.id.startsWith('AI#')) && room.options.mode === 0">单局模式</span>
<span i18n *ngIf="!(room.arena || room.id.startsWith('AI#')) && room.options.mode === 1">比赛模式</span>
<span i18n *ngIf="!(room.arena || room.id.startsWith('AI#')) && 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>
<span i18n *ngIf="room.arena || room.id.startsWith('AI#')">{{room.users[0] && room.users[0].username}} 跟 {{room.users[1] && room.users[1].username}} 的决斗</span>
<span *ngIf="!(room.arena || room.id.startsWith('AI#'))">{{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>
<span *ngIf="!(room.arena || room.id.startsWith('AI#'))">
<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>
</span>
</td>
</tr>
</tbody>
......
......@@ -161,6 +161,15 @@ export class YGOProComponent implements OnInit, OnDestroy {
connections: WebSocket[] = [];
replay_connections: WebSocket[] = [];
replay_rooms: Room[] = [];
replay_rooms_show: Room[];
replay_rooms_filter = {
athletic: true,
entertain: true,
single: true,
match: true,
tag: true,
windbot: false
};
matching: ISubscription | undefined;
matching_arena: string | undefined;
......@@ -229,6 +238,35 @@ export class YGOProComponent implements OnInit, OnDestroy {
}
}
refresh_replay_rooms() {
this.replay_rooms_show = this.replay_rooms.filter((room) => {
return ((this.replay_rooms_filter.athletic && room.arena === 'athletic') ||
(this.replay_rooms_filter.entertain && room.arena === 'entertain') ||
(this.replay_rooms_filter.single && room.options.mode === 0 && !room.arena && !room.id!.startsWith('AI#')) ||
(this.replay_rooms_filter.match && room.options.mode === 1 && !room.arena && !room.id!.startsWith('AI#')) ||
(this.replay_rooms_filter.tag && room.options.mode === 2 && !room.arena && !room.id!.startsWith('AI#')) ||
(this.replay_rooms_filter.windbot && room.id!.startsWith('AI#')));
}).sort((a, b) => {
// if (a.arena === 'athletic' && b.arena === 'athletic') {
// return a.dp - b.dp;
// } else if (a.arena === 'entertain' && b.arena === 'entertain') {
// return a.exp - b.exp;
// }
let [a_priority, b_priority] = [a, b].map((room) => {
if (room.arena === 'athletic') {
return 0;
} else if (room.arena === 'entertain') {
return 1;
} else if (room.id!.startsWith('AI#')) {
return 5;
} else {
return room.options.mode + 2;
}
});
return a_priority - b_priority;
});
}
async ngOnInit() {
let locale: string;
......@@ -292,6 +330,7 @@ export class YGOProComponent implements OnInit, OnDestroy {
let connection = new WebSocket(url.toString());
connection.onclose = () => {
this.replay_rooms = this.replay_rooms.filter(room => room.server !== server);
this.refresh_replay_rooms();
};
connection.onmessage = (event) => {
let message = JSON.parse(event.data);
......@@ -310,6 +349,7 @@ export class YGOProComponent implements OnInit, OnDestroy {
1
);
}
this.refresh_replay_rooms();
this.ref.detectChanges();
};
return connection;
......@@ -324,6 +364,7 @@ export class YGOProComponent implements OnInit, OnDestroy {
});
}
async refresh() {
this.decks = await this.get_decks();
let system_conf = await this.load_system_conf();
......
......@@ -147,7 +147,7 @@
</trans-unit>
<trans-unit datatype="html" id="be6d109c359b1d11b261280915e6b1706ca3ed9b">
<source>OCG &amp; TCG</source>
<source>OCG & TCG</source>
<target>TCG/OCG</target>
</trans-unit>
......@@ -195,6 +195,11 @@
<source>游戏模式</source>
<target>Game Mode</target>
</trans-unit>
<trans-unit datatype="html" id="968e4d8a0f7b5eaaa1d588a738abdaa0ec389d16">
<source>匹配</source>
<target>Matchmaking</target>
</trans-unit>
<trans-unit datatype="html" id="08afd8197e09842de9d76741588c6c1bcd3e2605">
<source>详情</source>
......@@ -478,4 +483,4 @@
</trans-unit>
</body>
</file>
</xliff>
\ No newline at end of file
</xliff>
......@@ -14,7 +14,9 @@
"dist": "tsc && build",
"build:aot": "ngc -p tsconfig-aot.json && rollup -c rollup-config.js",
"tsc": "tsc",
"i18n": "ng-xi18n && sed -i.bak 's/source-language=\"en\"/source-language=\"zh-CN\"/' messages.xlf"
"i18n": "ng-xi18n && sed -i.bak 's/source-language=\"en\"/source-language=\"zh-CN\"/' messages.xlf",
"i18n:upload": "npm run i18n && curl --location --user ${TRANSIFEX_USERNAME}:${TRANSIFEX_PASSWORD} --request PUT --header 'Content-type: multipart/form-data' --form content=@messages.xlf https://www.transifex.com/api/2/project/mycard/resource/messages/content/",
"i18n:download": "curl --output locale/messages.en-US.xlf --retry 5 --location --user ${TRANSIFEX_USERNAME}:zh112998 https://www.transifex.com/api/2/project/mycard/resource/messages/translation/en_US/?file && sed -i.bak 's/\\&amp;/\\&/g; s/\\&lt;/</g; s/\\&gt;/>/g; s/\\&quot;/\"/g;' locale/messages.en-US.xlf"
},
"dependencies": {
"@angular/common": "latest",
......
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