@@ -26,6 +26,107 @@ interface IProps {
2626}
2727const hasColumn = value => value === false ;
2828
29+ const isSameDate = ( departure : IDeparture , nextDay ) => {
30+ if ( ! departure ) {
31+ return false ;
32+ }
33+ const depDate = new Date (
34+ ( departure . realtimeDeparture + departure . serviceDay ) * 1000 ,
35+ ) ;
36+
37+ return depDate . getDate ( ) === nextDay . getDate ( ) ;
38+ } ;
39+
40+ /*
41+ Formats rows for a single column
42+ Returns a list of rows, date of last row and the index of remaining departures
43+ */
44+ const formatSingleColumnData = (
45+ departures : IDeparture [ ] ,
46+ nRows : number ,
47+ date : number ,
48+ departuresIndex : number ,
49+ currentLang : string ,
50+ ) => {
51+ let lastWasDayDivider = false ;
52+ const rows = Array ( nRows )
53+ . fill ( null )
54+ . map ( ( _ , rowIndex ) => {
55+ const departure = departures [ departuresIndex ] ;
56+ const isFirst = rowIndex === 0 || lastWasDayDivider ;
57+ const isLastRow = rowIndex === nRows - 1 ;
58+ if ( departure ) {
59+ if ( isSameDate ( departure , setDate ( date ) ) ) {
60+ departuresIndex ++ ;
61+ lastWasDayDivider = false ;
62+ return { departure, dayDivider : null , isFirst } ;
63+ } else if ( ! isLastRow ) {
64+ // if next departure is on a different day, add day divider
65+ // unless it's the last row of the column
66+ date ++ ;
67+ lastWasDayDivider = true ;
68+ return {
69+ departure : null ,
70+ dayDivider : formatDate ( setDate ( date ) , currentLang ) ,
71+ isFirst,
72+ } ;
73+ }
74+ }
75+ // if no more departures, return empty rows
76+ lastWasDayDivider = false ;
77+ return { departure : null , dayDivider : null , isFirst } ;
78+ } ) ;
79+ return { rows, date, departuresIndex } ;
80+ } ;
81+
82+ // Processess rows for a monitor containing a single stop display
83+ const formatSingleDisplayData = (
84+ departures : IDeparture [ ] ,
85+ leftColumnSize : number ,
86+ rightColumnSize : number ,
87+ currentLang : string ,
88+ ) => {
89+ const {
90+ rows : leftRows ,
91+ date,
92+ departuresIndex,
93+ } = formatSingleColumnData ( departures , leftColumnSize , 0 , 0 , currentLang ) ;
94+ const { rows : rightRows } = formatSingleColumnData (
95+ departures ,
96+ rightColumnSize ,
97+ date as number ,
98+ departuresIndex as number ,
99+ currentLang ,
100+ ) ;
101+
102+ return { leftRows, rightRows } ;
103+ } ;
104+
105+ // Processes rows for a multi display monitor (where right side has dedicated departures)
106+ const formatMultiDisplayData = (
107+ departuresLeft : IDeparture [ ] ,
108+ departuresRight : IDeparture [ ] ,
109+ leftColumnSize : number ,
110+ rightColumnSize : number ,
111+ currentLang : string ,
112+ ) => {
113+ const { rows : leftRows } = formatSingleColumnData (
114+ departuresLeft ,
115+ leftColumnSize ,
116+ 0 ,
117+ 0 ,
118+ currentLang ,
119+ ) ;
120+ const { rows : rightRows } = formatSingleColumnData (
121+ departuresRight ,
122+ rightColumnSize ,
123+ 0 ,
124+ 0 ,
125+ currentLang ,
126+ ) ;
127+ return { leftRows, rightRows } ;
128+ } ;
129+
29130const MonitorRowContainer : FC < IProps > = ( {
30131 viewId,
31132 departuresLeft,
@@ -47,47 +148,6 @@ const MonitorRowContainer: FC<IProps> = ({
47148 const { leftColumnCount, rightColumnCount, isMultiDisplay, tighten } =
48149 getLayout ( layout ) ;
49150
50- const leftColumn = [ ] ;
51- const rightColumn = [ ] ;
52-
53- const currentDay = setDate ( 0 ) ;
54- const nextDay = setDate ( 1 ) ;
55- const nextDayDepartureIndexLeft = departuresLeft
56- . slice ( 0 , leftColumnCount )
57- . findIndex ( departure => departure ?. serviceDay === nextDay . getTime ( ) / 1000 ) ;
58-
59- if ( nextDayDepartureIndexLeft !== - 1 ) {
60- departuresLeft . splice ( nextDayDepartureIndexLeft , 0 , null ) ;
61- }
62-
63- let currentDayDepartureIndexRight = - 1 ;
64- let nextDayDepartureIndexRight = departuresRight
65- . slice ( 0 , rightColumnCount )
66- . findIndex ( departure => departure . serviceDay === nextDay . getTime ( ) / 1000 ) ;
67-
68- const currentDayDeparturesRight = departuresRight
69- . slice ( 0 , rightColumnCount )
70- . filter ( departure => departure . serviceDay === currentDay . getTime ( ) / 1000 ) ;
71- const nextDayDeparturesRight = departuresRight
72- . slice ( 0 , rightColumnCount )
73- . filter ( departure => departure . serviceDay === nextDay . getTime ( ) / 1000 ) ;
74-
75- let rowCountRight = currentDayDeparturesRight . length ;
76- if ( nextDayDeparturesRight . length !== 0 ) {
77- rowCountRight += nextDayDeparturesRight . length + 1 ;
78- }
79-
80- if ( currentDayDepartureIndexRight !== - 1 ) {
81- if ( rowCountRight < rightColumnCount || rightColumnCount !== 0 ) {
82- nextDayDepartureIndexRight += departuresRight . length === 0 ? 0 : 1 ;
83- if ( currentDayDeparturesRight . length > 0 ) {
84- currentDayDepartureIndexRight = 0 ;
85- departuresRight . splice ( 0 , 0 , null ) ;
86- }
87- }
88- departuresRight . splice ( nextDayDepartureIndexRight , 0 , null ) ;
89- }
90-
91151 const isTighten = tighten !== undefined ;
92152 const hasRouteColumn = [ ] ;
93153 leftStops . forEach ( s => {
@@ -103,102 +163,69 @@ const MonitorRowContainer: FC<IProps> = ({
103163 if ( alertComponent && layout < 12 ) {
104164 leftColumnCountWithAlerts -= alertRowSpan ;
105165 }
106- for ( let i = 0 ; i < leftColumnCountWithAlerts ; i ++ ) {
107- const departure =
108- i !== nextDayDepartureIndexLeft ? departuresLeft [ i ] : null ;
109- leftColumn . push (
110- < MonitorRow
111- key = { departure ? stoptimeSpecificDepartureId ( departure ) : `row_l${ i } ` }
112- departure = { departure }
113- isFirst = { i === 0 || i - 1 === nextDayDepartureIndexLeft }
114- showVia = {
115- layout < 4 ||
116- layout === 12 ||
117- ( layout === 16 && i < 4 ) ||
118- leftColumnCount === 4
119- }
120- isTwoRow = {
121- leftColumnCount === 4 || layout === 12 || ( layout === 16 && i < 4 )
122- }
123- withTwoColumns = { withTwoColumns }
124- alertState = { alertState }
125- stops = { leftStops }
126- currentLang = { currentLang }
127- dayForDivider = {
128- i === nextDayDepartureIndexLeft
129- ? formatDate ( nextDay , currentLang )
130- : undefined
131- }
132- showMinutes = { showMinutes || 0 }
133- withoutRouteColumn = { withoutRouteColumn }
134- /> ,
135- ) ;
136- }
137166
138- if ( isLandscape ) {
139- if ( ! isMultiDisplay ) {
140- for (
141- let i = leftColumnCountWithAlerts ;
142- i < leftColumnCountWithAlerts + rightColumnCount ;
143- i ++
144- ) {
145- const departure =
146- i !== nextDayDepartureIndexLeft ? departuresLeft [ i ] : null ;
147- rightColumn . push (
148- < MonitorRow
149- key = {
150- departure ? stoptimeSpecificDepartureId ( departure ) : `row_c${ i } `
151- }
152- departure = { departure }
153- isFirst = {
154- i === leftColumnCountWithAlerts ||
155- i - 1 === nextDayDepartureIndexLeft
156- }
157- isTwoRow = { rightColumnCount === 4 || layout === 12 }
158- stops = { leftStops }
159- showVia = { rightColumnCount === 4 }
160- withTwoColumns = { withTwoColumns }
161- alertState = { alertState }
162- dayForDivider = {
163- i === nextDayDepartureIndexLeft
164- ? formatDate ( nextDay , currentLang )
165- : undefined
166- }
167- currentLang = { currentLang }
168- showMinutes = { showMinutes || 0 }
169- withoutRouteColumn = { withoutRouteColumn }
170- /> ,
171- ) ;
167+ const { leftRows, rightRows } = isMultiDisplay
168+ ? formatMultiDisplayData (
169+ departuresLeft ,
170+ departuresRight ,
171+ leftColumnCountWithAlerts ,
172+ rightColumnCount ,
173+ currentLang ,
174+ )
175+ : formatSingleDisplayData (
176+ departuresLeft ,
177+ leftColumnCountWithAlerts ,
178+ rightColumnCount ,
179+ currentLang ,
180+ ) ;
181+
182+ const leftColumn = leftRows . map ( ( { departure, dayDivider, isFirst } , i ) => (
183+ < MonitorRow
184+ key = { departure ? stoptimeSpecificDepartureId ( departure ) : `row_l${ i } ` }
185+ departure = { departure }
186+ isFirst = { isFirst }
187+ showVia = {
188+ layout < 4 ||
189+ layout === 12 ||
190+ ( layout === 16 && i < 4 ) ||
191+ leftColumnCount === 4
172192 }
173- } else {
174- for ( let i = 0 ; i < rightColumnCount ; i ++ ) {
175- const departure =
176- i !== nextDayDepartureIndexRight ? departuresRight [ i ] : null ;
177- rightColumn . push (
178- < MonitorRow
179- key = {
180- departure ? stoptimeSpecificDepartureId ( departure ) : `row_r${ i } `
181- }
182- departure = { departure }
183- isTwoRow = { rightColumnCount === 4 || layout === 12 }
184- stops = { rightStops }
185- isFirst = { i === 0 || i - 1 === nextDayDepartureIndexRight }
186- showVia = { rightColumnCount === 4 }
187- withTwoColumns = { withTwoColumns }
188- alertState = { alertState }
189- dayForDivider = {
190- i === nextDayDepartureIndexRight
191- ? formatDate ( nextDay , currentLang )
192- : undefined
193- }
194- currentLang = { currentLang }
195- showMinutes = { showMinutes || 0 }
196- withoutRouteColumn = { withoutRouteColumn }
197- /> ,
198- ) ;
193+ isTwoRow = {
194+ leftColumnCount === 4 || layout === 12 || ( layout === 16 && i < 4 )
199195 }
200- }
201- }
196+ withTwoColumns = { withTwoColumns }
197+ alertState = { alertState }
198+ stops = { leftStops }
199+ currentLang = { currentLang }
200+ dayForDivider = { dayDivider }
201+ showMinutes = { showMinutes || 0 }
202+ withoutRouteColumn = { withoutRouteColumn }
203+ />
204+ ) ) ;
205+
206+ const rightColumn = rightRows . map ( ( { departure, dayDivider, isFirst } , i ) => (
207+ < MonitorRow
208+ key = { departure ? stoptimeSpecificDepartureId ( departure ) : `row_r${ i } ` }
209+ departure = { departure }
210+ isFirst = { isFirst }
211+ showVia = {
212+ layout < 4 ||
213+ layout === 12 ||
214+ ( layout === 16 && i < 4 ) ||
215+ leftColumnCount === 4
216+ }
217+ isTwoRow = {
218+ leftColumnCount === 4 || layout === 12 || ( layout === 16 && i < 4 )
219+ }
220+ withTwoColumns = { withTwoColumns }
221+ alertState = { alertState }
222+ stops = { leftStops }
223+ currentLang = { currentLang }
224+ dayForDivider = { dayDivider }
225+ showMinutes = { showMinutes || 0 }
226+ withoutRouteColumn = { withoutRouteColumn }
227+ />
228+ ) ) ;
202229 const headers = ( columns , stops ) => {
203230 let withStopCode = false ;
204231 stops . forEach ( s => {
0 commit comments