66 {{ end }}
77{{ end }}
88
9- {{ $calPage := .Site.GetPage "resources/community-calendar.md" }}
10- {{ $calLink := $calPage.RelPermalink | default "/resources/calendar/" }}
9+ {{ $calLink := "/resources/calendar/" }}
10+ {{ with .Site.GetPage "resources/community-calendar" }}
11+ {{ $calLink = .RelPermalink }}
12+ {{ end }}
1113{{ $nco := .Site.Data.nco }}
1214
1315{{ $ncoData := dict
2123
2224< div class ="metadata-container nco-container my-4 " id ="nco-root " data-nco ='{{ $ncoData | jsonify }} ' aria-label ="Kubernetes New Contributor Orientation ">
2325
24- < div class ="d-flex flex-column align-items-center justify-content-center py-5 " id ="nco-loading " aria-live ="polite ">
26+ {{/* Loading is hidden until JS runs so no-JS users keep the static fallback. */}}
27+ < div class ="d-none flex-column align-items-center justify-content-center py-5 " id ="nco-loading " aria-live ="polite ">
2528 < div class ="nco-loader mb-3 "> </ div >
2629 < span class ="small fw-bold text-uppercase nco-muted "> Fetching next session...</ span >
2730 </ div >
2831
2932 < div class ="nco-state d-none " id ="nco-card ">
3033 < div class ="mb-4 " id ="nco-date-header ">
3134 < span class ="metadata-sublabel ">
32- < span class ="nco-pulse-dot "> </ span > Next Session Date
35+ < span class ="nco-pulse-dot "> </ span > < span id =" nco-date-sublabel " > Next Session Date</ span >
3336 </ span >
3437 < h3 class ="fw-bold h3 mt-1 mb-0 " id ="nco-date-display "> —</ h3 >
3538 </ div >
3639 < div class ="d-flex flex-column mb-4 " id ="nco-sessions-grid "> </ div >
3740 </ div >
3841
39- < div class ="nco-state d-none " id ="nco-fallback ">
42+ < div class ="nco-state " id ="nco-fallback ">
4043 < div class ="mb-4 ">
4144 < span class ="metadata-sublabel " id ="nco-fallback-sublabel "> Typical schedule (unconfirmed)</ span >
4245 < h3 class ="fw-bold h3 mt-1 mb-0 "> {{ $nco.schedule }}</ h3 >
@@ -133,24 +136,30 @@ <h3 class="fw-bold h3 mt-1 mb-0">{{ $nco.schedule }}</h3>
133136< script >
134137( function ( ) {
135138 var root = document . getElementById ( 'nco-root' ) ;
139+ if ( ! root ) return ;
136140 var d = JSON . parse ( root . dataset . nco ) ;
137141
138142 var loadingEl = document . getElementById ( 'nco-loading' ) ;
139143 var cardEl = document . getElementById ( 'nco-card' ) ;
140144 var fallbackEl = document . getElementById ( 'nco-fallback' ) ;
141145 var dateHeader = document . getElementById ( 'nco-date-header' ) ;
146+ var dateSublabel = document . getElementById ( 'nco-date-sublabel' ) ;
142147 var dateEl = document . getElementById ( 'nco-date-display' ) ;
143148 var gridEl = document . getElementById ( 'nco-sessions-grid' ) ;
144149 var fbSublabel = document . getElementById ( 'nco-fallback-sublabel' ) ;
145150 var fbMessage = document . getElementById ( 'nco-fallback-message' ) ;
146151
147- var ncoMatcher = / n e w c o n t r i b u t o r o r i e n t a t i o n | n c o / i;
152+ var ncoMatcher = / n e w c o n t r i b u t o r o r i e n t a t i o n | \b n c o \b / i;
148153 var JOIN_HOSTS = [ 'zoom.us' , 'meet.google.com' ] ;
149154 var CAL_HOSTS = [ 'google.com' , 'calendar.google.com' ] ;
150155
151156 function show ( el ) {
152- [ loadingEl , cardEl , fallbackEl ] . forEach ( function ( e ) { e . classList . add ( 'd-none' ) ; } ) ;
157+ [ loadingEl , cardEl , fallbackEl ] . forEach ( function ( e ) {
158+ e . classList . add ( 'd-none' ) ;
159+ e . classList . remove ( 'd-flex' ) ;
160+ } ) ;
153161 el . classList . remove ( 'd-none' ) ;
162+ if ( el === loadingEl ) el . classList . add ( 'd-flex' ) ;
154163 }
155164
156165 function el ( tag , className ) {
@@ -178,7 +187,7 @@ <h3 class="fw-bold h3 mt-1 mb-0">{{ $nco.schedule }}</h3>
178187 if ( ! raw || typeof raw !== 'string' ) return '' ;
179188 try {
180189 var u = new URL ( raw ) ;
181- if ( u . protocol !== 'http:' && u . protocol !== ' https:') return '' ;
190+ if ( u . protocol !== 'https:' ) return '' ;
182191 if ( allowedHosts && ! hostAllowed ( u . hostname , allowedHosts ) ) return '' ;
183192 return u . href ;
184193 } catch ( e ) {
@@ -214,7 +223,7 @@ <h3 class="fw-bold h3 mt-1 mb-0">{{ $nco.schedule }}</h3>
214223 if ( ev . location ) candidates . push ( ev . location ) ;
215224 if ( ev . hangoutLink ) candidates . push ( ev . hangoutLink ) ;
216225 if ( ev . description ) {
217- var re = / h t t p s ? : \/ \/ [ ^ \s " ' < > ] + / gi;
226+ var re = / h t t p s : \/ \/ [ ^ \s " ' < > ] + / gi;
218227 var m ;
219228 while ( ( m = re . exec ( ev . description ) ) !== null ) {
220229 candidates . push ( m [ 0 ] . replace ( / [ . , ) ; ] + $ / , '' ) ) ;
@@ -238,7 +247,7 @@ <h3 class="fw-bold h3 mt-1 mb-0">{{ $nco.schedule }}</h3>
238247 return a ;
239248 }
240249
241- function appendRow ( parent , ev , region , now ) {
250+ function appendRow ( parent , ev , region , now , showDate ) {
242251 var isEMEA = region === 'emea' ;
243252 var label = isEMEA ? d . emeaLabel : d . amerLabel ;
244253 var iconClass = isEMEA ? 'fas fa-globe-europe' : 'fas fa-globe-americas' ;
@@ -271,7 +280,11 @@ <h3 class="fw-bold h3 mt-1 mb-0">{{ $nco.schedule }}</h3>
271280 var joinLink = ended ? '' : extractJoinLink ( ev ) ;
272281 var calEvLink = safeHttpUrl ( ev . htmlLink || '' , CAL_HOSTS ) ;
273282
274- var timeStr = start . toLocaleTimeString ( undefined , { hour : 'numeric' , minute : '2-digit' } ) ;
283+ var timeStr = '' ;
284+ if ( showDate ) {
285+ timeStr = start . toLocaleDateString ( undefined , { weekday : 'short' , month : 'short' , day : 'numeric' } ) + ' \u00b7 ' ;
286+ }
287+ timeStr += start . toLocaleTimeString ( undefined , { hour : 'numeric' , minute : '2-digit' } ) ;
275288 if ( ev . end ) {
276289 timeStr += ' - ' + end . toLocaleTimeString ( undefined , { hour : 'numeric' , minute : '2-digit' , timeZoneName : 'short' } ) ;
277290 } else {
@@ -331,6 +344,8 @@ <h3 class="fw-bold h3 mt-1 mb-0">{{ $nco.schedule }}</h3>
331344
332345 if ( ! d . apiKey ) { runFallback ( 'error' ) ; return ; }
333346
347+ show ( loadingEl ) ;
348+
334349 var now = new Date ( ) ;
335350 var timeMin = new Date ( now . getTime ( ) - 86400000 ) . toISOString ( ) ;
336351 var url = 'https://www.googleapis.com/calendar/v3/calendars/'
@@ -372,45 +387,49 @@ <h3 class="fw-bold h3 mt-1 mb-0">{{ $nco.schedule }}</h3>
372387 } ) ;
373388
374389 var now = new Date ( ) ;
375- var anchor = null ;
376- for ( var i = 0 ; i < events . length ; i ++ ) {
377- if ( eventEnd ( events [ i ] ) > now ) {
378- anchor = events [ i ] ;
379- break ;
380- }
381- }
382-
383- if ( ! anchor ) {
384- runFallback ( 'empty' ) ;
385- return ;
386- }
387-
388- var dayKey = utcDayKey ( eventStart ( anchor ) ) ;
389390 var emeaEvent = null ;
390391 var amerEvent = null ;
391392
392393 for ( var j = 0 ; j < events . length ; j ++ ) {
393394 var ev = events [ j ] ;
394- if ( utcDayKey ( eventStart ( ev ) ) !== dayKey ) continue ;
395+ if ( eventEnd ( ev ) <= now ) continue ;
395396 var region = regionOf ( ev ) ;
396397 if ( region === 'emea' && ! emeaEvent ) emeaEvent = ev ;
397398 else if ( region === 'amer' && ! amerEvent ) amerEvent = ev ;
399+ if ( emeaEvent && amerEvent ) break ;
398400 }
399401
400402 if ( ! emeaEvent && ! amerEvent ) {
401403 runFallback ( 'empty' ) ;
402404 return ;
403405 }
404406
405- var dayDate = eventStart ( anchor ) ;
406- dateHeader . style . display = '' ;
407- dateEl . textContent = dayDate . toLocaleDateString ( undefined , {
408- weekday : 'long' , year : 'numeric' , month : 'long' , day : 'numeric'
409- } ) ;
407+ var sameDay = false ;
408+ var headerDate = null ;
409+ if ( emeaEvent && amerEvent ) {
410+ sameDay = utcDayKey ( eventStart ( emeaEvent ) ) === utcDayKey ( eventStart ( amerEvent ) ) ;
411+ headerDate = eventStart ( emeaEvent ) < eventStart ( amerEvent )
412+ ? eventStart ( emeaEvent )
413+ : eventStart ( amerEvent ) ;
414+ } else {
415+ sameDay = true ;
416+ headerDate = eventStart ( emeaEvent || amerEvent ) ;
417+ }
418+
419+ if ( dateHeader ) dateHeader . style . display = '' ;
420+ if ( sameDay ) {
421+ if ( dateSublabel ) dateSublabel . textContent = 'Next Session Date' ;
422+ dateEl . textContent = headerDate . toLocaleDateString ( undefined , {
423+ weekday : 'long' , year : 'numeric' , month : 'long' , day : 'numeric'
424+ } ) ;
425+ } else {
426+ if ( dateSublabel ) dateSublabel . textContent = 'Upcoming Sessions' ;
427+ dateEl . textContent = 'Different dates — see each region below' ;
428+ }
410429
411430 while ( gridEl . firstChild ) gridEl . removeChild ( gridEl . firstChild ) ;
412- appendRow ( gridEl , emeaEvent , 'emea' , now ) ;
413- appendRow ( gridEl , amerEvent , 'amer' , now ) ;
431+ appendRow ( gridEl , emeaEvent , 'emea' , now , ! sameDay ) ;
432+ appendRow ( gridEl , amerEvent , 'amer' , now , ! sameDay ) ;
414433 show ( cardEl ) ;
415434 } )
416435 . catch ( function ( ) { runFallback ( 'error' ) ; } ) ;
0 commit comments