qs: remove geocode API & set coordinates in settings.json
This commit is contained in:
@@ -38,6 +38,10 @@ Item {
|
|||||||
WallpaperCycle.applyNext();
|
WallpaperCycle.applyNext();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function prev() {
|
||||||
|
WallpaperCycle.applyPrev();
|
||||||
|
}
|
||||||
|
|
||||||
target: "background"
|
target: "background"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ Singleton {
|
|||||||
id: root
|
id: root
|
||||||
|
|
||||||
property bool dirsLoaded: false
|
property bool dirsLoaded: false
|
||||||
property bool initialized: dirsLoaded && ImageCacheService.initialized && ShellState.isLoaded
|
property bool initialized: dirsLoaded && ImageCacheService.initialized && ShellState.isLoaded && SettingsService.isLoaded
|
||||||
|
|
||||||
Component.onCompleted: {
|
Component.onCompleted: {
|
||||||
let mkdirs = "";
|
let mkdirs = "";
|
||||||
|
|||||||
@@ -15,14 +15,15 @@ Singleton {
|
|||||||
property int weatherUpdateFrequency: 30 * 60 // 30 minutes expressed in seconds
|
property int weatherUpdateFrequency: 30 * 60 // 30 minutes expressed in seconds
|
||||||
property bool isFetchingWeather: false
|
property bool isFetchingWeather: false
|
||||||
readonly property alias data: adapter
|
readonly property alias data: adapter
|
||||||
// Stable UI properties - only updated when location is successfully geocoded
|
property string locationName: SettingsService.location
|
||||||
property bool coordinatesReady: false
|
property string latitude: SettingsService.latitude
|
||||||
|
property string longitude: SettingsService.longitude
|
||||||
property string stableLatitude: ""
|
property string stableLatitude: ""
|
||||||
property string stableLongitude: ""
|
property string stableLongitude: ""
|
||||||
property string stableName: ""
|
property string stableName: ""
|
||||||
// Formatted coordinates for UI display
|
// Formatted coordinates for UI display
|
||||||
readonly property string displayCoordinates: {
|
readonly property string displayCoordinates: {
|
||||||
if (!root.coordinatesReady || root.stableLatitude === "" || root.stableLongitude === "")
|
if (root.stableLatitude === "" || root.stableLongitude === "")
|
||||||
return "";
|
return "";
|
||||||
|
|
||||||
const lat = parseFloat(root.stableLatitude).toFixed(4);
|
const lat = parseFloat(root.stableLatitude).toFixed(4);
|
||||||
@@ -39,19 +40,8 @@ Singleton {
|
|||||||
readonly property bool isClearDay: currentWeatherCode >= 0 && (currentWeatherCode === 0 || currentWeatherCode === 1) && isDayTime
|
readonly property bool isClearDay: currentWeatherCode >= 0 && (currentWeatherCode === 0 || currentWeatherCode === 1) && isDayTime
|
||||||
readonly property bool isClearNight: currentWeatherCode >= 0 && (currentWeatherCode === 0 || currentWeatherCode === 1) && !isDayTime
|
readonly property bool isClearNight: currentWeatherCode >= 0 && (currentWeatherCode === 0 || currentWeatherCode === 1) && !isDayTime
|
||||||
|
|
||||||
function init() {
|
|
||||||
Logger.i("Location", "Service started");
|
|
||||||
}
|
|
||||||
|
|
||||||
function resetWeather() {
|
function resetWeather() {
|
||||||
Logger.i("Location", "Resetting location and weather data");
|
Logger.i("Location", "Resetting location and weather data");
|
||||||
root.coordinatesReady = false;
|
|
||||||
root.stableLatitude = "";
|
|
||||||
root.stableLongitude = "";
|
|
||||||
root.stableName = "";
|
|
||||||
adapter.latitude = "";
|
|
||||||
adapter.longitude = "";
|
|
||||||
adapter.name = "";
|
|
||||||
adapter.weatherLastFetch = 0;
|
adapter.weatherLastFetch = 0;
|
||||||
adapter.weather = null;
|
adapter.weather = null;
|
||||||
update();
|
update();
|
||||||
@@ -59,44 +49,9 @@ Singleton {
|
|||||||
|
|
||||||
// Main update function - geocodes location if needed, then fetches weather if enabled
|
// Main update function - geocodes location if needed, then fetches weather if enabled
|
||||||
function update() {
|
function update() {
|
||||||
updateLocation();
|
|
||||||
updateWeatherData();
|
updateWeatherData();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Runs independently of weather toggle
|
|
||||||
function updateLocation() {
|
|
||||||
const locationChanged = adapter.name !== SettingsService.location;
|
|
||||||
const needsGeocoding = (adapter.latitude === "") || (adapter.longitude === "") || locationChanged;
|
|
||||||
if (!needsGeocoding)
|
|
||||||
return ;
|
|
||||||
|
|
||||||
if (isFetchingWeather) {
|
|
||||||
Logger.w("Location", "Location update already in progress");
|
|
||||||
return ;
|
|
||||||
}
|
|
||||||
isFetchingWeather = true;
|
|
||||||
if (locationChanged) {
|
|
||||||
root.coordinatesReady = false;
|
|
||||||
Logger.d("Location", "Location changed from", adapter.name, "to", SettingsService.location);
|
|
||||||
}
|
|
||||||
geocodeLocation(SettingsService.location, function(latitude, longitude, name, country) {
|
|
||||||
Logger.d("Location", "Geocoded", SettingsService.location, "to:", latitude, "/", longitude);
|
|
||||||
adapter.name = SettingsService.location;
|
|
||||||
adapter.latitude = latitude.toString();
|
|
||||||
adapter.longitude = longitude.toString();
|
|
||||||
root.stableLatitude = adapter.latitude;
|
|
||||||
root.stableLongitude = adapter.longitude;
|
|
||||||
root.stableName = `${name}, ${country}`;
|
|
||||||
root.coordinatesReady = true;
|
|
||||||
isFetchingWeather = false;
|
|
||||||
Logger.i("Location", "Coordinates ready");
|
|
||||||
if (locationChanged) {
|
|
||||||
adapter.weatherLastFetch = 0;
|
|
||||||
updateWeatherData();
|
|
||||||
}
|
|
||||||
}, errorCallback);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch weather data if enabled and coordinates are available
|
// Fetch weather data if enabled and coordinates are available
|
||||||
function updateWeatherData() {
|
function updateWeatherData() {
|
||||||
if (isFetchingWeather) {
|
if (isFetchingWeather) {
|
||||||
@@ -107,39 +62,13 @@ Singleton {
|
|||||||
Logger.w("Location", "Cannot fetch weather without coordinates");
|
Logger.w("Location", "Cannot fetch weather without coordinates");
|
||||||
return ;
|
return ;
|
||||||
}
|
}
|
||||||
const needsWeatherUpdate = (adapter.weatherLastFetch === "") || (adapter.weather === null) || (Time.timestamp >= adapter.weatherLastFetch + weatherUpdateFrequency);
|
const needsWeatherUpdate = (adapter.weather === null) || (Time.timestamp >= adapter.weatherLastFetch + weatherUpdateFrequency);
|
||||||
if (needsWeatherUpdate) {
|
if (needsWeatherUpdate) {
|
||||||
isFetchingWeather = true;
|
isFetchingWeather = true;
|
||||||
fetchWeatherData(adapter.latitude, adapter.longitude, errorCallback);
|
fetchWeatherData(root.latitude, root.longitude, errorCallback);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Query geocoding API to convert location name to coordinates
|
|
||||||
function geocodeLocation(locationName, callback, errorCallback) {
|
|
||||||
Logger.d("Location", "Geocoding location name");
|
|
||||||
var geoUrl = "https://api.noctalia.dev/geocode?city=" + encodeURIComponent(locationName);
|
|
||||||
var xhr = new XMLHttpRequest();
|
|
||||||
xhr.onreadystatechange = function() {
|
|
||||||
if (xhr.readyState === XMLHttpRequest.DONE) {
|
|
||||||
if (xhr.status === 200) {
|
|
||||||
try {
|
|
||||||
var geoData = JSON.parse(xhr.responseText);
|
|
||||||
if (geoData.lat != null)
|
|
||||||
callback(geoData.lat, geoData.lng, geoData.name, geoData.country);
|
|
||||||
else
|
|
||||||
errorCallback("Location", "could not resolve location name");
|
|
||||||
} catch (e) {
|
|
||||||
errorCallback("Location", "Failed to parse geocoding data: " + e);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
errorCallback("Location", "Geocoding error: " + xhr.status);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
|
||||||
xhr.open("GET", geoUrl);
|
|
||||||
xhr.send();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch weather data from Open-Meteo API
|
// Fetch weather data from Open-Meteo API
|
||||||
function fetchWeatherData(latitude, longitude, errorCallback) {
|
function fetchWeatherData(latitude, longitude, errorCallback) {
|
||||||
Logger.d("Location", "Fetching weather from api.open-meteo.com");
|
Logger.d("Location", "Fetching weather from api.open-meteo.com");
|
||||||
@@ -154,8 +83,8 @@ Singleton {
|
|||||||
data.weather = weatherData;
|
data.weather = weatherData;
|
||||||
data.weatherLastFetch = Time.timestamp;
|
data.weatherLastFetch = Time.timestamp;
|
||||||
// Update stable display values only when complete and successful
|
// Update stable display values only when complete and successful
|
||||||
root.stableLatitude = data.latitude = weatherData.latitude.toString();
|
SettingsService.latitude = data.latitude = weatherData.latitude.toString();
|
||||||
root.stableLongitude = data.longitude = weatherData.longitude.toString();
|
SettingsService.longitude = data.longitude = weatherData.longitude.toString();
|
||||||
root.coordinatesReady = true;
|
root.coordinatesReady = true;
|
||||||
isFetchingWeather = false;
|
isFetchingWeather = false;
|
||||||
Logger.d("Location", "Cached weather to disk - stable coordinates updated");
|
Logger.d("Location", "Cached weather to disk - stable coordinates updated");
|
||||||
@@ -284,11 +213,6 @@ Singleton {
|
|||||||
return Colors.mSky;
|
return Colors.mSky;
|
||||||
}
|
}
|
||||||
|
|
||||||
// --------------------------------
|
|
||||||
function celsiusToFahrenheit(celsius) {
|
|
||||||
return 32 + celsius * 1.8;
|
|
||||||
}
|
|
||||||
|
|
||||||
FileView {
|
FileView {
|
||||||
id: locationFileView
|
id: locationFileView
|
||||||
|
|
||||||
@@ -297,13 +221,6 @@ Singleton {
|
|||||||
onAdapterUpdated: saveTimer.start()
|
onAdapterUpdated: saveTimer.start()
|
||||||
onLoaded: {
|
onLoaded: {
|
||||||
Logger.d("Location", "Loaded cached data");
|
Logger.d("Location", "Loaded cached data");
|
||||||
if (adapter.latitude !== "" && adapter.longitude !== "" && adapter.weatherLastFetch > 0) {
|
|
||||||
root.stableLatitude = adapter.latitude;
|
|
||||||
root.stableLongitude = adapter.longitude;
|
|
||||||
root.stableName = adapter.name;
|
|
||||||
root.coordinatesReady = true;
|
|
||||||
Logger.i("Location", "Coordinates ready");
|
|
||||||
}
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
onLoadFailed: function(error) {
|
onLoadFailed: function(error) {
|
||||||
@@ -313,9 +230,6 @@ Singleton {
|
|||||||
JsonAdapter {
|
JsonAdapter {
|
||||||
id: adapter
|
id: adapter
|
||||||
|
|
||||||
property string latitude: ""
|
|
||||||
property string longitude: ""
|
|
||||||
property string name: ""
|
|
||||||
property int weatherLastFetch: 0
|
property int weatherLastFetch: 0
|
||||||
property var weather: null
|
property var weather: null
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,11 +11,14 @@ Singleton {
|
|||||||
property alias geoInfoToken: adapter.geoInfoToken
|
property alias geoInfoToken: adapter.geoInfoToken
|
||||||
property alias ipAliases: adapter.ipAliases
|
property alias ipAliases: adapter.ipAliases
|
||||||
property alias location: adapter.location
|
property alias location: adapter.location
|
||||||
|
property alias latitude: adapter.latitude
|
||||||
|
property alias longitude: adapter.longitude
|
||||||
property alias backgroundPath: adapter.backgroundPath
|
property alias backgroundPath: adapter.backgroundPath
|
||||||
property alias cycleWallpapers: cycleSettings.wallpapers
|
property alias cycleWallpapers: cycleSettings.wallpapers
|
||||||
property alias cycleShuffle: cycleSettings.shuffle
|
property alias cycleShuffle: cycleSettings.shuffle
|
||||||
property alias cycleInterval: cycleSettings.interval
|
property alias cycleInterval: cycleSettings.interval
|
||||||
property alias cycleEnabled: cycleSettings.enabled
|
property alias cycleEnabled: cycleSettings.enabled
|
||||||
|
property bool isLoaded: false
|
||||||
|
|
||||||
FileView {
|
FileView {
|
||||||
id: settingFile
|
id: settingFile
|
||||||
@@ -26,6 +29,8 @@ Singleton {
|
|||||||
reload();
|
reload();
|
||||||
}
|
}
|
||||||
onAdapterUpdated: writeAdapter()
|
onAdapterUpdated: writeAdapter()
|
||||||
|
onLoaded: isLoaded = true
|
||||||
|
onLoadFailed: isLoaded = true // Will create on change
|
||||||
|
|
||||||
JsonAdapter {
|
JsonAdapter {
|
||||||
id: adapter
|
id: adapter
|
||||||
@@ -35,6 +40,8 @@ Singleton {
|
|||||||
"127.0.0.1": "localhost"
|
"127.0.0.1": "localhost"
|
||||||
}
|
}
|
||||||
property string location: "New York"
|
property string location: "New York"
|
||||||
|
property string latitude: "43"
|
||||||
|
property string longitude: "-75"
|
||||||
property string backgroundPath: ""
|
property string backgroundPath: ""
|
||||||
property JsonObject cycle: JsonObject {
|
property JsonObject cycle: JsonObject {
|
||||||
id: cycleSettings
|
id: cycleSettings
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ pragma Singleton
|
|||||||
Singleton {
|
Singleton {
|
||||||
id: root
|
id: root
|
||||||
|
|
||||||
property double _latitude: -1
|
property string _latitude: SettingsService.latitude
|
||||||
property double _longitude: -1
|
property string _longitude: SettingsService.longitude
|
||||||
property int temperature: 0
|
property int temperature: 0
|
||||||
readonly property bool isEnabled: ShellState.sunsetEnabled
|
readonly property bool isEnabled: ShellState.sunsetEnabled
|
||||||
|
|
||||||
@@ -17,38 +17,17 @@ Singleton {
|
|||||||
ShellState.sunsetEnabled = !root.isEnabled;
|
ShellState.sunsetEnabled = !root.isEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
function setLat(lat) {
|
|
||||||
_latitude = lat;
|
|
||||||
Logger.i("Sunset", "Updated latitude to " + lat);
|
|
||||||
checkStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
function setLong(lng) {
|
|
||||||
_longitude = lng;
|
|
||||||
Logger.i("Sunset", "Updated longitude to " + lng);
|
|
||||||
checkStart();
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkStart() {
|
function checkStart() {
|
||||||
if (_latitude !== -1 && _longitude !== -1 && root.isEnabled) {
|
if (_latitude !== "" && _longitude !== "" && root.isEnabled) {
|
||||||
sunsetProcess.command = ["wlsunset", "-l", _latitude.toString(), "-L", _longitude.toString()];
|
sunsetProcess.command = ["wlsunset", "-l", _latitude, "-L", _longitude];
|
||||||
|
sunsetProcess.running = true;
|
||||||
|
} else if (root.isEnabled) {
|
||||||
|
Logger.w("Sunset", "Missing coordinates, starting wlsunset without location");
|
||||||
|
sunsetProcess.command = ["wlsunset"];
|
||||||
sunsetProcess.running = true;
|
sunsetProcess.running = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Connections {
|
|
||||||
function onLatitudeChanged() {
|
|
||||||
Logger.d("");
|
|
||||||
setLat(LocationService.data.latitude);
|
|
||||||
}
|
|
||||||
|
|
||||||
function onLongitudeChanged() {
|
|
||||||
setLong(LocationService.data.longitude);
|
|
||||||
}
|
|
||||||
|
|
||||||
target: LocationService.data
|
|
||||||
}
|
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
function onIsEnabledChanged() {
|
function onIsEnabledChanged() {
|
||||||
if (root.isEnabled)
|
if (root.isEnabled)
|
||||||
|
|||||||
Reference in New Issue
Block a user