fix: Hero showcase click not working

This commit is contained in:
Aleksi Lassila
2024-05-12 01:38:19 +03:00
parent 3a94690cdf
commit 8d5e071862
6 changed files with 57 additions and 25 deletions

View File

@@ -50,6 +50,7 @@
<Container
class="flex-1 flex"
on:enter
on:select
on:navigate={(event) => {
const detail = event.detail;
if (!backgroundHasFocus) return;

View File

@@ -9,8 +9,19 @@
import SidebarMargin from '../SidebarMargin.svelte';
import { get } from 'svelte/store';
import { registrars } from '../../selectable.js';
import { createEventDispatcher } from 'svelte';
const dispatch = createEventDispatcher<{
select: ShowcaseItemProps | undefined;
}>();
export let items: Promise<ShowcaseItemProps[]> = Promise.resolve([]);
let awaitedItems: undefined | ShowcaseItemProps[];
items.then((items) => (awaitedItems = items));
function openItem() {
if (awaitedItems) dispatch('select', awaitedItems[showcaseIndex]);
}
let showcaseIndex = 0;
</script>
@@ -24,23 +35,29 @@
get(registrars.sidebar)?.focus();
}
}}
on:select={openItem}
>
<div class="h-full flex-1 flex overflow-hidden z-10 relative">
{#await items}
<div class="flex-1 flex items-end">
<CardPlaceholder orientation="portrait" />
<div class="flex flex-col">
<div>stats</div>
<div>title</div>
<div>genres</div>
</div>
</div>
<!-- <div class="flex-1 flex items-end">-->
<!-- <CardPlaceholder orientation="portrait" />-->
<!-- <div class="flex flex-col">-->
<!-- <div>stats</div>-->
<!-- <div>title</div>-->
<!-- <div>genres</div>-->
<!-- </div>-->
<!-- </div>-->
{:then items}
{@const item = items[showcaseIndex]}
{#if item}
<div class="flex-1 flex items-end p-3">
<div class="flex-1 flex items-end">
<div class="mr-8">
<Card orientation="portrait" backdropUrl={TMDB_POSTER_SMALL + item.posterUrl} />
<!-- <Card orientation="portrait" backdropUrl={TMDB_POSTER_SMALL + item.posterUrl} />-->
<div
class="bg-center bg-cover rounded-xl w-44 h-64 cursor-pointer"
style={`background-image: url("${TMDB_POSTER_SMALL + item.posterUrl}")`}
on:click={openItem}
/>
</div>
<div class="flex flex-col">
<div
@@ -51,6 +68,7 @@
'text-3xl sm:text-4xl 2xl:text-5xl': item?.title.length >= 15
}
)}
on:click={openItem}
>
{item?.title}
</div>

View File

@@ -7,6 +7,7 @@ export type ShowcaseItemProps = {
posterUrl: string;
backdropUrl: string;
id: number;
trailerUrl?: string;
title: string;
@@ -23,6 +24,7 @@ export async function getShowcasePropsFromTmdbMovie(
response: Awaited<ReturnType<typeof tmdbApi.getPopularMovies>>
): Promise<ShowcaseItemProps[]> {
return response.slice(0, 10).map((movie) => ({
id: movie.id || 0,
title: movie.title || '',
posterUrl: movie.poster_path || '',
backdropUrl: movie.backdrop_path || '',
@@ -40,17 +42,18 @@ export async function getShowcasePropsFromTmdbMovie(
export async function getShowcasePropsFromTmdbSeries(
response: Awaited<ReturnType<typeof tmdbApi.getPopularSeries>>
): Promise<ShowcaseItemProps[]> {
return response.slice(0, 10).map((movie) => ({
title: movie.name || '',
posterUrl: movie.poster_path || '',
backdropUrl: movie.backdrop_path || '',
rating: movie.vote_average?.toFixed(1) || '0',
genres: [], //(movie as any)?.genres?.map((genre: any) => genre?.name),
year: movie.first_air_date ? new Date(movie.first_air_date).getFullYear() : undefined,
runtime: formatMinutesToTime((movie as any).runtime || 0),
return response.slice(0, 10).map((series) => ({
id: series.id || 0,
title: series.name || '',
posterUrl: series.poster_path || '',
backdropUrl: series.backdrop_path || '',
rating: series.vote_average?.toFixed(1) || '0',
genres: [], //(series as any)?.genres?.map((genre: any) => genre?.name),
year: series.first_air_date ? new Date(series.first_air_date).getFullYear() : undefined,
runtime: formatMinutesToTime((series as any).runtime || 0),
ratingSource: 'tmdb',
trailerUrl: '',
url: `https://www.themoviedb.org/movie/${movie.id}`,
overview: movie.overview || ''
url: `https://www.themoviedb.org/movie/${series.id}`,
overview: series.overview || ''
}));
}

View File

@@ -25,9 +25,9 @@
}));
</script>
<Container focusOnMount class="px-20">
<div class="my-8">
<div class="font-medium tracking-wide text-2xl text-zinc-200">Library</div>
<Container focusOnMount class="px-32 py-16">
<div class="mb-6">
<div class="header2">Library</div>
</div>
<CardGrid>
{#await libraryItemsP}

View File

@@ -9,11 +9,13 @@
import { jellyfinApi } from '../apis/jellyfin/jellyfin-api';
import { useRequest } from '../stores/data.store';
import JellyfinCard from '../components/Card/JellyfinCard.svelte';
import { Route } from 'svelte-navigator';
import { Route, useNavigate } from 'svelte-navigator';
import MoviePage from './MoviePage.svelte';
import { formatDateToYearMonthDay } from '../utils';
import TmdbCard from '../components/Card/TmdbCard.svelte';
const navigate = useNavigate();
const continueWatching = jellyfinApi.getContinueWatching('movie');
const recentlyAdded = jellyfinApi.getRecentlyAdded('movie');
@@ -61,6 +63,9 @@
<HeroShowcase
items={popularMovies.then(getShowcasePropsFromTmdbMovie)}
on:enter={scrollIntoView({ top: 0 })}
on:select={({ detail }) => {
navigate(`${detail?.id}`);
}}
/>
</div>
<div class="my-16 space-y-8">

View File

@@ -10,11 +10,13 @@
import { getShowcasePropsFromTmdbSeries } from '../components/HeroShowcase/HeroShowcase';
import { scrollIntoView } from '../selectable';
import JellyfinCard from '../components/Card/JellyfinCard.svelte';
import { Route } from 'svelte-navigator';
import { Route, useNavigate } from 'svelte-navigator';
import SeriesPage from '../components/SeriesPage/SeriesPage.svelte';
import { formatDateToYearMonthDay } from '../utils';
import TmdbCard from '../components/Card/TmdbCard.svelte';
const navigate = useNavigate();
const continueWatching = jellyfinApi.getContinueWatchingSeries();
const recentlyAdded = jellyfinApi.getRecentlyAdded('series');
@@ -58,6 +60,9 @@
<HeroShowcase
items={tmdbApi.getPopularSeries().then(getShowcasePropsFromTmdbSeries)}
on:enter={scrollIntoView({ top: 0 })}
on:select={({ detail }) => {
navigate(`${detail?.id}`);
}}
/>
</div>
<div class="my-16 space-y-8">