77 formatMultiResult ,
88} from '@wca/helpers' ;
99import { format , parseISO } from 'date-fns' ;
10- import * as ics from 'ics' ;
1110
1211export const byName = ( a : { name : string } , b : { name : string } ) => a . name . localeCompare ( b . name ) ;
1312export const byDate = < T > ( a : T & { startTime : string } , b : T & { startTime : string } ) =>
@@ -160,19 +159,40 @@ const AssignmentCodeDescription = {
160159 competitor : 'Competing in:' ,
161160} ;
162161
162+ function escapeCommas ( input ) {
163+ return input . replace ( / , / g, '\\,' ) ;
164+ }
165+
166+ function icsFormatDate ( date ) {
167+ const year = date . getUTCFullYear ( ) ;
168+ const month = date . getUTCMonth ( ) + 1 ;
169+ const day = date . getUTCDate ( ) ;
170+ const hours = date . getUTCHours ( ) ;
171+ const minutes = date . getUTCMinutes ( ) ;
172+ const seconds = date . getUTCSeconds ( ) ;
173+
174+ return `${ year } ${ month . toString ( ) . padStart ( 2 , '0' ) } ${ day . toString ( ) . padStart ( 2 , '0' ) } T${ hours
175+ . toString ( )
176+ . padStart ( 2 , '0' ) } ${ minutes . toString ( ) . padStart ( 2 , '0' ) } ${ seconds
177+ . toString ( )
178+ . padStart ( 2 , '0' ) } Z`;
179+ }
180+
163181export const generateIcs = ( assignments , wcif , fileName : string ) => {
182+ console . log ( assignments ) ;
183+
164184 if ( ! assignments ) {
165185 //Check if assignments is empty
166186 return ;
167187 }
168188
169- let events : {
170- title : string ;
171- description : string ;
172- location : string ;
173- start : ics . DateArray ;
174- end : ics . DateArray ;
175- } [ ] = [ ] ;
189+ let icalFile = `BEGIN:VCALENDAR
190+ VERSION:2.0
191+ CALSCALE:GREGORIAN
192+ PRODID:CompetitionGroups
193+ METHOD:PUBLISH
194+ X-PUBLISHED-TTL:PT1H
195+ ` ;
176196
177197 assignments . forEach ( ( item ) => {
178198 const titleFormatted = `${ AssignmentCodeDescription [ item . assignmentCode ] } ${
@@ -181,46 +201,36 @@ export const generateIcs = (assignments, wcif, fileName: string) => {
181201 const startDate = new Date ( item . activity . startTime ) ;
182202 const endDate = new Date ( item . activity . endTime ) ;
183203
184- const startDateArray : ics . DateArray = [
185- startDate . getFullYear ( ) ,
186- startDate . getMonth ( ) + 1 , // Months are 1-indexed in ics format
187- startDate . getDate ( ) ,
188- startDate . getHours ( ) ,
189- startDate . getMinutes ( ) ,
190- ] ;
191-
192- const endDateArray : ics . DateArray = [
193- endDate . getFullYear ( ) ,
194- endDate . getMonth ( ) + 1 ,
195- endDate . getDate ( ) ,
196- endDate . getHours ( ) ,
197- endDate . getMinutes ( ) ,
198- ] ;
199-
200- const location = {
201- lat : wcif . schedule . venues [ 0 ] . latitudeMicrodegrees / 100 ,
202- lon : wcif . schedule . venues [ 0 ] . longitudeMicrodegrees / 100 ,
203- } ;
204-
205- const icalEvent = {
206- title : titleFormatted ,
207- description : item . activity . name ,
208- location : item . activity . parent . room . name ,
209- ...( wcif . schedule . venues . length > 1 ? { } : { geo : location } ) ,
210- start : startDateArray ,
211- end : endDateArray ,
212- } ;
213-
214- events . push ( icalEvent ) ;
204+ console . log ( wcif . schedule ) ;
205+
206+ let location = '' ;
207+ if ( wcif . schedule . venues . length === 1 ) {
208+ location = `GEO: ${ wcif . schedule . venues [ 0 ] . latitudeMicrodegrees / 1000000 } ; ${
209+ wcif . schedule . venues [ 0 ] . longitudeMicrodegrees / 1000000
210+ } \n`;
211+ }
212+
213+ icalFile += `BEGIN:VEVENT
214+ UID:${ item . activity . id } ${ item . activity . activityCode }
215+ DTSTAMP:${ icsFormatDate ( new Date ( ) ) }
216+ SUMMARY:${ titleFormatted }
217+ DESCRIPTION:${ item . activity . name }
218+ LOCATION:${ item . activity . parent . room . name }
219+ DTSTART:${ icsFormatDate ( startDate ) }
220+ DTEND:${ icsFormatDate ( endDate ) }
221+ ${ location } END:VEVENT
222+ BEGIN:VALARM
223+ TRIGGER:-PT5M
224+ DURATION:PT5M
225+ ACTION:DISPLAY
226+ DESCRIPTION:${ item . activity . name }
227+ END:VALARM
228+ ` ;
215229 } ) ;
216230
217- const { error, value } = ics . createEvents ( events ) ;
218-
219- if ( error || ! value ) {
220- throw new Error ( 'Failed to create ICS events' ) ;
221- }
231+ icalFile += 'END:VCALENDAR' ;
222232
223- const blob = new Blob ( [ value ] , { type : 'text/calendar' } ) ;
233+ const blob = new Blob ( [ escapeCommas ( icalFile ) ] , { type : 'text/calendar' } ) ;
224234 const a = document . createElement ( 'a' ) ;
225235 a . href = URL . createObjectURL ( blob ) ;
226236 a . download = fileName ;
0 commit comments