feat: extended tribe profile

This commit is contained in:
Dawid Wysokiński 2023-02-18 16:50:54 +01:00
parent 2383730855
commit 8850bab152
Signed by: Kichiyaki
GPG Key ID: B5445E357FB8B892
2 changed files with 167 additions and 11 deletions

View File

@ -1,5 +1,6 @@
import { Tribe, TribeSnapshot, TWHelpClient } from './lib/twhelp';
import { createTranslationFunc } from './utils';
import { DialogTable } from './common/dialog-table';
const t = createTranslationFunc({
pl_PL: {
@ -8,8 +9,10 @@ const t = createTranslationFunc({
'Best rank': 'Najwyższy ranking',
'Most points': 'Najwięcej punktów',
'Most villages': 'Najwięcej wiosek',
'Show tribe changes': 'Pokaż zmiany plemion',
'Show history': 'Pokaż historię',
Changes: 'Zmiany',
'Number of members': 'Liczba członków',
Members: 'Członkowie',
Points: 'Punkty',
Rank: 'Ranking',
Villages: 'Wioski',
@ -19,6 +22,13 @@ const t = createTranslationFunc({
'ODA - rank': 'Pokonani agresor - ranking',
ODD: 'Pokonani obrońca',
'ODD - rank': 'Pokonani obrońca - ranking',
Player: 'Gracz',
'New tribe': 'Nowe plemię',
'Old tribe': 'Stare plemię',
'Date/time': 'Data/czas',
Action: 'Akcja',
Joined: 'Dołączył',
Left: 'Opuścił',
},
});
@ -46,6 +56,19 @@ class TWHelpConnector {
sort: ['date:desc'],
});
}
tribeTribeChanges(page: number, limit: number) {
return this.client.tribeTribeChanges(this.version, this.server, this.id, {
offset: (page - 1) * limit,
limit,
sort: ['createdAt:desc'],
});
}
}
enum DialogId {
HISTORY = 'extended_tribe_profile_history',
TRIBE_CHANGES = 'extended_tribe_profile_tribe_changes',
}
class UI {
@ -58,6 +81,7 @@ class UI {
public render() {
this.renderAdditionalInfo();
this.renderStats();
this.renderActions();
}
private renderAdditionalInfo() {
@ -119,7 +143,7 @@ class UI {
value: this.tribe.dominance - (this.latestSnapshot?.dominance ?? 0),
},
{
header: t('Number of members'),
header: t('Members'),
value: this.tribe.numMembers - (this.latestSnapshot?.numMembers ?? 0),
},
{
@ -198,6 +222,128 @@ class UI {
}
return '#808080';
}
private renderActions() {
const tbody = document
.querySelector('#content_value a[href*="twstats"]')
?.closest('tbody');
if (!(tbody instanceof HTMLTableSectionElement)) {
return;
}
[
{
name: t('Show tribe changes'),
handler: this.showTribeChanges.bind(this),
},
{ name: t('Show history'), handler: this.showHistory.bind(this) },
].forEach(({ name, handler }) => {
const tr = document.createElement('tr');
const td = document.createElement('td');
td.colSpan = 2;
const a = document.createElement('a');
a.innerText = name;
a.href = '#';
a.addEventListener('click', handler);
td.appendChild(a);
tr.appendChild(td);
tbody.appendChild(tr);
});
}
private async showTribeChanges(e: Event) {
e.preventDefault();
await new DialogTable(
DialogId.TRIBE_CHANGES,
[
{
header: t('Player'),
accessor: (tc) =>
`<a href="${tc.player.profileUrl}">${tc.player.name}</a>`,
},
{
header: t('Action'),
accessor: (tc) =>
t(tc.newTribe?.id !== this.tribe.id ? 'Left' : 'Joined'),
},
{
header: t('Old tribe'),
accessor: (tc) =>
tc.player.tribe
? `<a href="${tc.player.tribe.profileUrl}">${tc.player.tribe.tag}</a>`
: '-',
},
{
header: t('New tribe'),
accessor: (tc) =>
tc.newTribe
? `<a href="${tc.newTribe.profileUrl}">${tc.newTribe.tag}</a>`
: '-',
},
{
header: t('Date/time'),
accessor: (tc) => new Date(tc.createdAt).toLocaleString(),
},
],
30,
(page: number, limit: number) => {
return this.twhelpConnector.tribeTribeChanges(page, limit);
}
).render();
}
private async showHistory(e: Event) {
e.preventDefault();
await new DialogTable(
DialogId.HISTORY,
[
{
header: t('Date'),
accessor: (s) => s.date,
},
{
header: t('Points'),
accessor: (s) =>
`${s.allPoints.toLocaleString()} (<strong>${s.rank}</strong>)`,
},
{
header: t('Villages'),
accessor: (s) => `${s.numVillages.toLocaleString()}`,
},
{
header: t('Members'),
accessor: (s) => `${s.numMembers.toLocaleString()}`,
},
{
header: t('Dominance'),
accessor: (s) => `${s.dominance.toFixed(2)}%`,
},
{
header: t('OD'),
accessor: (s) =>
`${s.scoreTotal.toLocaleString()} (<strong>${
s.rankTotal
}</strong>)`,
},
{
header: t('ODA'),
accessor: (s) =>
`${s.scoreAtt.toLocaleString()} (<strong>${s.rankAtt}</strong>)`,
},
{
header: t('ODD'),
accessor: (s) =>
`${s.scoreDef.toLocaleString()} (<strong>${s.rankDef}</strong>)`,
},
],
30,
(page: number, limit: number) => {
return this.twhelpConnector.tribeHistory(page, limit);
}
).render();
}
}
class ExtendedTribeProfile {

View File

@ -182,13 +182,7 @@ export type ListEnnoblementsParams = {
sort?: string[];
};
export type ListTribeSnapshotsParams = {
offset?: number;
limit?: number;
sort?: string[];
};
export type ListPlayerSnapshotsParams = {
export type ListSnapshotsParams = {
offset?: number;
limit?: number;
sort?: string[];
@ -241,7 +235,7 @@ export class TWHelpClient {
version: string,
server: string,
id: number,
queryParams?: ListTribeSnapshotsParams
queryParams?: ListSnapshotsParams
): Promise<ListResult<TribeSnapshot>> {
const queryString = queryParams ? this.buildQueryString(queryParams) : '';
const resp = await this.client.get(
@ -253,6 +247,22 @@ export class TWHelpClient {
};
}
public async tribeTribeChanges(
version: string,
server: string,
id: number,
queryParams?: ListTribeChangesQueryParams
): Promise<ListResult<TribeChange>> {
const queryString = queryParams ? this.buildQueryString(queryParams) : '';
const resp = await this.client.get(
`/api/v1/versions/${version}/servers/${server}/tribes/${id}/tribe-changes?${queryString}`
);
return {
data: resp.data.data,
total: this.parseTotal(resp.headers),
};
}
public async player(
version: string,
server: string,
@ -300,7 +310,7 @@ export class TWHelpClient {
version: string,
server: string,
id: number,
queryParams?: ListPlayerSnapshotsParams
queryParams?: ListSnapshotsParams
): Promise<ListResult<PlayerSnapshot>> {
const queryString = queryParams ? this.buildQueryString(queryParams) : '';
const resp = await this.client.get(