refactor(scenery): improved components visibility on API data loading

This commit is contained in:
2026-03-22 14:04:49 +01:00
parent d643259102
commit eae62a8064
4 changed files with 171 additions and 172 deletions
+1 -15
View File
@@ -1,10 +1,6 @@
<template> <template>
<section class="info-header"> <section class="info-header">
<button <button class="btn btn-return" :title="$t('scenery.return-btn')" @click="onReturnButtonClick">
class="btn btn-return"
:title="$t('scenery.return-btn')"
@click="onReturnButtonClick"
>
<img src="/images/icon-back.svg" alt="return button" /> <img src="/images/icon-back.svg" alt="return button" />
</button> </button>
@@ -12,10 +8,6 @@
{{ stationName.replace(/_/g, ' ') }} {{ stationName.replace(/_/g, ' ') }}
</a> </a>
<div class="scenery-abbrev" v-if="station?.generalInfo?.abbr">
{{ $t('scenery.abbrev') }} <b>{{ station.generalInfo.abbr }}</b>
</div>
<div class="scenery-hash" v-if="onlineScenery?.hash">#{{ onlineScenery.hash }}</div> <div class="scenery-hash" v-if="onlineScenery?.hash">#{{ onlineScenery.hash }}</div>
</section> </section>
</template> </template>
@@ -81,13 +73,7 @@ function onReturnButtonClick() {
text-transform: uppercase; text-transform: uppercase;
} }
.scenery-abbrev {
font-size: 1.3em;
color: #aaa;
}
.scenery-hash { .scenery-hash {
margin-top: 0.5em;
color: #aaa; color: #aaa;
font-size: 1.2em; font-size: 1.2em;
} }
+38 -30
View File
@@ -1,29 +1,32 @@
<template> <template>
<div class="scenery-info"> <div class="scenery-info">
<section> <section>
<SceneryInfoIcons :station="station" /> <div class="info-station-data" v-if="apiStore.dataStatuses.sceneries == Status.Data.Loaded">
<SceneryInfoGeneral :station="station" /> <SceneryInfoIcons :station="station" />
<SceneryInfoRoutes v-if="station" :station="station" /> <SceneryInfoGeneral :station="station" />
<SceneryInfoAuthors :station="station" /> <SceneryInfoRoutes v-if="station" :station="station" />
<SceneryInfoAuthors :station="station" />
</div>
<div style="margin: 1em 0; height: 2px; background-color: white"></div> <div class="info-station-loading" v-else>
<Loading />
</div>
<div class="info-divider"></div>
<!-- info dispatcher -->
<SceneryInfoDispatcher :onlineScenery="onlineScenery" /> <SceneryInfoDispatcher :onlineScenery="onlineScenery" />
<div class="info-lists"> <div class="info-online-lists">
<!-- user list -->
<SceneryInfoUserList :onlineScenery="onlineScenery" :station="station" /> <SceneryInfoUserList :onlineScenery="onlineScenery" :station="station" />
<!-- spawn list -->
<SceneryInfoSpawnList :onlineScenery="onlineScenery" /> <SceneryInfoSpawnList :onlineScenery="onlineScenery" />
</div> </div>
</section> </section>
</div> </div>
</template> </template>
<script lang="ts"> <script lang="ts" setup>
import { PropType, defineComponent } from 'vue'; import { PropType } from 'vue';
import { ActiveScenery, Station, Status } from '../../typings/common';
import SceneryInfoDispatcher from './SceneryInfo/SceneryInfoDispatcher.vue'; import SceneryInfoDispatcher from './SceneryInfo/SceneryInfoDispatcher.vue';
import SceneryInfoIcons from './SceneryInfo/SceneryInfoIcons.vue'; import SceneryInfoIcons from './SceneryInfo/SceneryInfoIcons.vue';
@@ -32,27 +35,18 @@ import SceneryInfoSpawnList from './SceneryInfo/SceneryInfoSpawnList.vue';
import SceneryInfoRoutes from './SceneryInfo/SceneryInfoRoutes.vue'; import SceneryInfoRoutes from './SceneryInfo/SceneryInfoRoutes.vue';
import SceneryInfoGeneral from './SceneryInfo/SceneryInfoGeneral.vue'; import SceneryInfoGeneral from './SceneryInfo/SceneryInfoGeneral.vue';
import SceneryInfoAuthors from './SceneryInfo/SceneryInfoAuthors.vue'; import SceneryInfoAuthors from './SceneryInfo/SceneryInfoAuthors.vue';
import { useApiStore } from '../../store/apiStore';
import Loading from '../Global/Loading.vue';
import { ActiveScenery, Station } from '../../typings/common'; const apiStore = useApiStore();
export default defineComponent({ defineProps({
components: { station: {
SceneryInfoDispatcher, type: Object as PropType<Station>
SceneryInfoGeneral,
SceneryInfoIcons,
SceneryInfoAuthors,
SceneryInfoUserList,
SceneryInfoSpawnList,
SceneryInfoRoutes
}, },
props: {
station: {
type: Object as PropType<Station>
},
onlineScenery: { onlineScenery: {
type: Object as PropType<ActiveScenery> type: Object as PropType<ActiveScenery>
}
} }
}); });
</script> </script>
@@ -60,7 +54,15 @@ export default defineComponent({
<style lang="scss" scoped> <style lang="scss" scoped>
@use '../../styles/responsive'; @use '../../styles/responsive';
.info-lists { .info-station-loading {
display: flex;
align-items: center;
justify-content: center;
min-height: 300px;
}
.info-online-lists {
display: flex; display: flex;
flex-wrap: wrap; flex-wrap: wrap;
justify-content: space-around; justify-content: space-around;
@@ -68,6 +70,12 @@ export default defineComponent({
margin-top: 1em; margin-top: 1em;
} }
.info-divider {
margin: 1em 0;
height: 3px;
background-color: #5b5b5b;
}
.scenery-topic a { .scenery-topic a {
font-weight: bold; font-weight: bold;
} }
@@ -5,51 +5,57 @@
</div> </div>
<div v-else> <div v-else>
<span> <div>
<b>{{ $t('availability.title') }}:</b> <span>
{{ $t(`availability.${station.generalInfo.availability}`) }} <b>{{ $t('scenery.abbrev') }}</b> {{ station.generalInfo.abbr }}
<span v-if="station.generalInfo.reqLevel > -1">
-
{{
$t(
'scenery.req-level',
{ lvl: station.generalInfo.reqLevel },
station.generalInfo.reqLevel
)
}}
</span> </span>
</span>
<span> <span>
&bull; <b>{{ $t('controls.title') }}:</b> &bull; <b>{{ $t('availability.title') }}:</b>
{{ $t(`controls.${station.generalInfo.controlType}`) }} {{ $t(`availability.${station.generalInfo.availability}`) }}
</span>
<span> <span v-if="station.generalInfo.reqLevel > -1">
&bull; <b>{{ $t('signals.title') }}:</b> -
{{ $t(`signals.${station.generalInfo.signalType}`) }} {{
</span> $t(
'scenery.req-level',
{ lvl: station.generalInfo.reqLevel },
station.generalInfo.reqLevel
)
}}
</span>
</span>
<span v-if="station.generalInfo.lines"> <span>
&bull; <b>{{ $t('scenery.lines-title') }}:</b> {{ station.generalInfo.lines }} &bull; <b>{{ $t('controls.title') }}:</b>
</span> {{ $t(`controls.${station.generalInfo.controlType}`) }}
</span>
<span v-if="station.generalInfo.project"> <span>
&bull; <b>{{ $t('scenery.project-title') }}: </b> &bull; <b>{{ $t('signals.title') }}:</b>
<a {{ $t(`signals.${station.generalInfo.signalType}`) }}
style="color: salmon; text-decoration: underline; font-weight: bold" </span>
:href="station.generalInfo.projectUrl"
target="_blank"
>
{{ station.generalInfo.project }}
</a>
</span>
<span v-if="additionalTools.length != 0"> <span v-if="station.generalInfo.lines">
&bull; <b>{{ $t('scenery.additional-tools-title') }}: </b> &bull; <b>{{ $t('scenery.lines-title') }}:</b> {{ station.generalInfo.lines }}
{{ additionalTools.join(', ') }} </span>
</span>
<span v-if="station.generalInfo.project">
&bull; <b>{{ $t('scenery.project-title') }}: </b>
<a
style="color: salmon; text-decoration: underline; font-weight: bold"
:href="station.generalInfo.projectUrl"
target="_blank"
>
{{ station.generalInfo.project }}
</a>
</span>
<span v-if="additionalTools.length != 0">
&bull; <b>{{ $t('scenery.additional-tools-title') }}: </b>
{{ additionalTools.join(', ') }}
</span>
</div>
</div> </div>
</section> </section>
</template> </template>
@@ -84,9 +90,9 @@ export default defineComponent({
display: flex; display: flex;
justify-content: center; justify-content: center;
flex-wrap: wrap; flex-wrap: wrap;
}
div { .scenery-abbrev {
margin: 0 0.15em; font-size: 1.05em;
}
} }
</style> </style>
@@ -1,102 +1,101 @@
<template> <template>
<section class="info-icons"> <section class="info-icons-section">
<span v-if="!station || !station.generalInfo"> <div class="icons-box">
<span v-if="!station || !station.generalInfo">
<img
class="icon-info"
src="/images/icon-unknown.svg"
alt="icon-unknown"
:title="$t('sceneries.info.unknown')"
/>
</span>
<span
v-if="station?.generalInfo && station?.generalInfo.reqLevel >= 0"
class="scenery-icon icon-info level"
:style="calculateExpStyles(station?.generalInfo.reqLevel)"
>
{{ station?.generalInfo.reqLevel >= 2 ? station?.generalInfo.reqLevel : 'L' }}
</span>
<img <img
v-if="station?.generalInfo?.availability == 'nonPublic'"
class="icon-info" class="icon-info"
src="/images/icon-unknown.svg" src="/images/icon-lock.svg"
alt="icon-unknown" alt="Non-public scenery"
:title="$t('sceneries.info.unknown')" :title="$t('sceneries.info.non-public')"
/> />
</span>
<span <img
v-if="station?.generalInfo && station?.generalInfo.reqLevel >= 0" v-if="station?.generalInfo?.availability == 'unavailable'"
class="scenery-icon icon-info level" class="icon-info"
:style="calculateExpStyle(station?.generalInfo.reqLevel)" src="/images/icon-unavailable.svg"
> alt="Unavailable scenery"
{{ station?.generalInfo.reqLevel >= 2 ? station?.generalInfo.reqLevel : 'L' }} :title="$t('sceneries.info.unavailable')"
</span> />
<img <img
v-if="station?.generalInfo?.availability == 'nonPublic'" v-if="station?.generalInfo?.availability == 'abandoned'"
class="icon-info" class="icon-info"
src="/images/icon-lock.svg" src="/images/icon-abandoned.svg"
alt="Non-public scenery" alt="Abandoned scenery"
:title="$t('sceneries.info.non-public')" :title="$t('sceneries.info.abandoned')"
/> />
<img <span
v-if="station?.generalInfo?.availability == 'unavailable'" v-if="station?.generalInfo"
class="icon-info" class="scenery-icon icon-info"
src="/images/icon-unavailable.svg" :class="station?.generalInfo.controlType.replace('+', '-')"
alt="Unavailable scenery" :title="
:title="$t('sceneries.info.unavailable')" $t('sceneries.info.control-type') + $t(`controls.${station?.generalInfo.controlType}`)
/> "
>
{{ $t(`controls.abbrevs.${station.generalInfo.controlType}`) }}
</span>
<img <img
v-if="station?.generalInfo?.availability == 'abandoned'" v-if="station?.generalInfo?.signalType"
class="icon-info" class="icon-info"
src="/images/icon-abandoned.svg" :src="`/images/icon-${station.generalInfo.signalType}.svg`"
alt="Abandoned scenery" :alt="station.generalInfo.signalType"
:title="$t('sceneries.info.abandoned')" :title="$t('sceneries.info.signals-type') + $t(`signals.${station.generalInfo.signalType}`)"
/> />
<span <img
v-if="station?.generalInfo" v-if="station?.generalInfo?.lines"
class="scenery-icon icon-info" class="icon-info"
:class="station?.generalInfo.controlType.replace('+', '-')" src="/images/icon-real.svg"
:title=" alt="real scenery"
$t('sceneries.info.control-type') + $t(`controls.${station?.generalInfo.controlType}`) :title="`${$t('sceneries.info.real')} ${station.generalInfo.lines}`"
" />
>
{{ $t(`controls.abbrevs.${station.generalInfo.controlType}`) }}
</span>
<img <img
v-if="station?.generalInfo?.signalType" v-if="station?.generalInfo?.SUP"
class="icon-info" class="icon-info"
:src="`/images/icon-${station.generalInfo.signalType}.svg`" src="/images/icon-SUP.svg"
:alt="station.generalInfo.signalType" alt="SUP (RASP-UZK)"
:title="$t('sceneries.info.signals-type') + $t(`signals.${station.generalInfo.signalType}`)" :title="$t('sceneries.info.SUP')"
/> />
<img <img
v-if="station?.generalInfo?.lines" v-if="station?.generalInfo?.ASDEK"
class="icon-info" class="icon-info"
src="/images/icon-real.svg" src="/images/icon-ASDEK.svg"
alt="real scenery" alt="dSAT ASDEK"
:title="`${$t('sceneries.info.real')} ${station.generalInfo.lines}`" :title="$t('sceneries.info.ASDEK')"
/> />
</div>
<img
v-if="station?.generalInfo?.SUP"
class="icon-info"
src="/images/icon-SUP.svg"
alt="SUP (RASP-UZK)"
:title="$t('sceneries.info.SUP')"
/>
<img
v-if="station?.generalInfo?.ASDEK"
class="icon-info"
src="/images/icon-ASDEK.svg"
alt="dSAT ASDEK"
:title="$t('sceneries.info.ASDEK')"
/>
</section> </section>
</template> </template>
<script lang="ts"> <script lang="ts" setup>
import { PropType, defineComponent } from 'vue'; import { PropType } from 'vue';
import styleMixin from '../../../mixins/styleMixin';
import { Station } from '../../../typings/common'; import { Station } from '../../../typings/common';
import { calculateExpStyles } from '../../../composables/badge';
export default defineComponent({ defineProps({
mixins: [styleMixin], station: {
props: { type: Object as PropType<Station>
station: {
type: Object as PropType<Station>
}
} }
}); });
</script> </script>
@@ -104,12 +103,12 @@ export default defineComponent({
<style lang="scss" scoped> <style lang="scss" scoped>
@use '../../../styles/icons'; @use '../../../styles/icons';
.info-icons { .icons-box {
display: flex; display: flex;
justify-content: center; justify-content: center;
flex-wrap: wrap; flex-wrap: wrap;
margin: 1em; margin: 0.5em;
} }
.icon-info { .icon-info {