diff --git a/ios/Platform/Platform/ContentView.swift b/ios/Platform/Platform/ContentView.swift index f4c0a2a..efa170f 100644 --- a/ios/Platform/Platform/ContentView.swift +++ b/ios/Platform/Platform/ContentView.swift @@ -35,6 +35,14 @@ struct MainTabView: View { auth.currentUser?.id != 4 } + // Dynamic icon for the search-role tab based on context + private var actionIcon: String { + if selectedTab == 2 { + return isAutoScrolling ? "pause.fill" : "play.fill" + } + return "plus" + } + var body: some View { ZStack { TabView(selection: $selectedTab) { @@ -51,55 +59,37 @@ struct MainTabView: View { ReaderTabView(vm: readerVM, isAutoScrolling: $isAutoScrolling, scrollSpeed: $scrollSpeed) } } + + // Action button — separated circle on trailing side of tab bar + // Home/Fitness: quick add food (+) + // Reader: play/pause auto-scroll + Tab(value: 3, role: .search) { + // This view shows briefly when tapped — immediately redirect + Color.clear + .onAppear { + handleActionTap() + } + } label: { + Label("Action", systemImage: actionIcon) + } } .tint(Color.accentWarm) .tabBarMinimizeBehavior(.onScrollDown) - // Floating action button — context-dependent - VStack { - Spacer() - HStack(alignment: .bottom) { - if selectedTab != 2 { + // Feedback button (not on Reader) + if selectedTab != 2 { + VStack { + Spacer() + HStack { FeedbackButton() .padding(.leading, 20) + Spacer() } - - Spacer() - - if selectedTab == 2 && showReader { - // Reader: play/pause auto-scroll - Button { - withAnimation(.spring(duration: 0.3)) { - isAutoScrolling.toggle() - } - } label: { - Image(systemName: isAutoScrolling ? "pause.fill" : "play.fill") - .font(.system(size: 18)) - .foregroundStyle(.white) - .frame(width: 56, height: 56) - .background(isAutoScrolling ? Color.red.opacity(0.85) : Color.accentWarm) - .clipShape(Circle()) - .shadow(color: .black.opacity(0.2), radius: 8, y: 4) - } - .padding(.trailing, 20) - } else { - // Home/Fitness: FAB (+) for food - Button { showAssistant = true } label: { - Image(systemName: "plus") - .font(.title2.weight(.semibold)) - .foregroundStyle(.white) - .frame(width: 56, height: 56) - .background(Color.accentWarm) - .clipShape(Circle()) - .shadow(color: .black.opacity(0.2), radius: 8, y: 4) - } - .padding(.trailing, 20) - } + .padding(.bottom, 70) } - .padding(.bottom, 70) } - // Auto-scroll speed controls (overlay when playing) + // Auto-scroll speed controls (overlay when playing on Reader) if isAutoScrolling && selectedTab == 2 { VStack { Spacer() @@ -130,7 +120,7 @@ struct MainTabView: View { .padding(.vertical, 8) .background(.ultraThinMaterial, in: Capsule()) .shadow(color: .black.opacity(0.1), radius: 8, y: 2) - .padding(.bottom, 140) + .padding(.bottom, 90) .transition(.move(edge: .bottom).combined(with: .opacity)) } .animation(.spring(duration: 0.3), value: isAutoScrolling) @@ -157,11 +147,25 @@ struct MainTabView: View { await readerVM.loadInitial() } .onChange(of: selectedTab) { _, newTab in - // Stop auto-scroll when leaving Reader if newTab != 2 { isAutoScrolling = false } } } + private func handleActionTap() { + if selectedTab == 2 { + // Reader: toggle auto-scroll, stay on Reader + withAnimation(.spring(duration: 0.3)) { + isAutoScrolling.toggle() + } + selectedTab = 2 // stay on Reader (don't switch to the "action" tab) + } else { + // Home/Fitness: open food assistant, return to previous tab + let returnTab = selectedTab + showAssistant = true + selectedTab = returnTab + } + } + private func foodAdded() { showAssistant = false selectedTab = 1