Fix Steam game transition jumping to top of container
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 3m28s
All checks were successful
Deploy with Docker Compose / deploy (push) Successful in 3m28s
Wrap Transition in a relative-positioned game-container div so the leaving element's absolute positioning is scoped to the game area, not the full wrapper. Use flex layout so the container fills only the space below the header. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
@@ -17,91 +17,105 @@ let nextId = null;
|
|||||||
let refreshId = null;
|
let refreshId = null;
|
||||||
|
|
||||||
function nextGame() {
|
function nextGame() {
|
||||||
clearTimeout(nextId);
|
clearTimeout(nextId);
|
||||||
nextId = setTimeout(nextGame, 5000);
|
nextId = setTimeout(nextGame, 5000);
|
||||||
if (steamStatus.value.recentGames.length) {
|
if (steamStatus.value.recentGames.length) {
|
||||||
idx.value = (idx.value + 1) % steamStatus.value.recentGames.length;
|
idx.value = (idx.value + 1) % steamStatus.value.recentGames.length;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
nextId = setTimeout(nextGame, 5000);
|
nextId = setTimeout(nextGame, 5000);
|
||||||
refreshId = setInterval(() => steamStore.fetchSteam(), 5 * 60 * 1000);
|
refreshId = setInterval(() => steamStore.fetchSteam(), 5 * 60 * 1000);
|
||||||
});
|
});
|
||||||
onUnmounted(() => {
|
onUnmounted(() => {
|
||||||
clearTimeout(nextId);
|
clearTimeout(nextId);
|
||||||
clearInterval(refreshId);
|
clearInterval(refreshId);
|
||||||
});
|
});
|
||||||
|
|
||||||
function formatHours(minutes) {
|
function formatHours(minutes) {
|
||||||
const hrs = (minutes / 60).toFixed(1);
|
const hrs = (minutes / 60).toFixed(1);
|
||||||
return `${hrs}h`;
|
return `${hrs}h`;
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<template>
|
<template>
|
||||||
<div class="steam-wrapper">
|
<div class="steam-wrapper">
|
||||||
<Header class="text-left">
|
<Header class="text-left">
|
||||||
<span class="flex items-center gap-2">
|
<span class="flex items-center gap-2">
|
||||||
Steam
|
Steam
|
||||||
<span
|
<span
|
||||||
class="inline-block w-2 h-2 rounded-full"
|
class="inline-block w-2 h-2 rounded-full"
|
||||||
:class="steamStatus.online ? 'bg-green-500' : 'bg-gray-400'"
|
:class="steamStatus.online ? 'bg-green-500' : 'bg-gray-400'"
|
||||||
:title="steamStatus.online ? 'Online' : 'Offline'"
|
:title="steamStatus.online ? 'Online' : 'Offline'"
|
||||||
/>
|
/>
|
||||||
</span>
|
</span>
|
||||||
</Header>
|
</Header>
|
||||||
|
|
||||||
<div v-if="!loaded" class="p-2 text-sm">Loading...</div>
|
<div v-if="!loaded" class="p-2 text-sm">Loading...</div>
|
||||||
|
|
||||||
<Transition name="fade" v-else-if="game">
|
<div v-else-if="game" class="game-container">
|
||||||
<div @click="nextGame" :key="game.appId" class="flex flex-col items-center">
|
<Transition name="fade">
|
||||||
<img
|
<div
|
||||||
:src="game.headerImageUrl"
|
@click="nextGame"
|
||||||
:alt="game.name"
|
:key="game.appId"
|
||||||
class="game-img"
|
class="flex flex-col items-center"
|
||||||
/>
|
>
|
||||||
<p class="text-center">
|
<img
|
||||||
<strong>{{ game.name }}</strong>
|
:src="game.headerImageUrl"
|
||||||
</p>
|
:alt="game.name"
|
||||||
<p class="text-center text-tertiary text-xs">
|
class="game-img"
|
||||||
{{ formatHours(game.playtime2Weeks) }} last 2 weeks
|
/>
|
||||||
</p>
|
<p class="text-center">
|
||||||
</div>
|
<strong>{{ game.name }}</strong>
|
||||||
</Transition>
|
</p>
|
||||||
|
<p class="text-center text-tertiary text-xs">
|
||||||
|
{{ formatHours(game.playtime2Weeks) }} last 2 weeks
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</Transition>
|
||||||
|
</div>
|
||||||
|
|
||||||
<div v-else class="p-2 text-sm">No recent games.</div>
|
<div v-else class="p-2 text-sm">No recent games.</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.steam-wrapper {
|
.steam-wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
width: 100%;
|
height: 50mm;
|
||||||
height: 100%;
|
display: flex;
|
||||||
|
flex-direction: column;
|
||||||
|
}
|
||||||
|
|
||||||
|
.game-container {
|
||||||
|
position: relative;
|
||||||
|
flex: 1;
|
||||||
|
min-height: 0;
|
||||||
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
.game-img {
|
.game-img {
|
||||||
width: 90%;
|
width: 90%;
|
||||||
}
|
}
|
||||||
|
|
||||||
p {
|
p {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.fade-enter-active,
|
.fade-enter-active,
|
||||||
.fade-leave-active {
|
.fade-leave-active {
|
||||||
transition: opacity 0.5s ease;
|
transition: opacity 0.5s ease;
|
||||||
}
|
}
|
||||||
.fade-leave-active {
|
.fade-leave-active {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 0;
|
top: 0;
|
||||||
left: 0;
|
left: 0;
|
||||||
right: 0;
|
right: 0;
|
||||||
}
|
}
|
||||||
.fade-enter-from,
|
.fade-enter-from,
|
||||||
.fade-leave-to {
|
.fade-leave-to {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user