Raggiunto primo stato presentabile
This commit is contained in:
@@ -0,0 +1,13 @@
|
||||
export function createClock(elClock) {
|
||||
const renderClock = () => {
|
||||
const pad = s => (s + '').padStart(2, '0')
|
||||
const now = new Date(),
|
||||
hours = now.getHours(),
|
||||
minutes = now.getMinutes(),
|
||||
seconds = now.getSeconds()
|
||||
elClock.innerText = `${pad(hours)}:${pad(minutes)}:${pad(seconds)}`
|
||||
}
|
||||
|
||||
setInterval(renderClock, 1000)
|
||||
renderClock()
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
function renderGridLinesCanvas($canvas, [rows, cols]) {
|
||||
$canvas.width = $canvas.offsetWidth * 2
|
||||
$canvas.height = $canvas.offsetHeight * 2
|
||||
|
||||
const g = $canvas.getContext('2d')
|
||||
const width = $canvas.width / 2
|
||||
const height = $canvas.height / 2
|
||||
g.scale(2, 2)
|
||||
|
||||
g.strokeStyle = '#ddd'
|
||||
g.lineWidth = 2
|
||||
g.setLineDash([4, 4])
|
||||
|
||||
for (let i = 0; i < cols + 1; i++) {
|
||||
const x = 2 + ((width - 4) / cols) * i
|
||||
g.beginPath()
|
||||
g.moveTo(x, 0)
|
||||
g.lineTo(x, height)
|
||||
g.stroke()
|
||||
}
|
||||
|
||||
for (let j = 0; j < rows + 1; j++) {
|
||||
const y = 2 + ((height - 4) / rows) * j
|
||||
g.beginPath()
|
||||
g.moveTo(0, y)
|
||||
g.lineTo(width, y)
|
||||
g.stroke()
|
||||
}
|
||||
}
|
||||
|
||||
export function createGridLineCanvas($roomGrid) {
|
||||
const $canvas = document.createElement('canvas')
|
||||
$roomGrid.append($canvas)
|
||||
|
||||
$canvas.style.position = 'absolute'
|
||||
$canvas.style.inset = '0'
|
||||
$canvas.style.width = '100%'
|
||||
$canvas.style.height = '100%'
|
||||
$canvas.style.zIndex = '-1'
|
||||
|
||||
const [rows, cols] = getComputedStyle($roomGrid)
|
||||
.getPropertyValue('aspect-ratio')
|
||||
.split('/')
|
||||
.reverse()
|
||||
.map(s => parseInt(s))
|
||||
|
||||
const render = () => renderGridLinesCanvas($canvas, [rows, cols])
|
||||
|
||||
window.addEventListener('resize', render)
|
||||
render()
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
import { createRoomEventStream, Database, getLoggedUser } from '../index.js'
|
||||
import { addTooltipElementListener, resetTooltip, setTooltipText } from './tooltip.js'
|
||||
|
||||
async function renderWidget(elSeatMap, seats) {
|
||||
const user = await getLoggedUser()
|
||||
|
||||
Object.values(seats).forEach(seat => {
|
||||
const { id, occupiedBy } = seat
|
||||
|
||||
elSeatMap[id].classList.remove('libero')
|
||||
elSeatMap[id].classList.remove('occupato')
|
||||
elSeatMap[id].classList.remove('mio')
|
||||
|
||||
if (occupiedBy.length > 0) {
|
||||
const [seatOccupant] = occupiedBy
|
||||
|
||||
if (user && seatOccupant === user.id) {
|
||||
elSeatMap[id].classList.add('mio')
|
||||
} else {
|
||||
elSeatMap[id].classList.add('occupato')
|
||||
}
|
||||
} else {
|
||||
elSeatMap[id].classList.add('libero')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
export async function createSeatWidget($roomGrid, roomId) {
|
||||
const user = await getLoggedUser()
|
||||
|
||||
const elSeats = [...$roomGrid.querySelectorAll('[data-seat-id]')]
|
||||
const elSeatMap = {}
|
||||
|
||||
elSeats.forEach($seat => {
|
||||
const seatId = $seat.dataset.seatId
|
||||
$seat.dataset.index = seatId.split('-')[2]
|
||||
|
||||
elSeatMap[seatId] = $seat
|
||||
})
|
||||
|
||||
// Full widget state
|
||||
let seats = await Database.getSeats(roomId)
|
||||
|
||||
// First render
|
||||
renderWidget(elSeatMap, seats)
|
||||
|
||||
// Setup event listeners
|
||||
Object.entries(elSeatMap).forEach(([seatId, $seat]) => {
|
||||
addTooltipElementListener($hovering => {
|
||||
if ($seat.contains($hovering)) {
|
||||
const occupiedBy = seats[seatId].occupiedBy
|
||||
|
||||
if (occupiedBy.length > 0) {
|
||||
if (user && occupiedBy[0] === user.id) {
|
||||
setTooltipText(`Questo è il tuo posto!`)
|
||||
} else {
|
||||
setTooltipText(`Occupato da @${occupiedBy[0]}`)
|
||||
}
|
||||
} else {
|
||||
setTooltipText('Libero')
|
||||
}
|
||||
|
||||
return true
|
||||
} else {
|
||||
resetTooltip()
|
||||
}
|
||||
})
|
||||
|
||||
$seat.addEventListener('click', () => {
|
||||
if (!user) {
|
||||
location.href = '/login.html'
|
||||
return
|
||||
}
|
||||
|
||||
const occupiedBy = seats[seatId].occupiedBy
|
||||
|
||||
if (occupiedBy.length === 0) {
|
||||
const confirmResponse = confirm('Occupare il posto?')
|
||||
if (confirmResponse) {
|
||||
Database.occupySeat(seatId)
|
||||
}
|
||||
} else if (occupiedBy.length === 1 && occupiedBy[0] === user.id) {
|
||||
const answer = confirm('Lasciare veramente il posto?')
|
||||
if (answer) {
|
||||
Database.leaveSeat(seatId)
|
||||
}
|
||||
} else {
|
||||
alert('Posto già occupato!')
|
||||
}
|
||||
})
|
||||
})
|
||||
|
||||
// Refresh room diagram on message from server
|
||||
createRoomEventStream(roomId).addEventListener('message', async e => {
|
||||
console.log(e.data)
|
||||
|
||||
seats = await Database.getSeats(roomId)
|
||||
renderWidget(elSeatMap, seats)
|
||||
})
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
const LISTENERS = []
|
||||
const $tooltip = document.querySelector('#tooltip')
|
||||
|
||||
export function attachTooltip() {
|
||||
document.body.addEventListener('mousemove', e => {
|
||||
$tooltip.style.setProperty('--x', 10 + e.pageX + 'px')
|
||||
$tooltip.style.setProperty('--y', 10 + e.pageY + 'px')
|
||||
|
||||
LISTENERS.find(listener => listener(e.target))
|
||||
})
|
||||
}
|
||||
|
||||
export function addTooltipElementListener(callbackFn) {
|
||||
LISTENERS.push(callbackFn)
|
||||
}
|
||||
|
||||
export function setTooltip(mountFn) {
|
||||
$tooltip.classList.remove('hidden')
|
||||
mountFn($tooltip)
|
||||
}
|
||||
|
||||
export function setTooltipText(text) {
|
||||
$tooltip.classList.remove('hidden')
|
||||
setTooltip($t => {
|
||||
$t.innerText = text
|
||||
})
|
||||
}
|
||||
|
||||
export function resetTooltip() {
|
||||
$tooltip.classList.add('hidden')
|
||||
$tooltip.innerHTML = ''
|
||||
}
|
||||
Reference in New Issue
Block a user