mirror of
https://github.com/Spythere/stacjownik.git
synced 2026-05-03 05:18:11 +00:00
Compare commits
17 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 83444f64d0 | |||
| a5f9f8901b | |||
| 0276e0754b | |||
| 0d495ede2d | |||
| 48c0a32017 | |||
| 26f2ced266 | |||
| 4f17b1a704 | |||
| 50068a239c | |||
| 662748f705 | |||
| c2f7eef146 | |||
| 3c78af4dc0 | |||
| fc7a9be9dd | |||
| 3c3a114a38 | |||
| fe6972c1f8 | |||
| 08b9b72dcd | |||
| c90be042e7 | |||
| 430a05ab38 |
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "stacjownik",
|
"name": "stacjownik",
|
||||||
"version": "1.31.1",
|
"version": "1.32.0",
|
||||||
"private": true,
|
"private": true,
|
||||||
"type": "module",
|
"type": "module",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="history-list-box">
|
<div class="history-list-box">
|
||||||
<Loading v-if="journalDataStatus == Status.Data.Loading" />
|
<Loading v-if="journalStatus == Status.Data.Loading" />
|
||||||
|
|
||||||
<div v-else-if="combinedJournal.length == 0" class="no-recent-history">
|
<div v-else-if="combinedJournal.length == 0" class="no-recent-history">
|
||||||
{{ t('profile.list.no-recent-history') }}
|
{{ t('profile.list.no-recent-history') }}
|
||||||
@@ -107,12 +107,21 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, onActivated, onDeactivated, onMounted, reactive, ref } from 'vue';
|
import {
|
||||||
|
computed,
|
||||||
|
onActivated,
|
||||||
|
onDeactivated,
|
||||||
|
onMounted,
|
||||||
|
onUnmounted,
|
||||||
|
PropType,
|
||||||
|
reactive,
|
||||||
|
ref
|
||||||
|
} from 'vue';
|
||||||
import { dateToLocaleString, humanizeDuration } from '../../composables/time';
|
import { dateToLocaleString, humanizeDuration } from '../../composables/time';
|
||||||
import { API } from '../../typings/api';
|
import { API } from '../../typings/api';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useApiStore } from '../../store/apiStore';
|
import { useApiStore } from '../../store/apiStore';
|
||||||
import { useRoute } from 'vue-router';
|
import { onBeforeRouteUpdate, useRoute } from 'vue-router';
|
||||||
import { Status } from '../../typings/common';
|
import { Status } from '../../typings/common';
|
||||||
import Loading from '../Global/Loading.vue';
|
import Loading from '../Global/Loading.vue';
|
||||||
|
|
||||||
@@ -127,18 +136,19 @@ interface JournalEntry {
|
|||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
playerName: {
|
playerName: {
|
||||||
type: String
|
type: String
|
||||||
|
},
|
||||||
|
|
||||||
|
playerJournal: {
|
||||||
|
type: Object as PropType<API.PlayerJournal.Data>,
|
||||||
|
},
|
||||||
|
|
||||||
|
journalStatus: {
|
||||||
|
type: Number as PropType<Status.Data>,
|
||||||
|
required: true
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
const apiStore = useApiStore();
|
|
||||||
const route = useRoute();
|
|
||||||
|
|
||||||
const playerId = ref(-1);
|
|
||||||
const playerJournal = ref<API.PlayerJournal.Data | null>(null);
|
|
||||||
const journalDataStatus = ref(Status.Data.Initialized);
|
|
||||||
|
|
||||||
const intervalId = ref(-1);
|
|
||||||
|
|
||||||
const activeFilterTypes = reactive<Record<JournalEntryType, boolean>>({
|
const activeFilterTypes = reactive<Record<JournalEntryType, boolean>>({
|
||||||
Timetable: true,
|
Timetable: true,
|
||||||
@@ -146,23 +156,13 @@ const activeFilterTypes = reactive<Record<JournalEntryType, boolean>>({
|
|||||||
IssuedTimetable: true
|
IssuedTimetable: true
|
||||||
});
|
});
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
fetchPlayerJournal();
|
|
||||||
intervalId.value = setInterval(fetchPlayerJournal, 30000);
|
|
||||||
});
|
|
||||||
|
|
||||||
onDeactivated(() => {
|
|
||||||
clearInterval(intervalId.value);
|
|
||||||
intervalId.value = -1;
|
|
||||||
});
|
|
||||||
|
|
||||||
const combinedJournal = computed<JournalEntry[]>(() => {
|
const combinedJournal = computed<JournalEntry[]>(() => {
|
||||||
if (!playerJournal.value || !props.playerName) return [];
|
if (!props.playerJournal || !props.playerName) return [];
|
||||||
|
|
||||||
const list = [
|
const list = [
|
||||||
...playerJournal.value.timetables,
|
...props.playerJournal.timetables,
|
||||||
...playerJournal.value.duties,
|
...props.playerJournal.duties,
|
||||||
...playerJournal.value.issuedTimetables
|
...props.playerJournal.issuedTimetables
|
||||||
]
|
]
|
||||||
.reduce<JournalEntry[]>((acc, v) => {
|
.reduce<JournalEntry[]>((acc, v) => {
|
||||||
// Timetable or dispatcher type
|
// Timetable or dispatcher type
|
||||||
@@ -209,35 +209,6 @@ function toggleFilter(filterType: JournalEntryType) {
|
|||||||
|
|
||||||
activeFilterTypes[filterType] = toggledState;
|
activeFilterTypes[filterType] = toggledState;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function fetchPlayerJournal() {
|
|
||||||
const queryPlayerId = Number(route.query.playerId) || -1;
|
|
||||||
|
|
||||||
if (!apiStore.client || !queryPlayerId) return;
|
|
||||||
|
|
||||||
if (queryPlayerId != playerId.value) {
|
|
||||||
journalDataStatus.value = Status.Data.Loading;
|
|
||||||
}
|
|
||||||
|
|
||||||
playerId.value = queryPlayerId;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await apiStore.client.get<API.PlayerJournal.Data>('api/getPlayerJournal', {
|
|
||||||
params: {
|
|
||||||
playerId: queryPlayerId,
|
|
||||||
dateScope: '30d'
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
playerJournal.value = response.data;
|
|
||||||
journalDataStatus.value = Status.Data.Loaded;
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
journalDataStatus.value = Status.Data.Error;
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
|||||||
@@ -1,38 +1,46 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="player-avatar">
|
<div class="player-avatar">
|
||||||
<img
|
<img
|
||||||
v-if="avatarId"
|
v-if="props.playerTD2Info && props.playerTD2Info.avatar"
|
||||||
|
:src="`https://td2.info.pl/index.php?action=dlattach;attach=${props.playerTD2Info.avatar};type=avatar`"
|
||||||
class="player-avatar-image"
|
class="player-avatar-image"
|
||||||
ref="avatarImageRef"
|
ref="avatarImageRef"
|
||||||
:src="`https://td2.info.pl/index.php?action=dlattach;attach=${avatarId};type=avatar`"
|
|
||||||
alt="player image"
|
alt="player image"
|
||||||
@load="onAvatarLoadSuccess"
|
@load="onAvatarLoadSuccess"
|
||||||
@error="onAvatarLoadError"
|
@error="onAvatarLoadError"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<img
|
<img
|
||||||
v-if="avatarLoadingStatus == Status.Data.Error || avatarId == 0"
|
v-if="
|
||||||
|
avatarLoadingStatus == Status.Data.Error ||
|
||||||
|
(props.playerTD2Info && !props.playerTD2Info.avatar)
|
||||||
|
"
|
||||||
class="img-placeholder"
|
class="img-placeholder"
|
||||||
height="100"
|
height="100"
|
||||||
src="/images/default-avatar.jpg"
|
src="/images/default-avatar.jpg"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<Loading v-else-if="avatarLoadingStatus == Status.Data.Loading || avatarId === undefined" />
|
<Loading v-else-if="avatarLoadingStatus == Status.Data.Loading" />
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { ref } from 'vue';
|
import { computed, onMounted, PropType, ref, useTemplateRef } from 'vue';
|
||||||
import { Status } from '../../typings/common';
|
import { Status } from '../../typings/common';
|
||||||
import Loading from '../Global/Loading.vue';
|
import Loading from '../Global/Loading.vue';
|
||||||
|
import { Td2API } from '../../typings/api';
|
||||||
|
|
||||||
defineProps({
|
const props = defineProps({
|
||||||
avatarId: {
|
playerTD2Info: {
|
||||||
type: Number
|
type: Object as PropType<Td2API.UsersInfoByName.UserInfo>
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const avatarImageRef = ref<HTMLImageElement | null>(null);
|
onMounted(() => {
|
||||||
|
console.log(avatarImageRef.value);
|
||||||
|
});
|
||||||
|
|
||||||
|
const avatarImageRef = useTemplateRef('avatarImageRef');
|
||||||
const avatarLoadingStatus = ref<Status.Data>(Status.Data.Loading);
|
const avatarLoadingStatus = ref<Status.Data>(Status.Data.Loading);
|
||||||
|
|
||||||
function onAvatarLoadSuccess() {
|
function onAvatarLoadSuccess() {
|
||||||
|
|||||||
@@ -2,7 +2,7 @@
|
|||||||
<section class="profile-summary">
|
<section class="profile-summary">
|
||||||
<div class="player-info">
|
<div class="player-info">
|
||||||
<div class="info-main">
|
<div class="info-main">
|
||||||
<ProfilePlayerAvatar :avatarId="playerTD2Info?.avatar" />
|
<ProfilePlayerAvatar :playerTD2Info="playerTD2Info" />
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<h2 class="player-name-header" :class="{ 'text--donator': isPlayerDonator }">
|
<h2 class="player-name-header" :class="{ 'text--donator': isPlayerDonator }">
|
||||||
@@ -69,16 +69,16 @@
|
|||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Current activity -->
|
<!-- Current activities -->
|
||||||
<div
|
<div
|
||||||
class="player-activity"
|
class="player-activities-box"
|
||||||
v-if="activeDispatches.length > 0 || activeTrains.length > 0"
|
v-if="activeDispatches.length > 0 || activeTrains.length > 0"
|
||||||
>
|
>
|
||||||
<div class="info-activity" v-if="activeDispatches.length > 0">
|
<div class="info-activity" v-if="activeDispatches.length > 0">
|
||||||
<router-link
|
<router-link
|
||||||
v-for="d in activeDispatches"
|
v-for="d in activeDispatches"
|
||||||
class="dispatcher-badge"
|
class="dispatcher-badge"
|
||||||
:to="`/scenery?station=${d.stationName}`"
|
:to="`/scenery?station=${d.stationName}®ion=${d.region}`"
|
||||||
>
|
>
|
||||||
<img src="/images/icon-user.svg" width="25" alt="user icon" />
|
<img src="/images/icon-user.svg" width="25" alt="user icon" />
|
||||||
<b>{{ d.stationName }} ({{ getRegionNameById(d.region) }})</b>
|
<b>{{ d.stationName }} ({{ getRegionNameById(d.region) }})</b>
|
||||||
@@ -88,17 +88,17 @@
|
|||||||
|
|
||||||
<div class="info-activity" v-if="activeTrains.length > 0">
|
<div class="info-activity" v-if="activeTrains.length > 0">
|
||||||
<router-link
|
<router-link
|
||||||
v-for="d in activeTrains"
|
v-for="t in activeTrains"
|
||||||
:to="`/driver?trainId=${d.id}`"
|
:to="`/driver?trainId=${t.id}`"
|
||||||
class="driver-badge"
|
class="driver-badge"
|
||||||
>
|
>
|
||||||
<img src="/images/icon-train.svg" width="25" alt="train icon" />
|
<img src="/images/icon-train.svg" width="25" alt="train icon" />
|
||||||
<span v-if="d.timetable" class="text--primary">{{ d.timetable.category }}</span>
|
<span v-if="t.timetable" class="text--primary">{{ t.timetable.category }}</span>
|
||||||
<span>{{ d.trainNo }}</span>
|
<span>{{ t.trainNo }}</span>
|
||||||
•
|
•
|
||||||
<span>{{ d.currentStationName }} ({{ getRegionNameById(d.region) }})</span>
|
<span>{{ t.currentStationName }} ({{ getRegionNameById(t.region) }})</span>
|
||||||
•
|
•
|
||||||
<span class="text--grayed">{{ d.stockString.split(';')[0] }}</span>
|
<span class="text--grayed">{{ t.stockString.split(';')[0] }}</span>
|
||||||
</router-link>
|
</router-link>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -221,7 +221,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { computed, onMounted, PropType, ref } from 'vue';
|
import { computed, onActivated, onMounted, PropType, ref, watch } from 'vue';
|
||||||
import { API, Td2API } from '../../typings/api';
|
import { API, Td2API } from '../../typings/api';
|
||||||
import { calculateExpStyles } from '../../composables/badge';
|
import { calculateExpStyles } from '../../composables/badge';
|
||||||
import { getCountPercentage } from '../../utils/calcUtils';
|
import { getCountPercentage } from '../../utils/calcUtils';
|
||||||
@@ -230,7 +230,6 @@ import { useRoute } from 'vue-router';
|
|||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { useApiStore } from '../../store/apiStore';
|
import { useApiStore } from '../../store/apiStore';
|
||||||
import StationStatusBadge from '../Global/StationStatusBadge.vue';
|
import StationStatusBadge from '../Global/StationStatusBadge.vue';
|
||||||
import axios from 'axios';
|
|
||||||
import ProfilePlayerAvatar from './ProfilePlayerAvatar.vue';
|
import ProfilePlayerAvatar from './ProfilePlayerAvatar.vue';
|
||||||
import { getRegionNameById } from '../../utils/regionUtils';
|
import { getRegionNameById } from '../../utils/regionUtils';
|
||||||
|
|
||||||
@@ -245,21 +244,19 @@ const props = defineProps({
|
|||||||
required: true
|
required: true
|
||||||
},
|
},
|
||||||
|
|
||||||
|
playerTD2Info: {
|
||||||
|
type: Object as PropType<Td2API.UsersInfoByName.UserInfo>
|
||||||
|
},
|
||||||
|
|
||||||
playerName: {
|
playerName: {
|
||||||
type: String
|
type: String
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
const playerTD2Info = ref<Td2API.UsersInfoByName.UserInfo | null>(null);
|
|
||||||
|
|
||||||
const isPlayerDonator = computed(() =>
|
const isPlayerDonator = computed(() =>
|
||||||
props.playerName ? apiStore.donatorsData.includes(props.playerName) : false
|
props.playerName ? apiStore.donatorsData.includes(props.playerName) : false
|
||||||
);
|
);
|
||||||
|
|
||||||
onMounted(() => {
|
|
||||||
fetchTD2Data();
|
|
||||||
});
|
|
||||||
|
|
||||||
const activeDispatches = computed(() => {
|
const activeDispatches = computed(() => {
|
||||||
if (!props.playerName) return [];
|
if (!props.playerName) return [];
|
||||||
if (!apiStore.activeData || !apiStore.activeData.activeSceneries) return [];
|
if (!apiStore.activeData || !apiStore.activeData.activeSceneries) return [];
|
||||||
@@ -278,27 +275,6 @@ const activeTrains = computed(() => {
|
|||||||
(t) => t.driverName == props.playerName && (t.lastSeen >= Date.now() - 60000 || t.online)
|
(t) => t.driverName == props.playerName && (t.lastSeen >= Date.now() - 60000 || t.online)
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
async function fetchTD2Data() {
|
|
||||||
if (!props.playerName) return;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const response = await axios.get<Td2API.UsersInfoByName.Response>('https://api.td2.info.pl', {
|
|
||||||
params: {
|
|
||||||
method: 'getUsersInfoByName',
|
|
||||||
name: props.playerName
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (response.data.success && response.data.message.length == 1) {
|
|
||||||
playerTD2Info.value = response.data.message[0];
|
|
||||||
}
|
|
||||||
} catch (error) {
|
|
||||||
console.error(error);
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
@@ -372,8 +348,6 @@ async function fetchTD2Data() {
|
|||||||
|
|
||||||
gap: 0.25em;
|
gap: 0.25em;
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
|
|
||||||
padding: 0.25em 0.5em;
|
|
||||||
border-radius: 0.5em;
|
border-radius: 0.5em;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,7 +74,6 @@ const routes: Array<RouteRecordRaw> = [
|
|||||||
|
|
||||||
const router = createRouter({
|
const router = createRouter({
|
||||||
scrollBehavior(to, from, savedPosition) {
|
scrollBehavior(to, from, savedPosition) {
|
||||||
console.log(to.name);
|
|
||||||
if (
|
if (
|
||||||
(to.name == 'SceneryView' || to.name == 'DriverView' || to.name == 'PlayerProfileView') &&
|
(to.name == 'SceneryView' || to.name == 'DriverView' || to.name == 'PlayerProfileView') &&
|
||||||
from.name !== to.name &&
|
from.name !== to.name &&
|
||||||
|
|||||||
@@ -68,7 +68,7 @@ export const useApiStore = defineStore('apiStore', {
|
|||||||
// Active data fefresh
|
// Active data fefresh
|
||||||
if (t >= this.nextUpdateTime) {
|
if (t >= this.nextUpdateTime) {
|
||||||
this.fetchActiveData();
|
this.fetchActiveData();
|
||||||
this.nextUpdateTime = t + 20000;
|
this.nextUpdateTime = t + 31000;
|
||||||
}
|
}
|
||||||
|
|
||||||
window.requestAnimationFrame(this.updateTick);
|
window.requestAnimationFrame(this.updateTick);
|
||||||
|
|||||||
@@ -1,15 +1,23 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="profile-view">
|
<div class="profile-view">
|
||||||
<div class="profile-wrapper" v-if="playerInfo && playerDataStatus == Status.Data.Loaded">
|
<div class="profile-wrapper" v-if="playerInfo && playerInfoStatus == Status.Data.Loaded">
|
||||||
<ProfileSummary :playerInfo="playerInfo" :playerName="playerName" />
|
<ProfileSummary
|
||||||
|
:playerInfo="playerInfo"
|
||||||
|
:playerTD2Info="playerTD2Info"
|
||||||
|
:playerName="playerName"
|
||||||
|
/>
|
||||||
|
|
||||||
<div class="profile-side">
|
<div class="profile-side">
|
||||||
<ProfileRecentStats :playerInfo="playerInfo" />
|
<ProfileRecentStats :playerInfo="playerInfo" />
|
||||||
<ProfileHistoryList :playerName="playerName" />
|
<ProfileHistoryList
|
||||||
|
:playerName="playerName"
|
||||||
|
:playerJournal="playerJournal"
|
||||||
|
:journalStatus="playerJournalStatus"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Loading v-else-if="playerDataStatus == Status.Data.Loading" />
|
<Loading v-else-if="playerInfoStatus == Status.Data.Loading" />
|
||||||
|
|
||||||
<div class="no-data-found" v-else>
|
<div class="no-data-found" v-else>
|
||||||
<div>
|
<div>
|
||||||
@@ -22,9 +30,9 @@
|
|||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onActivated, onDeactivated, ref } from 'vue';
|
import { onActivated, onDeactivated, ref } from 'vue';
|
||||||
import { useRoute } from 'vue-router';
|
import { useRoute, useRouter } from 'vue-router';
|
||||||
import { useApiStore } from '../store/apiStore';
|
import { useApiStore } from '../store/apiStore';
|
||||||
import { API } from '../typings/api';
|
import { API, Td2API } from '../typings/api';
|
||||||
import { useI18n } from 'vue-i18n';
|
import { useI18n } from 'vue-i18n';
|
||||||
import { Status } from '../typings/common';
|
import { Status } from '../typings/common';
|
||||||
|
|
||||||
@@ -32,8 +40,10 @@ import Loading from '../components/Global/Loading.vue';
|
|||||||
import ProfileSummary from '../components/PlayerProfileView/ProfileSummary.vue';
|
import ProfileSummary from '../components/PlayerProfileView/ProfileSummary.vue';
|
||||||
import ProfileRecentStats from '../components/PlayerProfileView/ProfileRecentStats.vue';
|
import ProfileRecentStats from '../components/PlayerProfileView/ProfileRecentStats.vue';
|
||||||
import ProfileHistoryList from '../components/PlayerProfileView/ProfileHistoryList.vue';
|
import ProfileHistoryList from '../components/PlayerProfileView/ProfileHistoryList.vue';
|
||||||
|
import axios from 'axios';
|
||||||
|
|
||||||
const { t } = useI18n();
|
const { t } = useI18n();
|
||||||
|
const router = useRouter();
|
||||||
|
|
||||||
const apiStore = useApiStore();
|
const apiStore = useApiStore();
|
||||||
const route = useRoute();
|
const route = useRoute();
|
||||||
@@ -41,15 +51,18 @@ const route = useRoute();
|
|||||||
const playerId = ref(-1);
|
const playerId = ref(-1);
|
||||||
const playerName = ref('');
|
const playerName = ref('');
|
||||||
|
|
||||||
const playerInfo = ref<API.PlayerInfo.Data | null>(null);
|
const playerInfo = ref<API.PlayerInfo.Data | undefined>(undefined);
|
||||||
const playerDataStatus = ref(Status.Data.Initialized);
|
const playerTD2Info = ref<Td2API.UsersInfoByName.UserInfo | undefined>(undefined);
|
||||||
|
const playerJournal = ref<API.PlayerJournal.Data | undefined>(undefined);
|
||||||
|
|
||||||
|
const playerInfoStatus = ref(Status.Data.Initialized);
|
||||||
|
const playerJournalStatus = ref(Status.Data.Initialized);
|
||||||
|
|
||||||
const intervalId = ref(-1);
|
const intervalId = ref(-1);
|
||||||
|
|
||||||
onActivated(() => {
|
onActivated(() => {
|
||||||
fetchPlayerData();
|
fetchPlayerData();
|
||||||
|
intervalId.value = setInterval(fetchPlayerData, 32000);
|
||||||
intervalId.value = setInterval(fetchPlayerData, 30000);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
onDeactivated(() => {
|
onDeactivated(() => {
|
||||||
@@ -57,32 +70,85 @@ onDeactivated(() => {
|
|||||||
intervalId.value = -1;
|
intervalId.value = -1;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
async function fetchPlayerInfo(playerId: number) {
|
||||||
|
return apiStore.client!.get<API.PlayerInfo.Data>('api/getPlayerInfo', {
|
||||||
|
params: {
|
||||||
|
playerId
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchPlayerJournal(playerId: number) {
|
||||||
|
return apiStore.client!.get<API.PlayerJournal.Data>('api/getPlayerJournal', {
|
||||||
|
params: {
|
||||||
|
playerId,
|
||||||
|
dateScope: '30d'
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function fetchPlayerTd2Info(playerName: string) {
|
||||||
|
return axios.get<Td2API.UsersInfoByName.Response>('https://api.td2.info.pl', {
|
||||||
|
params: {
|
||||||
|
method: 'getUsersInfoByName',
|
||||||
|
name: playerName
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
async function fetchPlayerData() {
|
async function fetchPlayerData() {
|
||||||
const queryPlayerId = Number(route.query.playerId) || -1;
|
const queryPlayerId = Number(route.query.playerId) || -1;
|
||||||
|
|
||||||
if (!apiStore.client || !queryPlayerId) return;
|
if (!apiStore.client || !queryPlayerId) return;
|
||||||
|
|
||||||
if (queryPlayerId != playerId.value) {
|
if (queryPlayerId != playerId.value) {
|
||||||
playerDataStatus.value = Status.Data.Loading;
|
playerInfoStatus.value = Status.Data.Loading;
|
||||||
|
playerJournalStatus.value = Status.Data.Loading;
|
||||||
|
|
||||||
|
playerInfo.value = undefined;
|
||||||
|
playerTD2Info.value = undefined;
|
||||||
|
playerJournal.value = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
playerId.value = queryPlayerId;
|
playerId.value = queryPlayerId;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const response = await apiStore.client.get<API.PlayerInfo.Data>('api/getPlayerInfo', {
|
const playerInfoResp = await fetchPlayerInfo(playerId.value);
|
||||||
params: {
|
|
||||||
playerId: queryPlayerId
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
playerName.value =
|
playerName.value =
|
||||||
response.data.driverStats.driverName || response.data.dispatcherStats.dispatcherName || '';
|
playerInfoResp.data.driverStats.driverName ||
|
||||||
|
playerInfoResp.data.dispatcherStats.dispatcherName ||
|
||||||
|
'';
|
||||||
|
|
||||||
playerInfo.value = response.data || null;
|
if (!playerName.value) {
|
||||||
playerDataStatus.value = Status.Data.Loaded;
|
router.push('/');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
playerInfo.value = playerName.value ? playerInfoResp.data : undefined;
|
||||||
|
playerInfoStatus.value = Status.Data.Loaded;
|
||||||
|
|
||||||
|
if (playerName.value) {
|
||||||
|
const playerTD2InfoResp = await fetchPlayerTd2Info(playerName.value);
|
||||||
|
|
||||||
|
if (playerTD2InfoResp.data.success && playerTD2InfoResp.data.message.length == 1) {
|
||||||
|
playerTD2Info.value = playerTD2InfoResp.data.message[0];
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error(error);
|
playerInfo.value = undefined;
|
||||||
playerDataStatus.value = Status.Data.Error;
|
playerTD2Info.value = undefined;
|
||||||
|
playerInfoStatus.value = Status.Data.Error;
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
const playerJournalResp = await fetchPlayerJournal(playerId.value);
|
||||||
|
|
||||||
|
playerJournal.value = playerJournalResp.data;
|
||||||
|
playerJournalStatus.value = Status.Data.Loaded;
|
||||||
|
} catch (error) {
|
||||||
|
playerJournal.value = undefined;
|
||||||
|
playerJournalStatus.value = Status.Data.Error;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
@@ -100,7 +166,12 @@ async function fetchPlayerData() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.no-data-found {
|
.no-data-found {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: center;
|
||||||
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
font-size: 1.35em;
|
||||||
|
|
||||||
max-width: var(--max-container-width);
|
max-width: var(--max-container-width);
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
|||||||
Reference in New Issue
Block a user