iOS widget enhancements

This commit is contained in:
Marianum
2026-05-12 16:46:56 +02:00
parent 1ae3f7bb83
commit d8a5ccfe80
5 changed files with 145 additions and 57 deletions
@@ -16,7 +16,7 @@ struct TimetableDayWidget: Widget {
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: TimetableDayProvider()) { entry in
TimetableDayView(entry: entry).widgetContainerBackground()
TimetableDayView(entry: entry).widgetSurface(entry: entry)
}
.configurationDisplayName("Marianum · Heute")
.description("Stundenplan und Vertretungen für den anstehenden Schultag.")
@@ -52,7 +52,7 @@ struct TimetableWeekWidget: Widget {
var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: TimetableWeekProvider()) { entry in
TimetableWeekView(entry: entry).widgetContainerBackground()
TimetableWeekView(entry: entry).widgetSurface(entry: entry)
}
.configurationDisplayName("Marianum · Woche")
.description("Stundenplan und Vertretungen für die ganze Schulwoche.")
@@ -116,6 +116,8 @@ struct TimetableEntry: TimelineEntry {
}
extension View {
/// Applies the user's chosen light/dark override on top of the system
/// scheme so the widget honours the in-app theme setting.
@ViewBuilder
func widgetThemeOverride(_ mode: String) -> some View {
switch mode {
@@ -125,14 +127,38 @@ extension View {
}
}
/// `.containerBackground(_:for:)` is iOS 17+. Older iOS uses the
/// implicit `.background(...)` model and renders fine without it.
/// Wraps the widget view in the Marianum palette + container background
/// so all subviews can read `\.widgetPalette` and so the widget renders
/// in our warm off-white / dark-clay instead of system grey.
@ViewBuilder
func widgetContainerBackground() -> some View {
func widgetSurface(entry: TimetableEntry) -> some View {
WidgetSurface(entry: entry) { self }
}
}
private struct WidgetSurface<Content: View>: View {
let entry: TimetableEntry
@ViewBuilder let content: () -> Content
@Environment(\.colorScheme) private var colorScheme
var body: some View {
let palette = WidgetPalette.resolve(
themeMode: entry.themeMode,
colorScheme: colorScheme
)
return AnyView(
background(content: content(), palette: palette)
.environment(\.widgetPalette, palette)
.widgetThemeOverride(entry.themeMode)
)
}
@ViewBuilder
private func background<C: View>(content: C, palette: WidgetPalette) -> some View {
if #available(iOS 17.0, *) {
self.containerBackground(.fill.tertiary, for: .widget)
content.containerBackground(palette.background, for: .widget)
} else {
self
content.background(palette.background)
}
}
}