Add weather feature with WeatherKit integration for mood entries
Fetch and display weather data (temp, condition, hi/lo, humidity) when users log a mood. Weather is stored as JSON on MoodEntryModel and shown as a card in EntryDetailView. Premium-gated with location permission prompt. Includes BGTask retry for failed fetches and full analytics. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
70
Shared/Views/DayView/WeatherCardView.swift
Normal file
70
Shared/Views/DayView/WeatherCardView.swift
Normal file
@@ -0,0 +1,70 @@
|
||||
//
|
||||
// WeatherCardView.swift
|
||||
// Reflect
|
||||
//
|
||||
// Visual weather card shown in EntryDetailView.
|
||||
//
|
||||
|
||||
import SwiftUI
|
||||
|
||||
struct WeatherCardView: View {
|
||||
let weatherData: WeatherData
|
||||
|
||||
private var highTemp: String {
|
||||
formatTemperature(weatherData.highTemperature)
|
||||
}
|
||||
|
||||
private var lowTemp: String {
|
||||
formatTemperature(weatherData.lowTemperature)
|
||||
}
|
||||
|
||||
private var humidityPercent: String {
|
||||
"\(Int(weatherData.humidity * 100))%"
|
||||
}
|
||||
|
||||
var body: some View {
|
||||
HStack(spacing: 14) {
|
||||
Image(systemName: weatherData.conditionSymbol)
|
||||
.font(.system(size: 36))
|
||||
.symbolRenderingMode(.multicolor)
|
||||
.frame(width: 44)
|
||||
|
||||
VStack(alignment: .leading, spacing: 4) {
|
||||
Text(weatherData.condition)
|
||||
.font(.subheadline)
|
||||
.fontWeight(.medium)
|
||||
|
||||
HStack(spacing: 8) {
|
||||
Label(String(localized: "H: \(highTemp)"), systemImage: "thermometer.high")
|
||||
Label(String(localized: "L: \(lowTemp)"), systemImage: "thermometer.low")
|
||||
Label(humidityPercent, systemImage: "humidity")
|
||||
}
|
||||
.font(.caption)
|
||||
.foregroundStyle(.secondary)
|
||||
.labelStyle(.titleOnly)
|
||||
}
|
||||
|
||||
Spacer()
|
||||
}
|
||||
.padding()
|
||||
.background(
|
||||
RoundedRectangle(cornerRadius: 16)
|
||||
.fill(Color(.systemBackground))
|
||||
)
|
||||
}
|
||||
|
||||
private func formatTemperature(_ celsius: Double) -> String {
|
||||
let measurement = Measurement(value: celsius, unit: UnitTemperature.celsius)
|
||||
let formatter = MeasurementFormatter()
|
||||
formatter.unitOptions = .providedUnit
|
||||
formatter.numberFormatter.maximumFractionDigits = 0
|
||||
formatter.unitStyle = .short
|
||||
// Use locale-aware conversion
|
||||
let locale = Locale.current
|
||||
if locale.measurementSystem == .us {
|
||||
let fahrenheit = measurement.converted(to: .fahrenheit)
|
||||
return formatter.string(from: fahrenheit)
|
||||
}
|
||||
return formatter.string(from: measurement)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user