/ *
* This Source Code Form is subject to the terms of the Mozilla Public
* License , v . 2.0 . If a copy of the MPL was not distributed with this
* file , You can obtain one at http : //mozilla.org/MPL/2.0/.
* /
function ftoc ( f ) {
return ( f - 32 ) * 5 / 9 ;
}
function loadWeather ( reload ) {
if ( typeof reload == "undefined" ) {
reload = false ;
} else {
reload = reload == true ;
}
if ( userPosition . coords . accuracy > 99999 ) {
app . dialog . alert ( "Couldn't find your location. Wait for a GPS signal and try again." , "Error" ) ;
return ;
}
var requestfinished = false ;
var weatherdialogopen = false ;
$ . ajax ( {
url : SETTINGS . weatherapi ,
dataType : 'json' ,
data : {
// Round the numbers off to increase user privacy
// Accuracy with two decimal places is ~1.1km/0.6mi
latitude : userPosition . coords . latitude . toFixed ( 2 ) ,
longitude : userPosition . coords . longitude . toFixed ( 2 )
} ,
timeout : 15 * 1000 ,
success : function ( resp ) {
if ( weatherdialogopen ) {
app . dialog . close ( ) ;
weatherdialogopen = false ;
}
requestfinished = true ;
if ( resp . status == "OK" ) {
//
// Summary tab
//
var mintemp = ( getStorage ( "units" ) == "metric" ? Math . round ( ftoc ( resp . summary . temp . min ) ) + " °C" : Math . round ( resp . summary . temp . min ) + " °F" ) ;
var maxtemp = ( getStorage ( "units" ) == "metric" ? Math . round ( ftoc ( resp . summary . temp . max ) ) + " °C" : Math . round ( resp . summary . temp . max ) + " °F" ) ;
$ ( "#summarylowtemp" ) . html ( mintemp ) ;
$ ( "#summaryhightemp" ) . html ( maxtemp ) ;
$ ( "#summaryprecipchance" ) . text ( Math . round ( resp . summary . precipitation . chance * 100.0 ) + "% chance" ) ;
if ( getStorage ( "units" ) == "metric" ) {
$ ( "#summarywindspeed" ) . text ( Math . round ( resp . summary . windspeed * 1.609344 ) + " km/h" ) ;
} else {
$ ( "#summarywindspeed" ) . text ( Math . round ( resp . summary . windspeed ) + " mph" ) ;
}
if ( SETTINGS . weathericons . includes ( resp . summary . icon ) ) {
$ ( "#summaryweathericon" ) . attr ( "src" , "assets/images/weather-" + resp . summary . icon + ".svg" ) ;
} else {
$ ( "#summaryweathericon" ) . attr ( "src" , "assets/images/weather-none.svg" ) ;
}
$ ( "#summary-forecast-location" ) . text ( resp . location _name ) ;
$ ( "#summary-forecast-info" ) . text ( "Forecast covers the next " + resp . summary . forecast _hours + " hours (until " + timestampToTimeString ( resp . summary . forecast _until ) + ")." ) ;
$ ( "#summary-forecast-creditlink" ) . text ( resp . source . text ) ;
$ ( "#summary-forecast-creditlink" ) . attr ( "onclick" , "openExternalBrowser('" + resp . source . url + "')" ) ;
//
// Now tab
//
var temp = ( getStorage ( "units" ) == "metric" ? Math . round ( ftoc ( resp . now . temp ) ) + " °C" : Math . round ( resp . now . temp ) + " °F" ) ;
var feelslike = ( getStorage ( "units" ) == "metric" ? Math . round ( ftoc ( resp . now . feelslike ) ) + " °C" : Math . round ( resp . now . feelslike ) + " °F" ) ;
$ ( "#nowtemp" ) . html ( temp ) ;
$ ( "#nowfeelslike" ) . html ( feelslike ) ;
if ( SETTINGS . weathericons . includes ( resp . now . icon ) ) {
$ ( "#nowweathericon" ) . attr ( "src" , "assets/images/weather-" + resp . now . icon + ".svg" ) ;
} else {
$ ( "#nowweathericon" ) . attr ( "src" , "assets/images/weather-none.svg" ) ;
}
app . gauge . get ( '#nowuvindexgauge' ) . update ( {
value : Math . min ( resp . now . uv _index , 10 ) / 10 ,
valueText : resp . now . uv _index ,
borderColor : colorThemeNameToHex ( uvIndexToColor ( resp . now . uv _index ) )
} ) ;
if ( getStorage ( "units" ) == "metric" ) {
$ ( "#nowwindspeed" ) . text ( Math . round ( resp . now . windspeed * 1.609344 ) + " km/h" ) ;
} else {
$ ( "#nowwindspeed" ) . text ( Math . round ( resp . now . windspeed ) + " mph" ) ;
}
$ ( "#nowwinddirection" ) . text ( degreesToCardinal ( resp . now . winddirection ) ) ;
var minutelydata = [ ] ;
var maxprecip = 0 ;
for ( var i = 0 ; i < resp . today . minutely . length ; i ++ ) {
precip = resp . today . minutely [ i ] . precip ;
if ( getStorage ( "units" ) == "metric" ) {
precip = precip * 25.4 ;
}
minutelydata [ i ] = {
x : new Date ( resp . today . minutely [ i ] . time * 1000 ) ,
y : precip
} ;
if ( precip > maxprecip ) {
maxprecip = precip ;
}
}
if ( maxprecip > 0 ) {
// only make rain chart if there's rain
var precipChart = new Chart ( document . getElementById ( 'precipchart' ) , {
type : "line" ,
data : {
datasets : [
{
fill : true ,
data : minutelydata ,
borderWidth : 0 ,
spanGaps : true ,
backgroundColor : "#03A9F4" ,
borderColor : "#03A9F4"
}
]
} ,
options : {
responsive : true ,
elements : {
point : {
radius : 0
}
} ,
scales : {
xAxes : [ {
type : 'time' ,
display : true ,
scaleLabel : {
display : false
} ,
gridLines : {
display : true ,
drawBorder : false
} ,
time : {
unit : 'minute' ,
stepSize : 5 ,
displayFormats : {
minute : 'h:mm' ,
hour : 'hA'
}
}
} ] ,
yAxes : [ {
display : true ,
scaleLabel : {
display : true
} ,
gridLines : {
display : false ,
drawBorder : false
} ,
ticks : {
min : 0 ,
max : Math . round ( maxprecip ) ,
stepSize : ( Math . round ( maxprecip ) / 2 ) ,
callback : function ( value , index , values ) {
if ( getStorage ( "units" ) == "metric" ) {
return value + ' mm' ;
} else {
return value + ' in' ;
}
}
}
} ]
} ,
legend : {
display : false
} ,
tooltips : {
enabled : false
}
}
} ) ;
}
//
// Forecast tab
//
forecastItems = [ ] ;
for ( var i = 1 ; i < resp . forecast . length ; i ++ ) {
var low = ( getStorage ( "units" ) == "metric" ? Math . round ( ftoc ( resp . forecast [ i ] . temp . min ) ) : Math . round ( resp . forecast [ i ] . temp . min ) ) ;
var high = ( getStorage ( "units" ) == "metric" ? Math . round ( ftoc ( resp . forecast [ i ] . temp . max ) ) + " °C" : Math . round ( resp . forecast [ i ] . temp . max ) + " °F" ) ;
var precipcolor = precipChanceToColor ( resp . forecast [ i ] . precipitation . chance ) ;
forecastItems . push ( {
day : formatTimestamp ( 'l' , resp . forecast [ i ] . date ) ,
temps : low + " to " + high ,
uv _index : resp . forecast [ i ] . uv _index ,
uv _color : uvIndexToColor ( resp . forecast [ i ] . uv _index ) ,
precip _chance : Math . round ( resp . forecast [ i ] . precipitation . chance * 100 ) ,
precip _color : precipcolor
} ) ;
}
forecastItemTemplate = '<li>'
+ '<div class="item-content">'
+ ' <div class="item-inner">'
+ ' <div class="item-title">'
+ ' <div class="item-header">{{day}}</div>'
+ ' {{temps}}'
+ ' <br /><span class="padding-half forecast-uv-badge badge color-{{uv_color}}"><i class="fas fa-sun fa-fw"></i> {{uv_index}}</span>'
+ ' <span class="padding-half forecast-precip-badge badge color-{{precip_color}}"><i class="fas fa-tint fa-fw"></i> {{precip_chance}}%</span>'
+ ' </div>'
+ ' </div>'
+ '</div>'
+ '</li>' ;
forecastVirtualList = app . virtualList . create ( {
el : "#forecast-list" ,
items : forecastItems ,
itemTemplate : forecastItemTemplate
} ) ;
} else {
app . dialog . alert ( resp . message , "Error" ) ;
}
} ,
error : function ( jqXHR , status , errorThrown ) {
if ( weatherdialogopen ) {
app . dialog . close ( ) ;
weatherdialogopen = false ;
}
requestfinished = true ;
app . dialog . alert ( "There was a network issue while checking the weather. Please try again." , "Error" ) ;
}
} ) ;
// Open a loading message if there's a delay or we're reloading
if ( reload ) {
app . dialog . preloader ( "Checking Weather..." ) ;
weatherdialogopen = true ;
} else {
setTimeout ( function ( ) {
if ( ! requestfinished ) {
app . dialog . preloader ( "Checking Weather..." ) ;
weatherdialogopen = true ;
}
} , 1000 ) ;
}
}
$ ( "#app" ) . on ( "click" , "#weather-forecast .forecast-uv-badge" , function ( ) {
app . toast . show ( {
text : "<i class='fas fa-info-circle'></i> UV index" ,
position : "bottom" ,
destroyOnClose : true ,
closeTimeout : 1000 * 3
} ) ;
} ) ;
$ ( "#app" ) . on ( "click" , "#weather-forecast .forecast-precip-badge" , function ( ) {
app . toast . show ( {
text : "<i class='fas fa-info-circle'></i> Chance of precipitation" ,
position : "bottom" ,
destroyOnClose : true ,
closeTimeout : 1000 * 3
} ) ;
} ) ;
function uvIndexToColor ( index ) {
var uvcolor = "green" ;
if ( index >= 11 ) {
uvcolor = "purple" ;
} else if ( index >= 8 ) {
uvcolor = "red" ;
} else if ( index >= 6 ) {
uvcolor = "orange" ;
} else if ( index >= 3 ) {
uvcolor = "yellow" ;
}
return uvcolor ;
}
function precipChanceToColor ( chance ) {
var color = "lightblue" ;
if ( chance > 0.8 ) {
color = "gray" ;
} else if ( chance > 0.2 ) {
color = "blue" ;
} else {
color = "lightblue" ;
}
return color ;
}