vizwall_screensaver/frontend-dev/vwss-frontend/frontend.js

287 lines
8.8 KiB
JavaScript

function populateTable(resourceUPN, events, container) {
events.sort((a, b) => new Date(a.start.dateTime) - new Date(b.start.dateTime));
// Create a wrapper for the resource and its events
const resourceWrapper = document.createElement('div');
resourceWrapper.className = 'resource-wrapper';
// Create a row for the resource title
const titleRow = document.createElement('div');
titleRow.className = 'title-row';
switch (resourceUPN.split("@")[0]) {
case "s-er-1431-00":
titleRow.innerHTML = 'ER 1431-00 Open Space';
break;
case "s-er-1431-03":
titleRow.innerHTML = 'ER 1431-03 Visualization Lab';
break;
case "s-er-1431-33":
titleRow.innerHTML = 'ER 1431-33 Ideation Room';
break;
case "s-er-1431-37":
titleRow.innerHTML = 'ER 1431-37 Multipurpose Room';
break;
case "s-er-1431-39":
titleRow.innerHTML = 'ER 1431-39 Conference Room';
break;
}
resourceWrapper.appendChild(titleRow);
// Create a grid for events
const eventGrid = document.createElement('div');
eventGrid.className = 'event-row';
events.forEach((event, index) => {
if (index < 3) {
const eventCell = document.createElement('div');
eventCell.className = 'flex-cell';
const title = event.subject.length > 18 ? event.subject.substring(0, 18) + "..." : event.subject;
const organizer = !event.location.displayName || event.organizer.emailAddress.address === resourceUPN ? "Walk-Up" : event.organizer.emailAddress.name;
const startTime = formatTime(event.start.dateTime + "Z");
const endTime = formatTime(event.end.dateTime + "Z");
const endTimeCheck = new Date(event.end.dateTime);
const currentTime = new Date();
if (endTimeCheck > currentTime) {
const titleDiv = document.createElement('div');
titleDiv.textContent = title;
const organizerDiv = document.createElement('div');
organizerDiv.textContent = organizer;
organizerDiv.className = 'organizer';
const timeDiv = document.createElement('div');
timeDiv.className = 'time-range';
timeDiv.innerHTML = `${startTime} - ${endTime}`;
eventCell.appendChild(titleDiv);
eventCell.appendChild(organizerDiv);
eventCell.appendChild(timeDiv);
eventGrid.appendChild(eventCell);
}
}
});
if (eventGrid.children.length === 0) {
const noEventsMessage = document.createElement('div');
noEventsMessage.className = 'flex-cell';
noEventsMessage.textContent = 'No upcoming meetings at this time';
eventGrid.appendChild(noEventsMessage);
}
resourceWrapper.appendChild(eventGrid);
container.appendChild(resourceWrapper);
}
function formatTime(date) {
const etDate = new Date(date);
const hours = etDate.getHours();
const minutes = etDate.getMinutes().toString().padStart(2, '0');
return `<span class="time">${hours}</span><span class="separator">:</span><span class="time">${minutes}</span>`;
}
async function fetchAllEvents() {
console.log("fetching events");
const response = await fetch('/api/events');
const allEvents = await response.json();
const resourcesContainer = document.getElementById('resources-container');
resourcesContainer.innerHTML = '';
const keys = Object.keys(allEvents);
keys.forEach((key) => {
populateTable(key, allEvents[key], resourcesContainer);
});
}
function updateTime(showSeparator) {
let timeString = formatTime(new Date());
if (!showSeparator) {
timeString = timeString.replace(':', ' ');
}
document.getElementById('time').innerHTML = timeString;
}
function updateFontSize(elementId) {
const element = document.getElementById(elementId);
const textLength = element.textContent.length;
if (textLength <= 83) {
element.style.fontSize = '5em';
} else if (textLength <= 166) {
element.style.fontSize = '4em';
} else {
element.style.fontSize = '3em';
}
}
// Function to fetch and display a quote
async function fetchAndDisplayQuote() {
try {
// Update the endpoint if you created a new one
const response = await fetch('/api/quotes'); // or '/api/quotes/random'
if (response.ok) {
const randomQuote = await response.json();
// Validate the received quote
if (randomQuote && randomQuote.quote && randomQuote.author) {
document.getElementById('quote').innerHTML = `<i>${randomQuote.quote}</i>`;
updateFontSize('quote');
document.getElementById('author').innerHTML = `${randomQuote.author}`;
} else {
throw new Error('Invalid quote data received');
}
} else {
console.error('Server responded with status:', response.status);
displayDefaultQuote();
}
} catch (error) {
console.error('An error occurred:', error);
displayDefaultQuote();
}
}
// Helper function to display a default quote
function displayDefaultQuote() {
document.getElementById('quote').innerHTML = `<i>Wishing you an utmost wonderful day!</i>`;
updateFontSize('quote');
document.getElementById('author').innerHTML = `Next-Generation Cities Institute`;
}
// Fetch Current Weather
async function fetchWeather() {
const response = await fetch('/api/weather');
const data = await response.json();
if (data.cod === 200) {
const temperature = data.main.temp;
const description = data.weather[0].description;
const iconCode = data.weather[0].icon;
const iconUrl = `https://openweathermap.org/img/wn/${iconCode}.png`
document.getElementById("weather-icon-container").innerHTML = `<img id="weather-icon" alt="Weather Icon" src="${iconUrl}">`;
document.getElementById("temperature").innerHTML = `${temperature}°`;
document.getElementById("description").innerHTML = `${description}`;
} else {
document.getElementById("weather").innerText = 'Weather data unavailable';
}
}
// Display Current Time
function displayTime() {
const now = new Date();
const timeHtml = formatTime(now);
document.getElementById("time").innerHTML = timeHtml;
setTimeout(displayTime, 60000);
}
// Slideshow
async function fetchSlideshowImages() {
try {
const response = await fetch('/api/slideshow');
if (!response.ok) {
throw new Error('Failed to fetch slideshow images');
}
const images = await response.json();
updateSlideshow(images);
} catch (error) {
console.error('Error fetching slideshow images:', error);
}
}
function createSlideshowElement(src) {
const img = document.createElement('img');
// img.src = src;
img.src = `${src}`;
img.className = 'slideshow-img';
img.style.width = '100%';
img.style.maxHeight = '100vh';
img.style.objectFit = 'cover';
const filename = src.split('/').pop().split('.')[0]; // Extracts filename without extension
// Set the filename as the alt text
img.alt = filename;
// If you also want to set the title attribute
img.title = filename;
return img;
}
let currentIndex = 0;
function updateSlideshow(images) {
if (images.length === 0) {
console.log('No images found for the slideshow.');
return;
}
const slideshowContainer = document.getElementById('slideshow');
slideshowContainer.innerHTML = '';
const imageElement = createSlideshowElement(images[currentIndex]);
slideshowContainer.appendChild(imageElement);
// Wait a little bit before starting the fade-in to ensure it's loaded
setTimeout(() => { imageElement.style.opacity = '1'; }, 100);
// Clean up the previous image after the new one has faded in
setTimeout(() => {
while (slideshowContainer.children.length > 1) {
slideshowContainer.removeChild(slideshowContainer.firstChild);
}
}, 100);
currentIndex = (currentIndex + 1) % images.length;
setTimeout(() => updateSlideshow(images), 30000); // Change image every 30 seconds
}
const welcomeDiv = document.getElementById('welcome-message');
const logo = document.querySelector('#welcome-message img');
const backgroundColors = ['#00ADEF', '#912338', '#e5a712', '#db0272', '#8cc63e', '#573996'];
const logoColors = ['black', 'white', 'black', 'white', 'black', 'white'];
let colorIndex = 0;
function showWelcomeMessage() {
welcomeDiv.classList.add('visible');
welcomeDiv.style.backgroundColor = backgroundColors[colorIndex];
logo.src = logoColors[colorIndex] === 'white' ? 'ngci-logo-white-wide.svg' : 'ngci-logo-black.png';
colorIndex = (colorIndex + 1) % backgroundColors.length;
}
function hideWelcomeMessage() {
welcomeDiv.classList.remove('visible');
}
setInterval(function() {
showWelcomeMessage();
setTimeout(hideWelcomeMessage, 30000);
}, 600000);
fetchAndDisplayQuote();
setInterval(fetchAndDisplayQuote, 60 * 60 * 1000 * 24);
fetchWeather();
setInterval(fetchWeather, 5 * 60 * 1000);
let showSeparator = true;
updateTime(showSeparator);
setInterval(() => {
updateTime(showSeparator);
showSeparator = !showSeparator;
}, 1000);
fetchSlideshowImages();
fetchAllEvents();
setInterval(fetchAllEvents, 3 * 60 * 1000);