Skip to content

Commit 84c8ecb

Browse files
committed
Merge remote-tracking branch 'origin/master'
2 parents 2b4c939 + 5326049 commit 84c8ecb

File tree

10 files changed

+239
-1
lines changed

10 files changed

+239
-1
lines changed

src/app/menu.service.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -165,6 +165,12 @@ export class MenuService {
165165
url: 'mai2/dxpass',
166166
displayCondition: DisplayCondition.HasProfile,
167167
},
168+
{
169+
id: 7,
170+
name: 'Rival',
171+
url: 'mai2/rival',
172+
displayCondition: DisplayCondition.HasProfile,
173+
},
168174
{
169175
id: 6,
170176
name: 'MusicList',
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
.profile-icon{
2+
height: 5.4em;
3+
width: 5.4em;
4+
}
5+
6+
.profile-table{
7+
font-size: .8em;
8+
max-width: 20em;
9+
}
10+
11+
.profile-table th{
12+
width: 50%;
13+
}
14+
15+
.profile-table td{
16+
width: 50%;
17+
}
Lines changed: 66 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
<h1 class="page-heading">{{ 'Maimai2.RivalPage.Title' | translate }}</h1>
2+
<div class="card rival-id-card mb-3 p-1">
3+
<div class="d-flex align-items-center">
4+
<i class="bi bi-person-vcard me-2"></i>
5+
<div>
6+
<div class="text-muted small">{{ 'Maimai2.RivalPage.YourRivalID' | translate }}</div>
7+
<div class="h5 mb-0">{{10000000 + userService.currentUser.defaultCard.id}}</div>
8+
</div>
9+
</div>
10+
</div>
11+
<div class="input-group my-1">
12+
<input type="text" #rivalInput class="form-control form-control mb-3" [placeholder]="rivalList.length>2?('Maimai2.RivalPage.InputPlaceholder2' | translate):('Maimai2.RivalPage.InputPlaceholder' | translate)">
13+
<button class="btn btn-primary mb-3"
14+
type="button"
15+
[disabled]="loading || addingFriend || rivalList.length>2"
16+
(click)="addRival(rivalInput.value)">
17+
{{ 'Maimai2.RivalPage.AddButton' | translate }}
18+
</button>
19+
</div>
20+
<div *ngIf="!loading && rivalList.length == 0" class="text-center py-3">
21+
<span class="text-muted">{{ 'Maimai2.RivalPage.NoRivals' | translate }}</span>
22+
</div>
23+
<div *ngFor="let item of rivalList">
24+
<div class="card mb-2">
25+
<div class="card-header fw-bold d-flex align-items-center gap-2">
26+
<svg width="1em" height="1em" fill="currentColor" viewBox="0 0 1024 1024">
27+
<use href="assets/mai2.svg#icon"/>
28+
</svg>
29+
{{item.rivalName | fullWidth}}
30+
</div>
31+
<div class="card-body p-2">
32+
<div class="hstack gap-2">
33+
<img class="profile-icon" src="{{host}}assets/mai2/icon/UI_Icon_{{getFormattedNumberByDigit(String(item.iconId),6)}}.webp">
34+
<table class="profile-table">
35+
<tbody>
36+
<tr>
37+
<th>{{ 'Maimai2.RivalPage.AwakenLevel' | translate }}</th>
38+
<td>{{item.awakenCount}}</td>
39+
</tr>
40+
<tr>
41+
<th>{{ 'Maimai2.RivalPage.Rating' | translate }}</th>
42+
<td>{{item.playerRating}}</td>
43+
</tr>
44+
<tr>
45+
<th>{{ 'Maimai2.RivalPage.PlayCount' | translate }}</th>
46+
<td>{{item.playCount}}</td>
47+
</tr>
48+
<tr>
49+
<th>{{ 'Maimai2.RivalPage.RivalId' | translate }}</th>
50+
<td>{{item.rivalId}}</td>
51+
</tr>
52+
</tbody>
53+
</table>
54+
</div>
55+
</div>
56+
<div class="card-footer d-flex justify-content-between align-items-center">
57+
<button class="btn btn-danger btn-sm"
58+
(click)="removeRival(item.rivalId)">
59+
{{ 'Maimai2.RivalPage.RemoveButton' | translate }}
60+
</button>
61+
<div class="fw-bold small">
62+
{{ 'Maimai2.RivalPage.LastPlay' | translate }}{{(item.lastPlayDate | toDate).toLocaleString()}}
63+
</div>
64+
</div>
65+
</div>
66+
</div>
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
import { ComponentFixture, TestBed } from '@angular/core/testing';
2+
3+
import { Maimai2RivalComponent } from './maimai2-rival.component';
4+
5+
describe('Maimai2RivalComponent', () => {
6+
let component: Maimai2RivalComponent;
7+
let fixture: ComponentFixture<Maimai2RivalComponent>;
8+
9+
beforeEach(() => {
10+
TestBed.configureTestingModule({
11+
declarations: [Maimai2RivalComponent]
12+
});
13+
fixture = TestBed.createComponent(Maimai2RivalComponent);
14+
component = fixture.componentInstance;
15+
fixture.detectChanges();
16+
});
17+
18+
it('should create', () => {
19+
expect(component).toBeTruthy();
20+
});
21+
});
Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
import { Component } from '@angular/core';
2+
import {ApiService} from '../../../api.service';
3+
import {NgbModal} from '@ng-bootstrap/ng-bootstrap';
4+
import {UserService} from '../../../user.service';
5+
import {MessageService} from '../../../message.service';
6+
import {debounce} from '../../../util/debounce';
7+
import {Maimai2Rival} from '../model/Maimai2Rival';
8+
import {HttpParams} from '@angular/common/http';
9+
import {environment} from "../../../../environments/environment";
10+
11+
@Component({
12+
selector: 'app-maimai2-rival',
13+
templateUrl: './maimai2-rival.component.html',
14+
styleUrls: ['./maimai2-rival.component.css']
15+
})
16+
export class Maimai2RivalComponent {
17+
18+
host = environment.assetsHost;
19+
rivalList: Maimai2Rival[] = [];
20+
loading = true;
21+
addingFriend: boolean;
22+
private aimeId: string;
23+
24+
constructor(
25+
private api: ApiService,
26+
private modalService: NgbModal,
27+
protected userService: UserService,
28+
private messageService: MessageService,
29+
) {
30+
}
31+
32+
ngOnInit(){
33+
this.loading = true;
34+
this.aimeId = String(this.userService.currentUser.defaultCard.extId);
35+
this.loadRival();
36+
}
37+
38+
loadRival() {
39+
const param = new HttpParams().set('aimeId', this.aimeId);
40+
this.api.get('api/game/maimai2/rival', param).subscribe(
41+
(data) => {
42+
this.rivalList = data;
43+
this.loading = false;
44+
},
45+
error => {
46+
this.messageService.notice(`Cannot get rival list: ${error}`);
47+
}
48+
);
49+
}
50+
51+
removeRival(rivalUserId: string) {
52+
const param = new HttpParams().set('rivalId', (Number).parseInt(rivalUserId)).set('aimeId', this.aimeId);
53+
this.api.delete('api/game/maimai2/rival', param).subscribe(
54+
() => {
55+
const newList = this.rivalList.filter(item => item.rivalId !== rivalUserId);
56+
this.messageService.notice(`(id:${rivalUserId}) delete successfully.`);
57+
this.rivalList = newList;
58+
},
59+
error => this.messageService.notice(`remove rival failed: ${error}`)
60+
);
61+
}
62+
63+
getFormattedNumberByDigit(input: string, digit: number): string {
64+
return input.toString().padStart(digit, '0');
65+
}
66+
67+
addRival(rivalUserId: string) {
68+
this.addingFriend = true;
69+
const param = new HttpParams().set('rivalId',rivalUserId).set('aimeId', this.aimeId);
70+
this.api.post('api/game/maimai2/rival' , param).subscribe(
71+
data => {
72+
this.addingFriend = false;
73+
if (data) {
74+
this.messageService.notice(`Add rival success!`);
75+
this.ngOnInit();
76+
}
77+
},
78+
error => {
79+
this.messageService.notice(`add rival failed: ${error}`);
80+
this.addingFriend = false;
81+
}
82+
);
83+
}
84+
85+
protected readonly String = String;
86+
}

src/app/sega/maimai2/maimai2.module.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import { Maimai2DxpassComponent } from './maimai2-dxpass/maimai2-dxpass.componen
1515
import {Maimai2SonglistComponent} from "./maimai2-songlist/maimai2-songlist.component";
1616
import {Maimai2SongDetailComponent} from "./maimai2-song-detail/maimai2-song-detail.component";
1717
import {NgIcon} from "@ng-icons/core";
18+
import { Maimai2RivalComponent } from './maimai2-rival/maimai2-rival.component';
1819

1920

2021
@NgModule({
@@ -26,7 +27,8 @@ import {NgIcon} from "@ng-icons/core";
2627
Maimai2PhotosComponent,
2728
Maimai2DxpassComponent,
2829
Maimai2SonglistComponent,
29-
Maimai2SongDetailComponent
30+
Maimai2SongDetailComponent,
31+
Maimai2RivalComponent
3032
],
3133
imports: [
3234
CommonModule,

src/app/sega/maimai2/maimai2.routing.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import {Maimai2RecentComponent} from './maimai2-recent/maimai2-recent.component'
66
import {Maimai2PhotosComponent} from './maimai2-photos/maimai2-photos.component';
77
import {Maimai2DxpassComponent} from './maimai2-dxpass/maimai2-dxpass.component';
88
import {Maimai2SonglistComponent} from './maimai2-songlist/maimai2-songlist.component';
9+
import {Maimai2RivalComponent} from './maimai2-rival/maimai2-rival.component';
910

1011

1112
const routes: Routes = [
@@ -16,6 +17,7 @@ const routes: Routes = [
1617
{path: 'photos', component: Maimai2PhotosComponent, data: {title: 'Photos'}},
1718
{path: 'dxpass', component: Maimai2DxpassComponent, data: {title: 'DxPass'}},
1819
{path: 'songlist', component: Maimai2SonglistComponent, data: {title: 'Songlist'}},
20+
{path: 'rival', component: Maimai2RivalComponent, data: {title: 'Rival'}},
1921
];
2022

2123
export const Maimai2Routes = RouterModule.forChild(routes);
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
export interface Maimai2Rival {
2+
rivalName: string;
3+
rivalId: string;
4+
iconId: number;
5+
playerRating: number;
6+
lastPlayDate: string;
7+
awakenCount: number;
8+
playCount: number;
9+
isFavourite: boolean;
10+
}

src/assets/i18n/en.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,20 @@
606606
"Genre": "Genre",
607607
"Version": "Version",
608608
"MatchingSongs": "Matching Songs"
609+
},
610+
"RivalPage": {
611+
"Title": "Rival List",
612+
"YourRivalID": "Your Rival ID",
613+
"InputPlaceholder": "Input other's rival id here",
614+
"InputPlaceholder2": "Rival count is mor than 3",
615+
"AddButton": "Add Rival",
616+
"RemoveButton": "Remove",
617+
"NoRivals": "No rivals yet. Add one above!",
618+
"AwakenLevel": "Awaken Level",
619+
"Rating": "Rating",
620+
"PlayCount": "Play Count",
621+
"RivalId": "Rival Id",
622+
"LastPlay": "Last Play:"
609623
}
610624

611625
},

src/assets/i18n/zh.json

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -608,6 +608,20 @@
608608
"Genre": "流派",
609609
"Version": "版本",
610610
"MatchingSongs": "匹配歌曲"
611+
},
612+
"RivalPage": {
613+
"Title": "对手列表",
614+
"YourRivalID": "你的对手ID",
615+
"InputPlaceholder": "在此输入对方的对手ID",
616+
"InputPlaceholder2": "对手数超过3,不可手动添加",
617+
"AddButton": "添加对手",
618+
"RemoveButton": "移除对手",
619+
"NoRivals": "暂无对手,请在上方添加",
620+
"AwakenLevel": "觉醒等级",
621+
"Rating": "评级",
622+
"PlayCount": "游玩次数",
623+
"RivalId": "对手ID",
624+
"LastPlay": "最后游玩:"
611625
}
612626
},
613627
"ContributorsPage": {

0 commit comments

Comments
 (0)