feat: extended player profile
This commit is contained in:
parent
89f71f319d
commit
0026822768
|
@ -5,6 +5,8 @@ const translations: Record<string, Record<string, string>> = {
|
||||||
Loading: 'Wczytywanie',
|
Loading: 'Wczytywanie',
|
||||||
'Previous page': 'Poprzednia strona',
|
'Previous page': 'Poprzednia strona',
|
||||||
'Next page': 'Następna strona',
|
'Next page': 'Następna strona',
|
||||||
|
'Something went wrong while loading the data':
|
||||||
|
'Coś poszło nie tak podczas wczytywania danych',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,6 +20,9 @@ export type DialogTableColumn<T> = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export class DialogTable<T> {
|
export class DialogTable<T> {
|
||||||
|
prevPageId: string;
|
||||||
|
selectId: string;
|
||||||
|
nextPageId: string;
|
||||||
constructor(
|
constructor(
|
||||||
private readonly id: string,
|
private readonly id: string,
|
||||||
private readonly columns: DialogTableColumn<T>[],
|
private readonly columns: DialogTableColumn<T>[],
|
||||||
|
@ -26,7 +31,11 @@ export class DialogTable<T> {
|
||||||
page: number,
|
page: number,
|
||||||
limit: number
|
limit: number
|
||||||
) => Promise<ListResult<T>>
|
) => Promise<ListResult<T>>
|
||||||
) {}
|
) {
|
||||||
|
this.prevPageId = `${this.id}_page_prev`;
|
||||||
|
this.selectId = `${this.id}_page_select`;
|
||||||
|
this.nextPageId = `${this.id}_page_next`;
|
||||||
|
}
|
||||||
|
|
||||||
public async render() {
|
public async render() {
|
||||||
await this.renderPage(1);
|
await this.renderPage(1);
|
||||||
|
@ -35,9 +44,28 @@ export class DialogTable<T> {
|
||||||
private async renderPage(page: number) {
|
private async renderPage(page: number) {
|
||||||
window.Dialog.show(`${this.id}_loading`, `<p>${t('Loading')}...</p>`);
|
window.Dialog.show(`${this.id}_loading`, `<p>${t('Loading')}...</p>`);
|
||||||
|
|
||||||
const { data, total } = await this.loadData(page, this.limit);
|
try {
|
||||||
|
const { data, total } = await this.loadData(page, this.limit);
|
||||||
|
|
||||||
|
window.Dialog.show(
|
||||||
|
this.id,
|
||||||
|
`
|
||||||
|
${this.buildPagination(page, total)}
|
||||||
|
${this.buildTable(data)}
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
this.addEventListeners(page);
|
||||||
|
} catch (err) {
|
||||||
|
console.error(err);
|
||||||
|
window.Dialog.close();
|
||||||
|
window.UI.ErrorMessage(t('Something went wrong while loading the data'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private buildPagination(page: number, total: number): string {
|
||||||
const maxPage = Math.ceil(total / this.limit);
|
const maxPage = Math.ceil(total / this.limit);
|
||||||
|
|
||||||
const pageOpts = [];
|
const pageOpts = [];
|
||||||
for (let i = 1; i <= (page > maxPage ? page : maxPage); i++) {
|
for (let i = 1; i <= (page > maxPage ? page : maxPage); i++) {
|
||||||
pageOpts.push(
|
pageOpts.push(
|
||||||
|
@ -47,26 +75,25 @@ export class DialogTable<T> {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const prevPageId = `${this.id}_page_prev`;
|
return `
|
||||||
const selectId = `${this.id}_page_select`;
|
|
||||||
const nextPageId = `${this.id}_page_next`;
|
|
||||||
|
|
||||||
window.Dialog.show(
|
|
||||||
this.id,
|
|
||||||
`
|
|
||||||
<div style="display: flex; flex-direction: row; align-items: center; justify-content: center; margin-bottom: 10px">
|
<div style="display: flex; flex-direction: row; align-items: center; justify-content: center; margin-bottom: 10px">
|
||||||
<button title="${t(
|
<button title="${t(
|
||||||
'Previous page'
|
'Previous page'
|
||||||
)}" style="margin-right: 5px" class="btn" id="${prevPageId}"${
|
)}" style="margin-right: 5px" class="btn" id="${this.prevPageId}"${
|
||||||
page <= 1 ? ' disabled' : ''
|
page <= 1 ? ' disabled' : ''
|
||||||
}><</button>
|
}><</button>
|
||||||
<select style="margin-right: 5px" id="${selectId}">
|
<select style="margin-right: 5px" id="${this.selectId}">
|
||||||
${pageOpts.join('')}
|
${pageOpts.join('')}
|
||||||
</select>
|
</select>
|
||||||
<button title="${t('Next page')}" class="btn" id="${nextPageId}"${
|
<button title="${t('Next page')}" class="btn" id="${
|
||||||
page >= maxPage ? ' disabled' : ''
|
this.nextPageId
|
||||||
}>></button>
|
}"${page >= maxPage ? ' disabled' : ''}>></button>
|
||||||
</div>
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private buildTable(data: T[]) {
|
||||||
|
return `
|
||||||
<table style="width: 100%" class="vis">
|
<table style="width: 100%" class="vis">
|
||||||
<tbody>
|
<tbody>
|
||||||
<tr>
|
<tr>
|
||||||
|
@ -84,18 +111,19 @@ export class DialogTable<T> {
|
||||||
)
|
)
|
||||||
.join('')}
|
.join('')}
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
`
|
`;
|
||||||
);
|
}
|
||||||
|
|
||||||
|
private addEventListeners(page: number) {
|
||||||
document
|
document
|
||||||
.querySelector('#' + prevPageId)
|
.querySelector('#' + this.prevPageId)
|
||||||
?.addEventListener('click', (e: Event) => {
|
?.addEventListener('click', () => {
|
||||||
this.renderPage(page - 1);
|
this.renderPage(page - 1);
|
||||||
});
|
});
|
||||||
|
|
||||||
document
|
document
|
||||||
.querySelector('#' + selectId)
|
.querySelector('#' + this.selectId)
|
||||||
?.addEventListener('change', (e: Event) => {
|
?.addEventListener('change', (e: Event) => {
|
||||||
if (!(e.currentTarget instanceof HTMLSelectElement)) {
|
if (!(e.currentTarget instanceof HTMLSelectElement)) {
|
||||||
return;
|
return;
|
||||||
|
@ -105,8 +133,8 @@ export class DialogTable<T> {
|
||||||
});
|
});
|
||||||
|
|
||||||
document
|
document
|
||||||
.querySelector('#' + nextPageId)
|
.querySelector('#' + this.nextPageId)
|
||||||
?.addEventListener('click', (e: Event) => {
|
?.addEventListener('click', () => {
|
||||||
this.renderPage(page + 1);
|
this.renderPage(page + 1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@
|
||||||
|
|
||||||
import { Player, TWHelpClient } from './lib/twhelp';
|
import { Player, TWHelpClient } from './lib/twhelp';
|
||||||
import { DialogTable } from './common/DialogTable';
|
import { DialogTable } from './common/DialogTable';
|
||||||
import { buildURL } from './lib/twstats';
|
|
||||||
|
|
||||||
const SCREEN = 'info_player';
|
const SCREEN = 'info_player';
|
||||||
const MODE = null;
|
const MODE = null;
|
||||||
|
@ -14,7 +13,6 @@ const translations: Record<string, Record<string, string>> = {
|
||||||
'Best rank': 'Najlepszy ranking',
|
'Best rank': 'Najlepszy ranking',
|
||||||
'Most points': 'Najwięcej punktów',
|
'Most points': 'Najwięcej punktów',
|
||||||
'Most villages': 'Najwięcej wiosek',
|
'Most villages': 'Najwięcej wiosek',
|
||||||
'Show other servers': 'Pokaż inne światy',
|
|
||||||
'Show tribe changes': 'Pokaż zmiany plemion',
|
'Show tribe changes': 'Pokaż zmiany plemion',
|
||||||
'Show history': 'Pokaż historię',
|
'Show history': 'Pokaż historię',
|
||||||
'Show ennoblements': 'Pokaż przejęcia',
|
'Show ennoblements': 'Pokaż przejęcia',
|
||||||
|
@ -83,7 +81,6 @@ class TWHelpConnector {
|
||||||
}
|
}
|
||||||
|
|
||||||
enum DialogId {
|
enum DialogId {
|
||||||
OTHER_SERVERS = 'kichiyaki_other_servers',
|
|
||||||
TRIBE_CHANGES = 'kichiyaki_tribe_changes',
|
TRIBE_CHANGES = 'kichiyaki_tribe_changes',
|
||||||
ENNOBLEMENTS = 'kichiyaki_ennoblements',
|
ENNOBLEMENTS = 'kichiyaki_ennoblements',
|
||||||
HISTORY = 'kichiyaki_history',
|
HISTORY = 'kichiyaki_history',
|
||||||
|
@ -148,10 +145,6 @@ class UI {
|
||||||
}
|
}
|
||||||
|
|
||||||
[
|
[
|
||||||
{
|
|
||||||
name: t('Show other servers'),
|
|
||||||
handler: this.showOtherServers.bind(this),
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
name: t('Show tribe changes'),
|
name: t('Show tribe changes'),
|
||||||
handler: this.showTribeChanges.bind(this),
|
handler: this.showTribeChanges.bind(this),
|
||||||
|
@ -176,39 +169,6 @@ class UI {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private async showOtherServers(e: Event) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
await new DialogTable(
|
|
||||||
DialogId.OTHER_SERVERS,
|
|
||||||
[
|
|
||||||
{
|
|
||||||
header: t('Server'),
|
|
||||||
accessor: (s) =>
|
|
||||||
`<a href="${buildURL({
|
|
||||||
entity: 'player',
|
|
||||||
server: s.key,
|
|
||||||
id: this.player.id,
|
|
||||||
})}">${s.key}</a>`,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
header: t('Deleted'),
|
|
||||||
accessor: (s) =>
|
|
||||||
s.deletedAt
|
|
||||||
? `${t('Yes')} (${new Date(s.deletedAt).toLocaleString()})`
|
|
||||||
: t('No'),
|
|
||||||
},
|
|
||||||
],
|
|
||||||
this.player.otherServers.length,
|
|
||||||
() => {
|
|
||||||
return Promise.resolve({
|
|
||||||
data: this.player.otherServers,
|
|
||||||
total: this.player.otherServers.length,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
).render();
|
|
||||||
}
|
|
||||||
|
|
||||||
private async showTribeChanges(e: Event) {
|
private async showTribeChanges(e: Event) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
|
@ -314,25 +274,29 @@ class UI {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
header: t('Old owner'),
|
header: t('Old owner'),
|
||||||
accessor: (e) =>
|
accessor: ({ village: { player } }) => {
|
||||||
e.oldOwner
|
if (!player) {
|
||||||
? `<a href="${e.oldOwner.profileUrl}">${e.oldOwner.name}</a>${
|
return t('Barbarian');
|
||||||
e.oldOwner.tribe
|
}
|
||||||
? ` (<a href="${e.oldOwner.tribe.profileUrl}">${e.oldOwner.tribe.tag}</a>)`
|
return `<a href="${player.profileUrl}">${player.name}</a>${
|
||||||
: ''
|
player.tribe
|
||||||
}`
|
? ` (<a href="${player.tribe.profileUrl}">${player.tribe.tag}</a>)`
|
||||||
: t('Barbarian'),
|
: ''
|
||||||
|
}`;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
header: t('New owner'),
|
header: t('New owner'),
|
||||||
accessor: (e) =>
|
accessor: ({ newOwner }) => {
|
||||||
e.newOwner
|
if (!newOwner) {
|
||||||
? `<a href="${e.newOwner.profileUrl}">${e.newOwner.name}</a>${
|
return t('Unknown');
|
||||||
e.newOwner.tribe
|
}
|
||||||
? ` (<a href="${e.newOwner.tribe.profileUrl}">${e.newOwner.tribe.tag}</a>)`
|
return `<a href="${newOwner.profileUrl}">${newOwner.name}</a>${
|
||||||
: ''
|
newOwner.tribe
|
||||||
}`
|
? ` (<a href="${newOwner.tribe.profileUrl}">${newOwner.tribe.tag}</a>)`
|
||||||
: t('Unknown'),
|
: ''
|
||||||
|
}`;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
header: t('Date/time'),
|
header: t('Date/time'),
|
||||||
|
@ -379,5 +343,9 @@ class ExtendedPlayerProfile {
|
||||||
|
|
||||||
await new ExtendedPlayerProfile(
|
await new ExtendedPlayerProfile(
|
||||||
new TWHelpClient(process.env.TWHELP_API_BASE_URL ?? '')
|
new TWHelpClient(process.env.TWHELP_API_BASE_URL ?? '')
|
||||||
).render();
|
)
|
||||||
|
.render()
|
||||||
|
.catch((err) => {
|
||||||
|
console.log(err);
|
||||||
|
});
|
||||||
})();
|
})();
|
||||||
|
|
|
@ -30,6 +30,7 @@ declare global {
|
||||||
};
|
};
|
||||||
Dialog: {
|
Dialog: {
|
||||||
show: (id: string, html: string) => void;
|
show: (id: string, html: string) => void;
|
||||||
|
close: () => void;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,11 +10,6 @@ export type Version = {
|
||||||
timezone: string;
|
timezone: string;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type PlayerServer = {
|
|
||||||
key: string;
|
|
||||||
deletedAt: string | null;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type Player = {
|
export type Player = {
|
||||||
id: number;
|
id: number;
|
||||||
bestRank: number;
|
bestRank: number;
|
||||||
|
@ -25,7 +20,6 @@ export type Player = {
|
||||||
mostVillagesAt: string;
|
mostVillagesAt: string;
|
||||||
lastActivityAt: string;
|
lastActivityAt: string;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
otherServers: PlayerServer[];
|
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TribeMeta = {
|
export type TribeMeta = {
|
||||||
|
@ -49,6 +43,7 @@ export type VillageMeta = {
|
||||||
x: number;
|
x: number;
|
||||||
y: number;
|
y: number;
|
||||||
continent: string;
|
continent: string;
|
||||||
|
player: PlayerMeta | null;
|
||||||
};
|
};
|
||||||
|
|
||||||
export type TribeChange = {
|
export type TribeChange = {
|
||||||
|
@ -62,7 +57,6 @@ export type Ennoblement = {
|
||||||
id: number;
|
id: number;
|
||||||
points: number;
|
points: number;
|
||||||
newOwner: PlayerMeta | null;
|
newOwner: PlayerMeta | null;
|
||||||
oldOwner: PlayerMeta | null;
|
|
||||||
village: VillageMeta;
|
village: VillageMeta;
|
||||||
createdAt: string;
|
createdAt: string;
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue