summaryrefslogtreecommitdiffstats
path: root/Solsnu.Widget
diff options
context:
space:
mode:
authorivar <i@oiee.no>2026-05-06 21:21:17 +0200
committerivar <i@oiee.no>2026-05-06 21:21:17 +0200
commit54dd55db8c19667939536e18535ac9c45817e442 (patch)
tree7ccb609b16e731c6281aa8d23969fb51c42eb60f /Solsnu.Widget
parentefae4d08083f454975f08a2c0c6871c6a3d41e95 (diff)
downloadsolverv-54dd55db8c19667939536e18535ac9c45817e442.tar.xz
solverv-54dd55db8c19667939536e18535ac9c45817e442.zip
refactor: remove duplicate source files now served from Shared/
Diffstat (limited to 'Solsnu.Widget')
-rw-r--r--Solsnu.Widget/Models/Season.swift49
-rw-r--r--Solsnu.Widget/Models/SolsticeData.swift114
-rw-r--r--Solsnu.Widget/Models/SolsticeEvent.swift38
-rw-r--r--Solsnu.Widget/Solsnu_Widget.swift8
-rw-r--r--Solsnu.Widget/Solsnu_WidgetBundle.swift25
-rw-r--r--Solsnu.Widget/Solsnu_WidgetControl.swift1
-rw-r--r--Solsnu.Widget/Utilities/AppGroupManager.swift67
-rw-r--r--Solsnu.Widget/Utilities/SunTimes.swift148
-rw-r--r--Solsnu.Widget/Views/SmallWidgetView.swift5
9 files changed, 7 insertions, 448 deletions
diff --git a/Solsnu.Widget/Models/Season.swift b/Solsnu.Widget/Models/Season.swift
deleted file mode 100644
index 01eaf99..0000000
--- a/Solsnu.Widget/Models/Season.swift
+++ /dev/null
@@ -1,49 +0,0 @@
-import SwiftUI
-
-enum Season: String, Codable {
- case spring
- case summer
- case autumn
- case winter
-
- var displayName: String {
- switch self {
- case .spring: return "Spring"
- case .summer: return "Summer"
- case .autumn: return "Autumn"
- case .winter: return "Winter"
- }
- }
-
- var description: String {
- switch self {
- case .spring: return "Day and night are approximately equal length"
- case .summer: return "Longest day of the year"
- case .autumn: return "Day and night are approximately equal length"
- case .winter: return "Shortest day of the year"
- }
- }
-
- var colorLight: Color {
- switch self {
- case .spring: return Color(red: 0.298, green: 0.686, blue: 0.314) // #4CAF50
- case .summer: return Color(red: 1.0, green: 0.761, blue: 0.039) // #FFC107
- case .autumn: return Color(red: 1.0, green: 0.596, blue: 0.0) // #FF9800
- case .winter: return Color(red: 0.129, green: 0.588, blue: 0.953) // #2196F3
- }
- }
-
- var assetName: String {
- return "Season\(displayName)"
- }
-
- static func fromDate(_ date: Date) -> Season {
- let month = Calendar.current.component(.month, from: date)
- switch month {
- case 3, 4, 5: return .spring
- case 6, 7, 8: return .summer
- case 9, 10, 11: return .autumn
- default: return .winter
- }
- }
-}
diff --git a/Solsnu.Widget/Models/SolsticeData.swift b/Solsnu.Widget/Models/SolsticeData.swift
deleted file mode 100644
index 5a36da7..0000000
--- a/Solsnu.Widget/Models/SolsticeData.swift
+++ /dev/null
@@ -1,114 +0,0 @@
-import Foundation
-
-class SolsticeData {
- static let shared = SolsticeData()
-
- private let events: [SolsticeEvent]
-
- private init() {
- // Hardcoded solstice/equinox events for 2025-2030 (all in UTC)
- var allEvents: [SolsticeEvent] = []
-
- // 2025
- allEvents.append(SolsticeEvent(name: "Spring Equinox 2025", date: SolsticeData.dateFromUTC(year: 2025, month: 3, day: 20, hour: 9, minute: 1), season: .spring))
- allEvents.append(SolsticeEvent(name: "Summer Solstice 2025", date: SolsticeData.dateFromUTC(year: 2025, month: 6, day: 20, hour: 14, minute: 42), season: .summer))
- allEvents.append(SolsticeEvent(name: "Autumn Equinox 2025", date: SolsticeData.dateFromUTC(year: 2025, month: 9, day: 22, hour: 18, minute: 20), season: .autumn))
- allEvents.append(SolsticeEvent(name: "Winter Solstice 2025", date: SolsticeData.dateFromUTC(year: 2025, month: 12, day: 21, hour: 15, minute: 3), season: .winter))
-
- // 2026
- allEvents.append(SolsticeEvent(name: "Spring Equinox 2026", date: SolsticeData.dateFromUTC(year: 2026, month: 3, day: 20, hour: 14, minute: 46), season: .spring))
- allEvents.append(SolsticeEvent(name: "Summer Solstice 2026", date: SolsticeData.dateFromUTC(year: 2026, month: 6, day: 21, hour: 8, minute: 25), season: .summer))
- allEvents.append(SolsticeEvent(name: "Autumn Equinox 2026", date: SolsticeData.dateFromUTC(year: 2026, month: 9, day: 23, hour: 0, minute: 6), season: .autumn))
- allEvents.append(SolsticeEvent(name: "Winter Solstice 2026", date: SolsticeData.dateFromUTC(year: 2026, month: 12, day: 21, hour: 20, minute: 50), season: .winter))
-
- // 2027
- allEvents.append(SolsticeEvent(name: "Spring Equinox 2027", date: SolsticeData.dateFromUTC(year: 2027, month: 3, day: 20, hour: 20, minute: 25), season: .spring))
- allEvents.append(SolsticeEvent(name: "Summer Solstice 2027", date: SolsticeData.dateFromUTC(year: 2027, month: 6, day: 21, hour: 14, minute: 11), season: .summer))
- allEvents.append(SolsticeEvent(name: "Autumn Equinox 2027", date: SolsticeData.dateFromUTC(year: 2027, month: 9, day: 23, hour: 6, minute: 2), season: .autumn))
- allEvents.append(SolsticeEvent(name: "Winter Solstice 2027", date: SolsticeData.dateFromUTC(year: 2027, month: 12, day: 22, hour: 2, minute: 43), season: .winter))
-
- // 2028
- allEvents.append(SolsticeEvent(name: "Spring Equinox 2028", date: SolsticeData.dateFromUTC(year: 2028, month: 3, day: 20, hour: 2, minute: 17), season: .spring))
- allEvents.append(SolsticeEvent(name: "Summer Solstice 2028", date: SolsticeData.dateFromUTC(year: 2028, month: 6, day: 20, hour: 20, minute: 2), season: .summer))
- allEvents.append(SolsticeEvent(name: "Autumn Equinox 2028", date: SolsticeData.dateFromUTC(year: 2028, month: 9, day: 22, hour: 11, minute: 45), season: .autumn))
- allEvents.append(SolsticeEvent(name: "Winter Solstice 2028", date: SolsticeData.dateFromUTC(year: 2028, month: 12, day: 21, hour: 8, minute: 20), season: .winter))
-
- // 2029
- allEvents.append(SolsticeEvent(name: "Spring Equinox 2029", date: SolsticeData.dateFromUTC(year: 2029, month: 3, day: 20, hour: 8, minute: 1), season: .spring))
- allEvents.append(SolsticeEvent(name: "Summer Solstice 2029", date: SolsticeData.dateFromUTC(year: 2029, month: 6, day: 21, hour: 1, minute: 48), season: .summer))
- allEvents.append(SolsticeEvent(name: "Autumn Equinox 2029", date: SolsticeData.dateFromUTC(year: 2029, month: 9, day: 22, hour: 17, minute: 37), season: .autumn))
- allEvents.append(SolsticeEvent(name: "Winter Solstice 2029", date: SolsticeData.dateFromUTC(year: 2029, month: 12, day: 21, hour: 14, minute: 14), season: .winter))
-
- // 2030
- allEvents.append(SolsticeEvent(name: "Spring Equinox 2030", date: SolsticeData.dateFromUTC(year: 2030, month: 3, day: 20, hour: 13, minute: 51), season: .spring))
- allEvents.append(SolsticeEvent(name: "Summer Solstice 2030", date: SolsticeData.dateFromUTC(year: 2030, month: 6, day: 21, hour: 7, minute: 31), season: .summer))
- allEvents.append(SolsticeEvent(name: "Autumn Equinox 2030", date: SolsticeData.dateFromUTC(year: 2030, month: 9, day: 22, hour: 23, minute: 27), season: .autumn))
- allEvents.append(SolsticeEvent(name: "Winter Solstice 2030", date: SolsticeData.dateFromUTC(year: 2030, month: 12, day: 21, hour: 20, minute: 9), season: .winter))
-
- // Sort events by date
- self.events = allEvents.sorted { $0.date < $1.date }
- }
-
- /// Helper function to create UTC dates (static to be usable during init)
- private static func dateFromUTC(year: Int, month: Int, day: Int, hour: Int, minute: Int) -> Date {
- var components = DateComponents()
- components.year = year
- components.month = month
- components.day = day
- components.hour = hour
- components.minute = minute
- components.second = 0
- components.timeZone = TimeZone(abbreviation: "UTC")
-
- return Calendar(identifier: .gregorian).date(from: components) ?? Date()
- }
-
- /// Returns the next upcoming solstice/equinox event
- func nextEvent() -> SolsticeEvent? {
- let now = Date()
- return events.first { $0.date > now }
- }
-
- /// Returns the next N upcoming events
- func upcomingEvents(count: Int) -> [SolsticeEvent] {
- let now = Date()
- let futureEvents = events.filter { $0.date > now }
- return Array(futureEvents.prefix(count))
- }
-
- /// Returns the progress to the next event as (elapsed days, total days)
- func progressToNextEvent() -> (elapsed: Int, total: Int)? {
- guard let nextEvent = nextEvent() else {
- return nil
- }
-
- let now = Date()
- let today = Calendar.current.startOfDay(for: now)
- let eventDay = Calendar.current.startOfDay(for: nextEvent.date)
-
- // Find the previous event to calculate total days
- guard let previousEventIndex = events.firstIndex(where: { $0.date > now }) else {
- return nil
- }
-
- let previousEvent: Date
- if previousEventIndex > 0 {
- previousEvent = events[previousEventIndex - 1].date
- } else {
- // If this is the first event, we need to handle this case
- // Use the event itself minus some arbitrary period (not applicable for first event)
- return nil
- }
-
- let previousEventDay = Calendar.current.startOfDay(for: previousEvent)
-
- // Calculate elapsed and total days
- let elapsedComponents = Calendar.current.dateComponents([.day], from: previousEventDay, to: today)
- let totalComponents = Calendar.current.dateComponents([.day], from: previousEventDay, to: eventDay)
-
- let elapsed = max(0, elapsedComponents.day ?? 0)
- let total = max(1, totalComponents.day ?? 1)
-
- return (elapsed: elapsed, total: total)
- }
-}
diff --git a/Solsnu.Widget/Models/SolsticeEvent.swift b/Solsnu.Widget/Models/SolsticeEvent.swift
deleted file mode 100644
index d8c4a7b..0000000
--- a/Solsnu.Widget/Models/SolsticeEvent.swift
+++ /dev/null
@@ -1,38 +0,0 @@
-import Foundation
-
-struct SolsticeEvent: Identifiable, Codable {
- let id: UUID
- let name: String
- let date: Date // UTC
- let season: Season
-
- init(name: String, date: Date, season: Season) {
- self.id = UUID()
- self.name = name
- self.date = date
- self.season = season
- }
-
- /// Convert UTC date to user's local timezone
- func localDateTime() -> Date {
- let utcCalendar = Calendar(identifier: .gregorian)
- let utcComponents = utcCalendar.dateComponents([.year, .month, .day, .hour, .minute, .second], from: date)
- let timeZone = TimeZone.current
- let offset = timeZone.secondsFromGMT(for: date)
-
- var localCalendar = Calendar.current
- localCalendar.timeZone = timeZone
- var localComponents = utcComponents
- localComponents.second = (localComponents.second ?? 0) + offset
-
- return localCalendar.date(from: localComponents) ?? date
- }
-
- /// Days until this event from today
- func daysUntil() -> Int {
- let today = Calendar.current.startOfDay(for: Date())
- let eventDay = Calendar.current.startOfDay(for: date)
- let components = Calendar.current.dateComponents([.day], from: today, to: eventDay)
- return max(0, components.day ?? 0)
- }
-}
diff --git a/Solsnu.Widget/Solsnu_Widget.swift b/Solsnu.Widget/Solsnu_Widget.swift
index 20e8a8e..c36cc34 100644
--- a/Solsnu.Widget/Solsnu_Widget.swift
+++ b/Solsnu.Widget/Solsnu_Widget.swift
@@ -171,22 +171,22 @@ extension SolvervDef {
}
var nextEvent: SolsticeEvent? {
- SolsticeData.shared.nextEvent()
+ SolsticeData.shared.nextEvent(from: date)
}
func daysUntilNext() -> Int {
guard let next = nextEvent else { return 0 }
- return next.daysUntil()
+ return next.daysUntil(from: date)
}
func progressRatio() -> Double {
- guard let progress = SolsticeData.shared.progressToNextEvent() else { return 0.0 }
+ guard let progress = SolsticeData.shared.progressToNextEvent(from: date) else { return 0.0 }
let ratio = Double(progress.elapsed) / Double(progress.total)
return max(0, min(1.0, ratio))
}
func upcomingEventsPreview(count: Int) -> [SolsticeEvent] {
- SolsticeData.shared.upcomingEvents(count: count)
+ SolsticeData.shared.upcomingEvents(count: count, from: date)
}
static var preview: SolvervDef {
diff --git a/Solsnu.Widget/Solsnu_WidgetBundle.swift b/Solsnu.Widget/Solsnu_WidgetBundle.swift
index 8a7b718..7bd3f1a 100644
--- a/Solsnu.Widget/Solsnu_WidgetBundle.swift
+++ b/Solsnu.Widget/Solsnu_WidgetBundle.swift
@@ -13,11 +13,9 @@ struct Solsnu_WidgetBundle: WidgetBundle {
var body: some Widget {
Solsnu_Widget()
Solsnu_WidgetMedium()
- Solsnu_WidgetLarge()
}
}
-// Medium widget
struct Solsnu_WidgetMedium: Widget {
let kind: String = "Solsnu_Widget_Medium"
@@ -34,27 +32,6 @@ struct Solsnu_WidgetMedium: Widget {
}
.configurationDisplayName("Solstice Countdown")
.description("Days until next solstice or equinox")
- .supportedFamilies([.systemMedium])
- }
-}
-
-// Large widget
-struct Solsnu_WidgetLarge: Widget {
- let kind: String = "Solsnu_Widget_Large"
-
- var body: some WidgetConfiguration {
- StaticConfiguration(kind: kind, provider: Provider()) { entry in
- if #available(iOS 17.0, *) {
- LargeWidgetView(entry: entry)
- .containerBackground(.fill.tertiary, for: .widget)
- } else {
- LargeWidgetView(entry: entry)
- .padding()
- .background()
- }
- }
- .configurationDisplayName("Solstice Countdown")
- .description("Days until next solstice or equinox")
- .supportedFamilies([.systemLarge])
+ .supportedFamilies([.systemMedium,.systemSmall])
}
}
diff --git a/Solsnu.Widget/Solsnu_WidgetControl.swift b/Solsnu.Widget/Solsnu_WidgetControl.swift
index 62cd817..686a824 100644
--- a/Solsnu.Widget/Solsnu_WidgetControl.swift
+++ b/Solsnu.Widget/Solsnu_WidgetControl.swift
@@ -52,3 +52,4 @@ struct StartTimerIntent: SetValueIntent {
return .result()
}
}
+ \ No newline at end of file
diff --git a/Solsnu.Widget/Utilities/AppGroupManager.swift b/Solsnu.Widget/Utilities/AppGroupManager.swift
deleted file mode 100644
index 95ff2de..0000000
--- a/Solsnu.Widget/Utilities/AppGroupManager.swift
+++ /dev/null
@@ -1,67 +0,0 @@
-import Foundation
-
-class AppGroupManager {
- static let shared = AppGroupManager()
- static let appGroupID = "group.com.ivarlovlie.solverv"
-
- private lazy var userDefaults: UserDefaults? = {
- UserDefaults(suiteName: Self.appGroupID)
- }()
-
- // MARK: - Location Storage
-
- struct UserLocation: Codable {
- let latitude: Double
- let longitude: Double
- let timestamp: String // ISO 8601
- let isDefaultLocation: Bool
- }
-
- func saveLocation(_ location: UserLocation) {
- guard let ud = userDefaults else { return }
- if let encoded = try? JSONEncoder().encode(location) {
- ud.set(encoded, forKey: "userLocation")
- }
- }
-
- func getLocation() -> UserLocation? {
- guard let ud = userDefaults,
- let data = ud.data(forKey: "userLocation"),
- let location = try? JSONDecoder().decode(UserLocation.self, from: data) else {
- return nil
- }
- return location
- }
-
- // MARK: - Sunrise/Sunset Storage
-
- struct SunTimes: Codable {
- let date: String // ISO 8601 date only (YYYY-MM-DD)
- let sunrise: String // ISO 8601 datetime
- let sunset: String // ISO 8601 datetime
- let timestamp: String // ISO 8601 when calculated
- }
-
- func saveSunTimes(_ sunTimes: SunTimes) {
- guard let ud = userDefaults else { return }
- if let encoded = try? JSONEncoder().encode(sunTimes) {
- ud.set(encoded, forKey: "sunTimes")
- }
- }
-
- func getSunTimes() -> SunTimes? {
- guard let ud = userDefaults,
- let data = ud.data(forKey: "sunTimes"),
- let sunTimes = try? JSONDecoder().decode(SunTimes.self, from: data) else {
- return nil
- }
- return sunTimes
- }
-
- // MARK: - Helpers
-
- func clearAllData() {
- userDefaults?.removeObject(forKey: "userLocation")
- userDefaults?.removeObject(forKey: "sunTimes")
- }
-}
diff --git a/Solsnu.Widget/Utilities/SunTimes.swift b/Solsnu.Widget/Utilities/SunTimes.swift
deleted file mode 100644
index 8c7132e..0000000
--- a/Solsnu.Widget/Utilities/SunTimes.swift
+++ /dev/null
@@ -1,148 +0,0 @@
-import Foundation
-
-class SunTimes {
- let latitude: Double
- let longitude: Double
- let date: Date
-
- init(latitude: Double, longitude: Double, date: Date) {
- self.latitude = latitude
- self.longitude = longitude
- self.date = date
- }
-
- /// Calculate sunrise time for the location and date
- func sunrise() -> Date? {
- guard let result = calculateSunTimes() else { return nil }
- return result.sunrise
- }
-
- /// Calculate sunset time for the location and date
- func sunset() -> Date? {
- guard let result = calculateSunTimes() else { return nil }
- return result.sunset
- }
-
- // NOAA solar position algorithm
- // Reference: https://www.esrl.noaa.gov/gmd/grad/solcalc/
- private func calculateSunTimes() -> (sunrise: Date, sunset: Date)? {
- let calendar = Calendar(identifier: .gregorian)
- let components = calendar.dateComponents([.year, .month, .day], from: date)
- guard let year = components.year else {
- return nil
- }
-
- // Step 1: Calculate day of year
- let jan1 = calendar.date(from: DateComponents(year: year, month: 1, day: 1))!
- let dayOfYear = calendar.dateComponents([.day], from: jan1, to: date).day! + 1
-
- // Step 2: Fractional year in radians
- let daysInYear = Double(isLeapYear(year) ? 366 : 365)
- let gamma = 2.0 * Double.pi * Double(dayOfYear - 1) / daysInYear
-
- // Step 3: Solar declination (radians)
- let decl = 0.006918 - 0.399912 * cos(gamma) + 0.070257 * sin(gamma)
- - 0.006758 * cos(2.0 * gamma) + 0.000907 * sin(2.0 * gamma)
- - 0.002697 * cos(3.0 * gamma) + 0.00148 * sin(3.0 * gamma)
-
- // Step 4: Equation of time (minutes)
- let eot = 229.18 * (0.000075 + 0.001868 * cos(gamma) - 0.032077 * sin(gamma)
- - 0.014615 * cos(2.0 * gamma) - 0.040849 * sin(2.0 * gamma))
-
- // Step 5: Hour angle at sunrise/sunset
- let latRad = latitude * Double.pi / 180.0
- let cosH = -tan(latRad) * tan(decl)
-
- guard cosH >= -1.0 && cosH <= 1.0 else {
- // Sun is always up or always down at this latitude/date
- return nil
- }
-
- let h = acos(cosH) * 180.0 / Double.pi
-
- // Step 6: Solar noon in UTC (decimal hours)
- let solarNoonUTC = 12.0 - (longitude / 15.0) - (eot / 60.0)
-
- // Step 7: Sunrise and sunset in UTC (decimal hours)
- let sunriseUTC = solarNoonUTC - (h / 15.0)
- let sunsetUTC = solarNoonUTC + (h / 15.0)
-
- // Step 8: Convert to local time (add timezone offset)
- let tzOffset = Double(TimeZone.current.secondsFromGMT(for: date)) / 3600.0
- let sunriseLocal = sunriseUTC + tzOffset
- let sunsetLocal = sunsetUTC + tzOffset
-
- // Step 9: Create date components, handling day boundary crossing
- let currentCalendar = Calendar.current
- let baseComponents = currentCalendar.dateComponents([.year, .month, .day], from: date)
-
- // Sunrise
- var sunriseComp = baseComponents
- let srHourDouble = sunriseLocal
- let srHour = Int(srHourDouble)
- let srMinuteDouble = (srHourDouble - Double(srHour)) * 60.0
- let srMinute = Int(srMinuteDouble)
-
- if srHour < 0 {
- if let prevDay = currentCalendar.date(byAdding: .day, value: -1, to: date) {
- let prevComponents = currentCalendar.dateComponents([.year, .month, .day], from: prevDay)
- sunriseComp = prevComponents
- sunriseComp.hour = 24 + srHour
- } else {
- sunriseComp.hour = 0
- }
- } else if srHour >= 24 {
- if let nextDay = currentCalendar.date(byAdding: .day, value: 1, to: date) {
- let nextComponents = currentCalendar.dateComponents([.year, .month, .day], from: nextDay)
- sunriseComp = nextComponents
- sunriseComp.hour = srHour - 24
- } else {
- sunriseComp.hour = 23
- }
- } else {
- sunriseComp.hour = srHour
- }
- sunriseComp.minute = max(0, min(59, srMinute))
- sunriseComp.second = 0
-
- // Sunset
- var sunsetComp = baseComponents
- let ssHourDouble = sunsetLocal
- let ssHour = Int(ssHourDouble)
- let ssMinuteDouble = (ssHourDouble - Double(ssHour)) * 60.0
- let ssMinute = Int(ssMinuteDouble)
-
- if ssHour < 0 {
- if let prevDay = currentCalendar.date(byAdding: .day, value: -1, to: date) {
- let prevComponents = currentCalendar.dateComponents([.year, .month, .day], from: prevDay)
- sunsetComp = prevComponents
- sunsetComp.hour = 24 + ssHour
- } else {
- sunsetComp.hour = 0
- }
- } else if ssHour >= 24 {
- if let nextDay = currentCalendar.date(byAdding: .day, value: 1, to: date) {
- let nextComponents = currentCalendar.dateComponents([.year, .month, .day], from: nextDay)
- sunsetComp = nextComponents
- sunsetComp.hour = ssHour - 24
- } else {
- sunsetComp.hour = 23
- }
- } else {
- sunsetComp.hour = ssHour
- }
- sunsetComp.minute = max(0, min(59, ssMinute))
- sunsetComp.second = 0
-
- guard let sunriseDate = currentCalendar.date(from: sunriseComp),
- let sunsetDate = currentCalendar.date(from: sunsetComp) else {
- return nil
- }
-
- return (sunriseDate, sunsetDate)
- }
-
- private func isLeapYear(_ year: Int) -> Bool {
- return (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0)
- }
-}
diff --git a/Solsnu.Widget/Views/SmallWidgetView.swift b/Solsnu.Widget/Views/SmallWidgetView.swift
index 86aa913..16ca102 100644
--- a/Solsnu.Widget/Views/SmallWidgetView.swift
+++ b/Solsnu.Widget/Views/SmallWidgetView.swift
@@ -10,22 +10,19 @@ struct SmallWidgetView: View {
var body: some View {
ZStack {
Image(entry.def.bg)
- .resizable()
- .scaledToFill()
VStack(spacing: 8) {
Text("\(entry.def.daysUntilNext())")
.font(.system(size: 26, weight: .bold, design: .serif))
+ .position(x: 50,y: 50)
.foregroundStyle(Color(red: 0.152, green: 0.136, blue: 0.056))
.italic()
- if !entry.def.sunriseFormatted.isEmpty && !entry.def.sunsetFormatted.isEmpty {
HStack(spacing: 4) {
Text("↑ \(entry.def.sunriseFormatted)")
Text("↓ \(entry.def.sunsetFormatted)")
}
.font(.system(size: 11, weight: .regular))
.foregroundStyle(Color(red: 0.152, green: 0.136, blue: 0.056))
- }
}
}
.containerBackground(for: .widget, alignment: .center) { Color.clear }