import { Image } from "expo-image"; import type { FC } from "react"; import { View } from "react-native"; import { Text } from "@/components/common/Text"; import { CONTROLS_CONSTANTS } from "./constants"; // Slightly larger preview (scale 1.6 vs old 1.4) to give the overlay text // more room and feel closer to the Jellyfin web style. const BASE_IMAGE_SCALE = 1.6; const BUBBLE_LEFT_OFFSET = 62; const BUBBLE_WIDTH_MULTIPLIER = 1.5; interface TrickplayBubbleProps { trickPlayUrl: { x: number; y: number; url: string; } | null; trickplayInfo: { aspectRatio?: number; data: { TileWidth?: number; TileHeight?: number; }; } | null; time: { hours: number; minutes: number; seconds: number; }; /** Scale factor for the image (default 1). Does not affect timestamp text. */ imageScale?: number; /** Chapter name at the scrubbed position, if any. */ chapterName?: string | null; } export const TrickplayBubble: FC = ({ trickPlayUrl, trickplayInfo, time, imageScale = 1, chapterName, }) => { if (!trickPlayUrl || !trickplayInfo) { return null; } const { x, y, url } = trickPlayUrl; const tileWidth = CONTROLS_CONSTANTS.TILE_WIDTH; const tileHeight = tileWidth / trickplayInfo.aspectRatio!; const timeStr = `${time.hours > 0 ? `${time.hours}:` : ""}${ time.minutes < 10 ? `0${time.minutes}` : time.minutes }:${time.seconds < 10 ? `0${time.seconds}` : time.seconds}`; const finalScale = BASE_IMAGE_SCALE * imageScale; return ( {/* * Bottom-right overlay (Jellyfin web style) — chapter name (small, * faded) above the timestamp (small, bold). Sits on top of the * trickplay frame inside the same overflow:hidden container so it * always stays within the bubble bounds. */} {chapterName ? ( {chapterName} ) : null} {timeStr} ); };