From c2b529506eb26268af4f907f50ad7a5dc576d53f Mon Sep 17 00:00:00 2001 From: Till JS Date: Sun, 17 May 2026 23:28:00 +0200 Subject: [PATCH] feat(widget): Lock-Screen-Familien (inline + rectangular) - accessoryInline: kompakte Zitat-Vorschau (max 40 Zeichen) + Autor - accessoryRectangular: Zitat 2 Zeilen + Autor - widgetURL zitare://heute pro Family Co-Authored-By: Claude Opus 4.7 (1M context) --- Widgets/ZitareWidget/ZitareWidgetBundle.swift | 74 +++++++++++++++---- 1 file changed, 61 insertions(+), 13 deletions(-) diff --git a/Widgets/ZitareWidget/ZitareWidgetBundle.swift b/Widgets/ZitareWidget/ZitareWidgetBundle.swift index c4f29f0..7e12013 100644 --- a/Widgets/ZitareWidget/ZitareWidgetBundle.swift +++ b/Widgets/ZitareWidget/ZitareWidgetBundle.swift @@ -27,7 +27,13 @@ struct DailyQuoteWidget: Widget { } .configurationDisplayName("Zitat des Tages") .description("Ein kuratiertes Zitat von Zitare — täglich neu.") - .supportedFamilies([.systemSmall, .systemMedium, .systemLarge]) + .supportedFamilies([ + .systemSmall, + .systemMedium, + .systemLarge, + .accessoryInline, + .accessoryRectangular, + ]) } } @@ -113,6 +119,38 @@ struct DailyQuoteEntryView: View { @Environment(\.widgetFamily) private var family var body: some View { + switch family { + case .systemSmall, .systemMedium, .systemLarge: + homeScreenBody + .containerBackground(for: .widget) { + // Paper-Variant-Background. Statisch — Tokens aus + // ManaTokens wären schöner, aber app-extension- + // Targets können das Package nicht ohne XcodeGen- + // Reibung mitziehen. + LinearGradient( + colors: [ + Color(red: 0.95, green: 0.93, blue: 0.88), + Color(red: 0.93, green: 0.91, blue: 0.85) + ], + startPoint: .topLeading, + endPoint: .bottomTrailing + ) + } + .widgetURL(URL(string: "zitare://heute")) + case .accessoryInline: + accessoryInlineBody + .widgetURL(URL(string: "zitare://heute")) + case .accessoryRectangular: + accessoryRectangularBody + .containerBackground(.fill.tertiary, for: .widget) + .widgetURL(URL(string: "zitare://heute")) + default: + homeScreenBody + .containerBackground(.fill.tertiary, for: .widget) + } + } + + private var homeScreenBody: some View { VStack(alignment: .leading, spacing: family == .systemSmall ? 6 : 10) { Text(verbatim: "\u{201E}\(entry.text)\u{201C}") .font(font(for: family)) @@ -132,18 +170,28 @@ struct DailyQuoteEntryView: View { } .frame(maxWidth: .infinity, maxHeight: .infinity, alignment: .leading) .padding(family == .systemSmall ? 10 : 14) - .containerBackground(for: .widget) { - // Paper-Variant-Background. Statisch — Tokens aus ManaTokens - // wären schöner, aber Widget-Targets können das Package heute - // nicht so einfach mitziehen (eigene Compile-Pipeline). - LinearGradient( - colors: [ - Color(red: 0.95, green: 0.93, blue: 0.88), - Color(red: 0.93, green: 0.91, blue: 0.85) - ], - startPoint: .topLeading, - endPoint: .bottomTrailing - ) + } + + // MARK: Lock-Screen — Inline + + private var accessoryInlineBody: some View { + Label( + "„\(entry.text.prefix(40))\(entry.text.count > 40 ? "…" : "")“ — \(entry.author)", + systemImage: "quote.opening" + ) + } + + // MARK: Lock-Screen — Rectangular + + private var accessoryRectangularBody: some View { + VStack(alignment: .leading, spacing: 2) { + Text(verbatim: "\u{201E}\(entry.text)\u{201C}") + .font(.caption.weight(.medium)) + .lineLimit(2) + Text(verbatim: "— \(entry.author)") + .font(.caption2) + .foregroundStyle(.secondary) + .lineLimit(1) } }