feat: widget has two tap targets — fitness + add food
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:
@@ -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 {
|
||||||
|
|||||||
@@ -184,14 +184,23 @@ struct SmallWidgetView: View {
|
|||||||
let entry: CalorieEntry
|
let entry: CalorieEntry
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
VStack(spacing: 8) {
|
ZStack(alignment: .bottomTrailing) {
|
||||||
CalorieRingView(entry: entry, size: 90, lineWidth: 8)
|
VStack(spacing: 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)
|
||||||
|
|
||||||
|
// + 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))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,24 +208,32 @@ struct MediumWidgetView: View {
|
|||||||
let entry: CalorieEntry
|
let entry: CalorieEntry
|
||||||
|
|
||||||
var body: some View {
|
var body: some View {
|
||||||
HStack(spacing: 20) {
|
ZStack(alignment: .bottomTrailing) {
|
||||||
CalorieRingView(entry: entry, size: 100, lineWidth: 9)
|
HStack(spacing: 20) {
|
||||||
|
CalorieRingView(entry: entry, size: 100, lineWidth: 9)
|
||||||
|
|
||||||
VStack(alignment: .leading, spacing: 6) {
|
VStack(alignment: .leading, spacing: 6) {
|
||||||
Text("Calories")
|
Text("Calories")
|
||||||
.font(.headline)
|
.font(.headline)
|
||||||
.foregroundStyle(.primary)
|
.foregroundStyle(.primary)
|
||||||
|
|
||||||
Text("\(Int(entry.totalCalories)) of \(Int(entry.calorieGoal))")
|
Text("\(Int(entry.totalCalories)) of \(Int(entry.calorieGoal))")
|
||||||
.font(.subheadline)
|
.font(.subheadline)
|
||||||
.foregroundStyle(.secondary)
|
.foregroundStyle(.secondary)
|
||||||
|
|
||||||
Text("\(Int(entry.remaining)) remaining")
|
Text("\(Int(entry.remaining)) remaining")
|
||||||
.font(.caption)
|
.font(.caption)
|
||||||
.foregroundStyle(.tertiary)
|
.foregroundStyle(.tertiary)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.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))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity, maxHeight: .infinity)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -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")
|
||||||
|
|||||||
Reference in New Issue
Block a user