Add availability indicators on people tiles and share fetch service
New Availability module decorates each people-tile with a vertical status bar on the avatar and a dot+timestamp under the status text, showing ZeitConsens loggedIn state per extension. Status and Availability now share a single AvailabilityService that polls /availability every 30s, halving the API load. Avatars are enlarged to 57px and vertically centered to fit the new layout.
This commit is contained in:
@@ -0,0 +1,83 @@
|
||||
import './availability.css'
|
||||
import { AvailabilityInfo } from './availability-info'
|
||||
import { AvailabilityService } from './availability-service'
|
||||
|
||||
declare function waitForKeyElements(selectorOrFunction: any, callback: any, waitOnce: boolean): any;
|
||||
|
||||
export class Availability {
|
||||
private _service: AvailabilityService
|
||||
private _availabilities: AvailabilityInfo[] = []
|
||||
|
||||
constructor(service: AvailabilityService) {
|
||||
this._service = service
|
||||
}
|
||||
|
||||
public start() {
|
||||
this._service.subscribe((avs) => {
|
||||
this._availabilities = avs
|
||||
this.updateAllIndicators()
|
||||
})
|
||||
waitForKeyElements('people-tile', (element: HTMLElement) => { this.decorateTile(element) }, false)
|
||||
}
|
||||
|
||||
private decorateTile(tile: HTMLElement) {
|
||||
if (tile.querySelector('.tapi-availability')) {
|
||||
return
|
||||
}
|
||||
var extEl = tile.querySelector('span[data-id="extPhone"]') as HTMLElement
|
||||
if (!extEl) {
|
||||
return
|
||||
}
|
||||
var extension = extEl.textContent.trim()
|
||||
|
||||
var indicator = document.createElement('div')
|
||||
indicator.classList.add('tapi-availability')
|
||||
indicator.dataset.tapiExtension = extension
|
||||
tile.appendChild(indicator)
|
||||
this.updateIndicator(indicator)
|
||||
|
||||
var avatarContainer = tile.querySelector('app-avatar .avatar-container') as HTMLElement
|
||||
if (avatarContainer) {
|
||||
var square = document.createElement('i')
|
||||
square.classList.add('tapi-avatar-square')
|
||||
square.dataset.tapiExtension = extension
|
||||
avatarContainer.appendChild(square)
|
||||
this.updateSquare(square)
|
||||
}
|
||||
}
|
||||
|
||||
private updateAllIndicators() {
|
||||
var indicators = document.getElementsByClassName('tapi-availability')
|
||||
for (var i of indicators) {
|
||||
this.updateIndicator(i as HTMLElement)
|
||||
}
|
||||
var squares = document.getElementsByClassName('tapi-avatar-square')
|
||||
for (var s of squares) {
|
||||
this.updateSquare(s as HTMLElement)
|
||||
}
|
||||
}
|
||||
|
||||
private updateIndicator(indicator: HTMLElement) {
|
||||
var extension = indicator.dataset.tapiExtension
|
||||
var entry = this._availabilities.find(a => a.extension === extension)
|
||||
if (!entry) {
|
||||
indicator.innerHTML = ''
|
||||
return
|
||||
}
|
||||
var dotClass = entry.loggedIn ? 'tapi-dot-on' : 'tapi-dot-off'
|
||||
var mockedTime = '13.04. 08:30'
|
||||
indicator.innerHTML = '<span class="tapi-dot ' + dotClass + '"></span><small>' + mockedTime + '</small>'
|
||||
}
|
||||
|
||||
private updateSquare(square: HTMLElement) {
|
||||
var extension = square.dataset.tapiExtension
|
||||
var entry = this._availabilities.find(a => a.extension === extension)
|
||||
square.classList.remove('tapi-square-on', 'tapi-square-off')
|
||||
if (!entry) {
|
||||
square.style.display = 'none'
|
||||
return
|
||||
}
|
||||
square.style.display = ''
|
||||
square.classList.add(entry.loggedIn ? 'tapi-square-on' : 'tapi-square-off')
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user