migu/common/views/Home/Section.svelte
ThaUnknown 13c83bf297 feat: further improve dpad navigation
feat: make home lists scrollable on mobile
2024-06-30 14:47:45 +02:00

72 lines
1.9 KiB
Svelte

<script context='module'>
const fakecards = Array.from({ length: 15 }, () => ({ data: new Promise(() => {}) }))
</script>
<script>
import Card from '@/components/cards/Card.svelte'
import ErrorCard from '@/components/cards/ErrorCard.svelte'
import { search } from '../Search.svelte'
import { page } from '@/App.svelte'
import { click } from '@/modules/click.js'
export let opts
function deferredLoad (element) {
const observer = new IntersectionObserver(([entry]) => {
if (entry.isIntersecting) {
if (!opts.preview.value) opts.preview.value = opts.load(1, 15)
observer.unobserve(element)
}
}, { threshold: 0 })
observer.observe(element)
return { destroy () { observer.unobserve(element) } }
}
function _click () {
$search = {
...opts.variables,
load: opts.load
}
$page = 'search'
}
const preview = opts.preview
</script>
<span class='d-flex px-20 align-items-end pointer text-decoration-none text-muted'
use:deferredLoad>
<div class='font-size-24 font-weight-semi-bold' use:click={_click}>{opts.title}</div>
<div class='pr-10 ml-auto font-size-12' use:click={_click}>View More</div>
</span>
<div class='position-relative'>
<div class='pb-10 w-full d-flex flex-row justify-content-start gallery'>
{#each $preview || fakecards as card}
<Card {card} />
{/each}
{#if $preview?.length}
<ErrorCard promise={$preview[0].data} />
{/if}
</div>
</div>
<style>
.text-muted:hover {
color: var(--dm-link-text-color-hover) !important;
}
.gallery:after {
content: '';
position: absolute;
right: 0;
height: 100%;
width: 8rem;
background: linear-gradient(270deg, #17191cff 0%, #17191c00 100%);
pointer-events: none;
}
.gallery {
overflow-x: scroll;
flex-shrink: 0;
}
.gallery::-webkit-scrollbar {
display: none;
}
</style>