refactor to utils + bug-fixes
This commit is contained in:
@@ -1,12 +1,19 @@
|
||||
<template>
|
||||
<nav class="navbar navbar-expand navbar-dark fixed-top">
|
||||
<div class="container">
|
||||
<div class="navbar-nav fs-5">
|
||||
<button aria-controls="navbar-collapse" aria-expanded="false" aria-label="Toggle navigation" class="navbar-toggler"
|
||||
data-bs-target="#navbar-collapse" data-bs-toggle="collapse" type="button">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
<div class="collapse navbar-collapse navbar-nav fs-5" id="navbar-collapse">
|
||||
<router-link class="navbar-brand text-warning fw-bold fs-3" to="/">
|
||||
CSGO<span class="text-up text-white fw-bold">WTF</span>
|
||||
</router-link>
|
||||
|
||||
<router-link class="nav-link" to="/explore">Explore</router-link>
|
||||
</div>
|
||||
|
||||
<form class="d-flex justify-content-end" @keydown.enter.prevent="parseSearch">
|
||||
<label for="search">
|
||||
<svg class="bi bi-search" viewBox="0 0 16 16" xmlns="http://www.w3.org/2000/svg">
|
||||
@@ -14,6 +21,7 @@
|
||||
d="M11.742 10.344a6.5 6.5 0 1 0-1.397 1.398h-.001c.03.04.062.078.098.115l3.85 3.85a1 1 0 0 0 1.415-1.414l-3.85-3.85a1.007 1.007 0 0 0-.115-.1zM12 6.5a5.5 5.5 0 1 1-11 0 5.5 5.5 0 0 1 11 0z"/>
|
||||
</svg>
|
||||
</label>
|
||||
|
||||
<input id="search" v-model="data.searchInput" aria-label="Search"
|
||||
class="form-control bg-transparent border-0"
|
||||
placeholder="SteamID64, Profile Link or Custom URL"
|
||||
@@ -84,7 +92,6 @@ nav {
|
||||
max-width: 100vw;
|
||||
height: 70px;
|
||||
width: 100vw;
|
||||
//background: rgba(16, 18, 26, 0.5);
|
||||
background: rgba(16, 18, 26, 1);
|
||||
|
||||
.text-up {
|
||||
@@ -120,16 +127,14 @@ nav {
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
nav {
|
||||
background: rgba(16, 18, 26, 1);
|
||||
|
||||
input[type="search"] {
|
||||
min-width: 0;
|
||||
max-width: 0;
|
||||
|
||||
&:focus {
|
||||
min-width: 100%;
|
||||
max-width: 100%;
|
||||
}
|
||||
//
|
||||
//&:focus {
|
||||
// min-width: 100%;
|
||||
// max-width: 100%;
|
||||
//}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -1,7 +1,8 @@
|
||||
<template>
|
||||
<div class="scoreboard" :class="'team-' + props.team_id">
|
||||
<table>
|
||||
<caption :class="props.score === 16 ? 'text-success' : props.score === 15 ? 'text-warning' : 'text-danger'">{{props.score}}</caption>
|
||||
<caption v-if="props.rounds === 16" :class="props.score === 9 ? 'text-success' : props.score === 8 ? 'text-warning' : 'text-danger'">{{props.score}}</caption>
|
||||
<caption v-if="props.rounds === 30" :class="props.score === 16 ? 'text-success' : props.score === 15 ? 'text-warning' : 'text-danger'">{{props.score}}</caption>
|
||||
<thead>
|
||||
<tr>
|
||||
<th class="player__avatar"></th>
|
||||
@@ -72,6 +73,11 @@ export default {
|
||||
type: Number,
|
||||
required: true,
|
||||
default: 0
|
||||
},
|
||||
rounds: {
|
||||
type: Number,
|
||||
required: true,
|
||||
default: 0
|
||||
}
|
||||
},
|
||||
setup(props) {
|
||||
|
@@ -13,8 +13,9 @@
|
||||
</svg>
|
||||
</td>
|
||||
<td>
|
||||
<img :src="props.rank ? require('@/images/rank_icons/skillgroup' + props.rank + '.svg') : require('@/images/rank_icons/skillgroup0.svg')"
|
||||
alt="Player rank"
|
||||
<img :src="DisplayRank(props.rank)[0]"
|
||||
:alt="DisplayRank(props.rank)[1]"
|
||||
:title="DisplayRank(props.rank)[1]"
|
||||
class="player__rank">
|
||||
</td>
|
||||
<td class="player__kills">
|
||||
@@ -52,7 +53,7 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import {GetHLTV_1, GoToPlayer} from "../utils";
|
||||
import {GetHLTV_1, GoToPlayer, DisplayRank} from "../utils";
|
||||
|
||||
export default {
|
||||
name: 'ScoreTeamPlayer',
|
||||
@@ -144,7 +145,7 @@ export default {
|
||||
}
|
||||
},
|
||||
setup(props) {
|
||||
return {props, GetHLTV_1, GoToPlayer}
|
||||
return {props, GetHLTV_1, GoToPlayer, DisplayRank}
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
48
src/utils/DateTime.js
Normal file
48
src/utils/DateTime.js
Normal file
@@ -0,0 +1,48 @@
|
||||
import {DateTime, Duration} from "luxon/build/es6/luxon";
|
||||
|
||||
export const FormatDuration = (d) => {
|
||||
const duration = Duration.fromObject({hours: 0, minutes: 0, seconds: d}).normalize().toObject()
|
||||
|
||||
if (duration.hours > 1)
|
||||
return `${duration.hours} h ${duration.minutes} min`
|
||||
else if (duration.hours < 1)
|
||||
return `${duration.minutes} min`
|
||||
}
|
||||
|
||||
export const FormatFullDuration = (d) => {
|
||||
const duration = Duration.fromObject({hours: 0, minutes: 0, seconds: d}).normalize()
|
||||
|
||||
if (duration.hours > 1)
|
||||
return duration.toFormat('hh:mm:ss')
|
||||
else if (duration.hours < 1)
|
||||
return duration.toFormat('mm:ss')
|
||||
}
|
||||
|
||||
export const FormatDate = (date) => {
|
||||
const matchDate = DateTime.fromISO(date)
|
||||
const diff = DateTime.now().diff(matchDate)
|
||||
|
||||
if (diff.as('days') > 10)
|
||||
return matchDate.toLocaleString({weekday: 'short', day: '2-digit', month: '2-digit', year: 'numeric'})
|
||||
else if (diff.as('days') < 1)
|
||||
if (diff.as('hours') < 1)
|
||||
return Math.floor(diff.as('minutes')) + ' minutes ago'
|
||||
else
|
||||
return Math.floor(diff.as('hours')) + ' hours ago'
|
||||
else
|
||||
return Math.floor(diff.as('days')) + ' days ago'
|
||||
}
|
||||
|
||||
export const FormatFullDate = (date) => {
|
||||
const matchDate = DateTime.fromISO(date)
|
||||
|
||||
return matchDate.toLocaleString({
|
||||
weekday: 'short',
|
||||
day: '2-digit',
|
||||
month: '2-digit',
|
||||
year: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit'
|
||||
})
|
||||
}
|
24
src/utils/Display.js
Normal file
24
src/utils/Display.js
Normal file
@@ -0,0 +1,24 @@
|
||||
export const DisplayRank = (rankNr = 0) => {
|
||||
const rankMap = new Map([
|
||||
[0, 'Unranked'],
|
||||
[1, 'Silver I'],
|
||||
[2, 'Silver II'],
|
||||
[3, 'Silver III'],
|
||||
[4, 'Silver IV'],
|
||||
[5, 'Silver Elite'],
|
||||
[6, 'Silver Elite Master'],
|
||||
[7, 'Gold Nova I'],
|
||||
[8, 'Gold Nova II'],
|
||||
[9, 'Gold Nova III'],
|
||||
[10, 'Gold Nova IV'],
|
||||
[11, 'Master Guardian I'],
|
||||
[12, 'Master Guardian II'],
|
||||
[13, 'Master Guardian Elite'],
|
||||
[14, 'Distinguished Master Guardian'],
|
||||
[15, 'Legendary Eagle'],
|
||||
[16, 'Legendary Eagle Master'],
|
||||
[17, 'Supreme Master First Class'],
|
||||
[18, 'Global Elite'],
|
||||
])
|
||||
return [require(`../images/rank_icons/skillgroup${rankNr}.svg`), rankMap.get(rankNr)]
|
||||
}
|
9
src/utils/GoTo.js
Normal file
9
src/utils/GoTo.js
Normal file
@@ -0,0 +1,9 @@
|
||||
import router from "../router";
|
||||
|
||||
export const GoToMatch = (id) => {
|
||||
router.push(`/match/${id}`)
|
||||
}
|
||||
|
||||
export const GoToPlayer = (id) => {
|
||||
router.push(`/player/${id}`)
|
||||
}
|
12
src/utils/HLTV.js
Normal file
12
src/utils/HLTV.js
Normal file
@@ -0,0 +1,12 @@
|
||||
export const GetHLTV_1 = (kills = 0, rounds, deaths = 0, k2 = 0, k3 = 0, k4 = 0, k5 = 0) => {
|
||||
const k1 = kills - k2 - k3 - k4 - k5
|
||||
const Weight_KPR = 0.679 // weight kills per round
|
||||
const Weight_SPR = 0.317 // weight survived rounds per round
|
||||
const Weight_RMK = 1.277 // weight value calculated from rounds with multiple kills (1k + 4*2k + 9*3k + 16*4k + 25*5k)
|
||||
|
||||
const KillRating = kills / rounds / Weight_KPR
|
||||
const SurvivalRating = (rounds - deaths) / rounds / Weight_SPR
|
||||
const RoundsWithMultipleKillsRating = (k1 + 4 * k2 + 9 * k3 + 16 * k4 + 25 * k5) / rounds / Weight_RMK
|
||||
|
||||
return ((KillRating + 0.7 * SurvivalRating + RoundsWithMultipleKillsRating) / 2.7).toFixed(2)
|
||||
}
|
25
src/utils/LocalStorage.js
Normal file
25
src/utils/LocalStorage.js
Normal file
@@ -0,0 +1,25 @@
|
||||
export const SaveLastVisitedToLocalStorage = (data) => {
|
||||
let a = JSON.parse(localStorage.getItem('recent-visited')) || [];
|
||||
|
||||
if (a.length === 0) {
|
||||
a.push(data);
|
||||
} else if (a.length === 9) {
|
||||
if (a.find(p => p.steamid64 === data.steamid64)) {
|
||||
a.shift()
|
||||
a.splice(a.findIndex(i => i.steamid64 === data.steamid64), 1)
|
||||
a.push(data)
|
||||
} else if (!a.find(p => p.steamid64 === data.steamid64)) {
|
||||
a.shift()
|
||||
a.push(data)
|
||||
}
|
||||
} else if (a.length > 0 && a.length < 9) {
|
||||
if (a.find(p => p.steamid64 === data.steamid64)) {
|
||||
a.splice(a.findIndex(i => i.steamid64 === data.steamid64), 1)
|
||||
a.push(data)
|
||||
} else if (!a.find(p => p.steamid64 === data.steamid64)) {
|
||||
a.push(data)
|
||||
}
|
||||
}
|
||||
|
||||
localStorage.setItem('recent-visited', JSON.stringify(a));
|
||||
}
|
@@ -1,96 +1,13 @@
|
||||
import {DateTime, Duration} from "luxon/build/es6/luxon";
|
||||
import router from '../router'
|
||||
import {FormatDate, FormatDuration, FormatFullDate, FormatFullDuration} from "./DateTime";
|
||||
import {GoToMatch, GoToPlayer} from "./GoTo";
|
||||
import {SaveLastVisitedToLocalStorage} from "./LocalStorage";
|
||||
import {GetHLTV_1} from "./HLTV";
|
||||
import {DisplayRank} from "./Display";
|
||||
|
||||
export const FormatDuration = (d) => {
|
||||
const duration = Duration.fromObject({hours: 0, minutes: 0, seconds: d}).normalize().toObject()
|
||||
|
||||
if (duration.hours > 1)
|
||||
return `${duration.hours} h ${duration.minutes} min`
|
||||
else if (duration.hours < 1)
|
||||
return `${duration.minutes} min`
|
||||
}
|
||||
|
||||
export const FormatFullDuration = (d) => {
|
||||
const duration = Duration.fromObject({hours: 0, minutes: 0, seconds: d}).normalize()
|
||||
|
||||
if (duration.hours > 1)
|
||||
return duration.toFormat('hh:mm:ss')
|
||||
else if (duration.hours < 1)
|
||||
return duration.toFormat('mm:ss')
|
||||
}
|
||||
|
||||
export const FormatDate = (date) => {
|
||||
const matchDate = DateTime.fromISO(date)
|
||||
const diff = DateTime.now().diff(matchDate)
|
||||
|
||||
if (diff.as('days') > 10)
|
||||
return matchDate.toLocaleString({weekday: 'short', day: '2-digit', month: '2-digit', year: 'numeric'})
|
||||
else if (diff.as('days') < 1)
|
||||
if (diff.as('hours') < 1)
|
||||
return Math.floor(diff.as('minutes')) + ' minutes ago'
|
||||
else
|
||||
return Math.floor(diff.as('hours')) + ' hours ago'
|
||||
else
|
||||
return Math.floor(diff.as('days')) + ' days ago'
|
||||
}
|
||||
|
||||
export const FormatFullDate = (date) => {
|
||||
const matchDate = DateTime.fromISO(date)
|
||||
|
||||
return matchDate.toLocaleString({
|
||||
weekday: 'short',
|
||||
day: '2-digit',
|
||||
month: '2-digit',
|
||||
year: 'numeric',
|
||||
hour: '2-digit',
|
||||
minute: '2-digit',
|
||||
second: '2-digit'
|
||||
})
|
||||
}
|
||||
|
||||
export const GoToMatch = (id) => {
|
||||
router.push(`/match/${id}`)
|
||||
}
|
||||
|
||||
export const GoToPlayer = (id) => {
|
||||
router.push(`/player/${id}`)
|
||||
}
|
||||
|
||||
export const GetHLTV_1 = (kills = 0, rounds, deaths = 0, k2 = 0, k3 = 0, k4 = 0, k5 = 0) => {
|
||||
const k1 = kills - k2 - k3 - k4 - k5
|
||||
const Weight_KPR = 0.679 // weight kills per round
|
||||
const Weight_SPR = 0.317 // weight survived rounds per round
|
||||
const Weight_RMK = 1.277 // weight value calculated from rounds with multiple kills (1k + 4*2k + 9*3k + 16*4k + 25*5k)
|
||||
|
||||
const KillRating = kills / rounds / Weight_KPR
|
||||
const SurvivalRating = (rounds - deaths) / rounds / Weight_SPR
|
||||
const RoundsWithMultipleKillsRating = (k1 + 4 * k2 + 9 * k3 + 16 * k4 + 25 * k5) / rounds / Weight_RMK
|
||||
|
||||
return ((KillRating + 0.7 * SurvivalRating + RoundsWithMultipleKillsRating) / 2.7).toFixed(2)
|
||||
}
|
||||
|
||||
export const SaveLastVisitedToLocalStorage = (data) => {
|
||||
let a = JSON.parse(localStorage.getItem('recent-visited')) || [];
|
||||
|
||||
if (a.length === 0) {
|
||||
a.push(data);
|
||||
} else if (a.length === 9) {
|
||||
if (a.find(p => p.steamid64 === data.steamid64)) {
|
||||
a.shift()
|
||||
a.splice(a.findIndex(i => i.steamid64 === data.steamid64), 1)
|
||||
a.push(data)
|
||||
} else if (!a.find(p => p.steamid64 === data.steamid64)) {
|
||||
a.shift()
|
||||
a.push(data)
|
||||
}
|
||||
} else if (a.length > 0 && a.length < 9) {
|
||||
if (a.find(p => p.steamid64 === data.steamid64)) {
|
||||
a.splice(a.findIndex(i => i.steamid64 === data.steamid64), 1)
|
||||
a.push(data)
|
||||
} else if (!a.find(p => p.steamid64 === data.steamid64)) {
|
||||
a.push(data)
|
||||
}
|
||||
}
|
||||
|
||||
localStorage.setItem('recent-visited', JSON.stringify(a));
|
||||
export {
|
||||
FormatDate, FormatFullDuration, FormatFullDate, FormatDuration,
|
||||
GoToMatch, GoToPlayer,
|
||||
SaveLastVisitedToLocalStorage,
|
||||
GetHLTV_1,
|
||||
DisplayRank
|
||||
}
|
@@ -57,9 +57,13 @@ export default {
|
||||
setup() {
|
||||
document.title = 'Home | csgoWTF'
|
||||
|
||||
const recentVisited = JSON.parse(localStorage.getItem('recent-visited'))
|
||||
if (recentVisited !== null)
|
||||
let recentVisited = JSON.parse(localStorage.getItem('recent-visited'))
|
||||
if (recentVisited !== null) {
|
||||
recentVisited.reverse()
|
||||
if (window.innerWidth < 768) {
|
||||
recentVisited = recentVisited.filter(i => recentVisited.indexOf(i) < 6)
|
||||
}
|
||||
}
|
||||
|
||||
return {recentVisited, GoToPlayer}
|
||||
}
|
||||
@@ -129,9 +133,6 @@ export default {
|
||||
|
||||
@media screen and (max-width: 768px) {
|
||||
.recent-search {
|
||||
max-height: 240px;
|
||||
overflow: hidden;
|
||||
|
||||
.player-card {
|
||||
height: 60px;
|
||||
img {
|
||||
|
@@ -1,7 +1,6 @@
|
||||
<template>
|
||||
<img :alt="data.matchDetails.map" :src="require('../images/map_screenshots/' + data.matchDetails.map + '.png')"
|
||||
<img v-if="data.matchDetails.map" :alt="data.matchDetails.map" :src="require('../images/map_screenshots/' + data.matchDetails.map + '.png')"
|
||||
class="bg-img">
|
||||
<div class="bg-img"></div>
|
||||
<div class="">
|
||||
<div v-if="data.matchDetails.map" class="head row m-auto text-center">
|
||||
<div class="m-auto map">
|
||||
@@ -10,8 +9,9 @@
|
||||
:title="data.matchDetails.map" class="map-icon">
|
||||
</div>
|
||||
<p class="text-center fs-6">Average Rank: <img
|
||||
:src="require('@/images/rank_icons/skillgroup' + data.avgRank + '.svg')"
|
||||
alt="Rank icon"
|
||||
:src="DisplayRank(data.avgRank)[0]"
|
||||
:alt="DisplayRank(data.avgRank)[1]"
|
||||
:title="DisplayRank(data.avgRank)[1]"
|
||||
class="rank-icon"/></p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -27,9 +27,9 @@
|
||||
<div class="scoreboard">
|
||||
<div v-if="data.score.length === 2 && data.stats">
|
||||
<ScoreTeam :rounds_played="data.score.reduce((a, b) => a + b)" :score="data.score[0]" :stats="data.stats"
|
||||
:team_id="1"/>
|
||||
:team_id="1" :rounds="data.matchDetails.rounds"/>
|
||||
<ScoreTeam :rounds_played="data.score.reduce((a, b) => a + b)" :score="data.score[1]" :stats="data.stats"
|
||||
:team_id="2"/>
|
||||
:team_id="2" :rounds="data.matchDetails.rounds"/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@@ -37,7 +37,7 @@
|
||||
<script>
|
||||
import {defineAsyncComponent, onBeforeMount, reactive, watch} from "vue";
|
||||
import axios from 'axios'
|
||||
import {GetHLTV_1, GoToPlayer} from "../utils";
|
||||
import {GetHLTV_1, GoToPlayer, DisplayRank} from "../utils";
|
||||
|
||||
const ScoreTeam = defineAsyncComponent(() => import('../components/ScoreTeam'))
|
||||
|
||||
@@ -64,7 +64,7 @@ export default {
|
||||
data.matchDetails = response.data
|
||||
data.stats = response.data.stats
|
||||
data.score = response.data.score
|
||||
// console.log(response.data)
|
||||
console.log(response.data)
|
||||
})
|
||||
.catch((e) => {
|
||||
console.log(e)
|
||||
@@ -98,7 +98,7 @@ export default {
|
||||
})
|
||||
|
||||
return {
|
||||
GetMatch, GetAvgRank, data, GoToPlayer, GetHLTV_1
|
||||
GetMatch, GetAvgRank, data, GoToPlayer, GetHLTV_1, DisplayRank
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -107,11 +107,15 @@ export default {
|
||||
<style lang="scss" scoped>
|
||||
.bg-img {
|
||||
z-index: -1;
|
||||
top: 0;
|
||||
left: 0;
|
||||
//top: 0;
|
||||
//left: 0;
|
||||
position: fixed;
|
||||
//max-width: 100%;
|
||||
//height: auto;
|
||||
display: block;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
width: 100%;
|
||||
max-height: 95%;
|
||||
}
|
||||
|
||||
.head {
|
||||
|
@@ -104,17 +104,18 @@
|
||||
:key="match.match_id"
|
||||
:class="GetWinLoss(match.match_result, match.stats[0].team_id)"
|
||||
class="match"
|
||||
@click="GoToMatch(match.match_id)">
|
||||
@click="match.map !== '' ? GoToMatch(match.match_id) : ''">
|
||||
<td class="td-map text-center">
|
||||
<img :alt="match.map ? match.map : 'Map not found'"
|
||||
:src="require('@/images/map_icons/map_icon_' + match.map + '.svg')"
|
||||
:src="match.map !== '' ? require('@/images/map_icons/map_icon_' + match.map + '.svg') : require('../images/icons/image.svg')"
|
||||
:title="match.map"
|
||||
class="map-icon">
|
||||
</td>
|
||||
<td class="td-rank text-center">
|
||||
<img
|
||||
:src="match.stats[0].extended?.rank?.new ? require('@/images/rank_icons/skillgroup' + match.stats[0].extended?.rank?.new + '.svg') : require('@/images/rank_icons/skillgroup0.svg')"
|
||||
alt="Rank icon"
|
||||
:src="DisplayRank(match.stats[0].extended?.rank?.new)[0]"
|
||||
:alt="DisplayRank(match.stats[0].extended?.rank?.new)[1]"
|
||||
:title="DisplayRank(match.stats[0].extended?.rank?.new)[1]"
|
||||
class="rank-icon">
|
||||
</td>
|
||||
<td :class="match.stats[0].team_id === match.match_result ? 'text-success' : !match.match_result ? 'text-warning' : 'text-danger'"
|
||||
@@ -191,7 +192,8 @@ import {
|
||||
FormatFullDuration,
|
||||
GetHLTV_1,
|
||||
GoToMatch,
|
||||
SaveLastVisitedToLocalStorage
|
||||
SaveLastVisitedToLocalStorage,
|
||||
DisplayRank
|
||||
} from "../utils";
|
||||
|
||||
export default {
|
||||
@@ -292,7 +294,8 @@ export default {
|
||||
FormatDuration,
|
||||
FormatFullDuration,
|
||||
GoToMatch,
|
||||
GetHLTV_1
|
||||
GetHLTV_1,
|
||||
DisplayRank
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Reference in New Issue
Block a user