Fix weather panel clipping and units
This commit is contained in:
@@ -40,6 +40,7 @@ PanelWindow {
|
|||||||
property int padding: Style.spacing.popupPadding
|
property int padding: Style.spacing.popupPadding
|
||||||
property int contentWidth: Style.space(280)
|
property int contentWidth: Style.space(280)
|
||||||
property int contentHeight: Style.space(200)
|
property int contentHeight: Style.space(200)
|
||||||
|
property var borderSpec: Border.surfaceSpec("popups", "border", Color.popups.border, Math.max(1, Style.space(2)))
|
||||||
property bool centerOnBar: false
|
property bool centerOnBar: false
|
||||||
property bool open: false
|
property bool open: false
|
||||||
property int gap: Style.gapsOut // distance between bar edge and panel
|
property int gap: Style.gapsOut // distance between bar edge and panel
|
||||||
@@ -135,6 +136,7 @@ PanelWindow {
|
|||||||
readonly property real availableCardHeight: screenH > 0
|
readonly property real availableCardHeight: screenH > 0
|
||||||
? Math.max(120, screenH - ((barPos === "top" || barPos === "bottom") ? barH + gap + margin : margin * 2))
|
? Math.max(120, screenH - ((barPos === "top" || barPos === "bottom") ? barH + gap + margin : margin * 2))
|
||||||
: 0
|
: 0
|
||||||
|
readonly property real verticalContentInset: padding * 2 + Border.top(borderSpec) + Border.bottom(borderSpec)
|
||||||
|
|
||||||
function fittedContentWidth(width, cap) {
|
function fittedContentWidth(width, cap) {
|
||||||
var desired = Math.max(1, Number(width) || 1)
|
var desired = Math.max(1, Number(width) || 1)
|
||||||
@@ -144,7 +146,7 @@ PanelWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function fittedContentHeight(implicitHeight, cap) {
|
function fittedContentHeight(implicitHeight, cap) {
|
||||||
var desired = Math.max(root.padding * 2, (Number(implicitHeight) || 0) + root.padding * 2)
|
var desired = Math.max(root.verticalContentInset, (Number(implicitHeight) || 0) + root.verticalContentInset)
|
||||||
var maxHeight = root.availableCardHeight > 0 ? root.availableCardHeight : desired
|
var maxHeight = root.availableCardHeight > 0 ? root.availableCardHeight : desired
|
||||||
if (cap !== undefined && Number(cap) > 0) maxHeight = Math.min(maxHeight, Number(cap))
|
if (cap !== undefined && Number(cap) > 0) maxHeight = Math.min(maxHeight, Number(cap))
|
||||||
return Math.round(Math.min(desired, maxHeight))
|
return Math.round(Math.min(desired, maxHeight))
|
||||||
@@ -297,7 +299,7 @@ PanelWindow {
|
|||||||
width: root.contentWidth
|
width: root.contentWidth
|
||||||
height: root.contentHeight
|
height: root.contentHeight
|
||||||
color: Color.popups.background
|
color: Color.popups.background
|
||||||
borderSpec: Border.surfaceSpec("popups", "border", Color.popups.border, Math.max(1, Style.space(2)))
|
borderSpec: root.borderSpec
|
||||||
padding: root.padding
|
padding: root.padding
|
||||||
radius: Style.cornerRadius
|
radius: Style.cornerRadius
|
||||||
opacity: root.open || root.popoutSwitching ? 1.0 : 0
|
opacity: root.open || root.popoutSwitching ? 1.0 : 0
|
||||||
|
|||||||
@@ -35,6 +35,7 @@ PopupWindow {
|
|||||||
readonly property real availableCardHeight: screenH > 0
|
readonly property real availableCardHeight: screenH > 0
|
||||||
? Math.max(120, screenH - ((bar && (bar.position === "top" || bar.position === "bottom")) ? barH : 0) - root.margin * 2)
|
? Math.max(120, screenH - ((bar && (bar.position === "top" || bar.position === "bottom")) ? barH : 0) - root.margin * 2)
|
||||||
: 0
|
: 0
|
||||||
|
readonly property real verticalContentInset: padding * 2 + Border.top(borderSpec) + Border.bottom(borderSpec)
|
||||||
|
|
||||||
function fittedContentWidth(width, cap) {
|
function fittedContentWidth(width, cap) {
|
||||||
var desired = Math.max(1, Number(width) || 1)
|
var desired = Math.max(1, Number(width) || 1)
|
||||||
@@ -44,7 +45,7 @@ PopupWindow {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function fittedContentHeight(implicitHeight, cap) {
|
function fittedContentHeight(implicitHeight, cap) {
|
||||||
var desired = Math.max(root.padding * 2, (Number(implicitHeight) || 0) + root.padding * 2)
|
var desired = Math.max(root.verticalContentInset, (Number(implicitHeight) || 0) + root.verticalContentInset)
|
||||||
var maxHeight = root.availableCardHeight > 0 ? root.availableCardHeight : desired
|
var maxHeight = root.availableCardHeight > 0 ? root.availableCardHeight : desired
|
||||||
if (cap !== undefined && Number(cap) > 0) maxHeight = Math.min(maxHeight, Number(cap))
|
if (cap !== undefined && Number(cap) > 0) maxHeight = Math.min(maxHeight, Number(cap))
|
||||||
return Math.round(Math.min(desired, maxHeight))
|
return Math.round(Math.min(desired, maxHeight))
|
||||||
|
|||||||
@@ -32,6 +32,37 @@ function formatTemp(value, useImperial) {
|
|||||||
return value + "°" + (useImperial ? "F" : "C")
|
return value + "°" + (useImperial ? "F" : "C")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function normalizedUnit(value) {
|
||||||
|
return String(value || "").replace(/^\s+|\s+$/g, "").toLowerCase()
|
||||||
|
}
|
||||||
|
|
||||||
|
function localeUsesImperial(localeName) {
|
||||||
|
var name = String(localeName || "").replace(".", "_")
|
||||||
|
return /^en[_-]US($|[_.-])/.test(name) || /^en[_-]LR($|[_.-])/.test(name) || /^my($|[_.-])/.test(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
function countryUsesImperial(countryName) {
|
||||||
|
var country = String(countryName || "")
|
||||||
|
.replace(/^\s+|\s+$/g, "")
|
||||||
|
.replace(/[._-]+/g, " ")
|
||||||
|
.toLowerCase()
|
||||||
|
if (!country) return null
|
||||||
|
if (country === "us" || country === "usa" || country === "united states" || country === "united states of america") return true
|
||||||
|
if (country === "liberia" || country === "myanmar" || country === "burma") return true
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
|
||||||
|
function shouldUseImperial(unitOverride, localeName, countryName) {
|
||||||
|
var unit = normalizedUnit(unitOverride)
|
||||||
|
if (unit === "imperial") return true
|
||||||
|
if (unit === "metric") return false
|
||||||
|
|
||||||
|
var countryPreference = countryUsesImperial(countryName)
|
||||||
|
if (countryPreference !== null) return countryPreference
|
||||||
|
|
||||||
|
return localeUsesImperial(localeName)
|
||||||
|
}
|
||||||
|
|
||||||
function dayName(dateString, formatter) {
|
function dayName(dateString, formatter) {
|
||||||
if (!dateString) return ""
|
if (!dateString) return ""
|
||||||
var d = new Date(dateString + "T12:00:00")
|
var d = new Date(dateString + "T12:00:00")
|
||||||
@@ -143,6 +174,10 @@ if (typeof module !== "undefined") {
|
|||||||
roundedTemp: roundedTemp,
|
roundedTemp: roundedTemp,
|
||||||
celsiusToFahrenheit: celsiusToFahrenheit,
|
celsiusToFahrenheit: celsiusToFahrenheit,
|
||||||
formatTemp: formatTemp,
|
formatTemp: formatTemp,
|
||||||
|
normalizedUnit: normalizedUnit,
|
||||||
|
localeUsesImperial: localeUsesImperial,
|
||||||
|
countryUsesImperial: countryUsesImperial,
|
||||||
|
shouldUseImperial: shouldUseImperial,
|
||||||
dayName: dayName,
|
dayName: dayName,
|
||||||
openMeteoForecastDays: openMeteoForecastDays,
|
openMeteoForecastDays: openMeteoForecastDays,
|
||||||
wttrNextForecastDays: wttrNextForecastDays,
|
wttrNextForecastDays: wttrNextForecastDays,
|
||||||
|
|||||||
@@ -61,14 +61,9 @@ Panel {
|
|||||||
readonly property var current: report && report.current_condition && report.current_condition[0] ? report.current_condition[0] : null
|
readonly property var current: report && report.current_condition && report.current_condition[0] ? report.current_condition[0] : null
|
||||||
readonly property var areaInfo: report && report.nearest_area && report.nearest_area[0] ? report.nearest_area[0] : null
|
readonly property var areaInfo: report && report.nearest_area && report.nearest_area[0] ? report.nearest_area[0] : null
|
||||||
readonly property var forecastDays: buildForecastDays()
|
readonly property var forecastDays: buildForecastDays()
|
||||||
|
readonly property string reportCountry: areaInfo && areaInfo.country && areaInfo.country[0] ? areaInfo.country[0].value : ""
|
||||||
|
|
||||||
readonly property bool useImperial: {
|
readonly property bool useImperial: Model.shouldUseImperial(setting("unit", ""), Qt.locale().name, reportCountry)
|
||||||
var override = setting("unit", "")
|
|
||||||
if (override === "imperial") return true
|
|
||||||
if (override === "metric") return false
|
|
||||||
var name = String(Qt.locale().name || "")
|
|
||||||
return /^en_US/.test(name) || /^en_LR/.test(name) || /^my/.test(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Auto-refresh interval in minutes; clamped to a sane minimum.
|
// Auto-refresh interval in minutes; clamped to a sane minimum.
|
||||||
readonly property int refreshMinutes: Math.max(1, parseInt(setting("refreshMinutes", 15), 10) || 15)
|
readonly property int refreshMinutes: Math.max(1, parseInt(setting("refreshMinutes", 15), 10) || 15)
|
||||||
|
|||||||
@@ -18,6 +18,11 @@ assertEqual(weather.roundedTemp('21.6'), '22', 'weather rounds temperatures')
|
|||||||
assertEqual(weather.roundedTemp('nope'), '', 'weather ignores invalid temperatures')
|
assertEqual(weather.roundedTemp('nope'), '', 'weather ignores invalid temperatures')
|
||||||
assertEqual(weather.formatTemp(72, true), '72°F', 'weather formats imperial temperatures')
|
assertEqual(weather.formatTemp(72, true), '72°F', 'weather formats imperial temperatures')
|
||||||
assertEqual(weather.formatTemp(22, false), '22°C', 'weather formats metric temperatures')
|
assertEqual(weather.formatTemp(22, false), '22°C', 'weather formats metric temperatures')
|
||||||
|
assertEqual(weather.shouldUseImperial('', 'en_US', ''), true, 'weather falls back to US locale for imperial units')
|
||||||
|
assertEqual(weather.shouldUseImperial('', 'en_US', 'Denmark'), false, 'weather prefers reported metric country over US locale')
|
||||||
|
assertEqual(weather.shouldUseImperial('', 'da_DK', 'United States of America'), true, 'weather prefers reported imperial country over metric locale')
|
||||||
|
assertEqual(weather.shouldUseImperial('metric', 'en_US', 'United States of America'), false, 'weather metric override wins')
|
||||||
|
assertEqual(weather.shouldUseImperial('imperial', 'da_DK', 'Denmark'), true, 'weather imperial override wins')
|
||||||
assertEqual(weather.dayName('2026-05-25'), 'Monday', 'weather derives day names')
|
assertEqual(weather.dayName('2026-05-25'), 'Monday', 'weather derives day names')
|
||||||
|
|
||||||
const openMeteo = {
|
const openMeteo = {
|
||||||
|
|||||||
Reference in New Issue
Block a user