fix: Issues with grid item sizing
This commit is contained in:
@@ -4,46 +4,49 @@
|
||||
import classNames from 'classnames';
|
||||
import { getCardDimensions } from '../utils';
|
||||
|
||||
export let direction: 'horizontal' | 'vertical' = 'vertical';
|
||||
// export let direction: 'horizontal' | 'vertical' = 'vertical';
|
||||
export let type: 'portrait' | 'landscape' = 'portrait';
|
||||
|
||||
let cols = getCardDimensions(window.innerWidth).columns;
|
||||
let cols = getCardDimensions(window.innerWidth, type).columns;
|
||||
$: console.log('cols', cols);
|
||||
|
||||
// let cols: number = 1;
|
||||
const calculateRows = () => {
|
||||
const width = window.innerWidth;
|
||||
if (direction === 'vertical') {
|
||||
if (width >= 1536) {
|
||||
cols = 6;
|
||||
} else if (width >= 1280) {
|
||||
cols = 5;
|
||||
} else if (width >= 768) {
|
||||
cols = 4;
|
||||
} else {
|
||||
cols = 3;
|
||||
}
|
||||
} else {
|
||||
// if (width >= 1920) {
|
||||
// const calculateRows = () => {
|
||||
// const width = window.innerWidth;
|
||||
// if (direction === 'vertical') {
|
||||
// if (width >= 1536) {
|
||||
// cols = 6;
|
||||
// } else if (width >= 1280) {
|
||||
// cols = 5;
|
||||
// } else if (width >= 768) {
|
||||
// cols = 4;
|
||||
// } else
|
||||
if (width >= 1536) {
|
||||
cols = 3;
|
||||
} else if (width >= 1280) {
|
||||
cols = 2;
|
||||
} else if (width >= 768) {
|
||||
cols = 1;
|
||||
} else {
|
||||
cols = 1;
|
||||
}
|
||||
}
|
||||
};
|
||||
// } else {
|
||||
// cols = 3;
|
||||
// }
|
||||
// } else {
|
||||
// // if (width >= 1920) {
|
||||
// // cols = 4;
|
||||
// // } else
|
||||
// if (width >= 1536) {
|
||||
// cols = 3;
|
||||
// } else if (width >= 1280) {
|
||||
// cols = 2;
|
||||
// } else if (width >= 768) {
|
||||
// cols = 1;
|
||||
// } else {
|
||||
// cols = 1;
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
|
||||
// onMount(() => {
|
||||
// calculateRows();
|
||||
// });
|
||||
</script>
|
||||
|
||||
<svelte:window on:resize={(e) => (cols = getCardDimensions(e.currentTarget.innerWidth).columns)} />
|
||||
<svelte:window
|
||||
on:resize={(e) => (cols = getCardDimensions(e.currentTarget.innerWidth, type).columns)}
|
||||
/>
|
||||
|
||||
<Container
|
||||
direction="grid"
|
||||
@@ -51,8 +54,8 @@
|
||||
class={classNames(
|
||||
'grid gap-x-8 gap-y-8',
|
||||
{
|
||||
'grid-cols-1 md:grid-cols-1 xl:grid-cols-2 2xl:grid-cols-3 3xl:grid-cols-4':
|
||||
direction === 'horizontal'
|
||||
// 'grid-cols-1 md:grid-cols-1 xl:grid-cols-2 2xl:grid-cols-3 3xl:grid-cols-4':
|
||||
// direction === 'horizontal'
|
||||
// 'grid-cols-4 md:grid-cols-4 xl:grid-cols-5 2xl:grid-cols-6': direction === 'vertical'
|
||||
},
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
import { ArrowDown, Check, TriangleRight } from 'radix-icons-svelte';
|
||||
import type { Readable } from 'svelte/store';
|
||||
import AnimateScale from '../AnimateScale.svelte';
|
||||
import { getCardDimensions } from '../../utils';
|
||||
|
||||
export let episodeNumber: number;
|
||||
export let episodeName: string;
|
||||
@@ -16,36 +17,20 @@
|
||||
|
||||
let hasFocus: Readable<boolean>;
|
||||
|
||||
let dimensions = getDimensions(window.innerWidth);
|
||||
|
||||
function getDimensions(viewportWidth: number) {
|
||||
const minWidth = 240;
|
||||
|
||||
const margin = 128;
|
||||
const gap = 32;
|
||||
|
||||
const cols = Math.floor((gap - 2 * margin + viewportWidth) / (minWidth + gap));
|
||||
const scale = -(gap * (cols - 1) + 2 * margin - viewportWidth) / (cols * minWidth);
|
||||
|
||||
const newWidth = minWidth * scale;
|
||||
const newHeight = (3 / 2) * newWidth;
|
||||
|
||||
return {
|
||||
width: newWidth,
|
||||
height: newHeight
|
||||
};
|
||||
}
|
||||
let dimensions = getCardDimensions(window.innerWidth, 'landscape');
|
||||
</script>
|
||||
|
||||
<svelte:window on:resize={(e) => (dimensions = getDimensions(e.currentTarget.innerWidth))} />
|
||||
<svelte:window
|
||||
on:resize={(e) => (dimensions = getCardDimensions(e.currentTarget.innerWidth, 'landscape'))}
|
||||
/>
|
||||
|
||||
<AnimateScale hasFocus={$hasFocus}>
|
||||
<Container
|
||||
class={classNames(
|
||||
'w-full h-72',
|
||||
'flex flex-col shrink-0',
|
||||
'overflow-hidden rounded-2xl cursor-pointer group relative px-4 py-3 selectable transition-opacity'
|
||||
)}
|
||||
style={`width: ${dimensions.width}px; height: ${dimensions.height}px`}
|
||||
on:clickOrSelect
|
||||
on:enter
|
||||
on:mount
|
||||
|
||||
@@ -111,7 +111,7 @@
|
||||
</Container>
|
||||
{/each}
|
||||
</UICarousel>
|
||||
<CardGrid direction="horizontal" on:mount>
|
||||
<CardGrid type="landscape" on:mount>
|
||||
{#if $tmdbSeasons?.[seasonIndex]?.episodes?.length}
|
||||
{#each $tmdbSeasons?.[seasonIndex]?.episodes || [] as episode}
|
||||
{@const jellyfinEpisode = awaitedJellyfinEpisodes?.find(
|
||||
|
||||
@@ -4,19 +4,25 @@
|
||||
import AnimateScale from '../AnimateScale.svelte';
|
||||
import classNames from 'classnames';
|
||||
import { Plus, PlusCircled } from 'radix-icons-svelte';
|
||||
import { getCardDimensions } from '../../utils';
|
||||
|
||||
export let backdropUrl: string;
|
||||
|
||||
let hasFocus: Readable<boolean>;
|
||||
|
||||
let dimensions = getCardDimensions(window.innerWidth, 'landscape');
|
||||
</script>
|
||||
|
||||
<svelte:window
|
||||
on:resize={(e) => (dimensions = getCardDimensions(e.currentTarget.innerWidth, 'landscape'))}
|
||||
/>
|
||||
<AnimateScale hasFocus={$hasFocus}>
|
||||
<Container
|
||||
class={classNames(
|
||||
'w-full h-64',
|
||||
'flex flex-col shrink-0',
|
||||
'overflow-hidden rounded-2xl cursor-pointer group relative selectable transition-opacity'
|
||||
)}
|
||||
style={`width: ${dimensions.width}px; height: ${dimensions.height}px`}
|
||||
on:clickOrSelect
|
||||
on:enter
|
||||
bind:hasFocus
|
||||
|
||||
@@ -11,22 +11,27 @@
|
||||
import { radarrApi } from '../apis/radarr/radarr-api';
|
||||
import Card from '../components/Card/Card.svelte';
|
||||
import type { ComponentProps } from 'svelte';
|
||||
import TmdbCard from '../components/Card/TmdbCard.svelte';
|
||||
import { tmdbApi, type TmdbMovie2, type TmdbSeries2 } from '../apis/tmdb/tmdb-api';
|
||||
|
||||
const libraryItemsP = jellyfinApi.getLibraryItems();
|
||||
let sonarrDownloads: Promise<ComponentProps<Card>[]> = sonarrApi.getDownloads().then((items) =>
|
||||
const sonarrDownloads: Promise<TmdbSeries2[]> = sonarrApi
|
||||
.getDownloads()
|
||||
.then((items) =>
|
||||
Promise.all(
|
||||
items
|
||||
.filter(
|
||||
(value, index, self) => index === self.findIndex((t) => t.seriesId === value.seriesId)
|
||||
)
|
||||
.map((i) => ({
|
||||
backdropUrl: i.series.images?.find((i) => i.coverType === 'poster')?.remoteUrl || '',
|
||||
group: true
|
||||
}))
|
||||
.map((i) => tmdbApi.getTmdbSeriesFromTvdbId(String(i.series.tvdbId)))
|
||||
).then((i) => i.filter((i) => !!i) as TmdbSeries2[])
|
||||
);
|
||||
let radarrDownloads: Promise<ComponentProps<Card>[]> = radarrApi.getDownloads().then((items) =>
|
||||
items.map((i) => ({
|
||||
backdropUrl: i.movie.images?.find((i) => i.coverType === 'poster')?.remoteUrl || ''
|
||||
}))
|
||||
let radarrDownloads: Promise<TmdbMovie2[]> = radarrApi
|
||||
.getDownloads()
|
||||
.then((items) =>
|
||||
Promise.all(items.map((i) => tmdbApi.getTmdbMovie(i.movie.tmdbId || -1))).then(
|
||||
(i) => i.filter((i) => !!i) as TmdbMovie2[]
|
||||
)
|
||||
);
|
||||
|
||||
settings.update((prev) => ({
|
||||
@@ -46,12 +51,12 @@
|
||||
{#if sonarrDownloads?.length || radarrDownloads?.length}
|
||||
<Carousel scrollClass="px-32" on:enter={scrollIntoView({ vertical: 128 })}>
|
||||
<span slot="header">Downloading</span>
|
||||
{#each sonarrDownloads as props}
|
||||
<Card on:enter={scrollIntoView({ horizontal: 128 })} size="lg" {...props} />
|
||||
{#each sonarrDownloads as item}
|
||||
<TmdbCard on:enter={scrollIntoView({ horizontal: 128 })} size="lg" {item} group />
|
||||
{/each}
|
||||
|
||||
{#each radarrDownloads as props}
|
||||
<Card on:enter={scrollIntoView({ horizontal: 128 })} size="lg" {...props} />
|
||||
{#each radarrDownloads as item}
|
||||
<TmdbCard on:enter={scrollIntoView({ horizontal: 128 })} size="lg" {item} />
|
||||
{/each}
|
||||
</Carousel>
|
||||
{/if}
|
||||
|
||||
@@ -134,8 +134,11 @@ export function subscribeUntil<T>(store: Readable<T>, fn: (value: T) => boolean)
|
||||
});
|
||||
}
|
||||
|
||||
export function getCardDimensions(viewportWidth: number) {
|
||||
const minWidth = 240;
|
||||
export function getCardDimensions(
|
||||
viewportWidth: number,
|
||||
type: 'portrait' | 'landscape' = 'portrait'
|
||||
) {
|
||||
const minWidth = type === 'portrait' ? 240 : 400;
|
||||
|
||||
const margin = 128;
|
||||
const gap = 32;
|
||||
@@ -144,7 +147,7 @@ export function getCardDimensions(viewportWidth: number) {
|
||||
const scale = -(gap * (cols - 1) + 2 * margin - viewportWidth) / (cols * minWidth);
|
||||
|
||||
const newWidth = minWidth * scale;
|
||||
const newHeight = (3 / 2) * newWidth;
|
||||
const newHeight = (type === 'portrait' ? 3 / 2 : 9 / 16) * newWidth;
|
||||
|
||||
return {
|
||||
width: newWidth,
|
||||
|
||||
Reference in New Issue
Block a user