diff --git a/assets/favicon.svg b/assets/favicon.svg deleted file mode 100644 index ff672c2..0000000 --- a/assets/favicon.svg +++ /dev/null @@ -1,94 +0,0 @@ - - - - diff --git a/assets/favicon@192.png b/assets/favicon@192.png deleted file mode 100644 index c8ce1c3..0000000 Binary files a/assets/favicon@192.png and /dev/null differ diff --git a/assets/favicon@512.png b/assets/favicon@512.png deleted file mode 100644 index f2fc788..0000000 Binary files a/assets/favicon@512.png and /dev/null differ diff --git a/css/style.css b/css/style.css index efd425b..ca7547c 100644 --- a/css/style.css +++ b/css/style.css @@ -1,7 +1,6 @@ body, html { padding: 0; margin: 0; - font-family: sans-serif; } body { @@ -382,13 +381,13 @@ camp-feature .widget > :last-child { margin-bottom: 0; } -camp-feature .widget > h2 { +camp-feature .widget h2 { font-size: 1em; text-transform: uppercase; margin-bottom: 1ex; } -camp-feature .widget > p { +camp-feature .widget p { margin-top: 1ex; margin-bottom: 1ex; line-height: 1.5; @@ -460,69 +459,4 @@ camp-feature .box-widget h2:first-child, margin-left: -10px; margin-top: -10px; margin-right: 2em; -} - -/* TALKS */ - -camp-upcoming-talks > * { - margin-bottom: 1em; - display: block; - color: inherit; - text-decoration: inherit; -} - -camp-talk { - display: block; - --track-color: white; - border: solid 1px var(--track-color); - border-left-width: 5px; - border-radius: 2.5px; - padding: 5px 10px; - box-sizing: border-box; -} - -camp-talk .track-name { - font-weight: bold; - color: var(--track-color); -} - -camp-talk > * { - margin: 0; -} - -camp-talk > p:not(:last-child) { - margin-top: 1ex; - margin-bottom: 1ex; -} - -camp-talk[data-track-id="36"] { - --track-color: #33d8d8; -} - -camp-talk[data-track-id="35"] { - --track-color: #ffbf3e; -} - -camp-talk[data-track-id="33"] { - --track-color: #ff4e00; -} - -camp-talk[data-track-id="34"] { - --track-color: #8800ff; -} - -@keyframes active-talk { - from { - box-shadow: 0px 0px 0px var(--track-color), 0px 0px 0px var(--track-color); - } - 25% { - box-shadow: 0px 0px 10px var(--track-color), 0px 0px 0px var(--track-color); - } - 100% { - box-shadow: 0px 0px 15px var(--track-color), 0px 0px 7px var(--track-color); - } -} - -camp-talk.active { - animation: active-talk 1.5s alternate-reverse infinite linear; } \ No newline at end of file diff --git a/index.html b/index.html index 9516f51..bde105d 100644 --- a/index.html +++ b/index.html @@ -9,10 +9,6 @@ - - - -
diff --git a/js/components/talk.js b/js/components/talk.js deleted file mode 100644 index 6bbe8a2..0000000 --- a/js/components/talk.js +++ /dev/null @@ -1,64 +0,0 @@ -const TEMPLATE = document.createElement("template") -TEMPLATE.innerHTML = ` -
- - - → - -
-

-

-

-` - -class TalkElement extends HTMLElement { - - #activeChackInterval - - srcObject - - connectedCallback(){ - this.updateContent() - this.#activeChackInterval = setInterval(this.updateActiveState.bind(this), 1000) - } - - disconnectedCallback(){ - clearInterval(this.#activeChackInterval) - } - - updateActiveState(){ - this.classList.toggle("active", this.srcObject?.isActive) - } - - updateContent(){ - if(!this.srcObject){ - this.replaceChildren() - } - - this.dataset.trackId = this.srcObject.track_id - - this.replaceChildren(TEMPLATE.content.cloneNode(true)) - this.querySelector(".talk-title").textContent = this.srcObject.title - this.querySelector(".talk-abstract").textContent = this.srcObject.abstract - this.querySelector(".track-name").textContent = this.srcObject.track.fr - - let timeFormatter = new Intl.DateTimeFormat("fr-FR", { - timeStyle: "short" - }) - - let dateFormatter = new Intl.DateTimeFormat("fr-FR", { - dateStyle: "short" - }) - - this.querySelector(".talk-start-date").textContent = dateFormatter.format(this.srcObject.startTime) - this.querySelector(".talk-start-time").textContent = timeFormatter.format(this.srcObject.startTime) - this.querySelector(".talk-start-time").datetime = this.srcObject.startTime.toJSON() - this.querySelector(".talk-end-time").textContent = timeFormatter.format(this.srcObject.endTime) - this.querySelector(".talk-end-time").datetime = this.srcObject.endTime.toJSON() - - this.updateActiveState() - } - -} - -customElements.define("camp-talk", TalkElement) \ No newline at end of file diff --git a/js/components/upcoming-talks.js b/js/components/upcoming-talks.js deleted file mode 100644 index 9dee72f..0000000 --- a/js/components/upcoming-talks.js +++ /dev/null @@ -1,90 +0,0 @@ -import { getUpcomingTalksForRoom } from "../pretalx.js" - -class UpcomingTalksElement extends HTMLElement { - #roomId - #loadingPromise - - srcObject = undefined - - get roomId(){ - return this.#roomId - } - - set roomId(val){ - this.#roomId = val - } - - connectedCallback(){ - this.updateContent() - } - - updateContent(){ - if(!this.roomId){ - this.replaceChildren() - return - } - - if(!this.srcObject){ - - if(!this.#loadingPromise){ - this.fetchTalks() - } - - let loading = document.createElement("div") - loading.classList.add("loading") - loading.textContent = "Chargement des événements..." - this.replaceChildren(loading) - - } else { - - let childrens = [] - - for(let talk of this.srcObject){ - let item = document.createElement("camp-talk") - item.srcObject = talk - - let a = document.createElement("a") - a.href = talk.displayUrl - a.target = "_blank" - a.append(item) - - childrens.push(a) - } - - this.classList.toggle("empty", childrens.length == 0) - if(childrens.length == 0){ - let empty = document.createElement("p") - empty.classList.add("empty") - empty.textContent = `Aucun événement à venir dans cette salle` - childrens.push(empty) - } - this.replaceChildren(...childrens) - - } - - this.classList.toggle("loading", !this.srcObject && this.#loadingPromise) - } - - async fetchTalks(){ - let prom = (async () => { - this.srcObject = await getUpcomingTalksForRoom(this.roomId) - this.#loadingPromise = null - this.updateContent() - })() - this.#loadingPromise = prom - await prom - } - - static observedAttributes = ["room-id"] - - attributeChangedCallback(name, oldVal, newVal){ - switch(name){ - case "room-id": - this.roomId = newVal - break; - } - } - -} - -customElements.define("camp-upcoming-talks", UpcomingTalksElement); \ No newline at end of file diff --git a/js/feature-widgets/feature-widgets.js b/js/feature-widgets/feature-widgets.js index 4de408d..c809be1 100644 --- a/js/feature-widgets/feature-widgets.js +++ b/js/feature-widgets/feature-widgets.js @@ -4,7 +4,6 @@ import { capaciteEspaceWidget } from "./capacite-espace.js" import { capaciteParkingWidget } from "./capacite-parking.js" import { deposeMinuteWidget } from "./depose-minute.js" import { mixiteChoisieWidget } from "./mixite-choisie.js" -import { upcomingTalksWidget } from "./upcoming-talks.js" import { zoneInterditeWidget } from "./zone-interdite.js" export const FEATURE_WIDGETS = [ @@ -14,7 +13,6 @@ export const FEATURE_WIDGETS = [ // Other deposeMinuteWidget, campingCarsWidget, - upcomingTalksWidget, // Fields capaciteParkingWidget, capaciteDortoirWidget, diff --git a/js/feature-widgets/upcoming-talks.js b/js/feature-widgets/upcoming-talks.js deleted file mode 100644 index 9999a65..0000000 --- a/js/feature-widgets/upcoming-talks.js +++ /dev/null @@ -1,17 +0,0 @@ -export function upcomingTalksWidget(feature){ - if(feature.properties["pretalx-room-id"]){ - let content = document.createElement("div") - content.classList.add("widget") - content.classList.add("upcoming-talks-widget") - - let h2 = document.createElement("h2") - h2.textContent = "Événements à venir" - content.append(h2) - - let list = document.createElement("camp-upcoming-talks") - list.roomId = feature.properties["pretalx-room-id"] - content.append(list) - - return content - } -} \ No newline at end of file diff --git a/js/pretalx.js b/js/pretalx.js deleted file mode 100644 index a008333..0000000 --- a/js/pretalx.js +++ /dev/null @@ -1,101 +0,0 @@ -const PRETALX_URL = `https://pretalx.lebib.org/` -const EVENT_ID = `camp-interhack-2026-2025` -const TALKS_EXPIRATION = 60*60*1000; -const API_ROOT = new URL("api/", PRETALX_URL); - -// Database management - -let cached_talks = null; - -export async function getFreshTalks(){ - if(!cached_talks || (Date.now() - cached_talks.updatedAt.getTime()) > TALKS_EXPIRATION){ - let talk_list = [] - - for await(let talk_json of requestAllTalks()){ - if(talk_json.state != "confirmed"){ - continue - } - let talk = new Talk(talk_json); - talk_list.push(talk) - } - - talk_list.sort((a,b) => a.startTime.getTime() - b.startTime.getTime()) - - // { - // let mock_i = 2 - // talk_list[mock_i].slot.start = new Date(Date.now() - 120*1000).toJSON() - // talk_list[mock_i].slot.end = (new Date(Date.now() + 3600000 + ( Math.random()*10000))).toJSON() - // console.log("mock event", talk_list[mock_i]) - // } - - let talks_by_room_id = {} - for(let talk of talk_list) { - if(!talks_by_room_id[talk.slot.room_id]){ - talks_by_room_id[talk.slot.room_id] = [] - } - talks_by_room_id[talk.slot.room_id].push(talk) - } - - cached_talks = { - updatedAt: new Date(), - talks: talk_list, - talks_by_room: talks_by_room_id - } - } - - return cached_talks -} - -export async function getUpcomingTalksForRoom(room_id){ - let db = await getFreshTalks() - return (db.talks_by_room[room_id] || []).filter(it => it.endTime.getTime() > Date.now()) -} - -class Talk { - constructor(srcObj){ - Object.assign(this, srcObj) - } - - get startTime(){ - return new Date(this.slot.start) - } - - get endTime(){ - return new Date(this.slot.end) - } - - get displayUrl(){ - return new URL(`${encodeURIComponent(EVENT_ID)}/talk/${encodeURIComponent(this.code)}`, PRETALX_URL).toString() - } - - get isActive(){ - return this.startTime.getTime() <= Date.now() && this.endTime.getTime() >= Date.now() - } -} - -// Lower level tools - -const requestAllRooms = makePaginatedGenerator(new URL(`events/${encodeURIComponent(EVENT_ID)}/rooms/`, API_ROOT)) -const requestAllTalks = makePaginatedGenerator(new URL(`events/${encodeURIComponent(EVENT_ID)}/talks/`, API_ROOT)) - -function makePaginatedGenerator(baseUrl){ - return async function*(){ - let buffer = [] - let next_url = baseUrl - - while(buffer.length > 0 || next_url != null){ - let item = buffer.shift() - if(item){ - yield item - } else { - let res = await fetch(next_url) - if(!res.ok){ - throw new Error(`Server responded with error ${res.status} ${res.statusText}`) - } - let response = await res.json() - next_url = response.next - buffer.push(...response.results) - } - } - } -} \ No newline at end of file diff --git a/package-prod.sh b/package-prod.sh index 1ac3d2d..2cee094 100755 --- a/package-prod.sh +++ b/package-prod.sh @@ -10,7 +10,6 @@ echo "Copie des fichiers source" cp -v index.html "$OUT" cp -v logo.png "$OUT" -cp -v manifest.json "$OUT" cp -v -r ./js "$OUT" cp -v -r ./css "$OUT" cp -v -r ./icons "$OUT"