mirror of
https://github.com/streamyfin/streamyfin.git
synced 2026-05-22 14:56:38 +01:00
Merge branch 'feat/tv-interface' of https://github.com/streamyfin/streamyfin into feat/tv-interface
This commit is contained in:
@@ -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";
|
||||
|
||||
@@ -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={{
|
||||
|
||||
@@ -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),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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),
|
||||
};
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user