1.2.0: widget deep-link, Lock Screen widgets, in-app widget promo
- Tapping the widget now deep-links via mealmood://today back to the current week (URL scheme registered, onOpenURL handler in Home) - New Lock Screen widget families: accessoryRectangular (weekday + both meals) and accessoryInline (next relevant meal) - One-time dismissable widget promo card on Home from the 2nd session, with widget_promo_shown/dismissed analytics - 2 new strings × 6 languages Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UtWT52pAE91D7mbDda1cAM
This commit is contained in:
@@ -199,6 +199,51 @@ private struct MediumWidgetView: View {
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Lock Screen widgets
|
||||
|
||||
private struct AccessoryRectangularView: View {
|
||||
let entry: TodayMealEntry
|
||||
|
||||
var body: some View {
|
||||
VStack(alignment: .leading, spacing: 2) {
|
||||
HStack(spacing: 3) {
|
||||
Image(systemName: "fork.knife")
|
||||
.font(.system(size: 10, weight: .bold))
|
||||
Text(entry.weekdayName.isEmpty ? "MealMood" : entry.weekdayName)
|
||||
.font(.system(size: 12, weight: .bold))
|
||||
.lineLimit(1)
|
||||
}
|
||||
.widgetAccentable()
|
||||
|
||||
if let lunch = entry.lunch {
|
||||
Text("\(Image(systemName: "sun.max.fill")) \(lunch)")
|
||||
.font(.system(size: 12))
|
||||
.lineLimit(1)
|
||||
}
|
||||
if let dinner = entry.dinner {
|
||||
Text("\(Image(systemName: "moon.stars.fill")) \(dinner)")
|
||||
.font(.system(size: 12))
|
||||
.lineLimit(1)
|
||||
}
|
||||
if entry.lunch == nil && entry.dinner == nil {
|
||||
Text("—")
|
||||
.font(.system(size: 12))
|
||||
}
|
||||
}
|
||||
.frame(maxWidth: .infinity, alignment: .leading)
|
||||
}
|
||||
}
|
||||
|
||||
private struct AccessoryInlineView: View {
|
||||
let entry: TodayMealEntry
|
||||
|
||||
var body: some View {
|
||||
// Inline is a single line: show the next relevant meal.
|
||||
let name = entry.dinner ?? entry.lunch
|
||||
Label(name ?? "MealMood", systemImage: "fork.knife")
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - Widget entry view
|
||||
|
||||
struct MealMoodWidgetView: View {
|
||||
@@ -206,12 +251,24 @@ struct MealMoodWidgetView: View {
|
||||
@Environment(\.widgetFamily) var family
|
||||
|
||||
var body: some View {
|
||||
switch family {
|
||||
case .systemMedium:
|
||||
MediumWidgetView(entry: entry)
|
||||
default:
|
||||
SmallWidgetView(entry: entry)
|
||||
Group {
|
||||
switch family {
|
||||
case .systemMedium:
|
||||
MediumWidgetView(entry: entry)
|
||||
.containerBackground(for: .widget) { Color.white }
|
||||
case .accessoryRectangular:
|
||||
AccessoryRectangularView(entry: entry)
|
||||
.containerBackground(for: .widget) { Color.clear }
|
||||
case .accessoryInline:
|
||||
AccessoryInlineView(entry: entry)
|
||||
.containerBackground(for: .widget) { Color.clear }
|
||||
default:
|
||||
SmallWidgetView(entry: entry)
|
||||
.containerBackground(for: .widget) { Color.white }
|
||||
}
|
||||
}
|
||||
// Deep-link into the app's current week ("today") when tapped.
|
||||
.widgetURL(URL(string: "mealmood://today"))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -224,10 +281,9 @@ struct MealMoodWidget: Widget {
|
||||
var body: some WidgetConfiguration {
|
||||
StaticConfiguration(kind: kind, provider: Provider()) { entry in
|
||||
MealMoodWidgetView(entry: entry)
|
||||
.containerBackground(for: .widget) { Color.white }
|
||||
}
|
||||
.configurationDisplayName("MealMood")
|
||||
.description("Today's lunch and dinner at a glance.")
|
||||
.supportedFamilies([.systemSmall, .systemMedium])
|
||||
.supportedFamilies([.systemSmall, .systemMedium, .accessoryRectangular, .accessoryInline])
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user