cache into map
This commit is contained in:
+2
-2
@@ -14,8 +14,8 @@ module.exports = {
|
|||||||
rules: {
|
rules: {
|
||||||
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||||
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
|
||||||
indent: 'off',
|
'@typescript-eslint/indent': ['error', 2],
|
||||||
'@typescript-eslint/indent': ['error', 2]
|
camelcase: 0
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,65 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="hello">
|
|
||||||
<h1>{{ msg }}</h1>
|
|
||||||
<p>
|
|
||||||
For a guide and recipes on how to configure / customize this project,<br>
|
|
||||||
check out the
|
|
||||||
<a href="https://cli.vuejs.org" target="_blank" rel="noopener">vue-cli documentation</a>.
|
|
||||||
</p>
|
|
||||||
<h3>Installed CLI Plugins</h3>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-babel" target="_blank" rel="noopener">babel</a></li>
|
|
||||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-router" target="_blank" rel="noopener">router</a></li>
|
|
||||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-vuex" target="_blank" rel="noopener">vuex</a></li>
|
|
||||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-eslint" target="_blank" rel="noopener">eslint</a></li>
|
|
||||||
<li><a href="https://github.com/vuejs/vue-cli/tree/dev/packages/%40vue/cli-plugin-typescript" target="_blank" rel="noopener">typescript</a></li>
|
|
||||||
</ul>
|
|
||||||
<h3>Essential Links</h3>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://vuejs.org" target="_blank" rel="noopener">Core Docs</a></li>
|
|
||||||
<li><a href="https://forum.vuejs.org" target="_blank" rel="noopener">Forum</a></li>
|
|
||||||
<li><a href="https://chat.vuejs.org" target="_blank" rel="noopener">Community Chat</a></li>
|
|
||||||
<li><a href="https://twitter.com/vuejs" target="_blank" rel="noopener">Twitter</a></li>
|
|
||||||
<li><a href="https://news.vuejs.org" target="_blank" rel="noopener">News</a></li>
|
|
||||||
</ul>
|
|
||||||
<h3>Ecosystem</h3>
|
|
||||||
<ul>
|
|
||||||
<li><a href="https://router.vuejs.org" target="_blank" rel="noopener">vue-router</a></li>
|
|
||||||
<li><a href="https://vuex.vuejs.org" target="_blank" rel="noopener">vuex</a></li>
|
|
||||||
<li><a href="https://github.com/vuejs/vue-devtools#vue-devtools" target="_blank" rel="noopener">vue-devtools</a></li>
|
|
||||||
<li><a href="https://vue-loader.vuejs.org" target="_blank" rel="noopener">vue-loader</a></li>
|
|
||||||
<li><a href="https://github.com/vuejs/awesome-vue" target="_blank" rel="noopener">awesome-vue</a></li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<script lang="ts">
|
|
||||||
import { Options, Vue } from 'vue-class-component'
|
|
||||||
|
|
||||||
@Options({
|
|
||||||
props: {
|
|
||||||
msg: String
|
|
||||||
}
|
|
||||||
})
|
|
||||||
export default class HelloWorld extends Vue {
|
|
||||||
msg!: string
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<!-- Add "scoped" attribute to limit CSS to this component only -->
|
|
||||||
<style scoped>
|
|
||||||
h3 {
|
|
||||||
margin: 40px 0 0;
|
|
||||||
}
|
|
||||||
ul {
|
|
||||||
list-style-type: none;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
li {
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0 10px;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: #42b983;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@@ -19,7 +19,7 @@ import {
|
|||||||
} from 'chart.js'
|
} from 'chart.js'
|
||||||
import annotationPlugin, { AnnotationPluginOptions } from 'chartjs-plugin-annotation'
|
import annotationPlugin, { AnnotationPluginOptions } from 'chartjs-plugin-annotation'
|
||||||
import dataLabel from 'chartjs-plugin-datalabels'
|
import dataLabel from 'chartjs-plugin-datalabels'
|
||||||
import { useKillStore, Player, Filters } from '@/stores/kill'
|
import { useKillStore, Player, Filter } from '@/stores/kill'
|
||||||
|
|
||||||
import { Scatter } from 'vue-chartjs'
|
import { Scatter } from 'vue-chartjs'
|
||||||
import { defineComponent, PropType, Ref, toRaw, triggerRef, unref } from 'vue'
|
import { defineComponent, PropType, Ref, toRaw, triggerRef, unref } from 'vue'
|
||||||
@@ -33,7 +33,7 @@ ChartJS.register(LinearScale, PointElement, LineElement, Tooltip, Legend, annota
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'PlayerChart',
|
name: 'PlayerChart',
|
||||||
props: {
|
props: {
|
||||||
filters: Object as PropType<Filters>,
|
filters: Object as PropType<Filter>,
|
||||||
playerHighlighted: String
|
playerHighlighted: String
|
||||||
},
|
},
|
||||||
data: () => {
|
data: () => {
|
||||||
@@ -53,14 +53,17 @@ export default defineComponent({
|
|||||||
computed: {
|
computed: {
|
||||||
progress () {
|
progress () {
|
||||||
if (this.filters) {
|
if (this.filters) {
|
||||||
const { player: _, ...withoutPlayer } = this.filters
|
const filter = new Filter(this.filters)
|
||||||
return this.store.getPlayerList(withoutPlayer)?.value.progress
|
delete filter.player
|
||||||
|
return this.store.getList('players', filter)?.value.progress
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
},
|
},
|
||||||
playerList (): (Player & {id:string})[] {
|
playerList (): (Player & {id:string})[] {
|
||||||
const data = this.store.getPlayerList(this.filters || {})?.value.data
|
const filter = new Filter(this.filters)
|
||||||
if (!data) return Object.entries(this.store.fetchPlayers(this.filters || {}).value.data).map(e => ({ id: e[0], ...toRaw(e[1].value) }))
|
delete filter.player
|
||||||
|
const data = unref(this.store.getList('players', filter))?.data
|
||||||
|
if (!data) return Object.entries(this.store.fetch('players', filter).value.data).map(e => ({ id: e[0], ...toRaw(e[1].value) }))
|
||||||
const cut = Object.entries(data).map(e => ({ id: e[0], ...toRaw(e[1].value) }))
|
const cut = Object.entries(data).map(e => ({ id: e[0], ...toRaw(e[1].value) }))
|
||||||
cut.sort((a, b) => {
|
cut.sort((a, b) => {
|
||||||
return b.kills - a.kills
|
return b.kills - a.kills
|
||||||
@@ -140,7 +143,6 @@ 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
|
||||||
|
|||||||
@@ -28,15 +28,16 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { defineComponent, PropType, Ref } from 'vue'
|
import { defineComponent, PropType, Ref, isRef } from 'vue'
|
||||||
import { useKillStore, Player, Filters } from '@/stores/kill'
|
import { useKillStore, Player, Filter } from '@/stores/kill'
|
||||||
import VirtualList from './List/VirtualList.vue'
|
import VirtualList from './List/VirtualList.vue'
|
||||||
import LoadingBar from './LoadingBar.vue'
|
import LoadingBar from './LoadingBar.vue'
|
||||||
|
import { cloneProxy } from 'vue-chartjs/dist/utils'
|
||||||
|
|
||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
components: { VirtualList, LoadingBar },
|
components: { VirtualList, LoadingBar },
|
||||||
props: {
|
props: {
|
||||||
filters: { type: Object as PropType<Filters>, default: () => ({}) },
|
filters: { type: Object as PropType<Filter>, default: () => ({}) },
|
||||||
playerHighlighted: String
|
playerHighlighted: String
|
||||||
},
|
},
|
||||||
emits: ['highlightPlayer'],
|
emits: ['highlightPlayer'],
|
||||||
@@ -48,17 +49,26 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
progress () {
|
progress () {
|
||||||
const { player: _, ...withoutPlayer } = this.filters
|
const filter = new Filter(this.filters)
|
||||||
return this.store.getPlayerList(withoutPlayer)?.value.progress
|
delete filter.player
|
||||||
|
return this.store.getList('players', filter)?.value.progress
|
||||||
},
|
},
|
||||||
players (): { [key: string]: Ref<Player> } {
|
players (): { [key: string]: Ref<Player> } {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
const filter = new Filter(this.filters)
|
||||||
const { player: _, ...withoutPlayer } = this.filters
|
delete filter.player
|
||||||
const data = this.store.getPlayerList(withoutPlayer)?.value.data
|
const data = this.store.getList('players', filter)?.value.data
|
||||||
if (!data) return this.store.fetchPlayers(withoutPlayer).value.data
|
if (!data) return this.store.fetch('players', filter).value.data
|
||||||
|
console.log(isRef(data), isRef(Object.values(data)[0]))
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
playerList (): (Ref<Player> & { id: string })[] {
|
playerList (): (Ref<Player> & { id: string })[] {
|
||||||
|
const collator = new Intl.Collator('en', { numeric: true, sensitivity: 'base' })
|
||||||
|
const sortingFunctions = {
|
||||||
|
'k/d': ({ _rawValue: aVal }, { _rawValue: bVal }) => aVal.kills / Math.max(1, aVal.deaths) - bVal.kills / Math.max(1, bVal.deaths),
|
||||||
|
avg_distance: ({ _rawValue: aVal }, { _rawValue: bVal }) => ((aVal.total_distance / aVal.kills) || 0) - ((bVal.total_distance / bVal.kills) || 0),
|
||||||
|
username: ({ _rawValue: aVal }, { _rawValue: bVal }) => collator.compare(aVal.username, bVal.username)
|
||||||
|
} as {[k: string]: (a:Ref<Player>, b:Ref<Player>)=>number}
|
||||||
|
|
||||||
if (!this.players) return []
|
if (!this.players) return []
|
||||||
const 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>>
|
||||||
@@ -67,30 +77,10 @@ export default defineComponent({
|
|||||||
return player
|
return player
|
||||||
}) as (Ref<Player> & { id: string })[]
|
}) as (Ref<Player> & { id: string })[]
|
||||||
|
|
||||||
if (this.sortingData.argument === 'username') {
|
if (this.sortingData.argument in sortingFunctions) {
|
||||||
const collator = new Intl.Collator('en', { numeric: true, sensitivity: 'base' })
|
players.sort(sortingFunctions[this.sortingData.argument])
|
||||||
players.sort((a, b) => {
|
|
||||||
// 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') {
|
|
||||||
players.sort((a, b) => {
|
|
||||||
// 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') {
|
|
||||||
players.sort((a, b) => {
|
|
||||||
// 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 as Exclude<keyof Player, 'username' | 'avg_distance'>
|
||||||
players.sort((a, b) => {
|
players.sort((a, b) => {
|
||||||
// Hack because toRaw is slow as fuck
|
// Hack because toRaw is slow as fuck
|
||||||
const aVal = a._rawValue
|
const aVal = a._rawValue
|
||||||
|
|||||||
@@ -8,9 +8,9 @@
|
|||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Chart as ChartJS, ArcElement, Tooltip, Legend } from 'chart.js'
|
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, Filter, useKillStore } from '@/stores/kill'
|
||||||
import { Doughnut } from 'vue-chartjs'
|
import { Doughnut } from 'vue-chartjs'
|
||||||
import { defineComponent, PropType, Ref } from 'vue'
|
import { defineComponent, PropType, Ref, unref } from 'vue'
|
||||||
import weapons from '../stores/weapons.json'
|
import weapons from '../stores/weapons.json'
|
||||||
|
|
||||||
import LoadingBar from './LoadingBar.vue'
|
import LoadingBar from './LoadingBar.vue'
|
||||||
@@ -20,7 +20,7 @@ ChartJS.register(ArcElement, Tooltip, Legend, dataLabel)
|
|||||||
export default defineComponent({
|
export default defineComponent({
|
||||||
name: 'WeaponChart',
|
name: 'WeaponChart',
|
||||||
props: {
|
props: {
|
||||||
filters: Object as PropType<Filters>,
|
filters: Object as PropType<Filter>,
|
||||||
playerHighlighted: String
|
playerHighlighted: String
|
||||||
},
|
},
|
||||||
emits: ['highlightPlayer'],
|
emits: ['highlightPlayer'],
|
||||||
@@ -38,9 +38,10 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
progress () {
|
progress () {
|
||||||
const { weapon: _, ...withoutWeapon } = this.filters || {}
|
const filter = new Filter(this.filters)
|
||||||
const data = this.store.getWeaponList(withoutWeapon)?.value
|
delete filter.weapon
|
||||||
if (!data) return this.store.fetchWeapons(withoutWeapon).value.progress
|
const data = this.store.getList('weapons', filter)?.value
|
||||||
|
if (!data) return this.store.fetch('weapons', filter).value.progress
|
||||||
return data.progress
|
return data.progress
|
||||||
},
|
},
|
||||||
colors () {
|
colors () {
|
||||||
@@ -148,19 +149,21 @@ export default defineComponent({
|
|||||||
return options
|
return options
|
||||||
},
|
},
|
||||||
weapons (): { [key: string]: Ref<Weapon> } {
|
weapons (): { [key: string]: Ref<Weapon> } {
|
||||||
const { weapon: _, ...withoutWeapon } = this.filters || {}
|
const filter = new Filter({ ...this.filters, player: this.playerHighlighted })
|
||||||
const data = this.store.getWeaponList(withoutWeapon)?.value.data
|
delete filter.weapon
|
||||||
if (!data) return this.store.fetchWeapons(withoutWeapon).value.data
|
const data = this.store.getList('weapons', filter)?.value.data
|
||||||
|
if (!data) return this.store.fetch('weapons', filter).value.data
|
||||||
|
console.log(filter.toURLSearchParams().toString(), filter)
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
sortedWeaponList (): string[] {
|
sortedWeaponList (): string[] {
|
||||||
if (!this.weapons) return []
|
if (!this.weapons) return []
|
||||||
const weapons = Object.keys(this.weapons).filter(e => this.weapons[e].value.kills > 0)
|
const weapons = Object.keys(this.weapons).filter(e => unref(this.weapons[e]).kills > 0)
|
||||||
weapons.sort((a, b) => {
|
weapons.sort((a, b) => {
|
||||||
if (Number(this.weapons[a].value.kills) < Number(this.weapons[b].value.kills)) {
|
if (Number(this.weapons[a].value.kills) < Number(unref(this.weapons[b]).kills)) {
|
||||||
return -1
|
return -1
|
||||||
}
|
}
|
||||||
if (Number(this.weapons[a].value.kills) > Number(this.weapons[b].value.kills)) {
|
if (Number(this.weapons[a].value.kills) > Number(unref(this.weapons[b]).kills)) {
|
||||||
return 1
|
return 1
|
||||||
}
|
}
|
||||||
return 0
|
return 0
|
||||||
|
|||||||
+9
-10
@@ -3,7 +3,7 @@ import { createApp, ref, unref } from 'vue'
|
|||||||
import App from './App.vue'
|
import App from './App.vue'
|
||||||
import router from './router'
|
import router from './router'
|
||||||
import { createPinia } from 'pinia'
|
import { createPinia } from 'pinia'
|
||||||
import { Kill, KillData, objectEqual, useKillStore } from './stores/kill'
|
import { Filter, Kill, KillData, useKillStore } from './stores/kill'
|
||||||
|
|
||||||
const pinia = createPinia()
|
const pinia = createPinia()
|
||||||
|
|
||||||
@@ -48,22 +48,21 @@ const socket = new WebSocket('wss://tone.sleepycat.date/v2/client/websocket')
|
|||||||
socket.onmessage = function (e) {
|
socket.onmessage = function (e) {
|
||||||
if (e.data === 'ping') return socket.send('pong')
|
if (e.data === 'ping') return socket.send('pong')
|
||||||
const data = JSON.parse(e.data)
|
const data = JSON.parse(e.data)
|
||||||
registerWebSocketKill(data)
|
// registerWebSocketKill(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
function registerWebSocketKill (data : websocketData) {
|
function registerWebSocketKill (data : websocketData) {
|
||||||
const { player: _, ...filterWithoutPlayer } = store.$state.currentFilter
|
const { player: _, ...filterWithoutPlayer } = store.$state.currentFilter
|
||||||
const list = unref(store.$state.players.find((e) => {
|
const filter = new Filter(filterWithoutPlayer)
|
||||||
return objectEqual(filterWithoutPlayer, e.value.filter)
|
const list = unref(store.getList('players', filter))
|
||||||
}))
|
|
||||||
if (!list) return
|
if (!list) return
|
||||||
if (!(!list.filter.server || list.filter.server.includes(data.servername))) return
|
if (!(!filter.server || filter.server.includes(data.servername))) return
|
||||||
|
|
||||||
const WeaponFilter = (!list.filter.weapon || list.filter.weapon.includes(data.cause_of_death))
|
const WeaponFilter = (!filter.weapon || filter.weapon.includes(data.cause_of_death))
|
||||||
const CurrentWeaponFilter = list.filter.weapon?.includes(data.attacker_current_weapon)
|
const CurrentWeaponFilter = 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 (!(!filter.gamemode || 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({
|
||||||
@@ -99,7 +98,7 @@ function registerWebSocketKill (data : websocketData) {
|
|||||||
|
|
||||||
unref(list.data[data.victim_id]).username = data.victim_name
|
unref(list.data[data.victim_id]).username = data.victim_name
|
||||||
unref(list.data[data.attacker_id]).username = data.attacker_name
|
unref(list.data[data.attacker_id]).username = data.attacker_name
|
||||||
const serverlist = store.getServerList({})
|
const serverlist = store.getList('servers')
|
||||||
if (serverlist) {
|
if (serverlist) {
|
||||||
const server = unref(unref(serverlist).data[data.servername])
|
const server = unref(unref(serverlist).data[data.servername])
|
||||||
if (server) {
|
if (server) {
|
||||||
|
|||||||
+135
-187
@@ -1,110 +1,105 @@
|
|||||||
import { defineStore } from 'pinia'
|
import { defineStore } from 'pinia'
|
||||||
import * as assert from 'assert'
|
import { Ref, ref, shallowRef, triggerRef, unref, isRef } from 'vue'
|
||||||
import { Ref, ref, shallowRef, triggerRef, unref } from 'vue'
|
|
||||||
|
export class Filter {
|
||||||
|
constructor (filt?:{server?:string[], player?: string, weapon?: string[], host?: string[], map?: string[], gamemode?: string[]}) {
|
||||||
|
if (filt?.server) this.server = filt.server
|
||||||
|
if (filt?.player) this.player = filt.player
|
||||||
|
if (filt?.weapon) this.weapon = filt.weapon
|
||||||
|
if (filt?.host) this.host = filt.host
|
||||||
|
if (filt?.map) this.map = filt.map
|
||||||
|
if (filt?.gamemode) this.gamemode = filt.gamemode
|
||||||
|
}
|
||||||
|
|
||||||
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[];
|
||||||
}
|
toURLSearchParams (): URLSearchParams {
|
||||||
|
return new URLSearchParams(
|
||||||
export function removeNullEntries (a: Filters) {
|
Object.entries(this).filter(e => e[1] !== undefined)
|
||||||
return Object.fromEntries(
|
.map<string[][]>((e) => [e[1]].flat().map((v) => [e[0], v]))
|
||||||
Object.entries(a).filter((e) => e[1] !== undefined && e[1] !== null)
|
.flat(1)
|
||||||
)
|
)
|
||||||
}
|
|
||||||
export function objectEqual (a: Filters, b: Filters) {
|
|
||||||
try {
|
|
||||||
a = removeNullEntries(a)
|
|
||||||
b = removeNullEntries(b)
|
|
||||||
assert.deepStrictEqual(a, b)
|
|
||||||
return true
|
|
||||||
} catch {
|
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function fetchWithLoading (url: string, progress: (percentage: number) => void) {
|
function fetchWithLoading (url: string, progress: (percentage: number) => void) {
|
||||||
return fetch(url).then(response => {
|
return fetch(url)
|
||||||
if (!response.ok) {
|
.then((response) => {
|
||||||
throw Error(response.status + ' ' + response.statusText)
|
if (!response.ok) {
|
||||||
}
|
throw Error(response.status + ' ' + response.statusText)
|
||||||
|
}
|
||||||
|
|
||||||
if (!response.body) {
|
if (!response.body) {
|
||||||
throw Error('ReadableStream not yet supported in this browser.')
|
throw Error('ReadableStream not yet supported in this browser.')
|
||||||
}
|
}
|
||||||
|
|
||||||
// to access headers, server must send CORS header "Access-Control-Expose-Headers: content-encoding, content-length x-file-size"
|
// to access headers, server must send CORS header "Access-Control-Expose-Headers: content-encoding, content-length x-file-size"
|
||||||
// server must send custom x-file-size header if gzip or other content-encoding is used
|
// server must send custom x-file-size header if gzip or other content-encoding is used
|
||||||
const contentEncoding = response.headers.get('Content-Encoding')
|
const contentEncoding = response.headers.get('Content-Encoding')
|
||||||
const contentLength = response.headers.get(contentEncoding ? 'X-File-Size' : 'content-length')
|
const contentLength = response.headers.get(
|
||||||
if (contentLength === null) {
|
contentEncoding ? 'X-File-Size' : 'content-length'
|
||||||
throw Error('Response size header unavailable')
|
)
|
||||||
}
|
if (contentLength === null) {
|
||||||
|
throw Error('Response size header unavailable')
|
||||||
|
}
|
||||||
|
|
||||||
const total = parseInt(contentLength, 10)
|
const total = parseInt(contentLength, 10)
|
||||||
let loaded = 0
|
let loaded = 0
|
||||||
|
|
||||||
return new Response(
|
return new Response(
|
||||||
new ReadableStream({
|
new ReadableStream({
|
||||||
start (controller) {
|
start (controller) {
|
||||||
const reader = response.body!.getReader()
|
const reader = response.body!.getReader()
|
||||||
|
|
||||||
read()
|
read()
|
||||||
function read () {
|
function read () {
|
||||||
reader.read().then(({ done, value }) => {
|
reader
|
||||||
if (done) {
|
.read()
|
||||||
controller.close()
|
.then(({ done, value }) => {
|
||||||
progress(1)
|
if (done) {
|
||||||
return
|
controller.close()
|
||||||
}
|
progress(1)
|
||||||
if (value) {
|
return
|
||||||
loaded += value.byteLength
|
}
|
||||||
progress(loaded / total)
|
if (value) {
|
||||||
controller.enqueue(value)
|
loaded += value.byteLength
|
||||||
}
|
progress(loaded / total)
|
||||||
read()
|
controller.enqueue(value)
|
||||||
}).catch(error => {
|
}
|
||||||
console.error(error)
|
read()
|
||||||
controller.error(error)
|
})
|
||||||
})
|
.catch((error) => {
|
||||||
|
console.error(error)
|
||||||
|
controller.error(error)
|
||||||
|
})
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
})
|
)
|
||||||
)
|
})
|
||||||
})
|
.catch((error) => {
|
||||||
.catch(error => {
|
|
||||||
console.error(error)
|
console.error(error)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Kill {
|
export interface Kill {
|
||||||
deaths: number;
|
deaths: number;
|
||||||
// eslint-disable-next-line camelcase
|
deaths_while_equipped: number;
|
||||||
deaths_while_equipped:number
|
|
||||||
kills: number;
|
kills: number;
|
||||||
// eslint-disable-next-line camelcase
|
|
||||||
max_distance: number;
|
max_distance: number;
|
||||||
// eslint-disable-next-line camelcase
|
|
||||||
total_distance: number;
|
total_distance: number;
|
||||||
}
|
}
|
||||||
export interface KillData<T extends Kill> {
|
|
||||||
filter: Filters;
|
|
||||||
data: { [key: string]: Ref<T> };
|
|
||||||
progress?: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Player extends Kill {
|
export interface Player extends Kill {
|
||||||
username: string;
|
username: string;
|
||||||
// eslint-disable-next-line camelcase
|
|
||||||
// deaths_while_equipped?: number;
|
// deaths_while_equipped?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Weapon extends Kill {
|
export interface Weapon extends Kill {
|
||||||
// eslint-disable-next-line camelcase
|
|
||||||
deaths_while_equipped: number;
|
deaths_while_equipped: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -112,6 +107,11 @@ export interface Server extends Kill {
|
|||||||
host: number;
|
host: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface KillData<T extends Kill> {
|
||||||
|
data: { [key: string]: Ref<T> };
|
||||||
|
progress?: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface NSServer {
|
export interface NSServer {
|
||||||
name: string;
|
name: string;
|
||||||
region: string;
|
region: string;
|
||||||
@@ -121,160 +121,108 @@ export interface NSServer {
|
|||||||
map: string;
|
map: string;
|
||||||
playlist: string;
|
playlist: string;
|
||||||
hasPassword: boolean;
|
hasPassword: boolean;
|
||||||
modInfo: { Mods: [] }
|
modInfo: { Mods: [] };
|
||||||
}
|
}
|
||||||
|
|
||||||
// define your typings for the store state
|
// define your typings for the store state
|
||||||
export interface State {
|
export interface State {
|
||||||
servers: Ref<KillData<Server>>[];
|
killData:{
|
||||||
players: Ref<KillData<Player>>[];
|
servers: Ref<Map<string, Ref<KillData<Server>>>>;
|
||||||
weapons: Ref<KillData<Weapon>>[];
|
players: Ref<Map<string, Ref<KillData<Player>>>>;
|
||||||
maps: Ref<KillData<Kill>>[];
|
weapons: Ref<Map<string, Ref<KillData<Weapon>>>>;
|
||||||
gamemodes: Ref<KillData<Kill>>[];
|
maps: Ref<Map<string, Ref<KillData<Kill>>>>;
|
||||||
|
gamemodes: Ref<Map<string, Ref<KillData<Kill>>>>;
|
||||||
|
},
|
||||||
|
|
||||||
hosts: { [key: number]: string };
|
hosts: { [key: number]: string };
|
||||||
nsServers: NSServer[] | undefined;
|
nsServers: NSServer[] | undefined;
|
||||||
currentFilter:Filters;
|
currentFilter: Filter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type StateProperty = keyof State['killData']
|
||||||
|
type StateType<T extends StateProperty> =
|
||||||
|
T extends 'servers' ? Server :
|
||||||
|
T extends 'players' ? Player :
|
||||||
|
T extends 'weapons' ? Weapon :
|
||||||
|
Kill
|
||||||
|
|
||||||
let serverInterval: number
|
let serverInterval: number
|
||||||
export const useKillStore = defineStore('kill', {
|
export const useKillStore = defineStore('kill', {
|
||||||
state: (): State => ({
|
state: (): State => ({
|
||||||
servers: [],
|
killData: {
|
||||||
players: [],
|
servers: shallowRef(new Map()),
|
||||||
weapons: [],
|
players: shallowRef(new Map()),
|
||||||
maps: [],
|
weapons: shallowRef(new Map()),
|
||||||
gamemodes: [],
|
maps: shallowRef(new Map()),
|
||||||
|
gamemodes: shallowRef(new Map())
|
||||||
|
},
|
||||||
|
|
||||||
hosts: {},
|
hosts: {},
|
||||||
nsServers: undefined,
|
nsServers: undefined,
|
||||||
currentFilter: {}
|
currentFilter: new Filter()
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
getPlayerList: (state) => (filters: Filters) => {
|
getList:
|
||||||
return state.players.find((e) => objectEqual(unref(e).filter, filters))
|
(state) =>
|
||||||
},
|
<T extends StateProperty>(type: T, filters?: Filter): Ref<KillData<StateType<T>>> | undefined => {
|
||||||
getWeaponList: (state) => (filters: Filters) =>
|
return unref(state.killData[type as keyof typeof state.killData]).get(filters?.toURLSearchParams().toString() ?? '') as Ref<KillData<StateType<T>>>
|
||||||
state.weapons.find((e) => objectEqual(unref(e).filter, filters)),
|
},
|
||||||
getServerList: (state) => (filters: 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: {
|
||||||
fetchPlayers (filter: Filters) {
|
fetch <T extends StateProperty> (type:T, filter?:Filter): Ref<KillData<StateType<T>>> {
|
||||||
filter = removeNullEntries(filter)
|
let entry = this.getList(type, filter)
|
||||||
let entry = this.players.find((e) => objectEqual(unref(e).filter, filter))
|
|
||||||
if (entry === undefined) {
|
if (entry === undefined) {
|
||||||
entry = shallowRef({ filter, data: {} })
|
entry = shallowRef<KillData<StateType<T>>>({ data: {} })
|
||||||
this.players.push(entry)
|
unref(this.$state.killData[type as keyof typeof this.$state.killData] as Map<string, Ref<KillData<StateType<T>>>>).set(filter?.toURLSearchParams().toString() ?? '', entry)
|
||||||
|
// console.log(isRef(entry), this.$state.killData)
|
||||||
}
|
}
|
||||||
fetchWithLoading(
|
fetchWithLoading(
|
||||||
'https://tone.sleepycat.date/v2/client/players?' +
|
`https://tone.sleepycat.date/v2/client/${type}?` +
|
||||||
new URLSearchParams(Object.entries(filter).map<string[][]>(e => [e[1]].flat().map(v => [e[0], v])).flat(1)),
|
filter?.toURLSearchParams() ?? '',
|
||||||
(progress) => {
|
(progress) => {
|
||||||
if (entry && unref(entry).progress !== 1) {
|
if (entry && progress !== 1) {
|
||||||
unref(entry).progress = progress
|
unref(entry).progress = progress
|
||||||
if (progress !== 1) triggerRef(entry)
|
triggerRef(entry)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
).then(async response => {
|
).then(async (response) => {
|
||||||
if (entry) {
|
if (entry) {
|
||||||
unref(entry).data = Object.fromEntries(Object.entries(await response?.json()).map(e => [e[0], ref(e[1] as Player)]))
|
entry.value.data = Object.fromEntries(
|
||||||
triggerRef(entry)
|
Object.entries(await response?.json()).map<[string, Ref<StateType<T>>]>((e) => [
|
||||||
}
|
e[0],
|
||||||
})
|
ref(e[1]) as Ref<StateType<T>>
|
||||||
return entry
|
])
|
||||||
},
|
)
|
||||||
fetchWeapons (filter: Filters) {
|
unref(entry).progress = 1
|
||||||
filter = removeNullEntries(filter)
|
|
||||||
let entry = this.weapons.find((e) => objectEqual(unref(e).filter, filter))
|
|
||||||
if (!entry) {
|
|
||||||
entry = shallowRef({ filter, data: {} })
|
|
||||||
this.weapons.push(entry)
|
|
||||||
}
|
|
||||||
|
|
||||||
fetchWithLoading(
|
|
||||||
'https://tone.sleepycat.date/v2/client/weapons?' +
|
|
||||||
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 Weapon)]))
|
|
||||||
triggerRef(entry)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return entry
|
|
||||||
},
|
|
||||||
fetchServers (filter: Filters) {
|
|
||||||
filter = removeNullEntries(filter)
|
|
||||||
let entry = this.servers.find((e) => objectEqual(unref(e).filter, filter))
|
|
||||||
if (!entry) {
|
|
||||||
entry = shallowRef({ filter, data: {} })
|
|
||||||
this.servers.push(entry)
|
|
||||||
}
|
|
||||||
fetchWithLoading(
|
|
||||||
'https://tone.sleepycat.date/v2/client/servers?' +
|
|
||||||
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 Server)]))
|
|
||||||
triggerRef(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)
|
triggerRef(entry)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return entry
|
return entry
|
||||||
},
|
},
|
||||||
fetchNSServers () {
|
fetchNSServers () {
|
||||||
fetch(
|
fetch('https://northstar.tf/client/servers').then(async (response) => {
|
||||||
'https://northstar.tf/client/servers').then(async response => {
|
|
||||||
this.nsServers = await response.json()
|
this.nsServers = await response.json()
|
||||||
})
|
})
|
||||||
clearInterval(serverInterval)
|
clearInterval(serverInterval)
|
||||||
serverInterval = setInterval(() => this.fetchNSServers(), 60000)
|
serverInterval = setInterval(() => this.fetchNSServers(), 60000)
|
||||||
return this.nsServers || []
|
return this.nsServers || []
|
||||||
},
|
},
|
||||||
setFilter (filter:Filters) {
|
setFilter (filter: Filter) {
|
||||||
|
if (this.currentFilter.player === filter.player) {
|
||||||
|
const newfilter = new Filter(filter)
|
||||||
|
delete newfilter.player
|
||||||
|
this.fetch('players', newfilter)
|
||||||
|
}
|
||||||
|
|
||||||
|
if (this.currentFilter.weapon === filter.weapon) {
|
||||||
|
const newfilter = new Filter(filter)
|
||||||
|
delete newfilter.weapon
|
||||||
|
this.fetch('weapons', newfilter)
|
||||||
|
}
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
||||||
const { player: _player, ...withoutPlayers } = filter
|
// const { server: _server, ...withoutServer } = filter
|
||||||
if (this.currentFilter.player === _player) { this.fetchPlayers(withoutPlayers) }
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
const { weapon: _weapon, ...withoutWeapon } = filter
|
|
||||||
if (this.currentFilter.weapon === _weapon) { this.fetchWeapons(withoutWeapon) }
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
||||||
const { server: _server, ...withoutServer } = filter
|
|
||||||
// if (this.currentFilter.server === _server) { this.fetchServers(withoutServer) }
|
// if (this.currentFilter.server === _server) { this.fetchServers(withoutServer) }
|
||||||
this.currentFilter = filter
|
this.currentFilter = filter
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
<template>
|
|
||||||
<div class="about">
|
|
||||||
<h1>This is an about page</h1>
|
|
||||||
</div>
|
|
||||||
</template>
|
|
||||||
+22
-22
@@ -61,14 +61,14 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div id="playerView">
|
<div id="playerView">
|
||||||
<PlayerList
|
<PlayerList
|
||||||
:filters="filters"
|
:filters="filters"
|
||||||
v-on:highlightPlayer="highlight_player"
|
v-on:highlightPlayer="highlight_player"
|
||||||
:playerHighlighted="playerHighlighted?.id"
|
:playerHighlighted="playerHighlighted?.id"
|
||||||
>
|
>
|
||||||
</PlayerList>
|
</PlayerList>
|
||||||
|
|
||||||
<PlayerChart
|
<PlayerChart
|
||||||
:filters="filters"
|
:filters="filters"
|
||||||
v-on:highlightPlayer="highlight_player"
|
v-on:highlightPlayer="highlight_player"
|
||||||
:playerHighlighted="playerHighlighted?.id"
|
:playerHighlighted="playerHighlighted?.id"
|
||||||
@@ -83,7 +83,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
import { Player, Weapon, Server, Kill, useKillStore, Filters } from '@/stores/kill'
|
import { Player, Weapon, Server, Kill, useKillStore, Filter } 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'
|
||||||
@@ -109,7 +109,7 @@ export default defineComponent({
|
|||||||
server: string[] | undefined;
|
server: string[] | undefined;
|
||||||
gamemode: string[] | undefined;
|
gamemode: string[] | undefined;
|
||||||
},
|
},
|
||||||
filters: {} as Filters,
|
filters: new Filter(),
|
||||||
store: useKillStore(),
|
store: useKillStore(),
|
||||||
playerHighlighted: undefined as (Player & { id: string }) | undefined,
|
playerHighlighted: undefined as (Player & { id: string }) | undefined,
|
||||||
weaponLocale: weapons as { [key: string]: string }
|
weaponLocale: weapons as { [key: string]: string }
|
||||||
@@ -128,10 +128,10 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
servers (): { [key: string]: Ref<Server> } {
|
servers (): { [key: string]: Ref<Server> } {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
const filter = new Filter(this.filters)
|
||||||
const { server: _, player: _1, ...withoutServer } = this.filters
|
delete filter.server
|
||||||
const data = this.store.getServerList(withoutServer)?.value.data
|
const data = this.store.getList('servers', filter)?.value.data
|
||||||
if (!data) return unref(this.store.fetchServers(withoutServer)).data
|
if (!data) return unref(this.store.fetch('servers', filter)).data
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
groupedServers () {
|
groupedServers () {
|
||||||
@@ -149,24 +149,26 @@ export default defineComponent({
|
|||||||
return hosts
|
return hosts
|
||||||
},
|
},
|
||||||
weapons (): { [key: string]: Ref<Weapon> } {
|
weapons (): { [key: string]: Ref<Weapon> } {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
const filter = new Filter(this.filters)
|
||||||
const { weapon: _, player: _1, ...withoutWeapons } = this.filters
|
delete filter.weapon
|
||||||
const data = this.store.getWeaponList(withoutWeapons)?.value.data
|
delete filter.player
|
||||||
if (!data) return this.store.fetchWeapons(withoutWeapons).value.data
|
const data = this.store.getList('weapons', filter)?.value.data
|
||||||
|
if (!data) return this.store.fetch('weapons', filter).value.data
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
players (): { [key: string]: Ref<Player> } {
|
players (): { [key: string]: Ref<Player> } {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
const filter = new Filter(this.filters)
|
||||||
const { player: _, ...withoutPlayers } = this.filters
|
delete filter.player
|
||||||
const data = this.store.getPlayerList(withoutPlayers)?.value.data
|
const data = this.store.getList('players', filter)?.value.data
|
||||||
if (!data) return this.store.fetchPlayers(withoutPlayers).value.data
|
if (!data) return this.store.fetch('players', filter).value.data
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
gamemodes (): { [key: string]: Ref<Kill> } {
|
gamemodes (): { [key: string]: Ref<Kill> } {
|
||||||
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
const filter = new Filter(this.filters)
|
||||||
const { gamemode: _, player: _1, ...withoutGamemode } = this.filters
|
delete filter.gamemode
|
||||||
const data = this.store.getGamemodeList(withoutGamemode)?.value.data
|
delete filter.player
|
||||||
if (!data) return this.store.fetchGamemodes(withoutGamemode).value.data
|
const data = this.store.getList('gamemodes', filter)?.value.data
|
||||||
|
if (!data) return this.store.fetch('gamemodes', filter).value.data
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
sortedWeaponList (): string[] {
|
sortedWeaponList (): string[] {
|
||||||
@@ -263,8 +265,6 @@ export default defineComponent({
|
|||||||
if (this.$route.query.gamemode) this.model.gamemode = [this.$route.query.gamemode].flat().filter(e => e ?? false).map(e => e!.toString())
|
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
|
else this.model.gamemode = undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log(this.model, this.$route.query)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -52,8 +52,8 @@ export default defineComponent({
|
|||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
servers (): { [key: string]: Ref<Server> } {
|
servers (): { [key: string]: Ref<Server> } {
|
||||||
const data = this.store.getServerList({})?.value.data
|
const data = this.store.getList('servers')?.value.data
|
||||||
if (!data) return unref(this.store.fetchServers({})).data
|
if (!data) return unref(this.store.fetch('servers')).data
|
||||||
return data
|
return data
|
||||||
},
|
},
|
||||||
serverList (): (Ref<Server> & { name: string })[] {
|
serverList (): (Ref<Server> & { name: string })[] {
|
||||||
|
|||||||
Reference in New Issue
Block a user