ios widget showing what is available at chucks
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

feat: proper tab view layout

dunkirk.sh abb1e297 e7069558

verified
+44 -77
+44 -77
ios/wasup-chucks/ContentView.swift
··· 40 40 allMenus.keys.sorted() 41 41 } 42 42 43 + private func dateLabel(for index: Int) -> String { 44 + guard index < availableDates.count else { return "" } 45 + if index == 0 { return "Today" } 46 + if index == 1 { return "Tomorrow" } 47 + let dateKey = availableDates[index] 48 + let formatter = DateFormatter() 49 + formatter.dateFormat = "yyyy-MM-dd" 50 + formatter.timeZone = TimeZone(identifier: "America/New_York") 51 + guard let date = formatter.date(from: dateKey) else { return dateKey } 52 + let displayFormatter = DateFormatter() 53 + displayFormatter.dateFormat = "EEEE, MMM d" 54 + displayFormatter.timeZone = TimeZone(identifier: "America/New_York") 55 + return displayFormatter.string(from: date) 56 + } 57 + 43 58 var body: some View { 44 59 NavigationStack { 45 60 Group { ··· 51 66 } 52 67 } 53 68 .tabViewStyle(.page(indexDisplayMode: .never)) 69 + .ignoresSafeArea(.container, edges: .bottom) 54 70 .onChange(of: selectedDateIndex) { _ in 55 71 selectedFutureMeal = .breakfast 56 72 } 57 - .safeAreaInset(edge: .top, spacing: 0) { 58 - DateNavigationHeader( 59 - selectedDateIndex: $selectedDateIndex, 60 - selectedFutureMeal: $selectedFutureMeal, 61 - availableDates: availableDates 62 - ) 63 - .background(.bar) 64 - } 65 73 } else { 66 74 dayPage(for: 0) 67 75 } 68 76 } 69 77 .navigationTitle("Wasup Chuck's") 78 + .navigationBarTitleDisplayMode(.inline) 79 + .toolbar { 80 + if availableDates.count > 1 { 81 + ToolbarItem(placement: .topBarLeading) { 82 + Button { 83 + withAnimation { selectedDateIndex -= 1 } 84 + selectedFutureMeal = .breakfast 85 + } label: { 86 + Image(systemName: "chevron.left") 87 + } 88 + .disabled(selectedDateIndex <= 0) 89 + } 90 + ToolbarItem(placement: .principal) { 91 + Text(dateLabel(for: selectedDateIndex)) 92 + .font(.headline) 93 + .animation(.easeInOut, value: selectedDateIndex) 94 + } 95 + ToolbarItem(placement: .topBarTrailing) { 96 + Button { 97 + withAnimation { selectedDateIndex += 1 } 98 + selectedFutureMeal = .breakfast 99 + } label: { 100 + Image(systemName: "chevron.right") 101 + } 102 + .disabled(selectedDateIndex >= availableDates.count - 1) 103 + } 104 + } 105 + } 70 106 .onReceive(timer) { _ in 71 107 status = ChucksStatus.calculate() 72 108 } ··· 228 264 CurrentMealView(menu: menu, slot: selectedFutureMeal.apiSlot, isOpen: true, isRegularWidth: isRegularWidth) 229 265 } 230 266 } 231 - } 232 - } 233 - 234 - // MARK: - Date Navigation Header 235 - 236 - struct DateNavigationHeader: View { 237 - @Binding var selectedDateIndex: Int 238 - @Binding var selectedFutureMeal: MealPhase 239 - let availableDates: [String] 240 - 241 - private func dateLabel(for index: Int) -> String { 242 - guard index < availableDates.count else { return "" } 243 - if index == 0 { return "Today" } 244 - if index == 1 { return "Tomorrow" } 245 - let dateKey = availableDates[index] 246 - let formatter = DateFormatter() 247 - formatter.dateFormat = "yyyy-MM-dd" 248 - formatter.timeZone = TimeZone(identifier: "America/New_York") 249 - guard let date = formatter.date(from: dateKey) else { return dateKey } 250 - let displayFormatter = DateFormatter() 251 - displayFormatter.dateFormat = "EEEE, MMM d" 252 - displayFormatter.timeZone = TimeZone(identifier: "America/New_York") 253 - return displayFormatter.string(from: date) 254 - } 255 - 256 - var body: some View { 257 - HStack { 258 - Button { 259 - selectedDateIndex -= 1 260 - selectedFutureMeal = .breakfast 261 - } label: { 262 - Image(systemName: "chevron.left") 263 - .font(.title3.weight(.semibold)) 264 - } 265 - .disabled(selectedDateIndex <= 0) 266 - .modifier(LiquidGlassButtonModifier()) 267 - 268 - Spacer() 269 - 270 - Text(dateLabel(for: selectedDateIndex)) 271 - .font(.headline) 272 - .animation(.easeInOut, value: selectedDateIndex) 273 - 274 - Spacer() 275 - 276 - Button { 277 - selectedDateIndex += 1 278 - selectedFutureMeal = .breakfast 279 - } label: { 280 - Image(systemName: "chevron.right") 281 - .font(.title3.weight(.semibold)) 282 - } 283 - .disabled(selectedDateIndex >= availableDates.count - 1) 284 - .modifier(LiquidGlassButtonModifier()) 285 - } 286 - .padding(.horizontal, 8) 287 - .padding(.vertical, 4) 288 267 } 289 268 } 290 269 ··· 787 766 .padding(.vertical, 3) 788 767 .background(color.opacity(0.15), in: RoundedRectangle(cornerRadius: 4)) 789 768 .accessibilityHidden(true) 790 - } 791 - } 792 - 793 - // MARK: - Liquid Glass Button 794 - 795 - struct LiquidGlassButtonModifier: ViewModifier { 796 - func body(content: Content) -> some View { 797 - if #available(iOS 26.0, *) { 798 - content.buttonStyle(.glass) 799 - } else { 800 - content.buttonStyle(.bordered) 801 - } 802 769 } 803 770 } 804 771