You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

135 lines
3.3 KiB

<script setup lang="ts">
import ScrollerItemPortrait from './ScrollerItemPortrait.vue'
import ScrollerItemLandscape from './ScrollerItemLandscape.vue'
import type { FeedItem } from '@/feed'
import { ref, onBeforeMount } from 'vue'
const props = defineProps<{
title: string
landscape?: boolean
feedItems: Promise<FeedItem[]>
}>()
const items = ref<FeedItem[]>()
const overflow = ref(false)
const translate = ref(0)
const vw = Math.max(document.documentElement.clientWidth || 0, window.innerWidth || 0)
const renderSpace = vw * 0.55
onBeforeMount(async () => {
items.value = await props.feedItems
console.log('MediaScroller.vue =>', props.feedItems)
const itemLimit = renderSpace / (props.landscape ? 245 : 125)
console.log(props.title, '=>', itemLimit)
if (items.value.length > itemLimit) {
overflow.value = true
}
})
const translateForward = () => {
disableForward()
if (props.landscape) {
translate.value -= 1008
} else {
translate.value -= 1058
}
}
const translateBackward = () => {
if (props.landscape) {
translate.value += 1008
} else {
translate.value += 1058
}
}
const disableForward = () => {
const v =
(items.value ? items.value.length : 0) * (props.landscape ? 317 : 185) -
Math.abs(translate.value) <
renderSpace
return v
}
</script>
<template>
<div class="wrapper" v-show="(items ? items.length : 0) > 0">
<div class="scroller-header">
<div class="scroller-title">{{ props.title }}</div>
<div class="scroller-controls" v-show="overflow">
<button class="translate-button" @click="translateBackward()" :disabled="translate >= 0">
<font-awesome-icon icon="fa-solid fa-play" class="fa-flip-horizontal" size="sm" />
</button>
<button class="translate-button" @click="translateForward()" :disabled="disableForward()">
<font-awesome-icon icon="fa-solid fa-play" size="sm" />
</button>
</div>
</div>
<div
class="scroller-content no-select"
:style="{
height: `${props.landscape ? 250 : 320}px`,
transform: `translateX(${translate}px)`,
}"
>
<div class="scroller-wrapper" v-if="landscape">
<ScrollerItemLandscape
v-for="item in items"
:item="item"
:key="item.itemId"
class="scroller-item"
/>
</div>
<div class="scroller-wrapper" v-else>
<ScrollerItemPortrait
v-for="item in items"
:item="item"
:key="item.itemId"
class="scroller-item"
/>
</div>
</div>
</div>
</template>
<style scoped>
.scroller-title {
margin-bottom: 1em;
}
.scroller-wrapper {
display: flex;
gap: 1em;
}
.scroller-controls svg {
padding: 1em;
margin-right: 2em;
}
.scroller-controls {
margin-right: 10em;
}
.scroller-header {
display: flex;
align-items: center;
width: 100%;
justify-content: space-between;
}
.scroller-content {
transition: all 0.3s ease;
}
.translate-button {
border: none;
background: none;
color: var(--color-text);
}
.translate-button:hover {
cursor: pointer;
color: var(--color-text-faded);
}
.translate-button:disabled {
border: none;
background: none;
color: var(--color-text-faded);
}
.translate-button:disabled:hover {
cursor: default;
}
.wrapper {
overflow: hidden;
}
</style>