Merge branch 'feat/tv-interface' of https://github.com/streamyfin/streamyfin into feat/tv-interface

This commit is contained in:
Lance Chant
2026-05-22 12:39:37 +02:00
5 changed files with 47 additions and 22 deletions

View File

@@ -46,7 +46,7 @@ import { updateTVDiscovery } from "@/utils/tvDiscovery/sync";
const HORIZONTAL_PADDING = scaleSize(60);
const TOP_PADDING = scaleSize(100);
// Generous gap between sections for Apple TV+ aesthetic
const SECTION_GAP = scaleSize(10);
const SECTION_GAP = scaleSize(24);
type InfiniteScrollingCollectionListSection = {
type: "InfiniteScrollingCollectionList";

View File

@@ -207,7 +207,7 @@ export const TVHeroCarousel: React.FC<TVHeroCarouselProps> = ({
const typography = useScaledTVTypography();
const sizes = useScaledTVSizes();
const api = useAtomValue(apiAtom);
const _insets = useSafeAreaInsets();
const insets = useSafeAreaInsets();
const router = useRouter();
// Active item for featured display (debounced)
@@ -381,7 +381,13 @@ export const TVHeroCarousel: React.FC<TVHeroCarouselProps> = ({
const heroHeight = SCREEN_HEIGHT * sizes.padding.heroHeight;
return (
<View style={{ height: heroHeight, width: "100%" }}>
<View
style={{
height: heroHeight + insets.top,
width: "100%",
paddingTop: insets.top,
}}
>
{/* Backdrop layers with crossfade */}
<View
style={{

View File

@@ -438,7 +438,7 @@ export const TVPosterCard: React.FC<TVPosterCardProps> = ({
position: "relative",
width,
aspectRatio,
borderRadius: scaleSize(4),
borderRadius: scaleSize(24),
overflow: "hidden",
backgroundColor: "#1a1a1a",
borderWidth: scaleSize(2),

View File

@@ -79,7 +79,7 @@ export const TVAnimation = {
* Applied to poster sizes and gaps.
*/
const sizeScaleMultipliers: Record<TVTypographyScale, number> = {
[TVTypographyScale.Small]: 0.9,
[TVTypographyScale.Small]: 0.8,
[TVTypographyScale.Default]: 1.0,
[TVTypographyScale.Large]: 1.1,
[TVTypographyScale.ExtraLarge]: 1.2,

View File

@@ -1,56 +1,75 @@
import { TVTypographyScale, useSettings } from "@/utils/atoms/settings";
import { scaleSize } from "@/utils/scaleSize";
/**
* TV Typography Scale
*
* Consistent text sizes for TV interface components.
* Design values are for 1920×1080 and scaled proportionally
* to the actual viewport via scaleSize().
* Base values are designed for 1920x1080 and scaled to the actual viewport via
* scaleSize(), then further adjusted by the user's tvTypographyScale setting.
*/
import { scaleSize } from "@/utils/scaleSize";
// =============================================================================
// BASE VALUES (at Default scale)
// =============================================================================
export const TVTypography = {
/** Hero titles, movie/show names */
display: scaleSize(70),
display: 70,
/** Episode series name, major headings */
title: scaleSize(42),
title: 42,
/** Section headers (Cast, Technical Details, From this Series) */
heading: scaleSize(32),
heading: 32,
/** Overview, actor names, card titles, metadata */
body: scaleSize(40),
body: 40,
/** Secondary text, labels, subtitles */
callout: scaleSize(26),
callout: 26,
};
export type TVTypographyKey = keyof typeof TVTypography;
// =============================================================================
// SCALING
// =============================================================================
const scaleMultipliers: Record<TVTypographyScale, number> = {
[TVTypographyScale.Small]: 0.85,
[TVTypographyScale.Small]: 0.8,
[TVTypographyScale.Default]: 1.0,
[TVTypographyScale.Large]: 1.2,
[TVTypographyScale.ExtraLarge]: 1.4,
[TVTypographyScale.Large]: 1.1,
[TVTypographyScale.ExtraLarge]: 1.2,
};
// =============================================================================
// HOOKS
// =============================================================================
export type ScaledTVTypography = {
display: number;
title: number;
heading: number;
body: number;
callout: number;
};
/**
* Hook that returns scaled TV typography values based on user settings.
* Use this instead of the static TVTypography constant for dynamic scaling.
*/
export const useScaledTVTypography = () => {
export const useScaledTVTypography = (): ScaledTVTypography => {
const { settings } = useSettings();
const scale =
scaleMultipliers[settings.tvTypographyScale] ??
scaleMultipliers[TVTypographyScale.Default];
return {
display: Math.round(TVTypography.display * scale),
title: Math.round(TVTypography.title * scale),
heading: Math.round(TVTypography.heading * scale),
body: Math.round(TVTypography.body * scale),
callout: Math.round(TVTypography.callout * scale),
display: Math.round(scaleSize(TVTypography.display) * scale),
title: Math.round(scaleSize(TVTypography.title) * scale),
heading: Math.round(scaleSize(TVTypography.heading) * scale),
body: Math.round(scaleSize(TVTypography.body) * scale),
callout: Math.round(scaleSize(TVTypography.callout) * scale),
};
};