This commit is contained in:
Ly-sec 2025-08-31 16:44:43 +02:00
commit 4520ed3cbf
12 changed files with 60 additions and 53 deletions

View file

@ -26,7 +26,7 @@ Singleton {
property string defaultAvatar: Quickshell.env("HOME") + "/.face" property string defaultAvatar: Quickshell.env("HOME") + "/.face"
// Used to access via Settings.data.xxx.yyy // Used to access via Settings.data.xxx.yyy
property alias data: adapter readonly property alias data: adapter
property bool isLoaded: false property bool isLoaded: false

View file

@ -45,10 +45,10 @@ Loader {
margins { margins {
top: ((modelData && Settings.data.bar.monitors.includes(modelData.name)) top: ((modelData && Settings.data.bar.monitors.includes(modelData.name))
|| (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "top" || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "top"
&& Settings.data.bar.backgroundOpacity > 0 ? Math.floor(Style.barHeight * scaling) : 0 && Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0
bottom: ((modelData && Settings.data.bar.monitors.includes(modelData.name)) bottom: ((modelData && Settings.data.bar.monitors.includes(modelData.name))
|| (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "bottom" || (Settings.data.bar.monitors.length === 0)) && Settings.data.bar.position === "bottom"
&& Settings.data.bar.backgroundOpacity > 0 ? Math.floor(Style.barHeight * scaling) : 0 && Settings.data.bar.backgroundOpacity > 0 ? Math.round(Style.barHeight * scaling) : 0
} }
// Source we want to show only as a ring // Source we want to show only as a ring

View file

@ -104,7 +104,7 @@ Rectangle {
// Anchor the menu to the tray icon item (parent) and position it below the icon // Anchor the menu to the tray icon item (parent) and position it below the icon
const menuX = (width / 2) - (trayMenu.item.width / 2) const menuX = (width / 2) - (trayMenu.item.width / 2)
const menuY = (Style.barHeight * scaling) const menuY = Math.round(Style.barHeight * scaling)
trayMenu.item.menu = modelData.menu trayMenu.item.menu = modelData.menu
trayMenu.item.showAt(parent, menuX, menuY) trayMenu.item.showAt(parent, menuX, menuY)
} else { } else {

View file

@ -244,7 +244,7 @@ NPanel {
// Search bar // Search bar
Rectangle { Rectangle {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: Style.barHeight * scaling Layout.preferredHeight: Math.round(Style.barHeight * scaling)
Layout.bottomMargin: Style.marginM * scaling Layout.bottomMargin: Style.marginM * scaling
radius: Style.radiusM * scaling radius: Style.radiusM * scaling
color: Color.mSurface color: Color.mSurface

View file

@ -81,7 +81,7 @@ ColumnLayout {
Layout.alignment: Qt.AlignCenter Layout.alignment: Qt.AlignCenter
Layout.topMargin: Style.marginS * scaling Layout.topMargin: Style.marginS * scaling
Layout.preferredWidth: updateText.implicitWidth + 46 * scaling Layout.preferredWidth: updateText.implicitWidth + 46 * scaling
Layout.preferredHeight: Style.barHeight * scaling Layout.preferredHeight: Math.round(Style.barHeight * scaling)
radius: Style.radiusL * scaling radius: Style.radiusL * scaling
color: updateArea.containsMouse ? Color.mPrimary : Color.transparent color: updateArea.containsMouse ? Color.mPrimary : Color.transparent
border.color: Color.mPrimary border.color: Color.mPrimary

View file

@ -329,7 +329,7 @@ ColumnLayout {
NToggle { NToggle {
label: "Automatic Scheduling" label: "Automatic Scheduling"
description: `Based on the sunset and sunrise time in <i>${LocationService.data.stableName}</i> - recommended.` description: `Based on the sunset and sunrise time in <i>${LocationService.stableName}</i> - recommended.`
checked: Settings.data.nightLight.autoSchedule checked: Settings.data.nightLight.autoSchedule
onToggled: checked => Settings.data.nightLight.autoSchedule = checked onToggled: checked => Settings.data.nightLight.autoSchedule = checked
visible: Settings.data.nightLight.enabled visible: Settings.data.nightLight.enabled

View file

@ -30,8 +30,8 @@ ColumnLayout {
} }
NText { NText {
visible: LocationService.data.coordinatesReady visible: LocationService.coordinatesReady
text: `${LocationService.data.stableName} (${LocationService.displayCoordinates})` text: `${LocationService.stableName} (${LocationService.displayCoordinates})`
font.pointSize: Style.fontSizeS * scaling font.pointSize: Style.fontSizeS * scaling
color: Color.mOnSurfaceVariant color: Color.mOnSurfaceVariant
verticalAlignment: Text.AlignVCenter verticalAlignment: Text.AlignVCenter

View file

@ -271,7 +271,7 @@ NPanel {
Item { Item {
Layout.fillWidth: true Layout.fillWidth: true
Layout.preferredHeight: Style.barHeight * scaling Layout.preferredHeight: Math.round(Style.barHeight * scaling)
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
@ -313,7 +313,7 @@ NPanel {
Rectangle { Rectangle {
Layout.preferredWidth: Style.baseWidgetSize * 2.5 * scaling Layout.preferredWidth: Style.baseWidgetSize * 2.5 * scaling
Layout.preferredHeight: Style.barHeight * scaling Layout.preferredHeight: Math.round(Style.barHeight * scaling)
radius: Style.radiusM * scaling radius: Style.radiusM * scaling
color: Color.mPrimary color: Color.mPrimary

View file

@ -13,7 +13,7 @@ Singleton {
property string githubDataFile: Quickshell.env("NOCTALIA_GITHUB_FILE") || (Settings.cacheDir + "github.json") property string githubDataFile: Quickshell.env("NOCTALIA_GITHUB_FILE") || (Settings.cacheDir + "github.json")
property int githubUpdateFrequency: 60 * 60 // 1 hour expressed in seconds property int githubUpdateFrequency: 60 * 60 // 1 hour expressed in seconds
property bool isFetchingData: false property bool isFetchingData: false
property alias data: adapter // Used to access via GitHubService.data.xxx.yyy readonly property alias data: adapter // Used to access via GitHubService.data.xxx.yyy
// Public properties for easy access // Public properties for easy access
property string latestVersion: "Unknown" property string latestVersion: "Unknown"

View file

@ -13,18 +13,28 @@ Singleton {
property string locationFile: Quickshell.env("NOCTALIA_WEATHER_FILE") || (Settings.cacheDir + "location.json") property string locationFile: Quickshell.env("NOCTALIA_WEATHER_FILE") || (Settings.cacheDir + "location.json")
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
property alias data: adapter // Used to access via LocationService.data.xxx
readonly property alias data: adapter // Used to access via LocationService.data.xxx from outside, best to use "adapter" inside the service.
// Stable UI properties - only updated when location is fully resolved
property bool coordinatesReady: false
property string stableLatitude: ""
property string stableLongitude: ""
property string stableName: ""
FileView { FileView {
id: locationFileView id: locationFileView
path: locationFile path: locationFile
onAdapterUpdated: saveTimer.start() onAdapterUpdated: saveTimer.start()
onLoaded: { onLoaded: {
Logger.log("Location", "Loaded cached data")
// Initialize stable properties on load // Initialize stable properties on load
if (adapter.latitude !== "" && adapter.longitude !== "" && adapter.weatherLastFetch > 0) { if (adapter.latitude !== "" && adapter.longitude !== "" && adapter.weatherLastFetch > 0) {
adapter.stableLatitude = adapter.latitude root.stableLatitude = adapter.latitude
adapter.stableLongitude = adapter.longitude root.stableLongitude = adapter.longitude
adapter.coordinatesReady = true root.stableName = adapter.name
root.coordinatesReady = true
Logger.log("Location", "Coordinates ready")
} }
updateWeather() updateWeather()
} }
@ -42,21 +52,17 @@ Singleton {
property int weatherLastFetch: 0 property int weatherLastFetch: 0
property var weather: null property var weather: null
// Stable UI properties - only updated when location is fully resolved
property bool coordinatesReady: false
property string stableLatitude: ""
property string stableLongitude: ""
property string stableName: ""
} }
} }
// Helper property for UI components (outside JsonAdapter to avoid binding loops) // Helper property for UI components (outside JsonAdapter to avoid binding loops)
readonly property string displayCoordinates: { readonly property string displayCoordinates: {
if (!data.coordinatesReady || data.stableLatitude === "" || data.stableLongitude === "") { if (!root.coordinatesReady || root.stableLatitude === "" || root.stableLongitude === "") {
return "" return ""
} }
const lat = parseFloat(data.stableLatitude).toFixed(4) const lat = parseFloat(root.stableLatitude).toFixed(4)
const lon = parseFloat(data.stableLongitude).toFixed(4) const lon = parseFloat(root.stableLongitude).toFixed(4)
return `${lat}, ${lon}` return `${lat}, ${lon}`
} }
@ -90,19 +96,18 @@ Singleton {
Logger.log("Location", "Resetting weather data") Logger.log("Location", "Resetting weather data")
// Mark as changing to prevent UI updates // Mark as changing to prevent UI updates
data.coordinatesReady = false root.coordinatesReady = false
// Reset stable properties
root.stableLatitude = ""
root.stableLongitude = ""
root.stableName = ""
// Reset core data // Reset core data
data.latitude = "" adapter.latitude = ""
data.longitude = "" adapter.longitude = ""
data.name = "" adapter.name = ""
data.weatherLastFetch = 0 adapter.weatherLastFetch = 0
data.weather = null adapter.weather = null
// Reset stable properties
data.stableLatitude = ""
data.stableLongitude = ""
data.stableName = ""
// Try to fetch immediately // Try to fetch immediately
updateWeather() updateWeather()
@ -115,9 +120,9 @@ Singleton {
return return
} }
if ((data.weatherLastFetch === "") || (data.weather === null) || (data.latitude === "") || (data.longitude === "") if ((adapter.weatherLastFetch === "") || (adapter.weather === null) || (adapter.latitude === "") || (adapter.longitude === "")
|| (data.name !== Settings.data.location.name) || (adapter.name !== Settings.data.location.name)
|| (Time.timestamp >= data.weatherLastFetch + weatherUpdateFrequency)) { || (Time.timestamp >= adapter.weatherLastFetch + weatherUpdateFrequency)) {
getFreshWeather() getFreshWeather()
} }
} }
@ -129,28 +134,28 @@ Singleton {
// Check if location name has changed // Check if location name has changed
const locationChanged = data.name !== Settings.data.location.name const locationChanged = data.name !== Settings.data.location.name
if (locationChanged) { if (locationChanged) {
data.coordinatesReady = false root.coordinatesReady = false
Logger.log("Location", "Location changed from", data.name, "to", Settings.data.location.name) Logger.log("Location", "Location changed from", adapter.name, "to", Settings.data.location.name)
} }
if ((data.latitude === "") || (data.longitude === "") || locationChanged) { if ((adapter.latitude === "") || (adapter.longitude === "") || locationChanged) {
_geocodeLocation(Settings.data.location.name, function (latitude, longitude, name, country) { _geocodeLocation(Settings.data.location.name, function (latitude, longitude, name, country) {
Logger.log("Location", "Geocoded", Settings.data.location.name, "to:", latitude, "/", longitude) Logger.log("Location", "Geocoded", Settings.data.location.name, "to:", latitude, "/", longitude)
// Save location name // Save location name
data.name = Settings.data.location.name adapter.name = Settings.data.location.name
// Save GPS coordinates // Save GPS coordinates
data.latitude = latitude.toString() adapter.latitude = latitude.toString()
data.longitude = longitude.toString() adapter.longitude = longitude.toString()
data.stableName = `${name}, ${country}` root.stableName = `${name}, ${country}`
_fetchWeather(latitude, longitude, errorCallback) _fetchWeather(latitude, longitude, errorCallback)
}, errorCallback) }, errorCallback)
} else { } else {
_fetchWeather(data.latitude, data.longitude, errorCallback) _fetchWeather(adapter.latitude, adapter.longitude, errorCallback)
} }
} }
@ -200,9 +205,9 @@ Singleton {
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
data.stableLatitude = data.latitude = weatherData.latitude.toString() root.stableLatitude = data.latitude = weatherData.latitude.toString()
data.stableLongitude = data.longitude = weatherData.longitude.toString() root.stableLongitude = data.longitude = weatherData.longitude.toString()
data.coordinatesReady = true root.coordinatesReady = true
isFetchingWeather = false isFetchingWeather = false
Logger.log("Location", "Cached weather to disk - stable coordinates updated") Logger.log("Location", "Cached weather to disk - stable coordinates updated")

View file

@ -31,7 +31,7 @@ Singleton {
var cmd = ["wlsunset"] var cmd = ["wlsunset"]
cmd.push("-t", `${params.nightTemp}`, "-T", `${params.dayTemp}`) cmd.push("-t", `${params.nightTemp}`, "-T", `${params.dayTemp}`)
if (params.autoSchedule) { if (params.autoSchedule) {
cmd.push("-l", `${LocationService.data.stableLatitude}`, "-L", `${LocationService.data.stableLongitude}`) cmd.push("-l", `${LocationService.stableLatitude}`, "-L", `${LocationService.stableLongitude}`)
} else { } else {
cmd.push("-S", params.manualSunrise) cmd.push("-S", params.manualSunrise)
cmd.push("-s", params.manualSunset) cmd.push("-s", params.manualSunset)
@ -55,9 +55,11 @@ Singleton {
} }
Connections { Connections {
target: LocationService.data target: LocationService
function onCoordinatesReadyChanged() { function onCoordinatesReadyChanged() {
apply() if (LocationService.coordinatesReady) {
apply()
}
} }
} }

View file

@ -38,7 +38,7 @@ Loader {
property real opacityValue: originalOpacity property real opacityValue: originalOpacity
property alias isClosing: hideTimer.running property alias isClosing: hideTimer.running
readonly property real barHeight: Style.barHeight * scaling readonly property real barHeight: Math.round(Style.barHeight * scaling)
readonly property bool barAtBottom: Settings.data.bar.position === "bottom" readonly property bool barAtBottom: Settings.data.bar.position === "bottom"
signal opened signal opened