add some design to the app
This commit is contained in:
+108
-16
@@ -1,6 +1,7 @@
|
||||
<template>
|
||||
<div class="playerList">
|
||||
<div class="player">
|
||||
<div class="playerTable" v-on:keydown="selectNextPlayer" tabindex="0">
|
||||
<div class="playerHeaders">
|
||||
<span>Index</span>
|
||||
<span v-on:click="sortPlayerList('username')">username</span>
|
||||
<span v-on:click="sortPlayerList('kills')">kills</span>
|
||||
<span v-on:click="sortPlayerList('deaths')">deaths</span>
|
||||
@@ -8,7 +9,9 @@
|
||||
<span v-on:click="sortPlayerList('max_kill_distance')">max kill distance</span>
|
||||
<span v-on:click="sortPlayerList('avg_kill_distance')">average kill distance</span>
|
||||
</div>
|
||||
<div class="player" v-for="playerId in playerIdList" v-bind:key="playerId">
|
||||
<div class="playerRow" v-for="(playerId, index) in playerIdList" v-bind:key="playerId"
|
||||
v-on:click="$emit('highlightPlayer', playerId)" :ref="`player:` + playerId">
|
||||
<span>{{ index }}</span>
|
||||
<span>{{ players[playerId].username }}</span>
|
||||
<span>{{ players[playerId].kills }}</span>
|
||||
<span>{{ players[playerId].deaths }}</span>
|
||||
@@ -23,33 +26,58 @@
|
||||
import { defineComponent } from 'vue'
|
||||
import { Player } from '@/store/index'
|
||||
import { useStore } from 'vuex'
|
||||
import { Vue } from 'vue-class-component'
|
||||
|
||||
export default defineComponent({
|
||||
props: {
|
||||
filters: Object
|
||||
filters: Object,
|
||||
playerHighlighted: String
|
||||
},
|
||||
emits: ['highlightPlayer'],
|
||||
data () {
|
||||
return {
|
||||
sortingData: { direction: -1, argument: '' as keyof Player | 'k/d' },
|
||||
playerIdList: [] as string[],
|
||||
store: useStore()
|
||||
store: useStore(),
|
||||
selected: undefined as string | undefined
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
players ():{[key:string]:Player} { return this.store.getters.getPlayerList(this.filters) }
|
||||
players (): { [key: string]: Player } { return this.store.getters.getPlayerList(this.filters) }
|
||||
},
|
||||
watch: {
|
||||
players: {
|
||||
handler (newval:{[key:string]:Player}): void {
|
||||
handler (newval: { [key: string]: Player }): void {
|
||||
if (!newval) return
|
||||
this.playerIdList = []
|
||||
this.sortingData.direction *= -1
|
||||
this.playerIdList = Object.keys(newval)
|
||||
this.sortPlayerList(this.sortingData.argument)
|
||||
this.$nextTick(() => {
|
||||
const element = (this.$refs['player:' + this.selected] as HTMLElement[])
|
||||
if (element && element.length > 0) element[0].classList.add('selected')
|
||||
})
|
||||
},
|
||||
immediate: true
|
||||
},
|
||||
playerHighlighted (newval, oldval) {
|
||||
const oldElement = this.$refs['player:' + oldval] as HTMLElement[]
|
||||
if (oldElement) {
|
||||
oldElement[0].classList.remove('selected')
|
||||
delete this.selected
|
||||
}
|
||||
const newElement = this.$refs['player:' + newval] as HTMLElement[]
|
||||
if (!newElement) return
|
||||
newElement[0].classList.add('selected')
|
||||
newElement[0].scrollIntoView({ behavior: 'smooth', block: 'center' })
|
||||
this.selected = newval
|
||||
}
|
||||
},
|
||||
updated () {
|
||||
const element = this.$refs['player:' + this.$props.playerHighlighted] as HTMLElement[]
|
||||
if (!element || !element[0]) return
|
||||
element[0].scrollIntoView({ behavior: 'smooth', block: 'center' })
|
||||
},
|
||||
methods: {
|
||||
sortPlayerList (arg: ((keyof Player) | 'k/d')) {
|
||||
if (arg === this.sortingData.argument) {
|
||||
@@ -61,7 +89,7 @@ export default defineComponent({
|
||||
}
|
||||
this.sortingData.argument = arg
|
||||
|
||||
this.playerIdList.sort((a:string, b:string) => {
|
||||
this.playerIdList.sort((a: string, b: string) => {
|
||||
if (!this.players) {
|
||||
return 0
|
||||
}
|
||||
@@ -82,6 +110,26 @@ export default defineComponent({
|
||||
}
|
||||
return 0
|
||||
})
|
||||
},
|
||||
selectNextPlayer (e: KeyboardEvent) {
|
||||
const values = {
|
||||
Home: -Infinity,
|
||||
End: Infinity,
|
||||
PageDown: 100,
|
||||
PageUp: -100,
|
||||
ArrowUp: -1,
|
||||
ArrowDown: 1,
|
||||
ArrowRight: 10,
|
||||
ArrowLeft: -10
|
||||
} as { [key: string]: number }
|
||||
if (!this.selected) return
|
||||
if (!Object.keys(values).includes(e.key)) return
|
||||
e.preventDefault()
|
||||
const index = this.playerIdList.indexOf(this.selected)
|
||||
let nextIndex = (index + values[e.key])
|
||||
if (nextIndex >= this.playerIdList.length) nextIndex = this.playerIdList.length - 1
|
||||
if (nextIndex < 0) nextIndex = 0
|
||||
this.$emit('highlightPlayer', this.playerIdList[nextIndex])
|
||||
}
|
||||
}
|
||||
|
||||
@@ -89,17 +137,61 @@ export default defineComponent({
|
||||
</script>
|
||||
|
||||
<style scoped>
|
||||
.player {
|
||||
* {
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
.playerTable {
|
||||
overflow: auto;
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.playerHeaders {
|
||||
position: sticky;
|
||||
top: 0px;
|
||||
}
|
||||
|
||||
.playerRow,
|
||||
.playerHeaders {
|
||||
display: grid;
|
||||
grid-template-columns: 200px 75px 75px 75px 100px 100px;
|
||||
background: lightgray;
|
||||
margin: 10px;
|
||||
grid-template-columns: 50px 20ch 6ch 6ch 6ch 10ch 10ch;
|
||||
background: var(--bg-color);
|
||||
text-align: left;
|
||||
cursor: pointer;
|
||||
margin: 0;
|
||||
/* border: 2px solid transparent; */
|
||||
transition: border .25s;
|
||||
}
|
||||
|
||||
.playerHeaders,
|
||||
.playerRow:nth-child(2n) {
|
||||
background: var(--current-line);
|
||||
}
|
||||
|
||||
.playerRow:nth-child(2n+1) {
|
||||
background: var(--accent);
|
||||
}
|
||||
|
||||
.playerHeaders span:hover,
|
||||
.playerRow:hover {
|
||||
background: var(--bg-color);
|
||||
}
|
||||
|
||||
.playerRow>span:not(:last-child),
|
||||
.playerHeaders>span:not(:last-child) {
|
||||
border-right: solid var(--bg-color) 2px;
|
||||
}
|
||||
|
||||
span {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
.player span {
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
margin: 10px;
|
||||
pointer-events: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
.selected {
|
||||
background: var(--comment) !important;
|
||||
}</style>
|
||||
|
||||
Reference in New Issue
Block a user