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
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>
|