From 7b23b0a4df3908bca79c1e4f8834366e269b212f Mon Sep 17 00:00:00 2001 From: SergeantPanda Date: Fri, 27 Jun 2025 10:24:08 -0500 Subject: [PATCH] Slide text right when program starts before current view. Closes #223 --- frontend/src/pages/Guide.jsx | 234 +++++++++++++++++++---------------- 1 file changed, 126 insertions(+), 108 deletions(-) diff --git a/frontend/src/pages/Guide.jsx b/frontend/src/pages/Guide.jsx index eae1c2a7..cfc1d298 100644 --- a/frontend/src/pages/Guide.jsx +++ b/frontend/src/pages/Guide.jsx @@ -492,7 +492,6 @@ export default function TVChannelGuide({ startDate, endDate }) { guideRef.current.scrollLeft = scrollPosition; } }; - // Renders each program block function renderProgram(program, channelStart) { const programKey = `${program.tvg_id}-${program.start_time}`; @@ -522,18 +521,9 @@ export default function TVChannelGuide({ startDate, endDate }) { const isLive = now.isAfter(programStart) && now.isBefore(programEnd); // Determine if the program has ended - const isPast = now.isAfter(programEnd); - - // Check if this program is expanded + const isPast = now.isAfter(programEnd); // Check if this program is expanded const isExpanded = expandedProgramId === program.id; - // Calculate how much of the program is cut off - const cutOffMinutes = Math.max( - 0, - channelStart.diff(programStart, 'minute') - ); - const cutOffPx = (cutOffMinutes / MINUTE_INCREMENT) * MINUTE_BLOCK_WIDTH; - // Set the height based on expanded state const rowHeight = isExpanded ? EXPANDED_PROGRAM_HEIGHT : PROGRAM_HEIGHT; @@ -542,6 +532,25 @@ export default function TVChannelGuide({ startDate, endDate }) { const MIN_EXPANDED_WIDTH = 450; // Minimum width in pixels when expanded const expandedWidthPx = Math.max(widthPx, MIN_EXPANDED_WIDTH); + // Calculate text positioning for long programs that start before the visible area + const currentScrollLeft = guideRef.current?.scrollLeft || 0; + const programStartInView = leftPx + gapSize; + const programEndInView = leftPx + gapSize + widthPx; + const viewportLeft = currentScrollLeft; + + // Check if program starts before viewport but extends into it + const startsBeforeView = programStartInView < viewportLeft; + const extendsIntoView = programEndInView > viewportLeft; + + // Calculate text offset to position it at the visible portion + let textOffsetLeft = 0; + if (startsBeforeView && extendsIntoView) { + // Position text at the start of the visible area, but not beyond the program end + const visibleStart = Math.max(viewportLeft - programStartInView, 0); + const maxOffset = widthPx - 200; // Leave some space for text, don't push to very end + textOffsetLeft = Math.min(visibleStart, maxOffset); + } + return ( - + {programStart.format('h:mma')} - {programEnd.format('h:mma')} - - - {/* Description is always shown but expands when row is expanded */} + {/* Description is always shown but expands when row is expanded */} {program.description && ( - - {program.description} - + + {program.description} + + )} {/* Expanded content */} @@ -906,101 +925,100 @@ export default function TVChannelGuide({ startDate, endDate }) { borderBottom: '1px solid #27272A', width: hourTimeline.length * HOUR_WIDTH, }} - > - {hourTimeline.map((hourData, hourIndex) => { - const { time, isNewDay, dayLabel } = hourData; + > {hourTimeline.map((hourData) => { + const { time, isNewDay } = hourData; - return ( - handleTimeClick(time, e)} + > + {/* Remove the special day label for new days since we'll show day for all hours */} + + {/* Position time label at the left border of each hour block */} + handleTimeClick(time, e)} > - {/* Remove the special day label for new days since we'll show day for all hours */} - - {/* Position time label at the left border of each hour block */} + {/* Show day above time for every hour using the same format */} - {/* Show day above time for every hour using the same format */} - - {formatDayLabel(time)}{' '} - {/* Use same formatDayLabel function for all hours */} - - {time.format('h:mm')} - - {time.format('A')} - + {formatDayLabel(time)}{' '} + {/* Use same formatDayLabel function for all hours */} + {time.format('h:mm')} + + {time.format('A')} + + - {/* Hour boundary marker - more visible */} - + {/* Hour boundary marker - more visible */} + - {/* Quarter hour tick marks */} - - {[15, 30, 45].map((minute) => ( - - ))} - + {/* Quarter hour tick marks */} + + {[15, 30, 45].map((minute) => ( + + ))} - ); - })} + + ); + })}