From ed5bd01482c810f9047c7c0e882dfd8f6400de32 Mon Sep 17 00:00:00 2001 From: Scarriffle Date: Thu, 13 Aug 2026 16:07:26 +0200 Subject: [PATCH] =?UTF-8?q?Wetterkachel=20f=C3=BCllt=20die=20Kachel=20und?= =?UTF-8?q?=20ist=20lesbar?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Alles stand im oberen Drittel, die untere Hälfte war leer — und die Stundenwerte in acht Punkten, die man auf Armlänge nicht entziffert. Der Aufbau folgt jetzt der Reihenfolge, in der man liest: erst was jetzt ist — großes Symbol, große Temperatur, Höchst- und Tiefstwert daneben, darunter der Ort und die gefühlte Temperatur —, dann getrennt durch eine Linie, was noch kommt. Vier Stunden statt fünf: bei 180 Punkten Breite bleiben so gut vierzig je Spalte, und die Zahlen lassen sich in einer Größe setzen, die man auch liest. Die fünfte Stunde war der Grund, warum alles zusammengedrückt war. Co-Authored-By: Claude Opus 5 --- .../WeatherProvider/Localizable.xcstrings | 16 ++++ .../WeatherProvider/WeatherWidget.swift | 74 ++++++++++++------- 2 files changed, 63 insertions(+), 27 deletions(-) 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) } }