feat: extended player profile
This commit is contained in:
parent
29ae462b1f
commit
84c5c3fc9a
|
@ -0,0 +1,113 @@
|
||||||
|
import { ListResult } from '../lib/client';
|
||||||
|
|
||||||
|
const translations: Record<string, Record<string, string>> = {
|
||||||
|
pl_PL: {
|
||||||
|
Loading: 'Wczytywanie',
|
||||||
|
'Previous page': 'Poprzednia strona',
|
||||||
|
'Next page': 'Następna strona',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
const t = (s: string) => {
|
||||||
|
return translations[window.game_data.locale]?.[s] ?? s;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type DialogTableColumn<T> = {
|
||||||
|
header: string;
|
||||||
|
accessor: (row: T) => string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export class DialogTable<T> {
|
||||||
|
constructor(
|
||||||
|
private readonly id: string,
|
||||||
|
private readonly columns: DialogTableColumn<T>[],
|
||||||
|
private readonly limit: number,
|
||||||
|
private readonly loadData: (
|
||||||
|
page: number,
|
||||||
|
limit: number
|
||||||
|
) => Promise<ListResult<T>>
|
||||||
|
) {}
|
||||||
|
|
||||||
|
public async render() {
|
||||||
|
await this.renderPage(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
private async renderPage(page: number) {
|
||||||
|
window.Dialog.show(`${this.id}_loading`, `<p>${t('Loading')}...</p>`);
|
||||||
|
|
||||||
|
const { data, total } = await this.loadData(page, this.limit);
|
||||||
|
|
||||||
|
const maxPage = Math.ceil(total / this.limit);
|
||||||
|
const pageOpts = [];
|
||||||
|
for (let i = 1; i <= (page > maxPage ? page : maxPage); i++) {
|
||||||
|
pageOpts.push(
|
||||||
|
`<option${
|
||||||
|
i === page ? ' disabled selected' : ''
|
||||||
|
} value="${i}">${i}</option>`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const prevPageId = `${this.id}_page_prev`;
|
||||||
|
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">
|
||||||
|
<button title="${t(
|
||||||
|
'Previous page'
|
||||||
|
)}" style="margin-right: 5px" class="btn" id="${prevPageId}"${
|
||||||
|
page <= 1 ? ' disabled' : ''
|
||||||
|
}><</button>
|
||||||
|
<select style="margin-right: 5px" id="${selectId}">
|
||||||
|
${pageOpts.join('')}
|
||||||
|
</select>
|
||||||
|
<button title="${t('Next page')}" class="btn" id="${nextPageId}"${
|
||||||
|
page >= maxPage ? ' disabled' : ''
|
||||||
|
}>></button>
|
||||||
|
</div>
|
||||||
|
<table class="vis">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
${this.columns.map((col) => `<th>${col.header}</th>`).join('')}
|
||||||
|
</tr>
|
||||||
|
${data
|
||||||
|
.map(
|
||||||
|
(r) => `
|
||||||
|
<tr>
|
||||||
|
${this.columns
|
||||||
|
.map((col) => `<td>${col.accessor(r)}</td>`)
|
||||||
|
.join('')}
|
||||||
|
</tr>
|
||||||
|
`
|
||||||
|
)
|
||||||
|
.join('')}
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
`
|
||||||
|
);
|
||||||
|
|
||||||
|
document
|
||||||
|
.querySelector('#' + prevPageId)
|
||||||
|
?.addEventListener('click', (e: Event) => {
|
||||||
|
this.renderPage(page - 1);
|
||||||
|
});
|
||||||
|
|
||||||
|
document
|
||||||
|
.querySelector('#' + selectId)
|
||||||
|
?.addEventListener('change', (e: Event) => {
|
||||||
|
if (!(e.currentTarget instanceof HTMLSelectElement)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.renderPage(parseInt(e.currentTarget.value));
|
||||||
|
});
|
||||||
|
|
||||||
|
document
|
||||||
|
.querySelector('#' + nextPageId)
|
||||||
|
?.addEventListener('click', (e: Event) => {
|
||||||
|
this.renderPage(page + 1);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,6 +1,7 @@
|
||||||
// Extended player profile
|
// Extended player profile
|
||||||
|
|
||||||
import { ListResult, Player, TribeChange, TWHelpClient } from './lib/client';
|
import { ListResult, Player, TribeChange, TWHelpClient } from './lib/client';
|
||||||
|
import { DialogTable } from './common/DialogTable';
|
||||||
|
|
||||||
const SCREEN = 'info_player';
|
const SCREEN = 'info_player';
|
||||||
const MODE = null;
|
const MODE = null;
|
||||||
|
@ -15,7 +16,6 @@ const translations: Record<string, Record<string, string>> = {
|
||||||
'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',
|
||||||
'Fetching data': 'Pobieranie danych',
|
|
||||||
'Old tribe': 'Stare plemię',
|
'Old tribe': 'Stare plemię',
|
||||||
'New tribe': 'Nowe plemię',
|
'New tribe': 'Nowe plemię',
|
||||||
'Date/time': 'Data/czas',
|
'Date/time': 'Data/czas',
|
||||||
|
@ -47,13 +47,12 @@ class TWHelpConnector {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
interface UIConnector {
|
enum DialogId {
|
||||||
tribeChanges(page: number, limit: number): Promise<ListResult<TribeChange>>;
|
TRIBE_CHANGES = 'kichiyaki_tribe_changes',
|
||||||
}
|
}
|
||||||
|
|
||||||
enum DialogId {
|
interface UIConnector {
|
||||||
TRIBE_CHANGES_LOADING = 'kichiyaki_tribe_changes_loading',
|
tribeChanges(page: number, limit: number): Promise<ListResult<TribeChange>>;
|
||||||
TRIBE_CHANGES = 'kichiyaki_tribe_changes',
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class UI {
|
class UI {
|
||||||
|
@ -143,81 +142,33 @@ class UI {
|
||||||
private async showTribeChanges(e: Event) {
|
private async showTribeChanges(e: Event) {
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
|
|
||||||
await this._showTribeChanges(1);
|
await new DialogTable(
|
||||||
}
|
|
||||||
|
|
||||||
private async _showTribeChanges(page: number) {
|
|
||||||
window.Dialog.show(
|
|
||||||
DialogId.TRIBE_CHANGES_LOADING,
|
|
||||||
`<p>${t('Fetching data')}...</p>`
|
|
||||||
);
|
|
||||||
|
|
||||||
const tcs = await this.connector.tribeChanges(page, UI.TRIBE_CHANGES_LIMIT);
|
|
||||||
|
|
||||||
const maxPage = Math.ceil(tcs.total / UI.TRIBE_CHANGES_LIMIT);
|
|
||||||
const pageOpts = [];
|
|
||||||
for (let i = 1; i <= (page > maxPage ? page : maxPage); i++) {
|
|
||||||
pageOpts.push(
|
|
||||||
`<option${
|
|
||||||
i === page ? ' disabled selected' : ''
|
|
||||||
} value="${i}">${i}</option>`
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
const selectId = `${DialogId.TRIBE_CHANGES}_page`;
|
|
||||||
|
|
||||||
window.Dialog.show(
|
|
||||||
DialogId.TRIBE_CHANGES,
|
DialogId.TRIBE_CHANGES,
|
||||||
`
|
[
|
||||||
<div>
|
{
|
||||||
<label>
|
header: t('Old tribe'),
|
||||||
Page:
|
accessor: (tc) =>
|
||||||
<select id="${selectId}">
|
tc.player.tribe
|
||||||
${pageOpts.join('')}
|
? `<a href="${tc.player.tribe.profileUrl}">${tc.player.tribe.tag}</a>`
|
||||||
</select>
|
: '-',
|
||||||
</label>
|
},
|
||||||
</div>
|
{
|
||||||
<table class="vis">
|
header: t('New tribe'),
|
||||||
<tbody>
|
accessor: (tc) =>
|
||||||
<tr>
|
tc.newTribe
|
||||||
<th>${t('Old tribe')}</th>
|
? `<a href="${tc.newTribe.profileUrl}">${tc.newTribe.tag}</a>`
|
||||||
<th>${t('New tribe')}</th>
|
: '-',
|
||||||
<th>${t('Date/time')}</th>
|
},
|
||||||
</tr>
|
{
|
||||||
${tcs.data
|
header: t('Date/time'),
|
||||||
.map(
|
accessor: (tc) => new Date(tc.createdAt).toLocaleString(),
|
||||||
(tc) => `
|
},
|
||||||
<tr>
|
],
|
||||||
<td>${
|
2,
|
||||||
tc.player.tribe
|
(page: number, limit: number) => {
|
||||||
? `<a href="${tc.player.tribe.profileUrl}">${tc.player.tribe.tag}</a>`
|
return this.connector.tribeChanges(page, limit);
|
||||||
: '-'
|
}
|
||||||
}</td>
|
).render();
|
||||||
<td>${
|
|
||||||
tc.newTribe
|
|
||||||
? `<a href="${tc.newTribe.profileUrl}">${tc.newTribe.tag}</a>`
|
|
||||||
: '-'
|
|
||||||
}</td>
|
|
||||||
<td>${new Date(tc.createdAt).toLocaleString()}</td>
|
|
||||||
</tr>
|
|
||||||
`
|
|
||||||
)
|
|
||||||
.join('')}
|
|
||||||
</tbody>
|
|
||||||
</table>
|
|
||||||
`
|
|
||||||
);
|
|
||||||
|
|
||||||
document
|
|
||||||
.querySelector('#' + selectId)
|
|
||||||
?.addEventListener('change', (e: Event) => {
|
|
||||||
console.log(e.currentTarget);
|
|
||||||
if (!(e.currentTarget instanceof HTMLSelectElement)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
this._showTribeChanges(parseInt(e.currentTarget.value));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private showHistory(e: Event) {
|
private showHistory(e: Event) {
|
||||||
|
|
Loading…
Reference in New Issue