Add JavaScript geolocation for weather (close #3)

master
Skylar Ittner 5 years ago
parent 30f38037bc
commit 32d17f9bf9

@ -4,5 +4,6 @@
"Temperature: {temp}{units}": "Temperature: {temp}{units}", "Temperature: {temp}{units}": "Temperature: {temp}{units}",
"{temp}{units}": "{temp}{units}", "{temp}{units}": "{temp}{units}",
"{tempLow} to {tempHigh}{units}": "{tempLow} to {tempHigh}{units}", "{tempLow} to {tempHigh}{units}": "{tempLow} to {tempHigh}{units}",
"Low: {tempLow}{units} High: {tempHigh}{units}": "Low: {tempLow}{units} | High: {tempHigh}{units}" "Low: {tempLow}{units} High: {tempHigh}{units}": "Low: {tempLow}{units} | High: {tempHigh}{units}",
"Geolocate": "Geolocate"
} }

@ -28,7 +28,7 @@ abstract class Weather {
* @global type $SETTINGS * @global type $SETTINGS
* @return boolean true if successful, false if not * @return boolean true if successful, false if not
*/ */
public function setLocationByUserIP() { public function setLocationByUserIP(): bool {
global $SETTINGS; global $SETTINGS;
// Make sure we'll have a valid IP when testing on localhost // Make sure we'll have a valid IP when testing on localhost
if ($SETTINGS['debug'] && $_SERVER['REMOTE_ADDR'] == "127.0.0.1") { if ($SETTINGS['debug'] && $_SERVER['REMOTE_ADDR'] == "127.0.0.1") {
@ -59,6 +59,24 @@ abstract class Weather {
} }
} }
/**
* Attempt to set the user's location based on sent cookies named "Latitude"
* and "Longitude".
* @return bool true if successful.
*/
public function setLocationByCookie(): bool {
if (!empty($_COOKIE['Latitude']) && !empty($_COOKIE['Longitude'])) {
$latlngregex = "/-?[0-9]{1,3}(\.[0-9]+)?/";
if (preg_match($latlngregex, $_COOKIE['Latitude']) && preg_match($latlngregex, $_COOKIE['Longitude'])) {
$this->lat = $_COOKIE['Latitude'] * 1.0;
$this->lng = $_COOKIE['Longitude'] * 1.0;
return true;
}
return false;
}
return false;
}
abstract protected function loadForecast(); abstract protected function loadForecast();
// Getters // Getters

@ -15,6 +15,7 @@ define("PAGES", [
], ],
"scripts" => [ "scripts" => [
"static/Shuffle/dist/shuffle.min.js", "static/Shuffle/dist/shuffle.min.js",
"static/js/locationcookie.js",
"static/js/newsgrid.js", "static/js/newsgrid.js",
"static/js/home.js" "static/js/home.js"
] ]
@ -36,6 +37,9 @@ define("PAGES", [
"styles" => [ "styles" => [
"static/weather-icons/css/weather-icons.min.css" "static/weather-icons/css/weather-icons.min.css"
], ],
"scripts" => [
"static/js/locationcookie.js"
]
], ],
"404" => [ "404" => [
"title" => "404 error" "title" => "404 error"

@ -8,8 +8,12 @@
header("Link: <static/img/news-placeholder.svg>; rel=preload; as=image", false); header("Link: <static/img/news-placeholder.svg>; rel=preload; as=image", false);
$weatherclass = "Weather_" . $SETTINGS['sources']['weather']; $weatherclass = "Weather_" . $SETTINGS['sources']['weather'];
$weather = new $weatherclass(46.595, -112.027); // TODO: get user location $lat = 46.595;
$weather->setLocationByUserIP(); $lng = -112.027;
$weather = new $weatherclass($lat, $lng);
if (!$weather->setLocationByCookie()) {
$weather->setLocationByUserIP();
}
$weather->loadForecast(); $weather->loadForecast();
$tempunits = "C"; $tempunits = "C";
@ -112,13 +116,18 @@ foreach ($newsitems as $item) {
<a class="px-2" href="./action.php?action=settempunits&source=home&unit=K">K</a> <a class="px-2" href="./action.php?action=settempunits&source=home&unit=K">K</a>
</div> </div>
<div class="text-muted"> <div>
<i class="fas fa-map-marker-alt"></i> <?php <span class="text-muted">
if (!empty($weather->getLocationName())) { <i class="fas fa-map-marker-alt"></i> <?php
echo htmlentities($weather->getLocationName()) . " | "; if (!empty($weather->getLocationName())) {
} echo htmlentities($weather->getLocationName()) . " | ";
echo round($weather->getLatitude(), 2) . ", " . round($weather->getLongitude(), 2); }
?> echo round($weather->getLatitude(), 2) . ", " . round($weather->getLongitude(), 2);
?>
</span>
<span id="geolocate-btn" class="btn btn-link btn-sm ml-2">
<i class="fas fa-compass"></i> <?php $Strings->get("Geolocate"); ?>
</span>
</div> </div>
</div> </div>
</div> </div>

@ -6,8 +6,12 @@
*/ */
$weatherclass = "Weather_" . $SETTINGS['sources']['weather']; $weatherclass = "Weather_" . $SETTINGS['sources']['weather'];
$weather = new $weatherclass(46.595, -112.027); // TODO: get user location $lat = 46.595;
$weather->setLocationByUserIP(); $lng = -112.027;
$weather = new $weatherclass($lat, $lng);
if (!$weather->setLocationByCookie()) {
$weather->setLocationByUserIP();
}
$weather->loadForecast(); $weather->loadForecast();
$tempunits = "C"; $tempunits = "C";
@ -112,13 +116,18 @@ if (!empty($_COOKIE['TemperatureUnitsPref']) && preg_match("/[FCK]/", $_COOKIE['
<a class="px-2" href="./action.php?action=settempunits&source=weather&unit=K">K</a> <a class="px-2" href="./action.php?action=settempunits&source=weather&unit=K">K</a>
</div> </div>
<div class="text-muted"> <div>
<i class="fas fa-map-marker-alt"></i> <?php <span class="text-muted">
if (!empty($weather->getLocationName())) { <i class="fas fa-map-marker-alt"></i> <?php
echo htmlentities($weather->getLocationName()) . " | "; if (!empty($weather->getLocationName())) {
} echo htmlentities($weather->getLocationName()) . " | ";
echo round($weather->getLatitude(), 2) . ", " . round($weather->getLongitude(), 2); }
?> echo round($weather->getLatitude(), 2) . ", " . round($weather->getLongitude(), 2);
?>
</span>
<span id="geolocate-btn" class="btn btn-link btn-sm ml-2">
<i class="fas fa-compass"></i> <?php $Strings->get("Geolocate"); ?>
</span>
</div> </div>
</div> </div>
</div> </div>

@ -0,0 +1,21 @@
/*
* 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 geolocateToCookie() {
navigator.geolocation.getCurrentPosition(function (pos) {
document.cookie = "Latitude=" + pos.coords.latitude.toFixed(2) + ";samesite=strict;max-age=" + (60 * 60 * 24 * 90);
document.cookie = "Longitude=" + pos.coords.longitude.toFixed(2) + ";samesite=strict;max-age=" + (60 * 60 * 24 * 90);
document.location.reload();
}, function () {
alert("Could not determine location. Please note that your coordinates are rounded to approx. 1km before being sent to the server.");
}, {
timeout: 1000 * 60,
enableHighAccuracy: true
});
}
$("#geolocate-btn").click(geolocateToCookie);
Loading…
Cancel
Save