@@ -71,62 +71,83 @@ async function initCalendar() {
7171 window . ec = ec ;
7272}
7373
74- // Parse events from iCal file
75- async function loadEventsFromICal ( ) {
74+ async function fetchFirstOk ( urls ) {
75+ let lastErr ;
76+ for ( const url of urls ) {
7677 try {
77- const response = await fetch ( 'https://raw.githubusercontent.com/fs-ise/handbook/main/assets/calendar/fs-ise.ical' ) ;
78- if ( ! response . ok ) {
79- throw new Error ( "Network response was not ok: " + response . statusText ) ;
80- }
81- const iCalText = await response . text ( ) ;
82- const jcalData = ICAL . parse ( iCalText ) ;
83- const vcalendar = new ICAL . Component ( jcalData ) ;
84- const vevents = vcalendar . getAllSubcomponents ( 'vevent' ) ;
85-
86- return vevents . map ( ( vevent ) => {
87- const event = new ICAL . Event ( vevent ) ;
88-
89- const title = ( event . summary || "" ) . toLowerCase ( ) ;
90-
91- // Default: teaching (blue)
92- let category = "teaching" ;
93- let color = "#007acc" ;
94-
95- // General (light grey)
96- if ( title . includes ( "vacation" ) || title . includes ( "remote work" ) || title . includes ( "professorium" ) ) {
97- category = "general" ;
98- color = "#C8D1DC" ;
99- }
100-
101- // Events (green) — add/remove keywords as you like
102- const eventKeywords = [
103- "feier" ,
104- "conference" ,
105- "dies academicus" ,
106- "weihnachtsfeier" ,
107- "end-of-year" ,
108- "choose-a-chair" ,
109- ] ;
110- if ( eventKeywords . some ( ( kw ) => title . includes ( kw ) ) ) {
111- category = "events" ;
112- color = "#2e7d32" ;
113- }
114-
115- return {
116- start : event . startDate . toJSDate ( ) ,
117- end : event . endDate . toJSDate ( ) ,
118- title : event . summary ,
119- description : event . description ,
120- location : event . location ,
121- category, // optional, but handy for filtering/legends later
122- color,
123- } ;
124- } ) ;
125-
126- } catch ( error ) {
127- console . error ( "Error fetching or parsing iCal file:" , error ) ;
128- return [ ] ;
78+ const res = await fetch ( url , { cache : "no-cache" } ) ;
79+ if ( ! res . ok ) throw new Error ( `${ res . status } ${ res . statusText } ` ) ;
80+ return await res . text ( ) ;
81+ } catch ( err ) {
82+ lastErr = err ;
83+ console . warn ( "Failed to fetch" , url , err ) ;
12984 }
85+ }
86+ throw lastErr || new Error ( "No URL succeeded" ) ;
87+ }
88+
89+ // Parse events from iCal file
90+ async function loadEventsFromICal ( ) {
91+ try {
92+ // 1) Prefer local/relative (works when served by your site or local server)
93+ // Adjust these paths to match where the .ical is in your built site.
94+ const localCandidates = [
95+ "./assets/calendar/fs-ise.ical" ,
96+ "/assets/calendar/fs-ise.ical" ,
97+ ] ;
98+
99+ // 2) Fallback: GitHub raw
100+ const githubRaw =
101+ "https://raw.githubusercontent.com/fs-ise/handbook/main/assets/calendar/fs-ise.ical" ;
102+
103+ const iCalText = await fetchFirstOk ( [ ...localCandidates , githubRaw ] ) ;
104+
105+ const jcalData = ICAL . parse ( iCalText ) ;
106+ const vcalendar = new ICAL . Component ( jcalData ) ;
107+ const vevents = vcalendar . getAllSubcomponents ( "vevent" ) ;
108+
109+ return vevents . map ( ( vevent ) => {
110+ const event = new ICAL . Event ( vevent ) ;
111+ const title = ( event . summary || "" ) . toLowerCase ( ) ;
112+
113+ // Default: teaching (blue)
114+ let category = "teaching" ;
115+ let color = "#007acc" ;
116+
117+ // General
118+ if ( title . includes ( "vacation" ) || title . includes ( "remote work" ) || title . includes ( "professorium" ) ) {
119+ category = "general" ;
120+ color = "#C8D1DC" ;
121+ }
122+
123+ // Events
124+ const eventKeywords = [
125+ "feier" ,
126+ "conference" ,
127+ "dies academicus" ,
128+ "weihnachtsfeier" ,
129+ "end-of-year" ,
130+ "choose-a-chair" ,
131+ ] ;
132+ if ( eventKeywords . some ( ( kw ) => title . includes ( kw ) ) ) {
133+ category = "events" ;
134+ color = "#2e7d32" ;
135+ }
136+
137+ return {
138+ start : event . startDate . toJSDate ( ) ,
139+ end : event . endDate . toJSDate ( ) ,
140+ title : event . summary ,
141+ description : event . description ,
142+ location : event . location ,
143+ category,
144+ color,
145+ } ;
146+ } ) ;
147+ } catch ( error ) {
148+ console . error ( "Error fetching or parsing iCal file:" , error ) ;
149+ return [ ] ;
150+ }
130151}
131152
132153function _pad ( num ) {
0 commit comments