Support du calendrier NextCloud (fix #7).
This commit is contained in:
5
content/calendrier.html
Normal file
5
content/calendrier.html
Normal file
@@ -0,0 +1,5 @@
|
||||
---
|
||||
layout: calendar.njk
|
||||
permalink: false
|
||||
title: Événements à venir
|
||||
---
|
||||
8
content/donnees/calendrier.php
Normal file
8
content/donnees/calendrier.php
Normal file
@@ -0,0 +1,8 @@
|
||||
<?php
|
||||
|
||||
const ICS_URL = 'https://cloud.ti-nuage.fr/remote.php/dav/public-calendars/gqm9WNa9eoXGEiNc?export';
|
||||
|
||||
$ics = file_get_contents(ICS_URL);
|
||||
echo $ics;
|
||||
|
||||
?>
|
||||
153
content/js/calendar.js
Normal file
153
content/js/calendar.js
Normal file
@@ -0,0 +1,153 @@
|
||||
|
||||
const http = require('http')
|
||||
const ical = require('ical')
|
||||
|
||||
const MONTH = 30 * 24 * 60 * 60 * 1000
|
||||
|
||||
const Accumulator = {
|
||||
|
||||
init: function (pastLimit, futureLimit) {
|
||||
this.entries = {}
|
||||
this.futureLimit = futureLimit
|
||||
this.pastLimit = pastLimit
|
||||
},
|
||||
|
||||
add: function (time, element) {
|
||||
if (!this.entries.hasOwnProperty(time)) {
|
||||
this.entries[time] = []
|
||||
}
|
||||
this.entries[time].push(element)
|
||||
},
|
||||
|
||||
offer: function (time, element) {
|
||||
if (time >= this.pastLimit && time < this.futureLimit) {
|
||||
this.add(time, element)
|
||||
}
|
||||
},
|
||||
|
||||
offerEvent: function (event) {
|
||||
const content = document.createElement('p')
|
||||
const element = document.createElement('div')
|
||||
const formatDate = Intl.DateTimeFormat('fr', { dateStyle: 'long', timeStyle: 'short' }).format
|
||||
const header = document.createElement('h3')
|
||||
|
||||
content.innerHTML = event.location
|
||||
header.textContent = formatDate(event.date) + ' | ' + event.summary
|
||||
|
||||
element.className = 'event-entry news-entry'
|
||||
element.setAttribute('entry-time', event.date.getTime())
|
||||
element.appendChild(header)
|
||||
element.appendChild(content)
|
||||
|
||||
this.offer(event.date.getTime(), element)
|
||||
},
|
||||
|
||||
iterate: function (cb) {
|
||||
Object
|
||||
.keys(this.entries)
|
||||
.sort(function (a, b) { return a < b })
|
||||
.forEach(time => { cb(time, this.entries[time]) })
|
||||
}
|
||||
}
|
||||
|
||||
function createLoader (target) {
|
||||
const message = document.createElement('p')
|
||||
const spinner = document.createElement('div')
|
||||
const wrapper = document.createElement('div')
|
||||
|
||||
wrapper.className = 'loader-wrapper'
|
||||
message.innerHTML = 'Chargement du calendrier...'
|
||||
|
||||
wrapper.appendChild(spinner)
|
||||
wrapper.appendChild(message)
|
||||
|
||||
target.insertBefore(wrapper, target.firstChild)
|
||||
}
|
||||
|
||||
function loadEvents (cb) {
|
||||
const events = []
|
||||
|
||||
http.get({
|
||||
host: 'www.ti-nuage.fr',
|
||||
path: '/donnees/calendrier.php'
|
||||
}, function (response) {
|
||||
let str = ''
|
||||
|
||||
response.on('data', (chunk) => {
|
||||
str += chunk
|
||||
})
|
||||
|
||||
response.on('end', () => {
|
||||
/* Extract the events. */
|
||||
Object.values(ical.parseICS(str)).forEach(event => {
|
||||
if (event.type === 'VEVENT') {
|
||||
events.push({
|
||||
date: event.start,
|
||||
location: event.location,
|
||||
summary: event.summary
|
||||
})
|
||||
}
|
||||
})
|
||||
|
||||
cb(events)
|
||||
})
|
||||
|
||||
response.on('error', (e) => {
|
||||
console.error(`Error on calendar response: ${e.message}`)
|
||||
cb(events)
|
||||
})
|
||||
}).on('error', (e) => {
|
||||
console.error(`Could not fetch calendar: ${e.message}`)
|
||||
cb(events)
|
||||
})
|
||||
}
|
||||
|
||||
module.exports = {
|
||||
|
||||
fill: function (target) {
|
||||
const now = Date.now()
|
||||
const accumulator = Object.create(Accumulator)
|
||||
|
||||
accumulator.init(now - 1 * MONTH, now + 3 * MONTH)
|
||||
createLoader(target)
|
||||
|
||||
loadEvents(events => {
|
||||
events.forEach(event => { accumulator.offerEvent(event) })
|
||||
|
||||
target.innerHTML = ''
|
||||
|
||||
accumulator.iterate((time, elements) => {
|
||||
elements.forEach(e => {
|
||||
if (time < now) {
|
||||
e.className = e.className + ' event-elapsed'
|
||||
}
|
||||
target.appendChild(e)
|
||||
})
|
||||
})
|
||||
})
|
||||
},
|
||||
|
||||
mergeWithNews: function (target) {
|
||||
const now = Date.now()
|
||||
const accumulator = Object.create(Accumulator)
|
||||
const blogElements = target.getElementsByClassName('blog-entry')
|
||||
|
||||
accumulator.init(now, now + 1 * MONTH)
|
||||
createLoader(target)
|
||||
|
||||
for (let i = 0; i < blogElements.length; ++i) {
|
||||
const item = blogElements.item(i)
|
||||
accumulator.add(item.getAttribute('entry-time'), item)
|
||||
}
|
||||
|
||||
loadEvents(events => {
|
||||
events.forEach(event => { accumulator.offerEvent(event) })
|
||||
|
||||
target.innerHTML = ''
|
||||
|
||||
accumulator.iterate((time, elements) => {
|
||||
elements.forEach(e => { target.appendChild(e) })
|
||||
})
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user