feat: widget has two tap targets — fitness + add food
All checks were successful
Security Checks / dependency-audit (push) Successful in 13s
Security Checks / secret-scanning (push) Successful in 3s
Security Checks / dockerfile-lint (push) Successful in 4s

Widget background tap → platform://fitness → opens Fitness tab
Widget + button tap → platform://add-food → opens Fitness + food assistant

Small widget: + button in bottom-right corner (emerald green)
Medium widget: + button in bottom-right corner
Lock screen widgets: single tap → fitness (no room for + button)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Yusuf Suleman
2026-04-04 11:45:08 -05:00
parent 7cfe3eeed5
commit a5c95c2e5f
2 changed files with 45 additions and 22 deletions

View File

@@ -121,9 +121,15 @@ struct MainTabView: View {
AssistantSheetView(onFoodAdded: foodAdded) AssistantSheetView(onFoodAdded: foodAdded)
} }
.onOpenURL { url in .onOpenURL { url in
if url.scheme == "platform" && url.host == "add-food" { guard url.scheme == "platform" else { return }
selectedTab = 1 // Fitness tab switch url.host {
case "fitness":
selectedTab = 1
case "add-food":
selectedTab = 1
showAssistant = true showAssistant = true
default:
break
} }
} }
.task { .task {

View File

@@ -184,14 +184,23 @@ struct SmallWidgetView: View {
let entry: CalorieEntry let entry: CalorieEntry
var body: some View { var body: some View {
ZStack(alignment: .bottomTrailing) {
VStack(spacing: 8) { VStack(spacing: 8) {
CalorieRingView(entry: entry, size: 90, lineWidth: 8) CalorieRingView(entry: entry, size: 80, lineWidth: 7)
Text("\(Int(entry.remaining)) left") Text("\(Int(entry.remaining)) left")
.font(.caption2.weight(.medium)) .font(.caption2.weight(.medium))
.foregroundStyle(.secondary) .foregroundStyle(.secondary)
} }
.frame(maxWidth: .infinity, maxHeight: .infinity) .frame(maxWidth: .infinity, maxHeight: .infinity)
// + button separate tap target opens food assistant
Link(destination: URL(string: "platform://add-food")!) {
Image(systemName: "plus.circle.fill")
.font(.title2)
.foregroundStyle(Color(red: 0.020, green: 0.588, blue: 0.412))
}
}
} }
} }
@@ -199,6 +208,7 @@ struct MediumWidgetView: View {
let entry: CalorieEntry let entry: CalorieEntry
var body: some View { var body: some View {
ZStack(alignment: .bottomTrailing) {
HStack(spacing: 20) { HStack(spacing: 20) {
CalorieRingView(entry: entry, size: 100, lineWidth: 9) CalorieRingView(entry: entry, size: 100, lineWidth: 9)
@@ -217,6 +227,13 @@ struct MediumWidgetView: View {
} }
} }
.frame(maxWidth: .infinity, maxHeight: .infinity) .frame(maxWidth: .infinity, maxHeight: .infinity)
Link(destination: URL(string: "platform://add-food")!) {
Image(systemName: "plus.circle.fill")
.font(.title2)
.foregroundStyle(Color(red: 0.020, green: 0.588, blue: 0.412))
}
}
} }
} }
@@ -290,7 +307,7 @@ struct PlatformWidget: Widget {
var body: some WidgetConfiguration { var body: some WidgetConfiguration {
StaticConfiguration(kind: kind, provider: CalorieProvider()) { entry in StaticConfiguration(kind: kind, provider: CalorieProvider()) { entry in
PlatformWidgetEntryView(entry: entry) PlatformWidgetEntryView(entry: entry)
.widgetURL(URL(string: "platform://add-food")) .widgetURL(URL(string: "platform://fitness"))
.containerBackground(.fill.tertiary, for: .widget) .containerBackground(.fill.tertiary, for: .widget)
} }
.configurationDisplayName("Calories") .configurationDisplayName("Calories")