UNPKG

unified-video-framework

Version:

Cross-platform video player framework supporting iOS, Android, Web, Smart TVs (Samsung/LG), Roku, and more

233 lines 11.3 kB
import React, { useState, useCallback } from 'react'; import { DEFAULT_EPG_THEME } from '../types/EPGTypes.js'; import { hexToRgba } from '../utils/ColorUtils.js'; export const EPGNavigationControls = ({ onNavigate, onTimeRangeChange, canNavigateLeft = true, canNavigateRight = true, currentTime = Date.now(), timelineStart, timelineEnd, visibleHours = 4, className = '', style = {}, theme: themeProp, }) => { const theme = { ...DEFAULT_EPG_THEME, ...themeProp }; const [isNavigating, setIsNavigating] = useState(false); const handleNavigate = useCallback(async (direction) => { if (isNavigating) return; setIsNavigating(true); try { await onNavigate(direction); } finally { setTimeout(() => setIsNavigating(false), 300); } }, [onNavigate, isNavigating]); const handleTimeRangeChange = useCallback((hours) => { if (onTimeRangeChange) { onTimeRangeChange(hours); } }, [onTimeRangeChange]); const getTimeRangeDisplay = () => { if (!timelineStart || !timelineEnd) return ''; const startDate = new Date(timelineStart); const endDate = new Date(timelineEnd); const today = new Date(); if (startDate.toDateString() === today.toDateString()) { return `Today, ${startDate.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit', hour12: true })} - ${endDate.toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit', hour12: true })}`; } return `${startDate.toLocaleDateString('en-US', { weekday: 'short', month: 'short', day: 'numeric' })}, ${startDate.toLocaleTimeString('en-US', { hour: 'numeric', hour12: true })} - ${endDate.toLocaleTimeString('en-US', { hour: 'numeric', hour12: true })}`; }; return (React.createElement("div", { className: `epg-navigation-controls ${className}`, style: { display: 'flex', alignItems: 'center', justifyContent: 'space-between', padding: '16px 70px 16px 24px', backgroundColor: 'rgba(20, 20, 20, 0.7)', borderBottom: '1px solid rgba(255, 255, 255, 0.1)', height: '70px', backdropFilter: 'blur(10px)', ...style, } }, React.createElement("div", { className: "epg-time-range-display" }, React.createElement("div", { style: { color: '#fff', fontSize: '16px', fontWeight: '600', lineHeight: '1.2', } }, getTimeRangeDisplay()), timelineStart && timelineEnd && (React.createElement("div", { style: { color: '#888', fontSize: '12px', lineHeight: '1.2', marginTop: '2px', } }, visibleHours, " hour", visibleHours !== 1 ? 's' : '', " view"))), React.createElement("div", { className: "epg-navigation-buttons", style: { display: 'flex', alignItems: 'center', gap: '8px', } }, React.createElement("button", { className: "epg-nav-button epg-nav-left", disabled: !canNavigateLeft || isNavigating, onClick: () => handleNavigate('left'), style: { display: 'flex', alignItems: 'center', justifyContent: 'center', width: '48px', height: '48px', borderRadius: '8px', border: '1px solid rgba(255, 255, 255, 0.2)', backgroundColor: canNavigateLeft && !isNavigating ? hexToRgba(theme.selectionColor, 0.2) : 'rgba(255, 255, 255, 0.05)', color: canNavigateLeft && !isNavigating ? '#fff' : 'rgba(255, 255, 255, 0.4)', cursor: canNavigateLeft && !isNavigating ? 'pointer' : 'not-allowed', transition: 'all 200ms ease', fontSize: '18px', fontWeight: '600', }, onMouseEnter: (e) => { if (canNavigateLeft && !isNavigating) { e.currentTarget.style.backgroundColor = '#3a3a3a'; } }, onMouseLeave: (e) => { if (canNavigateLeft && !isNavigating) { e.currentTarget.style.backgroundColor = '#2a2a2a'; } } }, "\u25C0"), React.createElement("button", { className: "epg-nav-button epg-nav-today", disabled: isNavigating, onClick: () => handleNavigate('today'), style: { display: 'flex', alignItems: 'center', justifyContent: 'center', height: '48px', padding: '0 24px', borderRadius: '8px', border: 'none', backgroundColor: !isNavigating ? theme.primaryColor : hexToRgba(theme.primaryColor, 0.6), color: '#fff', cursor: !isNavigating ? 'pointer' : 'not-allowed', transition: 'all 200ms ease', fontSize: '16px', fontWeight: '700', whiteSpace: 'nowrap', boxShadow: !isNavigating ? `0 4px 12px ${hexToRgba(theme.primaryColor, 0.3)}` : 'none', }, onMouseEnter: (e) => { if (!isNavigating) { e.currentTarget.style.backgroundColor = '#ff8555'; } }, onMouseLeave: (e) => { if (!isNavigating) { e.currentTarget.style.backgroundColor = theme.primaryColor; } } }, isNavigating ? '...' : 'NOW'), React.createElement("button", { className: "epg-nav-button epg-nav-right", disabled: !canNavigateRight || isNavigating, onClick: () => handleNavigate('right'), style: { display: 'flex', alignItems: 'center', justifyContent: 'center', width: '48px', height: '48px', borderRadius: '8px', border: '1px solid rgba(255, 255, 255, 0.2)', backgroundColor: canNavigateRight && !isNavigating ? hexToRgba(theme.selectionColor, 0.2) : 'rgba(255, 255, 255, 0.05)', color: canNavigateRight && !isNavigating ? '#fff' : 'rgba(255, 255, 255, 0.4)', cursor: canNavigateRight && !isNavigating ? 'pointer' : 'not-allowed', transition: 'all 200ms ease', fontSize: '18px', fontWeight: '600', }, onMouseEnter: (e) => { if (canNavigateRight && !isNavigating) { e.currentTarget.style.backgroundColor = '#3a3a3a'; } }, onMouseLeave: (e) => { if (canNavigateRight && !isNavigating) { e.currentTarget.style.backgroundColor = '#2a2a2a'; } } }, "\u25B6")), React.createElement("div", { className: "epg-view-options", style: { display: 'flex', alignItems: 'center', gap: '12px', } }, onTimeRangeChange && (React.createElement("div", { className: "epg-time-range-selector", style: { display: 'flex', alignItems: 'center', gap: '8px', padding: '6px 12px', backgroundColor: hexToRgba(theme.primaryColor, 0.1), border: `1px solid ${hexToRgba(theme.primaryColor, 0.3)}`, borderRadius: '6px', transition: 'all 0.2s ease', position: 'relative', } }, React.createElement("label", { style: { color: theme.primaryColor, fontSize: '11px', fontWeight: '600', textTransform: 'uppercase', letterSpacing: '0.5px', whiteSpace: 'nowrap', } }, "Time Range"), React.createElement("select", { value: visibleHours, onChange: (e) => handleTimeRangeChange(Number(e.target.value)), style: { backgroundColor: '#1a1a1a', color: '#fff', border: '1px solid #555', borderRadius: '4px', padding: '6px 8px', fontSize: '13px', fontWeight: '500', cursor: 'pointer', outline: 'none', minWidth: '90px', transition: 'all 0.2s ease', }, onMouseEnter: (e) => { e.currentTarget.style.borderColor = theme.primaryColor; e.currentTarget.style.backgroundColor = '#222'; }, onMouseLeave: (e) => { e.currentTarget.style.borderColor = '#555'; e.currentTarget.style.backgroundColor = '#1a1a1a'; } }, React.createElement("option", { value: 2 }, "2 hours"), React.createElement("option", { value: 4 }, "4 hours"), React.createElement("option", { value: 6 }, "6 hours"), React.createElement("option", { value: 8 }, "8 hours"), React.createElement("option", { value: 12 }, "12 hours"), React.createElement("option", { value: 24 }, "24 hours")))), React.createElement("div", { className: "epg-current-time-badge", style: { display: 'flex', alignItems: 'center', gap: '4px', color: theme.primaryColor, fontSize: '12px', fontWeight: '600', } }, React.createElement("div", { style: { width: '6px', height: '6px', borderRadius: '50%', backgroundColor: theme.primaryColor, animation: 'pulse 2s infinite', } }), new Date(currentTime).toLocaleTimeString('en-US', { hour: 'numeric', minute: '2-digit', hour12: true, }))), React.createElement("style", null, ` @keyframes pulse { 0%, 100% { opacity: 1; } 50% { opacity: 0.5; } } `))); }; export default EPGNavigationControls; //# sourceMappingURL=EPGNavigationControls.js.map