Create CCCHH theme
This commit is contained in:
parent
8394b08524
commit
2d267ba9fe
23 changed files with 629 additions and 1 deletions
59
themes/ccchh/assets/images/logo.svg
Normal file
59
themes/ccchh/assets/images/logo.svg
Normal file
File diff suppressed because one or more lines are too long
After Width: | Height: | Size: 86 KiB |
84
themes/ccchh/assets/js/roomstate.js
Normal file
84
themes/ccchh/assets/js/roomstate.js
Normal file
|
@ -0,0 +1,84 @@
|
|||
import timeDistance, { deLocale } from 'js/util/timeDistance'
|
||||
|
||||
const spaceapiUrl = "https://www.hamburg.ccc.de/dooris/status.json"
|
||||
const interval_ms = 60000
|
||||
|
||||
const classNameOpen = "open"
|
||||
const classNameClosed = "closed"
|
||||
|
||||
|
||||
function updateRoomState(openState, lastChangeTimestamp) {
|
||||
console.debug("SpaceAPI: Setting room " + openState + " since " + lastChangeTimestamp)
|
||||
|
||||
const roomstate = document.querySelector('#roomstate')
|
||||
var statusItem = roomstate.querySelector(".state")
|
||||
var durationItem = roomstate.querySelector(".duration")
|
||||
|
||||
if (openState === null || lastChangeTimestamp === null) {
|
||||
console.warn("SpaceAPI: Room state unknown");
|
||||
statusItem.textContent = "unbekannt"
|
||||
roomstate.classList.remove(classNameOpen)
|
||||
roomstate.classList.remove(classNameClosed)
|
||||
durationItem.textContent = "(seit unbekannt)"
|
||||
|
||||
} else {
|
||||
if (openState) {
|
||||
statusItem.textContent = "offen"
|
||||
roomstate.classList.remove(classNameClosed)
|
||||
roomstate.classList.add(classNameOpen)
|
||||
|
||||
} else {
|
||||
statusItem.textContent = "geschlossen"
|
||||
roomstate.classList.remove(classNameOpen)
|
||||
roomstate.classList.add(classNameClosed)
|
||||
|
||||
}
|
||||
|
||||
const changeDate = new Date(lastChangeTimestamp * 1000)
|
||||
const changeText = timeDistance(deLocale).inWords(changeDate)
|
||||
|
||||
durationItem.textContent = "(" + changeText + ")"
|
||||
}
|
||||
}
|
||||
|
||||
function parseResponse(apiJson) {
|
||||
console.debug('SpaceAPI got:', apiJson)
|
||||
|
||||
if (typeof apiJson.api === "undefined") {
|
||||
console.error("SpaceAPI JSON invalid: 'api' item not present")
|
||||
return [null, null]
|
||||
}
|
||||
if (typeof apiJson.state === "undefined") {
|
||||
console.error("SpaceAPI JSON invalid: 'state' item not present")
|
||||
return [null, null]
|
||||
}
|
||||
if (typeof apiJson.state.open === "undefined") {
|
||||
console.error("SpaceAPI JSON invalid: 'state.open' item not present")
|
||||
return [null, null]
|
||||
}
|
||||
|
||||
console.debug('SpaceAPI state:', apiJson.state)
|
||||
var openState = (apiJson.state.open == true)
|
||||
var lastchange = null
|
||||
|
||||
if (apiJson.state.lastchange !== "undefined") {
|
||||
lastchange = apiJson.state.lastchange
|
||||
}
|
||||
|
||||
return [openState, lastchange]
|
||||
}
|
||||
|
||||
function update() {
|
||||
fetch(spaceapiUrl)
|
||||
.then(resp => resp.json())
|
||||
.then(function (data) {
|
||||
var state = parseResponse(data)
|
||||
updateRoomState(state[0], state[1])
|
||||
})
|
||||
.catch(err => { throw err });
|
||||
}
|
||||
|
||||
window.onload = function () {
|
||||
update()
|
||||
window.setTimeout(update, interval_ms)
|
||||
}
|
104
themes/ccchh/assets/js/util/timeDistance.js
Normal file
104
themes/ccchh/assets/js/util/timeDistance.js
Normal file
|
@ -0,0 +1,104 @@
|
|||
export default ((locale) => {
|
||||
const self = {}
|
||||
|
||||
if (locale === undefined) {
|
||||
self.locales = {
|
||||
pastPrefix: '',
|
||||
pastSufix: 'ago',
|
||||
|
||||
futurePrefix: 'in',
|
||||
futureSufix: '',
|
||||
|
||||
seconds: '%p less than a minutei %s',
|
||||
minute: '%p about a minute %s',
|
||||
minutes: '%p %d minutes %s',
|
||||
hour: '%p about an hour %s',
|
||||
hours: '%p about %d%r hours %s',
|
||||
day: '%p a day %s',
|
||||
days: '%p %d%r days %s',
|
||||
month: '%p about a month %s',
|
||||
months: '%p %d%r months %s',
|
||||
year: '%p about a year %s',
|
||||
years: '%p %d%r years %s'
|
||||
}
|
||||
} else {
|
||||
self.locales = locale
|
||||
}
|
||||
|
||||
self.inWords = (timeDistance, start) => {
|
||||
if (start === undefined) {
|
||||
start = new Date()
|
||||
} else {
|
||||
start = start instanceof(Date) ? start : parseInt(start)
|
||||
}
|
||||
timeDistance = timeDistance instanceof(Date) ? timeDistance : parseInt(timeDistance)
|
||||
const prefix = timeDistance < new Date() ? self.locales.pastPrefix : self.locales.futurePrefix
|
||||
const sufix = timeDistance < new Date() ? self.locales.pastSufix : self.locales.futureSufix
|
||||
|
||||
let seconds = Math.abs(Math.floor((start - timeDistance) / 1000)),
|
||||
interval = 0,
|
||||
rest = 0,
|
||||
intervals = {
|
||||
year: seconds / 31536000,
|
||||
month: seconds / 2592000,
|
||||
day: seconds / 86400,
|
||||
hour: seconds / 3600,
|
||||
minute: seconds / 60
|
||||
}
|
||||
|
||||
let distance = self.locales.seconds
|
||||
let key
|
||||
|
||||
for (key in intervals) {
|
||||
interval = Math.floor(intervals[key])
|
||||
rest = intervals[key] - interval
|
||||
|
||||
if (interval >= 1) {
|
||||
distance = self.locales[key + 's']
|
||||
break
|
||||
} else if (interval === 1) {
|
||||
distance = self.locales[key]
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if (rest > 0.5) {
|
||||
distance = distance.replace(/%r/, "½")
|
||||
} else if (rest > 0.25) {
|
||||
distance = distance.replace(/%r/, "¼")
|
||||
} else {
|
||||
if (interval === 1) {
|
||||
distance = self.locales[key]
|
||||
}
|
||||
distance = distance.replace(/\s*%r/, "")
|
||||
}
|
||||
|
||||
distance = distance.replace(/%d/i, interval)
|
||||
distance = distance.replace(/%p/i, prefix)
|
||||
distance = distance.replace(/%s/i, sufix)
|
||||
|
||||
return distance.trim()
|
||||
}
|
||||
|
||||
return self
|
||||
})
|
||||
|
||||
export const deLocale = {
|
||||
pastPrefix: 'seit',
|
||||
pastSufix: '',
|
||||
|
||||
futurePrefix: 'in',
|
||||
futureSufix: '',
|
||||
|
||||
seconds: '%p %d Sekunden',
|
||||
minute: '%p einer Minute',
|
||||
minutes: '%p %d Minuten',
|
||||
hour: '%p einer Stunde',
|
||||
hours: '%p %d%r Stunden',
|
||||
day: '%p einem Tag',
|
||||
days: '%p %d%r Tagen',
|
||||
month: '%p einem Monat',
|
||||
months: '%p %d%r Monaten',
|
||||
year: '%p einem Jahr',
|
||||
years: '%p %d%r Jahren'
|
||||
}
|
78
themes/ccchh/assets/sass/main.scss
Normal file
78
themes/ccchh/assets/sass/main.scss
Normal file
|
@ -0,0 +1,78 @@
|
|||
$roomstate_color_unknown: #dda218;
|
||||
$roomstate_color_open: var(--ins-color);
|
||||
$roomstate_color_closed: var(--del-color);
|
||||
|
||||
|
||||
// Room State in Menu
|
||||
#roomstate {
|
||||
font-size: 0.9em;
|
||||
line-height: 1.0em;
|
||||
max-width: 8em;
|
||||
padding: 5px;
|
||||
|
||||
color: $roomstate_color_unknown;
|
||||
|
||||
&.open {
|
||||
color: $roomstate_color_open;
|
||||
}
|
||||
|
||||
&.closed {
|
||||
color: $roomstate_color_closed;
|
||||
}
|
||||
|
||||
span.duration {
|
||||
font-size: 0.7em;
|
||||
}
|
||||
}
|
||||
|
||||
// CCCHH Icon in Menu
|
||||
@media only screen and (prefers-color-scheme: light) {
|
||||
.invert-on-light {
|
||||
filter: invert(1);
|
||||
}
|
||||
}
|
||||
|
||||
// Home page Announcements
|
||||
.announcement {
|
||||
border-radius: var(--border-radius);
|
||||
background: var(--code-background-color);
|
||||
padding: 10px 15px;
|
||||
|
||||
margin-bottom: var(--typography-spacing-vertical);
|
||||
|
||||
p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@media only screen and (prefers-color-scheme: dark) {
|
||||
.announcement {
|
||||
background: var(--code-background-color);
|
||||
}
|
||||
}
|
||||
|
||||
// Home Friends&Family Gallery
|
||||
.flex-grid {
|
||||
display: flex;
|
||||
flex-wrap: wrap;
|
||||
justify-content: center;
|
||||
|
||||
div {
|
||||
width: 250px;
|
||||
|
||||
// 2*250px + 2*var(--spacing) + 1px
|
||||
@media only screen and (max-width: 533px) {
|
||||
width: 150px;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.img-link {
|
||||
a {
|
||||
img {
|
||||
display: block;
|
||||
padding: var(--grid-spacing-horizontal);
|
||||
margin: 0 auto;
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue