player search

This commit is contained in:
Edgar 2023-08-13 17:05:07 +02:00
parent 315aec40fd
commit 11b00d8097
4 changed files with 46 additions and 22 deletions

11
package-lock.json generated
View file

@ -8,7 +8,8 @@
"name": "ddmaster", "name": "ddmaster",
"version": "0.0.1", "version": "0.0.1",
"dependencies": { "dependencies": {
"date-fns": "^2.30.0" "date-fns": "^2.30.0",
"fuse.js": "^6.6.2"
}, },
"devDependencies": { "devDependencies": {
"@sveltejs/adapter-auto": "^2.1.0", "@sveltejs/adapter-auto": "^2.1.0",
@ -2064,6 +2065,14 @@
"integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==",
"dev": true "dev": true
}, },
"node_modules/fuse.js": {
"version": "6.6.2",
"resolved": "https://registry.npmjs.org/fuse.js/-/fuse.js-6.6.2.tgz",
"integrity": "sha512-cJaJkxCCxC8qIIcPBF9yGxY0W/tVZS3uEISDxhYIdtk8OL93pe+6Zj7LjCqVV4dzbqcriOZ+kQ/NE4RXZHsIGA==",
"engines": {
"node": ">=10"
}
},
"node_modules/glob": { "node_modules/glob": {
"version": "7.2.3", "version": "7.2.3",
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",

View file

@ -33,6 +33,7 @@
}, },
"type": "module", "type": "module",
"dependencies": { "dependencies": {
"date-fns": "^2.30.0" "date-fns": "^2.30.0",
"fuse.js": "^6.6.2"
} }
} }

View file

@ -11,6 +11,7 @@
} }
code_to_country[-1] = { id: 'default', name: '' }; code_to_country[-1] = { id: 'default', name: '' };
code_to_country[906] = { id: 'XCA', name: '' };
export let clients: ClientEntry[]; export let clients: ClientEntry[];
</script> </script>

View file

@ -7,6 +7,7 @@
import { serverStore } from '$lib/stores'; import { serverStore } from '$lib/stores';
import countries from '$lib/countries.json'; import countries from '$lib/countries.json';
import Tee from '$lib/components/Tee.svelte'; import Tee from '$lib/components/Tee.svelte';
import Fuse from 'fuse.js';
interface ClientInfo { interface ClientInfo {
client: ClientEntry; client: ClientEntry;
@ -14,6 +15,14 @@
} }
let players: ClientInfo[] = []; let players: ClientInfo[] = [];
let playerSearch: ClientInfo[] = [];
const fuseOptions = {
includeScore: true,
keys: ['client.name']
};
let fuse: Fuse<ClientInfo> | null = null;
serverStore.subscribe((servers) => { serverStore.subscribe((servers) => {
players = []; players = [];
@ -32,17 +41,14 @@
}); });
}); });
players.reverse(); players.reverse();
playerSearch = players;
fuse = new Fuse(players, fuseOptions);
}); });
let page = 0; let page = 0;
let perPage = 250; let perPage = 250;
let inputSearch = ''; let inputSearch = '';
let currentPlayers: ClientInfo[] = [];
$: {
currentPlayers = players.slice(page * perPage, page * perPage + perPage);
}
async function update() { async function update() {
const servers = await fetchMaster(fetch); const servers = await fetchMaster(fetch);
serverStore.set(servers); serverStore.set(servers);
@ -54,23 +60,30 @@
} }
code_to_country[-1] = { id: 'default', name: '' }; code_to_country[-1] = { id: 'default', name: '' };
code_to_country[906] = { id: 'XCA', name: '' };
const address_re = /.*\/\//; const address_re = /.*\/\//;
let currentPlayers: ClientInfo[] = [];
$: {
currentPlayers = players.slice(page * perPage, page * perPage + perPage);
}
async function onSearch() { async function onSearch() {
const servers = await fetchMaster(fetch); let what = inputSearch.trim();
serverStore.set(servers); if (what.length > 0) {
playerSearch = fuse!.search(what).map((x) => x.item);
} else {
playerSearch = players;
}
page = 0;
}
function truncate(str: string, n: number) {
return str.length > n ? str.slice(0, n - 1) + '...' : str;
} }
</script> </script>
<Button
class="fixed bottom-8 right-8 z-10"
on:click={() =>
window.scrollTo({
top: 0
})}>Go to top</Button
>
<Container> <Container>
<Card class="px-4 py-3"> <Card class="px-4 py-3">
<p class="font-bold text-4xl mb-2">Player Browser</p> <p class="font-bold text-4xl mb-2">Player Browser</p>
@ -92,7 +105,7 @@
</Card> </Card>
<Card class="px-4 py-3 my-2 flex justify-center"> <Card class="px-4 py-3 my-2 flex justify-center">
<Paginate total={Math.floor(players.length / perPage)} bind:page /> <Paginate total={Math.floor(playerSearch.length / perPage)} bind:page />
</Card> </Card>
<div class="flex w-full bg-gray-700 shadow-md"> <div class="flex w-full bg-gray-700 shadow-md">
@ -111,13 +124,13 @@
</tr> </tr>
</thead> </thead>
<tbody class="bg-gray-800 border border-gray-800"> <tbody class="bg-gray-800 border border-gray-800">
{#each currentPlayers as client, index (page * perPage + index)} {#each playerSearch as client, index (page * perPage + index)}
<tr class="border border-gray-700"> <tr class="border border-gray-700">
<td class="px-2 py-2 font-bold text-left">{client.client.name}</td> <td class="px-2 py-2 font-bold text-left">{client.client.name}</td>
<td class="px-2 py-2 font-bold text-left">{client.client.clan}</td> <td class="px-2 py-2 font-bold text-left">{client.client.clan}</td>
<td class="px-2 py-2 font-bold text-left"> <td class="px-2 py-2 font-bold text-left">
{#if client.server.info.map !== undefined} {#if client.server.info.map !== undefined}
{client.server.info.map.name} <span title={client.server.info.map.name}>{truncate(client.server.info.map.name.trim(), 20)}</span>
{/if} {/if}
</td> </td>
<td class="px-2 py-2 font-bold text-left" <td class="px-2 py-2 font-bold text-left"
@ -126,7 +139,7 @@
href={`ddnet://${client.server.addresses[0].replace(address_re, '')}`}>{client.server.info.name}</a href={`ddnet://${client.server.addresses[0].replace(address_re, '')}`}>{client.server.info.name}</a
></td ></td
> >
<td class="px-2 py-2 font-bold text-center flex justify-center" <td class="px-2 py-2 font-bold text-center flex justify-center" title={client.client.country}
>{#if code_to_country[client.client.country] !== undefined} >{#if code_to_country[client.client.country] !== undefined}
<img <img
alt={code_to_country[client.client.country].name} alt={code_to_country[client.client.country].name}
@ -152,6 +165,6 @@
</div> </div>
<Card class="px-4 py-3 my-2 flex justify-center"> <Card class="px-4 py-3 my-2 flex justify-center">
<Paginate total={Math.floor(players.length / perPage)} bind:page /> <Paginate total={Math.floor(playerSearch.length / perPage)} bind:page />
</Card> </Card>
</Container> </Container>