1
0
forked from ti-nuage/site

Support du calendrier NextCloud (fix #7).

This commit is contained in:
David Soulayrol
2023-01-14 15:21:03 +01:00
parent 4d71bbe764
commit d0f95cdecf
15 changed files with 3275 additions and 24 deletions

153
content/js/calendar.js Normal file
View 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) })
})
})
}
}