Add multiselection

This commit is contained in:
2023-06-20 12:24:33 +02:00
parent 8bdfc2586a
commit a6e75006e6
3 changed files with 92 additions and 26 deletions
+5 -3
View File
@@ -57,12 +57,14 @@ function registerWebSocketKill (data : websocketData) {
return objectEqual(filterWithoutPlayer, e.value.filter) return objectEqual(filterWithoutPlayer, e.value.filter)
})) }))
if (!list) return if (!list) return
if (!(!list.filter.server || list.filter.server === data.servername)) return if (!(!list.filter.server || list.filter.server.includes(data.servername))) return
const WeaponFilter = (!list.filter.weapon || list.filter.weapon === data.cause_of_death) const WeaponFilter = (!list.filter.weapon || list.filter.weapon.includes(data.cause_of_death))
const CurrentWeaponFilter = list.filter.weapon === data.attacker_current_weapon const CurrentWeaponFilter = list.filter.weapon?.includes(data.attacker_current_weapon)
if (!(WeaponFilter || CurrentWeaponFilter)) return if (!(WeaponFilter || CurrentWeaponFilter)) return
if (!(!list.filter.gamemode || list.filter.gamemode.includes(data.game_mode))) return
if (!list.data[data.victim_id]) { if (!list.data[data.victim_id]) {
list.data[data.victim_id] = ref({ list.data[data.victim_id] = ref({
deaths: 0, deaths: 0,
+34 -8
View File
@@ -3,12 +3,12 @@ import * as assert from 'assert'
import { Ref, ref, shallowRef, triggerRef, unref } from 'vue' import { Ref, ref, shallowRef, triggerRef, unref } from 'vue'
export interface Filters { export interface Filters {
server?: string; server?: string[];
player?: string; player?: string;
weapon?: string; weapon?: string[];
host?: string; host?: string[];
map?: string; map?: string[];
gamemode?: string; gamemode?: string[];
} }
export function removeNullEntries (a: Filters) { export function removeNullEntries (a: Filters) {
@@ -155,6 +155,8 @@ export const useKillStore = defineStore('kill', {
state.weapons.find((e) => objectEqual(unref(e).filter, filters)), state.weapons.find((e) => objectEqual(unref(e).filter, filters)),
getServerList: (state) => (filters: Filters) => getServerList: (state) => (filters: Filters) =>
state.servers.find((e) => objectEqual(unref(e).filter, filters)), state.servers.find((e) => objectEqual(unref(e).filter, filters)),
getGamemodeList: (state) => (filters: Filters) =>
state.gamemodes.find((e) => objectEqual(unref(e).filter, filters)),
getNSServers: (state) => state.nsServers getNSServers: (state) => state.nsServers
}, },
actions: { actions: {
@@ -167,7 +169,7 @@ export const useKillStore = defineStore('kill', {
} }
fetchWithLoading( fetchWithLoading(
'https://tone.sleepycat.date/v2/client/players?' + 'https://tone.sleepycat.date/v2/client/players?' +
new URLSearchParams(filter as Record<keyof Filters, string>), new URLSearchParams(Object.entries(filter).map<string[][]>(e => [e[1]].flat().map(v => [e[0], v])).flat(1)),
(progress) => { (progress) => {
if (entry && unref(entry).progress !== 1) { if (entry && unref(entry).progress !== 1) {
unref(entry).progress = progress unref(entry).progress = progress
@@ -192,7 +194,7 @@ export const useKillStore = defineStore('kill', {
fetchWithLoading( fetchWithLoading(
'https://tone.sleepycat.date/v2/client/weapons?' + 'https://tone.sleepycat.date/v2/client/weapons?' +
new URLSearchParams(filter as Record<keyof Filters, string>), new URLSearchParams(Object.entries(filter).map<string[][]>(e => [e[1]].flat().map(v => [e[0], v])).flat(1)),
(progress) => { (progress) => {
if (entry && unref(entry).progress !== 1) { if (entry && unref(entry).progress !== 1) {
unref(entry).progress = progress unref(entry).progress = progress
@@ -216,7 +218,7 @@ export const useKillStore = defineStore('kill', {
} }
fetchWithLoading( fetchWithLoading(
'https://tone.sleepycat.date/v2/client/servers?' + 'https://tone.sleepycat.date/v2/client/servers?' +
new URLSearchParams(filter as Record<keyof Filters, string>), new URLSearchParams(Object.entries(filter).map<string[][]>(e => [e[1]].flat().map(v => [e[0], v])).flat(1)),
(progress) => { (progress) => {
if (entry && unref(entry).progress !== 1) { if (entry && unref(entry).progress !== 1) {
unref(entry).progress = progress unref(entry).progress = progress
@@ -231,6 +233,30 @@ export const useKillStore = defineStore('kill', {
}) })
return entry return entry
}, },
fetchGamemodes (filter: Filters) {
filter = removeNullEntries(filter)
let entry = this.gamemodes.find((e) => objectEqual(unref(e).filter, filter))
if (!entry) {
entry = shallowRef({ filter, data: {} })
this.gamemodes.push(entry)
}
fetchWithLoading(
'https://tone.sleepycat.date/v2/client/gamemodes?' +
new URLSearchParams(Object.entries(filter).map<string[][]>(e => [e[1]].flat().map(v => [e[0], v])).flat(1)),
(progress) => {
if (entry && unref(entry).progress !== 1) {
unref(entry).progress = progress
if (progress !== 1) triggerRef(entry)
}
}
).then(async response => {
if (entry) {
unref(entry).data = Object.fromEntries(Object.entries(await response?.json()).map(e => [e[0], ref(e[1] as Kill)]))
triggerRef(entry)
}
})
return entry
},
fetchNSServers () { fetchNSServers () {
fetch( fetch(
'https://northstar.tf/client/servers').then(async response => { 'https://northstar.tf/client/servers').then(async response => {
+53 -15
View File
@@ -8,11 +8,28 @@
v-model="model.server" v-model="model.server"
:options="sortedServerList" :options="sortedServerList"
:allow-empty="true" :allow-empty="true"
:close-on-select="false"
:multiple="true"
> >
</VueMultiselect> </VueMultiselect>
<button @click="model.server = undefined" :disabled="!model.server">X</button> <button @click="model.server = undefined" :disabled="!model.server">X</button>
</span> </span>
<span class="multiselect-wrapper">
<VueMultiselect
selectLabel=""
deselectLabel="remove"
placeholder="Select gamemode"
v-model="model.gamemode"
:options="sortedGamemodeList"
:allow-empty="true"
:close-on-select="false"
:multiple="true"
>
</VueMultiselect>
<button @click="model.gamemode = undefined" :disabled="!model.gamemode">X</button>
</span>
<span class="multiselect-wrapper"> <span class="multiselect-wrapper">
<VueMultiselect <VueMultiselect
selectLabel="" selectLabel=""
@@ -40,6 +57,7 @@
></VueMultiselect> ></VueMultiselect>
<button @click="playerHighlighted = undefined" :disabled="!playerHighlighted">X</button> <button @click="playerHighlighted = undefined" :disabled="!playerHighlighted">X</button>
</span> </span>
<button @click="applyFilters" :disabled="filters.server == model.server && filters.gamemode == model.gamemode && filters.weapon == model.weapon">Apply Filters</button>
</div> </div>
<div id="playerView"> <div id="playerView">
@@ -65,7 +83,7 @@
</template> </template>
<script lang="ts"> <script lang="ts">
import { Player, Weapon, Server, useKillStore, Filters } from '@/stores/kill' import { Player, Weapon, Server, Kill, useKillStore, Filters } from '@/stores/kill'
import PlayerList from '@/components/PlayerList.vue' import PlayerList from '@/components/PlayerList.vue'
import PlayerChart from '@/components/PlayerChart.vue' import PlayerChart from '@/components/PlayerChart.vue'
import WeaponChart from '@/components/WeaponChart.vue' import WeaponChart from '@/components/WeaponChart.vue'
@@ -87,8 +105,9 @@ export default defineComponent({
data () { data () {
return { return {
model: { server: undefined, weapon: undefined } as unknown as { model: { server: undefined, weapon: undefined } as unknown as {
weapon: string | undefined; weapon: string[] | undefined;
server: string | undefined; server: string[] | undefined;
gamemode: string[] | undefined;
}, },
filters: {} as Filters, filters: {} as Filters,
store: useKillStore(), store: useKillStore(),
@@ -98,10 +117,13 @@ export default defineComponent({
}, },
beforeCreate () { beforeCreate () {
let server let server
if (this.$route.query.server) server = this.$route.query.server?.toString() if (this.$route.query.server) server = [this.$route.query.server?.toString()]
this.model = { this.model = {
server, server,
weapon: this.$route.query.weapon?.toString() // eslint-disable-next-line @typescript-eslint/no-non-null-assertion
weapon: [this.$route.query.weapon].flat().filter(e => e ?? false).map(e => e!.toString()),
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
gamemode: [this.$route.query.gamemode].flat().filter(e => e ?? false).map(e => e!.toString())
} }
}, },
computed: { computed: {
@@ -140,6 +162,13 @@ export default defineComponent({
if (!data) return this.store.fetchPlayers(withoutPlayers).value.data if (!data) return this.store.fetchPlayers(withoutPlayers).value.data
return data return data
}, },
gamemodes (): { [key: string]: Ref<Kill> } {
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const { gamemode: _, player: _1, ...withoutGamemode } = this.filters
const data = this.store.getGamemodeList(withoutGamemode)?.value.data
if (!data) return this.store.fetchGamemodes(withoutGamemode).value.data
return data
},
sortedWeaponList (): string[] { sortedWeaponList (): string[] {
if (!this.weapons) return [] if (!this.weapons) return []
const weapons = Object.keys(this.weapons) const weapons = Object.keys(this.weapons)
@@ -150,6 +179,11 @@ export default defineComponent({
const servers = Object.keys(this.servers) const servers = Object.keys(this.servers)
return servers.sort() return servers.sort()
}, },
sortedGamemodeList (): string[] {
if (!this.gamemodes) return []
const gamemodes = Object.keys(this.gamemodes)
return gamemodes.sort()
},
sortedPlayerList (): Player[] { sortedPlayerList (): Player[] {
if (!this.players) return [] if (!this.players) return []
const players = Object.entries(this.players).map((e) => ({ const players = Object.entries(this.players).map((e) => ({
@@ -174,17 +208,10 @@ export default defineComponent({
this.highlight_player(player) this.highlight_player(player)
} }
}, },
model: {
handler (newModel) {
this.filters.server = newModel.server
this.filters.weapon = newModel.weapon
},
deep: true
},
filters: { filters: {
handler (newValue) { handler (newValue) {
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
const { server: _, weapon: _2, ...withoutFilters } = this.$route.query const { server: _, weapon: _2, gamemode: _3, ...withoutFilters } = this.$route.query
router.push({ query: { ...newValue, ...withoutFilters } })// .then(e => { console.log(e) }) router.push({ query: { ...newValue, ...withoutFilters } })// .then(e => { console.log(e) })
this.store.setFilter({ player: this.store.currentFilter.player, ...newValue }) this.store.setFilter({ player: this.store.currentFilter.player, ...newValue })
}, },
@@ -205,6 +232,11 @@ export default defineComponent({
} }
}, },
methods: { methods: {
applyFilters () {
this.filters.server = this.model.server
this.filters.weapon = this.model.weapon
this.filters.gamemode = this.model.gamemode
},
highlight_player (playerid: string) { highlight_player (playerid: string) {
const player = this.players[playerid] const player = this.players[playerid]
if (player) { if (player) {
@@ -221,12 +253,18 @@ export default defineComponent({
} }
} }
if (this.filters.weapon !== this.$route.query.weapon) { if (this.filters.weapon !== this.$route.query.weapon) {
this.model.weapon = this.$route.query.weapon?.toString() this.model.weapon = [this.$route.query.weapon].flat().filter(e => e ?? false).map(e => e!.toString())
} }
if (this.filters.server !== this.$route.query.server) { if (this.filters.server !== this.$route.query.server) {
if (this.$route.query.server) this.model.server = this.$route.query.server?.toString() if (this.$route.query.server) this.model.server = [this.$route.query.server].flat().filter(e => e ?? false).map(e => e!.toString())
else this.model.server = undefined else this.model.server = undefined
} }
if (this.filters.gamemode !== this.$route.query.gamemode) {
if (this.$route.query.gamemode) this.model.gamemode = [this.$route.query.gamemode].flat().filter(e => e ?? false).map(e => e!.toString())
else this.model.gamemode = undefined
}
console.log(this.model, this.$route.query)
} }
} }
}) })