mirror of
https://github.com/manilarome/the-glorious-startpage.git
synced 2024-11-23 16:13:28 +01:00
dashboard add weather screen gui and backend
This commit is contained in:
parent
90ff2c7150
commit
824bf84b8a
@ -13,6 +13,7 @@
|
||||
@import url('greeter-date-message.css');
|
||||
@import url('search-engine-settings.css');
|
||||
@import url('theme-engine.css');
|
||||
@import url('weather-screen.css');
|
||||
|
||||
:root {
|
||||
/* Colors */
|
||||
|
247
css/weather-screen.css
Normal file
247
css/weather-screen.css
Normal file
@ -0,0 +1,247 @@
|
||||
#weatherScreen {
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
margin: 0;
|
||||
background: var(--panel-bg);
|
||||
/*z-index: 0;*/
|
||||
z-index: 3;
|
||||
overflow: hidden;
|
||||
backdrop-filter: blur(var(--blur-strength));
|
||||
|
||||
display:flex;
|
||||
justify-content:center;
|
||||
align-items:center;
|
||||
|
||||
padding-top: 6vh;
|
||||
padding-bottom: 6vh;
|
||||
padding-left: 12vw;
|
||||
padding-right: 12vw;
|
||||
|
||||
/*Dont increase the geometry by using padding*/
|
||||
-webkit-box-sizing: border-box;
|
||||
-moz-box-sizing: border-box;
|
||||
box-sizing: border-box;
|
||||
|
||||
/*Disable user touch/select on text elements*/
|
||||
-webkit-touch-callout: none;
|
||||
-webkit-user-select: none;
|
||||
-khtml-user-select: none;
|
||||
-moz-user-select: none;
|
||||
-ms-user-select: none;
|
||||
user-select: none;
|
||||
|
||||
opacity: 0;
|
||||
transform: scale(0);
|
||||
transition: transform var(--transition-speed),
|
||||
opacity var(--transition-speed),
|
||||
z-index var(--transition-speed);
|
||||
}
|
||||
|
||||
@media screen and (max-width: 580px) {
|
||||
#weatherScreen {
|
||||
padding-top: 6vh;
|
||||
padding-bottom: 0vh;
|
||||
padding-left: 18vw;
|
||||
padding-right: 18vw;
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-height: 799px) {
|
||||
#weatherScreen {
|
||||
padding-top: 40px;
|
||||
}
|
||||
}
|
||||
|
||||
.showWeatherScreen{
|
||||
transform: scale(1) !important;
|
||||
opacity: 1 !important;
|
||||
z-index: 3 !important;
|
||||
}
|
||||
|
||||
#weatherScreenContainer {
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
/*Align vertically center*/
|
||||
margin: 0;
|
||||
position: absolute;
|
||||
top: 50%;
|
||||
-ms-transform: translateY(-50%);
|
||||
transform: translateY(-50%);
|
||||
}
|
||||
|
||||
#weatherTodayIcon {
|
||||
background: url('../assets/weather-icons/weather-error.svg');
|
||||
background-size: cover;
|
||||
width: 128px;
|
||||
height: 128px;
|
||||
|
||||
position: relative;
|
||||
left: 50%;
|
||||
-ms-transform: translateX(-50%);
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
#weatherTodayLocation {
|
||||
color: var(--base-color);
|
||||
font-family: roboto;
|
||||
font-size: 16pt;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#weatherTodayDescription {
|
||||
color: var(--base-color);
|
||||
font-family: roboto-bold;
|
||||
font-size: 20pt;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
#weatherHourDataTodayContainer,
|
||||
.weatherDataHour {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
|
||||
margin-left: 5px;
|
||||
margin-right: 5px;
|
||||
}
|
||||
|
||||
.hourDataIcon {
|
||||
height: 22px;
|
||||
width: 22px;
|
||||
background-size: cover;
|
||||
}
|
||||
|
||||
.hourDataLabel {
|
||||
color: var(--base-color);
|
||||
font-family: roboto;
|
||||
font-size: 14pt;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#sunriseHourDataIcon {
|
||||
background: url("../assets/weather-icons/sunrise.svg");
|
||||
background-size: cover;
|
||||
|
||||
}
|
||||
|
||||
#sunsetHourDataIcon {
|
||||
background: url("../assets/weather-icons/sunset.svg");
|
||||
background-size: cover;
|
||||
margin-left: 5px
|
||||
}
|
||||
|
||||
#updateHourDataIcon {
|
||||
background: url("../assets/weather-icons/refresh.svg");
|
||||
background-size: cover;
|
||||
margin-left: 5px
|
||||
}
|
||||
|
||||
|
||||
.weatherForecast {
|
||||
display: flex;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
|
||||
/*Forecast Container*/
|
||||
.weatherForecastDay {
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
|
||||
float: left;
|
||||
clear: both;
|
||||
margin-left: 10px;
|
||||
}
|
||||
|
||||
/*Add fixed geometry to weatherForecastDay children*/
|
||||
.weatherForecastDay > div {
|
||||
width: 100px;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.weatherForecastDayIconContainer {
|
||||
clear:both;
|
||||
}
|
||||
|
||||
.weatherForecastDayIcon {
|
||||
background: url('../assets/weather-icons/weather-error.svg');
|
||||
background-size: cover;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
|
||||
position: relative;
|
||||
left: 50%;
|
||||
-ms-transform: translateX(-50%);
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
/*Center*/
|
||||
.weatherForecastDayDetails {
|
||||
|
||||
clear:both;
|
||||
}
|
||||
|
||||
.weatherForecastDayDetailsTemperature,
|
||||
.weatherForecastDayDetailsDescription,
|
||||
.weatherForecastDayDate {
|
||||
color: var(--base-color);
|
||||
font-family: roboto;
|
||||
font-size: 11pt;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
/*Right side*/
|
||||
.weatherForecastDayDate {
|
||||
clear:both;
|
||||
}
|
||||
|
||||
@media screen and (max-width: 580px) {
|
||||
|
||||
.weatherForecast {
|
||||
display: inline-block;
|
||||
flex-direction: row;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
/*Forecast Container*/
|
||||
.weatherForecastDay {
|
||||
text-align: center;
|
||||
margin-top: 20px;
|
||||
|
||||
float: none;
|
||||
clear: none;
|
||||
margin-left : 0px;
|
||||
}
|
||||
|
||||
/*Add fixed geometry to weatherForecastDay children*/
|
||||
.weatherForecastDay > div {
|
||||
width: 75px;
|
||||
height: 50px;
|
||||
}
|
||||
|
||||
.weatherForecastDayIconContainer {
|
||||
float: left;
|
||||
clear: none;
|
||||
}
|
||||
|
||||
/*Center*/
|
||||
.weatherForecastDayDetails {
|
||||
display: inline-block;
|
||||
margin: 0 auto;
|
||||
clear: none;
|
||||
}
|
||||
|
||||
/*Right side*/
|
||||
.weatherForecastDayDate {
|
||||
float: right;
|
||||
clear: none;
|
||||
}
|
||||
|
||||
}
|
41
index.html
41
index.html
@ -81,8 +81,6 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
<!-- Theme engine -->
|
||||
<div class="themeEngine">
|
||||
<div id="themeEnginePadding">
|
||||
@ -128,6 +126,44 @@
|
||||
<div class="dashboardOverlay" id="dashboardOverlay"></div>
|
||||
|
||||
|
||||
|
||||
|
||||
<!-- Weather screen -->
|
||||
<div id="weatherScreen">
|
||||
<div id="weatherScreenContainer">
|
||||
<div id="weatherTodayIcon"></div>
|
||||
<div id="weatherTodayLocation">
|
||||
Earth, Milky Way
|
||||
</div>
|
||||
<div id="weatherTodayDescription">
|
||||
dust & clouds, -1000°C
|
||||
</div>
|
||||
<div id="weatherHourDataTodayContainer">
|
||||
<div class="weatherDataHour" id="weatherTodaySunrise">
|
||||
<div class="hourDataIcon" id="sunriseHourDataIcon"></div>
|
||||
<div class="hourDataLabel" id="sunriseTodayHour">00:00</div>
|
||||
</div>
|
||||
<div class="weatherDataHour" id="weatherTodaySunset">
|
||||
<div class="hourDataIcon" id="sunsetHourDataIcon"></div>
|
||||
<div class="hourDataLabel" id="sunsetTodayHour">00:00</div>
|
||||
</div>
|
||||
<div class="weatherDataHour" id="weatherTodayUpdate">
|
||||
<div class="hourDataIcon" id="updateHourDataIcon"></div>
|
||||
<div class="hourDataLabel" id="updateTodayHour">00:00</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="weatherForecast" id="forecastContainer">
|
||||
|
||||
<!-- Javascript will generate a list here -->
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<script src="js/body-background-set.js"></script>
|
||||
<script src="js/clock.js"></script>
|
||||
<script src="js/sites-list.js"></script>
|
||||
@ -139,5 +175,6 @@
|
||||
<script src="js/search-engine-settings.js"></script>
|
||||
<script src="js/search-query-send.js"></script>
|
||||
<script src="js/theme-engine.js"></script>
|
||||
<script src="js/weather-screen.js"></script>
|
||||
</body>
|
||||
</html>
|
@ -79,7 +79,8 @@ const populateDock = () => {
|
||||
'Weather',
|
||||
'weather',
|
||||
() => {
|
||||
alert('toggle weather creen');
|
||||
// Toggle weather screen
|
||||
toggleWeatherScreen();
|
||||
}
|
||||
);
|
||||
|
||||
|
259
js/weather-screen.js
Normal file
259
js/weather-screen.js
Normal file
@ -0,0 +1,259 @@
|
||||
var weatherScreen = document.getElementById("weatherScreen");
|
||||
|
||||
let weatherScreenVisibility = false;
|
||||
|
||||
var weatherIcon = document.getElementById("weatherTodayIcon");
|
||||
var weatherLocation = document.getElementById("weatherTodayLocation");
|
||||
var weatherDescription = document.getElementById("weatherTodayDescription");
|
||||
|
||||
var sunriseHour = document.getElementById("sunriseTodayHour");
|
||||
var sunsetHour = document.getElementById("sunsetTodayHour");
|
||||
var updateHour = document.getElementById("updateTodayHour")
|
||||
|
||||
var weatherDockImageButton = document.getElementById("buttonImageWeather");
|
||||
var forecastContainer = document.getElementById("forecastContainer");
|
||||
|
||||
const formatUnixTime = (unix) => {
|
||||
var date = new Date(unix*1000);
|
||||
var hour = date.getHours();
|
||||
var minutes = "0" + date.getMinutes();
|
||||
var formattedTime = hour + ':' + minutes.substr(-2);
|
||||
return formattedTime;
|
||||
}
|
||||
|
||||
const getWeatherIcon = (code) => {
|
||||
var icon_tbl = {
|
||||
'01d': 'sun_icon.svg',
|
||||
'01n': 'moon_icon.svg',
|
||||
'02d': 'dfew_clouds.svg',
|
||||
'02n': 'nfew_clouds.svg',
|
||||
'03d': 'dscattered_clouds.svg',
|
||||
'03n': 'nscattered_clouds.svg',
|
||||
'04d': 'dbroken_clouds.svg',
|
||||
'04n': 'nbroken_clouds.svg',
|
||||
'09d': 'dshower_rain.svg',
|
||||
'09n': 'nshower_rain.svg',
|
||||
'10d': 'd_rain.svg',
|
||||
'10n': 'n_rain.svg',
|
||||
'11d': 'dthunderstorm.svg',
|
||||
'11n': 'nthunderstorm.svg',
|
||||
'13d': 'snow.svg',
|
||||
'13n': 'snow.svg',
|
||||
'50d': 'dmist.svg',
|
||||
'50n': 'nmist.svg'
|
||||
};
|
||||
|
||||
return icon_tbl[code];
|
||||
}
|
||||
|
||||
const updateWeatherDockButton = (icon) => {
|
||||
weatherDockImageButton.style.background = "url('assets/weather-icons/" + icon + "')";
|
||||
weatherDockImageButton.style.backgroundSize = "cover";
|
||||
}
|
||||
|
||||
const setWeatherValue = (loc, desc, icon, sunr, suns, updt) => {
|
||||
|
||||
var temp_symbol = (units === "metric") ? "°C" : "°F";
|
||||
|
||||
weatherLocation.innerHTML = loc;
|
||||
weatherDescription.innerHTML = desc + temp_symbol;
|
||||
|
||||
weatherIcon.style.background = "url('assets/weather-icons/" + icon + "')";
|
||||
weatherIcon.style.backgroundSize = "cover";
|
||||
|
||||
sunriseHour.innerHTML = sunr;
|
||||
sunsetHour.innerHTML = suns;
|
||||
updateHour.innerHTML = updt;
|
||||
|
||||
// Update weather button on dock
|
||||
updateWeatherDockButton(icon);
|
||||
}
|
||||
|
||||
const createForecastBody = (fIcon, forecastTemp, foreDescription, fHour, fDate) => {
|
||||
|
||||
// Main Div
|
||||
var forecastDay = document.createElement('div');
|
||||
forecastDay.className = 'weatherForecastDay';
|
||||
|
||||
// Icon Container Div
|
||||
var forecastIconContainer = document.createElement('div');
|
||||
forecastIconContainer.className = 'weatherForecastDayIconContainer';
|
||||
|
||||
// Icon Div
|
||||
var forecastIcon = document.createElement('div');
|
||||
forecastIcon.className = 'weatherForecastDayIcon';
|
||||
forecastIcon.style.background = "url('assets/weather-icons/" + fIcon + "')";
|
||||
forecastIcon.style.backgroundSize = 'cover';
|
||||
|
||||
// Details Div
|
||||
var forecastDetails = document.createElement('div');
|
||||
forecastDetails.className = 'weatherForecastDayDetails';
|
||||
|
||||
var forecastTemperature = document.createElement('div');
|
||||
forecastTemperature.className = 'weatherForecastDayDetailsTemperature';
|
||||
forecastTemperature.innerHTML = forecastTemp;
|
||||
|
||||
var forecastDescription = document.createElement('div');
|
||||
forecastDescription.className = 'weatherForecastDayDetailsDescription';
|
||||
forecastDescription.innerHTML = foreDescription;
|
||||
|
||||
// Append details to div container
|
||||
forecastDetails.appendChild(forecastTemperature);
|
||||
forecastDetails.appendChild(forecastDescription);
|
||||
|
||||
// Date Div
|
||||
var forecastDayDate = document.createElement('div');
|
||||
forecastDayDate.className = 'weatherForecastDayDate';
|
||||
|
||||
var forecastHour = document.createElement('div');
|
||||
forecastHour.className = 'weatherForecastDayDateHour';
|
||||
forecastHour.innerHTML = fHour;
|
||||
|
||||
var forecastDate = document.createElement('div');
|
||||
forecastDate.className = 'weatherForecastDayDateDate';
|
||||
forecastDate.innerHTML = fDate;
|
||||
|
||||
// Append icon image to div container
|
||||
forecastIconContainer.appendChild(forecastIcon);
|
||||
|
||||
// Append details to div container
|
||||
forecastDayDate.appendChild(forecastHour);
|
||||
forecastDayDate.appendChild(forecastDate);
|
||||
|
||||
// Append to main div
|
||||
forecastDay.appendChild(forecastIconContainer);
|
||||
forecastDay.appendChild(forecastDetails);
|
||||
forecastDay.appendChild(forecastDayDate);
|
||||
|
||||
// Append to the main container
|
||||
forecastContainer.appendChild(forecastDay);
|
||||
}
|
||||
|
||||
const setErrValue = () => {
|
||||
var wLoc = "Earth, Milky Way";
|
||||
var wDesc = "dust & clouds, -1000";
|
||||
var wIcon = "weather-error.svg";
|
||||
|
||||
var time = "00:00";
|
||||
|
||||
setWeatherValue(wLoc, wDesc, wIcon, time, time, time);
|
||||
}
|
||||
|
||||
// Process weather data
|
||||
const processWeatherData = (data) => {
|
||||
|
||||
var cityName = data.name;
|
||||
var countryName = data.sys.country;
|
||||
var weatherDescription = data.weather[0].description;
|
||||
var weatherIcon = data.weather[0].icon;
|
||||
var weatherTemp = Math.floor(data.main.temp);
|
||||
var sunRise = data.sys.sunrise;
|
||||
var sunSet = data.sys.sunset;
|
||||
var update = data.dt;
|
||||
|
||||
var wLoc = cityName + ", " + countryName;
|
||||
var wDesc = weatherDescription + ", " + weatherTemp;
|
||||
|
||||
// Capitalize first word
|
||||
wDesc = wDesc && wDesc[0].toUpperCase() + wDesc.slice(1)
|
||||
|
||||
var wIcon = getWeatherIcon(weatherIcon);
|
||||
var rise = formatUnixTime(sunRise);
|
||||
var set = formatUnixTime(sunSet);
|
||||
var upd = formatUnixTime(update);
|
||||
|
||||
setWeatherValue(wLoc, wDesc, wIcon, rise, set, upd);
|
||||
}
|
||||
|
||||
// This will be called in weather-settings
|
||||
const getWeatherData = (appID, cityID, units) => {
|
||||
|
||||
requestString = "https://api.openweathermap.org/data/2.5/weather?APPID=" + appID + "&id=" + cityID + "&units=" + units;
|
||||
|
||||
var request = new XMLHttpRequest();
|
||||
request.open("GET", requestString, true);
|
||||
request.onload = e => {
|
||||
if (request.readyState === 4 && request.status === 200 && request.status < 400) {
|
||||
processWeatherData(JSON.parse(request.response));
|
||||
} else {
|
||||
setErrValue();
|
||||
};
|
||||
};
|
||||
request.send();
|
||||
};
|
||||
|
||||
// Fetch forecast
|
||||
const getForecastData = (appID, cityID, units) => {
|
||||
requestString = "https://api.openweathermap.org/data/2.5/forecast?APPID=" + appID + "&id=" + cityID + "&units=" + units;
|
||||
|
||||
request = new XMLHttpRequest();
|
||||
request.open("GET", requestString, true);
|
||||
request.onload = e => {
|
||||
if (request.readyState === 4 && request.status === 200 && request.status < 400) {
|
||||
processForecastData(JSON.parse(request.response));
|
||||
} else {
|
||||
setErrValue();
|
||||
};
|
||||
};
|
||||
request.send();
|
||||
}
|
||||
|
||||
// Process forecast data
|
||||
const processForecastData = (data) => {
|
||||
|
||||
// Empty forecast container to avoid duplication
|
||||
forecastContainer.innerHTML = '';
|
||||
|
||||
var forecast = data.list;
|
||||
|
||||
for (var i = 8; i < forecast.length; i+=8) {
|
||||
|
||||
var temp_symbol = (units === "metric") ? "°C" : "°F";
|
||||
|
||||
var foreIcon = forecast[i].weather[0].icon;
|
||||
var minimumTemp = forecast[i].main.temp_min;
|
||||
var maximumTemp = forecast[i].main.temp_max;
|
||||
var foreDescription = forecast[i].weather[0].description;
|
||||
var dateTime = forecast[i].dt_txt;
|
||||
|
||||
var fIcon = getWeatherIcon(foreIcon);
|
||||
var minTemp = Math.floor(minimumTemp);
|
||||
var maxTemp = Math.floor(maximumTemp);
|
||||
var forecastTemp = minTemp + ' ~ ' + maxTemp + temp_symbol;
|
||||
var fHour = dateTime.substr(dateTime.indexOf(' ') + 1).slice(0, -3);;
|
||||
var fDate = dateTime.substr(0, dateTime.indexOf(' '));
|
||||
|
||||
createForecastBody(fIcon, forecastTemp, foreDescription, fHour, fDate);
|
||||
}
|
||||
}
|
||||
|
||||
const showWeatherScreen = () => {
|
||||
weatherScreen.classList.add('showWeatherScreen');
|
||||
weatherScreenVisibility = !weatherScreenVisibility;
|
||||
}
|
||||
|
||||
const hideWeatherScreen = () => {
|
||||
weatherScreen.classList.remove('showWeatherScreen');
|
||||
weatherScreenVisibility = !weatherScreenVisibility;
|
||||
}
|
||||
|
||||
const toggleWeatherScreen = () => {
|
||||
|
||||
// If profile anim is still running,
|
||||
// Return to avoid spam
|
||||
if (profileAnimRunning) return;
|
||||
|
||||
// Rotate profile
|
||||
rotateProfile();
|
||||
|
||||
if (weatherScreenVisibility) {
|
||||
// Hide search box
|
||||
hideWeatherScreen();
|
||||
|
||||
} else {
|
||||
// Show search box
|
||||
showWeatherScreen();
|
||||
}
|
||||
|
||||
console.log('toggle weather screen');
|
||||
}
|
Loading…
Reference in New Issue
Block a user