diff --git a/Packages/OnyxKit/Sources/WeatherProvider/Localizable.xcstrings b/Packages/OnyxKit/Sources/WeatherProvider/Localizable.xcstrings index db1dd4e..6d3830d 100644 --- a/Packages/OnyxKit/Sources/WeatherProvider/Localizable.xcstrings +++ b/Packages/OnyxKit/Sources/WeatherProvider/Localizable.xcstrings @@ -17,6 +17,22 @@ } } }, + "weather.feelsLike %@": { + "localizations": { + "de": { + "stringUnit": { + "state": "translated", + "value": "gefühlt %@" + } + }, + "en": { + "stringUnit": { + "state": "translated", + "value": "feels like %@" + } + } + } + }, "widget.weather.asOf": { "comment": "%@ ist die Uhrzeit des Messwerts", "localizations": { diff --git a/Packages/OnyxKit/Sources/WeatherProvider/WeatherWidget.swift b/Packages/OnyxKit/Sources/WeatherProvider/WeatherWidget.swift index 8e85423..f17ce17 100644 --- a/Packages/OnyxKit/Sources/WeatherProvider/WeatherWidget.swift +++ b/Packages/OnyxKit/Sources/WeatherProvider/WeatherWidget.swift @@ -210,52 +210,72 @@ private struct WideWeather: View { let isStale: Bool var body: some View { - VStack(alignment: .leading, spacing: 6) { - HStack(alignment: .top, spacing: 8) { + // Der Aufbau folgt der Reihenfolge, in der man liest: erst was jetzt + // ist, dann was noch kommt. Vorher stand alles im oberen Drittel und + // die untere Hälfte war leer — bei Schriftgrößen von acht Punkten, die + // man auf Armlänge nicht entziffert. + VStack(alignment: .leading, spacing: 0) { + HStack(alignment: .center, spacing: 10) { Image(systemName: snapshot.condition.symbolName(isDaylight: snapshot.isDaylight)) - .font(.system(size: 22)) + .font(.system(size: 34)) .symbolRenderingMode(.hierarchical) .foregroundStyle(Onyx.Color.textPrimary) - VStack(alignment: .leading, spacing: 1) { + VStack(alignment: .leading, spacing: 0) { Text(snapshot.temperature.onyxFormatted) - .font(Onyx.Font.metric) + .font(.system(size: 30, weight: .medium)) + .monospacedDigit() .foregroundStyle(Onyx.Color.textPrimary) - Text(snapshot.placeName) - .font(.system(size: 10)) - .foregroundStyle(Onyx.Color.textSecondary) - .lineLimit(1) + if let high = snapshot.high, let low = snapshot.low { + Text("↑ \(high.onyxFormatted) ↓ \(low.onyxFormatted)") + .font(Onyx.Font.metricSmall) + .monospacedDigit() + .foregroundStyle(Onyx.Color.textTertiary) + } } Spacer(minLength: 0) - - if let high = snapshot.high, let low = snapshot.low { - VStack(alignment: .trailing, spacing: 1) { - Text("↑ \(high.onyxFormatted)") - Text("↓ \(low.onyxFormatted)") - } - .font(Onyx.Font.metricSmall) - .foregroundStyle(Onyx.Color.textTertiary) - } } + Text(snapshot.placeName) + .font(Onyx.Font.caption) + .foregroundStyle(Onyx.Color.textSecondary) + .lineLimit(1) + .padding(.top, 2) + + if snapshot.apparentTemperature != snapshot.temperature { + Text("weather.feelsLike \(snapshot.apparentTemperature.onyxFormatted)", + bundle: .module) + .font(Onyx.Font.metricSmall) + .foregroundStyle(Onyx.Color.textTertiary) + } + + Spacer(minLength: 6) + if !snapshot.hourly.isEmpty { + Divider().overlay(Onyx.Color.hairline) + + // Vier statt fünf Stunden: bei 180 Punkten Breite bleiben so + // gut vierzig je Spalte, und die Zahlen lassen sich in einer + // lesbaren Größe setzen. HStack(spacing: 0) { - ForEach(snapshot.hourly.prefix(5)) { point in - VStack(spacing: 2) { + ForEach(snapshot.hourly.prefix(4)) { point in + VStack(spacing: 3) { Text(point.date.formatted(.dateTime.hour())) - .font(.system(size: 8)) + .font(Onyx.Font.metricSmall) .foregroundStyle(Onyx.Color.textTertiary) Image(systemName: point.condition.symbolName(isDaylight: true)) - .font(.system(size: 9)) + .font(.system(size: 13)) + .symbolRenderingMode(.hierarchical) .foregroundStyle(Onyx.Color.textSecondary) Text(point.temperature.onyxFormatted) - .font(.system(size: 9)) + .font(Onyx.Font.caption) .monospacedDigit() - .foregroundStyle(Onyx.Color.textSecondary) + .foregroundStyle(Onyx.Color.textPrimary) } .frame(maxWidth: .infinity) } } + .padding(.vertical, 8) } Spacer(minLength: 0) @@ -263,17 +283,17 @@ private struct WideWeather: View { HStack(spacing: 4) { if isStale { Image(systemName: "exclamationmark.triangle.fill") - .font(.system(size: 8)) + .font(.system(size: 9)) .foregroundStyle(Onyx.Color.warning) } Text(stampText) - .font(.system(size: 8)) + .font(Onyx.Font.metricSmall) .foregroundStyle(Onyx.Color.textTertiary) Spacer(minLength: 0) if let attribution = snapshot.attribution { // Pflichtangabe, klickbar auf Apples Rechtshinweise. Link(attribution.name, destination: attribution.legalPageURL) - .font(.system(size: 8)) + .font(Onyx.Font.metricSmall) .foregroundStyle(Onyx.Color.textTertiary) } }