@@ -12,6 +12,12 @@ import TimetableTask, {
1212 TimetableTaskProps ,
1313} from "@/components/timetable_task" ;
1414
15+ /*
16+ NOTES:
17+ - Should rename timetable-barrier to timetable-content to be more descriptive.
18+ - Should use element.parentElement for position adjusting for more clarity.
19+ */
20+
1521/*
1622Returns a rect {left, right, top, bottom, width, height} of the visible area of
1723the timetable where timetable tasks are to be rendered.
@@ -96,6 +102,11 @@ export function getDayLeftPosition(day: string) {
96102 return day_label . getBoundingClientRect ( ) . left ;
97103}
98104
105+ /*
106+ Sync the timetable-foreground element's position and size with the
107+ timetable-barrier element. Ensures foreground elements inhabit the same area
108+ as the background elements.
109+ */
99110function resizeAndPositionTimetableForeground ( ) {
100111 const foreground = document . getElementById ( "timetable-foreground" ) ;
101112 if ( foreground == null ) return ;
@@ -110,6 +121,10 @@ function resizeAndPositionTimetableForeground() {
110121 foreground . style . height = barrier . clientHeight + "px" ;
111122}
112123
124+ /*
125+ Sync the left position of the TimetableHeaders in the foreground with their
126+ respective columns, set the top position to 0px.
127+ */
113128function resizeAndPositionTimetableHeaders ( ) {
114129 const timetable_headers = document . getElementById ( "timetable-headers" ) ;
115130 if ( timetable_headers == null ) return ;
@@ -140,6 +155,10 @@ function resizeAndPositionTimetableHeaders() {
140155 time_header . style . zIndex = "1000" ;
141156}
142157
158+ /*
159+ Sync the TimeLabels column top position with the underlying Time column and set
160+ the left position to 0px.
161+ */
143162function resizeAndPositionTimetableTimeLabels ( ) {
144163 const time_labels = document . getElementById ( "Time-Labels" ) ;
145164 if ( time_labels == null ) return ;
@@ -187,6 +206,11 @@ function resizeAndPositionTimetableSeparator() {
187206 separator . style . height = col_rect . height + "px" ;
188207}
189208
209+ /*
210+ Sync the timetable-tasks element's size and position with the visible area of
211+ the timetable (area returned by getVisibleTimetableRect() ). Allows overflowing
212+ TimetableTasks to be hidden.
213+ */
190214function resizeAndPositionTimetableTaskArea ( ) {
191215 const task_container = document . getElementById ( "timetable-tasks" ) ;
192216 if ( task_container == null ) return ;
@@ -206,9 +230,10 @@ function resizeAndPositionTimetableTaskArea() {
206230}
207231
208232/*
209- Calls all of the resizeAndPosition functions.
233+ Calls all of the resizeAndPosition functions. Syncs the foreground elements of
234+ the timetable with the background elements.
210235*/
211- export function resizeTimetableElements ( ) {
236+ export function resizeAndPositionTimetableElements ( ) {
212237 resizeAndPositionTimetableForeground ( ) ;
213238 resizeAndPositionTimetableHeaders ( ) ;
214239 resizeAndPositionTimetableTimeLabels ( ) ;
@@ -230,37 +255,25 @@ specified "top" or "bottom".
230255export function scrollToCurrentTime ( align ?: string ) {
231256 const timetable_barrier = document . getElementById ( "timetable-barrier" ) ;
232257 if ( timetable_barrier == null ) return ;
258+ const barrier_rect = timetable_barrier . getBoundingClientRect ( ) ;
233259
234260 const visible = getVisibleTimetableRect ( ) ;
235261 if ( visible == undefined ) return ;
236262
237- const timetable = document . getElementById ( "timetable" ) ;
263+ const timetable = document . getElementById ( "timetable-background " ) ;
238264 if ( timetable == null ) return ;
239265
240- const time_header = document . getElementById ( "time-header" ) ;
241- if ( time_header == null ) return ;
242- const time_header_height = time_header . getBoundingClientRect ( ) . height ;
243- if ( time_header_height == undefined ) return ;
244-
245- const scroll_height = timetable . scrollHeight - time_header_height ;
246- const scroll_max = scroll_height - visible . height ; // Top row is sticky
247-
248- timetable_barrier . scrollTop = 0 ; // Ensures consistent position
249-
250266 const now = new Date ( Date . now ( ) ) ;
251267 const now_top = getTimeTopPosition ( now . getHours ( ) , now . getMinutes ( ) ) ;
252268 if ( now_top == undefined ) return ;
253269
254270 let target_top ;
255271 if ( align === "top" ) target_top = visible . top ;
256272 else if ( align === "bottom" ) target_top = visible . bottom ;
257- else target_top = visible . top + visible . height / 2 ;
258-
259- let scroll_amount = now_top - target_top ;
260- if ( scroll_amount < 0 ) scroll_amount = 0 ;
261- if ( scroll_amount > scroll_max ) scroll_amount = scroll_max ;
273+ else target_top = barrier_rect . top + barrier_rect . height / 2 ;
262274
263- timetable_barrier . scrollTop = scroll_amount ;
275+ const scroll_amount = now_top - target_top ;
276+ timetable_barrier . scrollTop += scroll_amount ;
264277}
265278
266279/*
@@ -280,20 +293,14 @@ export function scrollToCurrentDay(align?: string) {
280293 const visible = getVisibleTimetableRect ( ) ;
281294 if ( visible == undefined ) return ;
282295
283- const timetable = document . getElementById ( "timetable" ) ;
296+ const timetable = document . getElementById ( "timetable-background " ) ;
284297 if ( timetable == null ) return ;
285298
286- const time_header = document . getElementById ( "time-header " ) ;
287- if ( time_header == undefined ) return ;
299+ const time_header = document . getElementById ( "Time-Header " ) ;
300+ if ( time_header == null ) return ;
288301 const time_header_width = time_header . getBoundingClientRect ( ) . width ;
289- if ( time_header_width == undefined ) return ;
290302 const row_width = time_header_width ; // easier to read later
291303
292- const scroll_width = timetable . scrollWidth - time_header_width ; // sticky
293- const scroll_max = scroll_width - visible . width ;
294-
295- timetable_barrier . scrollLeft = 0 ;
296-
297304 enum DateDay {
298305 Monday = 1 ,
299306 Tuesday ,
@@ -314,11 +321,8 @@ export function scrollToCurrentDay(align?: string) {
314321 else if ( align == "right" ) target_left = visible . right - row_width ;
315322 else target_left = visible . left + visible . width / 2 - row_width / 2 ;
316323
317- let scroll_amount = today_left - target_left ;
318- if ( scroll_amount < 0 ) scroll_amount = 0 ;
319- if ( scroll_amount > scroll_max ) scroll_amount = scroll_max ;
320-
321- timetable_barrier . scrollLeft = scroll_amount ;
324+ const scroll_amount = today_left - target_left ;
325+ timetable_barrier . scrollLeft += scroll_amount ;
322326}
323327
324328/*
@@ -355,7 +359,7 @@ There can only be one timetable per page as the logic uses ids.
355359*/
356360function Timetable ( { timetable_tasks_props } : TimetableProps ) {
357361 useEffect ( ( ) => {
358- resizeTimetableElements ( ) ;
362+ resizeAndPositionTimetableElements ( ) ;
359363 scrollToCurrentTimeAndDay ( ) ;
360364 } ) ;
361365
@@ -367,11 +371,11 @@ function Timetable({ timetable_tasks_props }: TimetableProps) {
367371 < div
368372 id = "timetable-barrier"
369373 className = "h-full w-full overflow-auto overscroll-none"
370- onScroll = { resizeTimetableElements }
374+ onScroll = { resizeAndPositionTimetableElements }
371375 >
372376 < div
373- id = "timetable"
374- className = "timetable flex h-full w-full flex-row gap-[4px]"
377+ id = "timetable-background "
378+ className = "timetable-background flex h-full w-full flex-row gap-[4px]"
375379 >
376380 < TimetableColumn day = "Time" />
377381 < TimetableColumn day = "Monday" />
0 commit comments