diff --git a/calendar-new.html b/calendar-new.html new file mode 100644 index 0000000..2fe456f --- /dev/null +++ b/calendar-new.html @@ -0,0 +1,42 @@ +--- +layout: default +--- +
+

Termine

+ +
+

Coronabedingt sind die Clubräume derzeit geschlossen. Alle Termine finden virtuell statt.

+
+ +

Events

+ +
+ Loading Events, please stand by … +
+ +
+ +

Regelmäßige Treffen

+ +
+ +

Chaostreff

+ +

Mittwochs, ab ca. 19 Uhr + Ein offener Tag für Außenstehende. Jeder, der sich für den CCC oder einen Hackerspace interessiert, ist eingeladen. + Um 20:00 Uhr gibt es immer einen Kurzvortrag ‘Petit Foo’ zu ganz unterschiedlichen Themen. + Der Chaostreff findet zur Zeit online über Big Blue Button statt: + treff.chaospott.de

+
+ +

+

+ +
+ +

Den Kalender gibt es auch per CalDAV. Fehlt etwas? Oder hast du Fragen? Dann schreib uns einfach eine Mail!

+ +
+ + + diff --git a/js/calv2.js b/js/calv2.js new file mode 100644 index 0000000..93b6dea --- /dev/null +++ b/js/calv2.js @@ -0,0 +1,278 @@ +var eventList = [] +var recurringEventList = [] +var cancelledEvents = {} + +function Event (start, event) { + if (!(start instanceof Date)) { + start = start.toJSDate() + } + this.start = start + this.event = event + this.end = new Date(this.start.getTime() + this.event.duration.toSeconds()*1000) + this.summary = event.summary || 'No title' + this.description = event.description + this.location = event.location || false + this.isRecurring = event.isRecurring() + + this.lasts_several_days = this.start.toDateString() !== this.end.toDateString() +} + +Event.prototype.isCancelled = function () { + if (cancelledEvents[this.event.uid] instanceof Array + && cancelledEvents[this.event.uid].includes(this.start.getTime())) return true + return false +} + +Event.prototype.toHTML = function () { + + var div_cal = document.createElement('div') + + + if (this.isRecurring) { + + div_cal.setAttribute('class', 'cal_entry') + + var div_datetime = document.createElement('div') + div_datetime.setAttribute('class', 'cal_datetime') + + var span_summary = document.createElement('span') + span_summary.setAttribute('class', 'cal_summary') + span_summary.appendChild(document.createTextNode(this.summary)) + + div_datetime.appendChild(span_summary) + div_cal.appendChild(div_datetime) + + var div_description = document.createElement('div') + div_description.setAttribute('class', 'cal_descriptionbox') + //div_description.appendChild(span_summary) + + var span_description = document.createElement('div') + span_description.setAttribute('class', 'cal_description') + + if (this.description !== null) { + var span_description = document.createElement('span') + span_description.setAttribute('class', 'cal_description') + span_description.appendChild(document.createTextNode(this.description)) + } + + div_description.appendChild(span_description) + + + var span_next = document.createElement('span') + span_next.setAttribute('class', 'cal_description') + span_next.appendChild(document.createTextNode("Das nächste Treffen findet am " + + this.start.toLocaleDateString('de-DE', {year: 'numeric', month: '2-digit', day: '2-digit'}) + + " um " + this.start.toLocaleTimeString('de-DE', {hour: '2-digit', minute:'2-digit'}) + + " statt." + )) + + div_description.appendChild(span_next) + + div_cal.appendChild(div_description) + + + } else { + + div_cal.setAttribute('class', 'cal_entry') + + var div_datetime = document.createElement('div') + div_datetime.setAttribute('class', 'cal_datetime') + + var span_date = document.createElement('span') + span_date.setAttribute('class', 'cal_date') + span_date.appendChild(document.createTextNode(this.start.toLocaleDateString('de-DE', {year: 'numeric', month: '2-digit', day: '2-digit'}))) + div_datetime.appendChild(span_date) + + if (this.lasts_several_days) { + var span_end_date = document.createElement('span') + span_end_date.setAttribute('class', 'cal_date') + span_end_date.appendChild(document.createTextNode(' - ' + this.end.toLocaleString('de-DE', {year: 'numeric', month: '2-digit', day: '2-digit'}))) + div_datetime.appendChild(span_end_date) + } else { + var span_day = document.createElement('span') + span_day.setAttribute('class', 'cal_day') + span_day.appendChild((document.createTextNode(this.start.toLocaleDateString('de-DE', {weekday: 'long'})))) + div_datetime.appendChild(span_day) + } + + var span_time = document.createElement('span') + span_time.setAttribute('class', 'cal_time') + span_time.appendChild(document.createTextNode(this.start.toLocaleTimeString('de-DE', {hour: '2-digit', minute:'2-digit'}))) + div_datetime.appendChild(span_time) + + var span_summary = document.createElement('span') + span_summary.setAttribute('class', 'cal_summary') + span_summary.appendChild(document.createTextNode(this.summary)) + + var div_description = document.createElement('div') + div_description.setAttribute('class', 'cal_descriptionbox') + div_description.appendChild(span_summary) + + if (this.location !== false && !/s(ibyllastra(ss|ß)e )9/i.test(this.location)) { + var span_location = document.createElement('span') + span_location.setAttribute('class', 'cal_location') + + var span_location_icon = document.createElement('i') + span_location_icon.setAttribute('class', 'fa fa-map-marker') + span_location_icon.setAttribute('aria-hidden', 'true') + + span_location.appendChild(span_location_icon) + + if (this.location.match(/tb(a|d)/i)) { + span_location.appendChild(document.createTextNode(this.location)) + } else { + var a_location_osm = document.createElement('a') + a_location_osm.setAttribute('href', 'https://www.openstreetmap.org/search?query=' + encodeURI(this.location)) + a_location_osm.appendChild(document.createTextNode(this.location)) + span_location.appendChild(a_location_osm) + } + + div_description.appendChild(span_location) + } + + div_cal.appendChild(div_datetime) + div_cal.appendChild(div_description) + + if (this.description !== null) { + var parts = this.description.split(/\r\n|\r|\n/) + + parts.map(function (i) { + var span_description = document.createElement('span') + span_description.setAttribute('class', 'cal_description') + + words = i.split(' ') + + words.forEach(function(word) { + if (word.match(/(ht|f)tps?\:\/\//i)) { + var a = document.createElement('a') + a.setAttribute('href', word) + a.appendChild(document.createTextNode(word)) + span_description.appendChild(a) + } else { + span_description.appendChild(document.createTextNode(word)) + } + span_description.appendChild(document.createTextNode(' ')) + }) + + div_description.appendChild(span_description) + }) + } + + // if (this.event.component.getFirstPropertyValue("status") == "CANCELLED") { + // div_cal.style.textDecoration = 'line-through' + // } + + } + + return div_cal + +} + +function parseIcalData(data) { + var timeRangeStart = new Date() + var timeRangeStop = new Date() + timeRangeStart.setHours(0, 0, 0) + timeRangeStop.setMonth(timeRangeStop.getMonth() + 1) + + var jcalData = ICAL.parse(data) + var vcalendar = new ICAL.Component(jcalData) + var events = vcalendar.getAllSubcomponents('vevent') + + events.map(function (e) { + var event = new ICAL.Event(e) + if (event.component.getFirstPropertyValue("status") == "CANCELLED") { +// console.log(event) + if (!(cancelledEvents[event.uid] instanceof Array)) { + cancelledEvents[event.uid] = [] + } + + cancelledEvents[event.uid].push(event.startDate.toJSDate().getTime()) + } else if (event.isRecurring()) { + var expand = event.iterator() + var next + var exList = [] + event.component.getAllProperties('exdate').map(function (ex) { + exList.push(ex.getFirstValue().toJSDate().getTime()) + }) + + // particularly crappy code, but it works + while ((next = expand.next()) && next.toJSDate() < timeRangeStop) { + if (!exList.includes(next.toJSDate().getTime()) && timeRangeStart < next.toJSDate() && next.toJSDate() < timeRangeStop) { + recurringEventList.push(new Event(next, event)) + break + } + } + + } else if (eventInTimeRange(event, timeRangeStart, timeRangeStop)) { + eventList.push(new Event(event.startDate, event)) + } + }) +} + +function eventInTimeRange(event, start, stop) { + if (start < event.startDate.toJSDate() && event.startDate.toJSDate() < stop + || start < event.endDate.toJSDate() && event.endDate.toJSDate() < stop + || event.startDate.toJSDate() < start && stop < event.endDate.toJSDate()) return true + return false +} + +function orderEvents() { + eventList.sort(function (e1, e2) { + return e1.start - e2.start + }) +} + +function writeEvents() { + var cal = document.getElementById('calendar') + cal.textContent = '' + + // TODO: Wenn EventList leer, dann Event-Abschnitt ausblenden + if (eventList.length > 0) { + eventList.map(function (e) { + cal.appendChild(e.toHTML()) + }) + } else { + cal.textContent = 'No events found.' + } + + var calRecur = document.getElementById('calendar-recurring') + calRecur.textContent = '' + + if (recurringEventList.length > 0) { + recurringEventList.map(function (e) { + calRecur.appendChild(e.toHTML()) + }) + } else { + calRecur.textContent = 'No events found.' + } +} + +function xhrRequest(url, callback, fail) { + var xhr = new XMLHttpRequest() + + xhr.onreadystatechange = function () { + if (xhr.readyState === XMLHttpRequest.DONE) { + if (xhr.status === 200) { + callback(xhr.responseText) + } else { + fail(xhr.status) + } + } + } + + xhr.open('GET', url) + xhr.send() +} + +function processData(data) { + parseIcalData(data) + orderEvents() + writeEvents() +} + +function requestFailed(status) { + document.getElementById('calendar').textContent = 'Something has gone wrong. Try reloading the page.' + document.getElementById('calendar-recurring').textContent = 'Something has gone wrong. Try reloading the page.' +} + +xhrRequest('https://cloud.chaospott.ru/remote.php/dav/public-calendars/5HM7B0ZOLEYC3QD0?export', processData, requestFailed)