Some optimizations and virtual list
This commit is contained in:
Vendored
+7
@@ -0,0 +1,7 @@
|
|||||||
|
import { Ref } from '@vue/reactivity'
|
||||||
|
|
||||||
|
declare module '@vue/reactivity' {
|
||||||
|
export interface Ref<T> extends Ref<T> {
|
||||||
|
_rawValue: T
|
||||||
|
}
|
||||||
|
}
|
||||||
+2
-7
@@ -16,16 +16,11 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Player, Weapon, Server, useKillStore } from '@/stores/kill'
|
|
||||||
import { defineComponent } from 'vue'
|
import { defineComponent } from 'vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
setup () {
|
|
||||||
/* const store = useKillStore()
|
|
||||||
store.fetchPlayers({})
|
|
||||||
store.fetchServers({})
|
|
||||||
store.fetchWeapons({}) */
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,23 @@
|
|||||||
|
<template>
|
||||||
|
<div >
|
||||||
|
test
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { defineComponent, PropType, Ref, toRaw, unref } from 'vue'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
components: { },
|
||||||
|
props: {
|
||||||
|
},
|
||||||
|
emits: ['highlightPlayer'],
|
||||||
|
data () {
|
||||||
|
return { test: 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
</style>
|
||||||
@@ -0,0 +1,100 @@
|
|||||||
|
<template>
|
||||||
|
<div ref="vlist" class="vlist" @scroll="scroll">
|
||||||
|
<div ref="vscroll" class="vscroll" :style="`padding: ${(vIndex*$props.rowHeight!)}px 0px ${(list.length*$props.rowHeight!)-(vIndex*$props.rowHeight!)}px;`">
|
||||||
|
<div :class="'playerRow ' + (player.id === $props.highlighted ? 'selected' : '')" v-for="(player, index) in visibleList"
|
||||||
|
v-bind:key="player.id" v-on:click="$emit('highlightPlayer', player.id)" :ref="`player:` + player.id">
|
||||||
|
<div><span>{{ index + 1 + vIndex }}</span></div>
|
||||||
|
<div><span>{{ player.value.username }}</span></div>
|
||||||
|
<div><span>{{ player.value.kills }}</span></div>
|
||||||
|
<div><span>{{ player.value.deaths }}</span></div>
|
||||||
|
<div><span>{{ Math.round(player.value.kills / Math.max(1, player.value.deaths) * 100) / 100 }}</span></div>
|
||||||
|
<div><span>{{ player.value.max_distance }}</span></div>
|
||||||
|
<div><span>{{ Math.round(((player.value.total_distance / player.value.kills) || 0) * 100) / 100 }}</span></div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts">
|
||||||
|
import { Player } from '@/stores/kill'
|
||||||
|
import { defineComponent, PropType, Ref } from 'vue'
|
||||||
|
|
||||||
|
export default defineComponent({
|
||||||
|
data () {
|
||||||
|
return {
|
||||||
|
toLoad: 10,
|
||||||
|
vlistHeight: 0,
|
||||||
|
vIndex: 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
list: { type: Array as PropType<(Ref<Player> & { id: string })[]>, default: () => [] },
|
||||||
|
rowHeight: { type: Number, default: () => 32 },
|
||||||
|
highlighted: String
|
||||||
|
},
|
||||||
|
emits: ['highlightPlayer'],
|
||||||
|
|
||||||
|
computed: {
|
||||||
|
visibleList () {
|
||||||
|
return this.list.slice(Math.max(this.vIndex, 0), Math.min(this.vIndex + this.visibleCount * 3, this.list.length))
|
||||||
|
},
|
||||||
|
visibleCount () {
|
||||||
|
return Math.ceil(this.vlistHeight / this.$props.rowHeight)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
watch: {
|
||||||
|
list () {
|
||||||
|
this.vlistHeight = (this.$refs.vlist as HTMLElement)?.getBoundingClientRect().height || 0
|
||||||
|
},
|
||||||
|
highlighted (newVal) {
|
||||||
|
setTimeout(() => (this.$refs.vlist as HTMLElement)?.scrollBy({ top: ((this.list.findIndex(e => e.id === newVal)) * this.rowHeight) - ((this.$refs.vlist as HTMLElement))?.scrollTop - (this.vlistHeight / 2 - this.$props.rowHeight), behavior: 'smooth' }), 1)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
scroll (e:Event) {
|
||||||
|
const scrollTop = (e.target as HTMLElement)?.scrollTop
|
||||||
|
const scrollIndex = Math.round(scrollTop / this.$props.rowHeight)
|
||||||
|
|
||||||
|
const mustScrollUp = Math.max(0, scrollIndex - (this.visibleCount)) < this.vIndex
|
||||||
|
const mustScrollDown = Math.min(this.list.length, scrollIndex + (this.visibleCount)) > this.vIndex + (this.visibleCount * 2)
|
||||||
|
if (mustScrollUp) {
|
||||||
|
this.vIndex = Math.max(0, Math.floor((scrollIndex - this.visibleCount) / 4) * 4)
|
||||||
|
} else if (mustScrollDown) {
|
||||||
|
this.vIndex = Math.max(0, Math.floor(scrollIndex / 4) * 4)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style scoped>
|
||||||
|
.vlist{
|
||||||
|
overflow-y:auto;
|
||||||
|
}
|
||||||
|
.vlist, .vscroll {
|
||||||
|
height: calc(100% - 3em);
|
||||||
|
}
|
||||||
|
|
||||||
|
.playerRow:nth-child(2n+1) {
|
||||||
|
background: var(--accent);
|
||||||
|
}
|
||||||
|
|
||||||
|
.playerRow:nth-child(2n) {
|
||||||
|
background: var(--current-line);
|
||||||
|
}
|
||||||
|
|
||||||
|
.playerRow:hover {
|
||||||
|
background: var(--bg-color);
|
||||||
|
}
|
||||||
|
|
||||||
|
.playerRow>div:not(:last-child){
|
||||||
|
border-right: solid var(--bg-color) 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.playerRow>div {
|
||||||
|
padding: .5em .8em 0 .25em;
|
||||||
|
overflow: hidden;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
@@ -22,7 +22,7 @@ import dataLabel from 'chartjs-plugin-datalabels'
|
|||||||
import { useKillStore, Player, Filters } from '@/stores/kill'
|
import { useKillStore, Player, Filters } from '@/stores/kill'
|
||||||
|
|
||||||
import { Scatter } from 'vue-chartjs'
|
import { Scatter } from 'vue-chartjs'
|
||||||
import { defineComponent, PropType, toRaw, unref } from 'vue'
|
import { defineComponent, PropType, Ref, toRaw, triggerRef, unref } from 'vue'
|
||||||
import { ChartEvent } from 'chart.js/dist/core/core.plugins'
|
import { ChartEvent } from 'chart.js/dist/core/core.plugins'
|
||||||
import { _DeepPartialObject } from 'chart.js/dist/types/utils'
|
import { _DeepPartialObject } from 'chart.js/dist/types/utils'
|
||||||
|
|
||||||
@@ -74,7 +74,6 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
return colors
|
return colors
|
||||||
},
|
},
|
||||||
|
|
||||||
chart () {
|
chart () {
|
||||||
const playerIndex = this.playerList.findIndex(e => e.id === this.$props.playerHighlighted)
|
const playerIndex = this.playerList.findIndex(e => e.id === this.$props.playerHighlighted)
|
||||||
const defaultColor = this.colors.cyan
|
const defaultColor = this.colors.cyan
|
||||||
@@ -132,6 +131,7 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
onClick: (e: ChartEvent, element: any) => {
|
onClick: (e: ChartEvent, element: any) => {
|
||||||
this.$emit('highlightPlayer', element.length > 0 ? this.playerList[element[0].index].id : undefined)
|
this.$emit('highlightPlayer', element.length > 0 ? this.playerList[element[0].index].id : undefined)
|
||||||
|
if (this.store.getPlayerList(this.filters || {}) !== undefined) triggerRef(this.store.getPlayerList(this.filters || {}) as unknown as Ref)
|
||||||
},
|
},
|
||||||
onHover: (e: any, element: any) => {
|
onHover: (e: any, element: any) => {
|
||||||
if (!e.native.target) return
|
if (!e.native.target) return
|
||||||
@@ -210,6 +210,11 @@ export default defineComponent({
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
/* methods: {
|
||||||
|
refreshChart () {
|
||||||
|
if (this.store.getPlayerList(this.filters || {}) !== undefined) triggerRef(this.store.getPlayerList(this.filters || {}) as unknown as Ref)
|
||||||
|
}
|
||||||
|
} */
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
@@ -217,7 +222,14 @@ export default defineComponent({
|
|||||||
canvas {
|
canvas {
|
||||||
background: var(--accent);
|
background: var(--accent);
|
||||||
}
|
}
|
||||||
|
.playerChart{
|
||||||
|
position:relative;
|
||||||
|
}
|
||||||
|
#refreshChart{
|
||||||
|
position:absolute;
|
||||||
|
top: 0;
|
||||||
|
left:0;
|
||||||
|
}
|
||||||
@media only screen and (max-width: 922px) {
|
@media only screen and (max-width: 922px) {
|
||||||
canvas {
|
canvas {
|
||||||
display: none !important
|
display: none !important
|
||||||
|
|||||||
@@ -7,13 +7,14 @@
|
|||||||
<span v-on:click="updateSort('kills')" :class="sortingData.argument == 'kills' ? 'selected' : ''">K</span>
|
<span v-on:click="updateSort('kills')" :class="sortingData.argument == 'kills' ? 'selected' : ''">K</span>
|
||||||
<span v-on:click="updateSort('deaths')" :class="sortingData.argument == 'deaths' ? 'selected' : ''">D</span>
|
<span v-on:click="updateSort('deaths')" :class="sortingData.argument == 'deaths' ? 'selected' : ''">D</span>
|
||||||
<span v-on:click="updateSort('k/d')" :class="sortingData.argument == 'k/d' ? 'selected' : ''">K/D</span>
|
<span v-on:click="updateSort('k/d')" :class="sortingData.argument == 'k/d' ? 'selected' : ''">K/D</span>
|
||||||
<span v-on:click="updateSort('max_distance')"
|
<span v-on:click="updateSort('max_distance')" :class="sortingData.argument == 'max_distance' ? 'selected' : ''">max
|
||||||
:class="sortingData.argument == 'max_distance' ? 'selected' : ''">max distance</span>
|
distance</span>
|
||||||
<span v-on:click="updateSort('avg_distance')"
|
<span v-on:click="updateSort('avg_distance')"
|
||||||
:class="sortingData.argument == 'avg_distance' ? 'selected' : ''">average distance</span>
|
:class="sortingData.argument == 'avg_distance' ? 'selected' : ''">average distance</span>
|
||||||
</div>
|
</div>
|
||||||
<div :class="'playerRow ' + (player.id === $props.playerHighlighted ? 'selected' : '')"
|
<VirtualList :list="playerList" :row-height="32" @highlightPlayer="$emit('highlightPlayer', $event)" :highlighted="playerHighlighted"></VirtualList>
|
||||||
v-for="(player, index) in playerList" v-bind:key="player.id" v-on:click="$emit('highlightPlayer', player.id)"
|
<!-- <div :class="'playerRow ' + (player.id === $props.playerHighlighted ? 'selected' : '')"
|
||||||
|
v-on:click="$emit('highlightPlayer', player.id)"
|
||||||
:ref="`player:` + player.id">
|
:ref="`player:` + player.id">
|
||||||
<div><span>{{ index+1 }}</span></div>
|
<div><span>{{ index+1 }}</span></div>
|
||||||
<div><span>{{ player.value.username }}</span></div>
|
<div><span>{{ player.value.username }}</span></div>
|
||||||
@@ -22,15 +23,17 @@
|
|||||||
<div><span>{{ Math.round(player.value.kills / Math.max(1, player.value.deaths) * 100) / 100 }}</span></div>
|
<div><span>{{ Math.round(player.value.kills / Math.max(1, player.value.deaths) * 100) / 100 }}</span></div>
|
||||||
<div><span>{{ player.value.max_distance }}</span></div>
|
<div><span>{{ player.value.max_distance }}</span></div>
|
||||||
<div><span>{{ Math.round(((player.value.total_distance / player.value.kills) || 0) * 100) / 100 }}</span></div>
|
<div><span>{{ Math.round(((player.value.total_distance / player.value.kills) || 0) * 100) / 100 }}</span></div>
|
||||||
</div>
|
</div> -->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, PropType, Ref, toRaw, unref } from 'vue'
|
import { defineComponent, PropType, Ref } from 'vue'
|
||||||
import { useKillStore, Player, Filters } from '@/stores/kill'
|
import { useKillStore, Player, Filters } from '@/stores/kill'
|
||||||
|
import VirtualList from './List/VirtualList.vue'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
|
components: { VirtualList },
|
||||||
props: {
|
props: {
|
||||||
filters: { type: Object as PropType<Filters>, default: () => ({}) },
|
filters: { type: Object as PropType<Filters>, default: () => ({}) },
|
||||||
playerHighlighted: String
|
playerHighlighted: String
|
||||||
@@ -44,6 +47,7 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
players (): { [key: string]: Ref<Player> } {
|
players (): { [key: string]: Ref<Player> } {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
const { player: _, ...withoutPlayer } = this.filters
|
const { player: _, ...withoutPlayer } = this.filters
|
||||||
const data = this.store.getPlayerList(withoutPlayer)?.value.data
|
const data = this.store.getPlayerList(withoutPlayer)?.value.data
|
||||||
if (!data) return this.store.fetchPlayers(withoutPlayer).value.data
|
if (!data) return this.store.fetchPlayers(withoutPlayer).value.data
|
||||||
@@ -51,38 +55,49 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
playerList (): (Ref<Player> & { id: string })[] {
|
playerList (): (Ref<Player> & { id: string })[] {
|
||||||
if (!this.players) return []
|
if (!this.players) return []
|
||||||
let players = Object.entries(this.players).map(e => {
|
const players = Object.entries(this.players).map(e => {
|
||||||
const target = {} as ProxyHandler<Ref<Player>>
|
const target = {} as ProxyHandler<Ref<Player>>
|
||||||
const player = new Proxy(e[1], target) as Ref<Player> & { id: string }
|
const player = new Proxy(e[1], target) as Ref<Player> & { id: string }
|
||||||
player.id = e[0]
|
player.id = e[0]
|
||||||
return player
|
return player
|
||||||
}) as (Ref<Player> & { id: string })[]
|
}) as (Ref<Player> & { id: string })[]
|
||||||
|
|
||||||
|
const date = new Date()
|
||||||
if (this.sortingData.argument === 'username') {
|
if (this.sortingData.argument === 'username') {
|
||||||
const collator = new Intl.Collator('en', { numeric: true, sensitivity: 'base' })
|
const collator = new Intl.Collator('en', { numeric: true, sensitivity: 'base' })
|
||||||
players.sort((a: Ref<Player>, b: Ref<Player>) => {
|
players.sort((a, b) => {
|
||||||
return collator.compare(toRaw(a.value).username, toRaw(b.value).username)
|
// Hack because toRaw is slow as fuck
|
||||||
|
const aVal = a._rawValue
|
||||||
|
const bVal = b._rawValue
|
||||||
|
return collator.compare(aVal.username, bVal.username)
|
||||||
})
|
})
|
||||||
} else if (this.sortingData.argument === 'k/d') {
|
} else if (this.sortingData.argument === 'k/d') {
|
||||||
players.sort((a: Ref<Player>, b: Ref<Player>) => {
|
players.sort((a, b) => {
|
||||||
return toRaw(a.value).kills / Math.max(1, toRaw(a.value).deaths) - toRaw(b.value).kills / Math.max(1, toRaw(b.value).deaths)
|
// Hack because toRaw is slow as fuck
|
||||||
|
const aVal = a._rawValue
|
||||||
|
const bVal = b._rawValue
|
||||||
|
return aVal.kills / Math.max(1, aVal.deaths) - bVal.kills / Math.max(1, bVal.deaths)
|
||||||
})
|
})
|
||||||
} else if (this.sortingData.argument === 'avg_distance') {
|
} else if (this.sortingData.argument === 'avg_distance') {
|
||||||
players.sort((a: Ref<Player>, b: Ref<Player>) => {
|
players.sort((a, b) => {
|
||||||
return ((toRaw(a.value).total_distance / toRaw(a.value).kills) || 0) - ((toRaw(b.value).total_distance / toRaw(b.value).kills) || 0)
|
// Hack because toRaw is slow as fuck
|
||||||
|
const aVal = a._rawValue
|
||||||
|
const bVal = b._rawValue
|
||||||
|
return ((aVal.total_distance / aVal.kills) || 0) - ((bVal.total_distance / bVal.kills) || 0)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
const argument = this.sortingData.argument
|
const argument = this.sortingData.argument
|
||||||
players.sort((a: Ref<Player>, b: Ref<Player>) => {
|
players.sort((a, b) => {
|
||||||
return toRaw(a.value)[argument] - toRaw(b.value)[argument]
|
// Hack because toRaw is slow as fuck
|
||||||
|
const aVal = a._rawValue
|
||||||
|
const bVal = b._rawValue
|
||||||
|
return aVal[argument] - bVal[argument]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
console.log('Sorting the player object took + ' + ((new Date()).getTime() - date.getTime()) + 'ms')
|
||||||
if (this.sortingData.direction < 0) {
|
if (this.sortingData.direction < 0) {
|
||||||
players.reverse()
|
players.reverse()
|
||||||
}
|
}
|
||||||
|
|
||||||
players = players.slice(0, 500)
|
|
||||||
return players
|
return players
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@@ -140,15 +155,14 @@ export default defineComponent({
|
|||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style>
|
||||||
* {
|
.playerTable * {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
.playerTable {
|
.playerTable {
|
||||||
grid-area: list;
|
grid-area: list;
|
||||||
margin-right: 1rem;
|
margin-right: 1rem;
|
||||||
overflow: auto;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
@@ -177,26 +191,14 @@ export default defineComponent({
|
|||||||
padding: .5em .8em 0 .25em;
|
padding: .5em .8em 0 .25em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.playerRow>div {
|
.playerHeaders{
|
||||||
padding: .5em .8em 0 .25em;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
|
||||||
|
|
||||||
.playerHeaders,
|
|
||||||
.playerRow:nth-child(2n) {
|
|
||||||
background: var(--current-line);
|
background: var(--current-line);
|
||||||
}
|
}
|
||||||
|
|
||||||
.playerRow:nth-child(2n+1) {
|
.playerHeaders div:hover {
|
||||||
background: var(--accent);
|
|
||||||
}
|
|
||||||
|
|
||||||
.playerHeaders div:hover,
|
|
||||||
.playerRow:hover {
|
|
||||||
background: var(--bg-color);
|
background: var(--bg-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.playerRow>div:not(:last-child),
|
|
||||||
.playerHeaders>div:not(:last-child) {
|
.playerHeaders>div:not(:last-child) {
|
||||||
border-right: solid var(--bg-color) 2px;
|
border-right: solid var(--bg-color) 2px;
|
||||||
}
|
}
|
||||||
@@ -226,4 +228,5 @@ export default defineComponent({
|
|||||||
|
|
||||||
.selected {
|
.selected {
|
||||||
background: var(--comment) !important;
|
background: var(--comment) !important;
|
||||||
}</style>
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import { Chart as ChartJS, ArcElement, Tooltip, Legend } from 'chart.js'
|
|||||||
import dataLabel from 'chartjs-plugin-datalabels'
|
import dataLabel from 'chartjs-plugin-datalabels'
|
||||||
import { Weapon, Filters, useKillStore } from '@/stores/kill'
|
import { Weapon, Filters, useKillStore } from '@/stores/kill'
|
||||||
import { Doughnut } from 'vue-chartjs'
|
import { Doughnut } from 'vue-chartjs'
|
||||||
import { defineComponent, PropType, Ref, unref } from 'vue'
|
import { defineComponent, PropType, Ref } from 'vue'
|
||||||
import weapons from '../stores/weapons.json'
|
import weapons from '../stores/weapons.json'
|
||||||
|
|
||||||
ChartJS.register(ArcElement, Tooltip, Legend, dataLabel)
|
ChartJS.register(ArcElement, Tooltip, Legend, dataLabel)
|
||||||
|
|||||||
+4
-2
@@ -23,8 +23,10 @@ const websocketData = {
|
|||||||
host: 1
|
host: 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// dev stuff
|
||||||
|
|
||||||
const store = useKillStore()
|
const store = useKillStore()
|
||||||
setInterval(() => {
|
function registerWebSocketKill () {
|
||||||
const allPlayerArrays = store.$state.players.filter((e) => {
|
const allPlayerArrays = store.$state.players.filter((e) => {
|
||||||
return (
|
return (
|
||||||
(!e.value.filter.server ||
|
(!e.value.filter.server ||
|
||||||
@@ -106,4 +108,4 @@ setInterval(() => {
|
|||||||
unref(e.value.data[websocketData.cause_of_death]).kills++
|
unref(e.value.data[websocketData.cause_of_death]).kills++
|
||||||
unref(e.value.data[websocketData.cause_of_death]).max_distance = Math.max(websocketData.distance, unref(e.value.data[websocketData.cause_of_death]).max_distance)
|
unref(e.value.data[websocketData.cause_of_death]).max_distance = Math.max(websocketData.distance, unref(e.value.data[websocketData.cause_of_death]).max_distance)
|
||||||
})
|
})
|
||||||
}, 100)
|
}
|
||||||
|
|||||||
@@ -1,16 +1,5 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="filters">
|
<div id="filters">
|
||||||
<!-- <input type="number" min="0" v-model="filters.minKills">
|
|
||||||
<input type="number" min="0" v-model="filters.minDeaths"> -->
|
|
||||||
<!-- <select v-on:change="changeFilter({ server: ($event.target as HTMLInputElement).value })">
|
|
||||||
<option></option>
|
|
||||||
<option v-for="(serverData) in servers" v-bind:key="serverData.id" :value="serverData.id">{{ serverData.name }}
|
|
||||||
</option>
|
|
||||||
</select>
|
|
||||||
<select v-on:change="changeFilter({ weapon: ($event.target as HTMLInputElement).value })">
|
|
||||||
<option></option>
|
|
||||||
<option v-for="weaponId in sortedWeaponList" v-bind:key="weaponId" :value="weaponId">{{ weaponId }}</option>
|
|
||||||
</select> -->
|
|
||||||
<span class="multiselect-wrapper">
|
<span class="multiselect-wrapper">
|
||||||
<VueMultiselect
|
<VueMultiselect
|
||||||
selectLabel=""
|
selectLabel=""
|
||||||
@@ -67,6 +56,7 @@
|
|||||||
:playerHighlighted="playerHighlighted?.id"
|
:playerHighlighted="playerHighlighted?.id"
|
||||||
>
|
>
|
||||||
</PlayerList>
|
</PlayerList>
|
||||||
|
|
||||||
<PlayerChart
|
<PlayerChart
|
||||||
:filters="filters"
|
:filters="filters"
|
||||||
v-on:highlightPlayer="highlight_player"
|
v-on:highlightPlayer="highlight_player"
|
||||||
@@ -86,7 +76,7 @@ import { Player, Weapon, Server, 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'
|
||||||
import { Ref, defineComponent, toRaw, unref } from 'vue'
|
import { Ref, defineComponent, unref } from 'vue'
|
||||||
import VueMultiselect from 'vue-multiselect'
|
import VueMultiselect from 'vue-multiselect'
|
||||||
import 'vue-multiselect/dist/vue-multiselect.css'
|
import 'vue-multiselect/dist/vue-multiselect.css'
|
||||||
import weapons from '../stores/weapons.json'
|
import weapons from '../stores/weapons.json'
|
||||||
@@ -171,9 +161,9 @@ export default defineComponent({
|
|||||||
if (!this.players) return []
|
if (!this.players) return []
|
||||||
const players = Object.entries(this.players).map((e) => ({
|
const players = Object.entries(this.players).map((e) => ({
|
||||||
id: e[0],
|
id: e[0],
|
||||||
...toRaw(e[1].value)
|
...e[1]._rawValue
|
||||||
}))
|
}))
|
||||||
return players.sort((a: Player, b: Player) => {
|
return players.sort((a, b) => {
|
||||||
if (a.username < b.username) {
|
if (a.username < b.username) {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
@@ -202,7 +192,7 @@ export default defineComponent({
|
|||||||
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, ...withoutFilters } = this.$route.query
|
||||||
router.push({ query: { ...newValue, ...withoutFilters } }).then(e => { console.log(e) })
|
router.push({ query: { ...newValue, ...withoutFilters } })// .then(e => { console.log(e) })
|
||||||
},
|
},
|
||||||
deep: true
|
deep: true
|
||||||
},
|
},
|
||||||
@@ -210,7 +200,7 @@ export default defineComponent({
|
|||||||
if (newValue?.id === oldValue?.id) return
|
if (newValue?.id === oldValue?.id) return
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
const { player: _, ...withoutPlayer } = this.$route.query
|
const { player: _, ...withoutPlayer } = this.$route.query
|
||||||
router.push({ query: { player: newValue?.id, ...withoutPlayer } }).then(e => { console.log(e) })
|
router.push({ query: { player: newValue?.id, ...withoutPlayer } })// .then(e => { console.log(e) })
|
||||||
},
|
},
|
||||||
'$route' (to) {
|
'$route' (to) {
|
||||||
if (this.playerHighlighted?.id !== to.query.player) {
|
if (this.playerHighlighted?.id !== to.query.player) {
|
||||||
|
|||||||
@@ -14,6 +14,7 @@
|
|||||||
"useDefineForClassFields": true,
|
"useDefineForClassFields": true,
|
||||||
"sourceMap": true,
|
"sourceMap": true,
|
||||||
"baseUrl": ".",
|
"baseUrl": ".",
|
||||||
|
"typeRoots" : ["node_modules/@types", "src/@types"],
|
||||||
"types": [
|
"types": [
|
||||||
"webpack-env"
|
"webpack-env"
|
||||||
],
|
],
|
||||||
|
|||||||
Reference in New Issue
Block a user