From 6bf51fe91183eb5689cef05bf2b9be0ba6506ef3 Mon Sep 17 00:00:00 2001 From: Chris Ballinger Date: Thu, 21 Aug 2025 17:19:13 -0700 Subject: [PATCH 1/2] Fix detail screen distance display and event times MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Convert distance from meters to feet (more familiar for Burning Man) - Add walk/bike time estimates as separate cell with color coding - Show actual times for "All Day" events alongside the "All Day" label - Changes only affect SwiftUI detail view, not legacy implementation πŸ€– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- ...2-fix-detail-screen-distance-and-events.md | 107 ++++++++++++++++++ iBurn/Detail/Models/DetailCellType.swift | 1 + iBurn/Detail/ViewModels/DetailViewModel.swift | 5 +- iBurn/Detail/Views/DetailView.swift | 22 +++- 4 files changed, 132 insertions(+), 3 deletions(-) create mode 100644 Docs/2025-08-22-fix-detail-screen-distance-and-events.md diff --git a/Docs/2025-08-22-fix-detail-screen-distance-and-events.md b/Docs/2025-08-22-fix-detail-screen-distance-and-events.md new file mode 100644 index 00000000..f6ac4b4d --- /dev/null +++ b/Docs/2025-08-22-fix-detail-screen-distance-and-events.md @@ -0,0 +1,107 @@ +# Fix Detail Screen Distance Display and Event Times + +## Date: 2025-08-22 + +## Problem Statement +The SwiftUI detail screen had two issues: +1. Distance was displayed in meters instead of feet +2. "All Day" events only showed "All Day" without actual start/end times + +## Solution Overview +Fixed both issues and added walk/bike time estimates as a separate cell for better user experience. + +## Key Changes + +### 1. Distance Display Fix +**File**: `iBurn/Detail/Views/DetailView.swift` +- Modified `DetailDistanceCell` to convert meters to feet (1 meter = 3.28084 feet) +- Changed display format from "Distance: X meters" to "Distance: X ft" + +### 2. Added Walk/Bike Time Estimates +**Files Modified**: +- `iBurn/Detail/Models/DetailCellType.swift`: Added new `.travelTime(CLLocationDistance)` case +- `iBurn/Detail/Views/DetailView.swift`: + - Created new `DetailTravelTimeCell` view + - Added case handling in `DetailCellView` + - Updated `isCellTappable` function +- `iBurn/Detail/ViewModels/DetailViewModel.swift`: Added travel time cell after distance cell + +The new cell uses the existing `TTTLocationFormatter.brc_humanizedString(forDistance:)` to display: +- Walking time with emoji 🚢🏽 +- Biking time with emoji 🚴🏽 +- Color coding (green/orange/red) based on difficulty + +### 3. All Day Event Times Fix +**File**: `iBurn/Detail/ViewModels/DetailViewModel.swift` +- Modified `formatEventSchedule` method +- Changed "All Day" events to display: "All Day (startTime - endTime)" +- Provides clarity on actual event hours while maintaining "All Day" designation + +## Technical Details + +### Code Snippets + +#### Distance Cell Update +```swift +struct DetailDistanceCell: View { + let distance: CLLocationDistance + @Environment(\.themeColors) var themeColors + + var body: some View { + HStack { + Image(systemName: "ruler") + .foregroundColor(themeColors.detailColor) + Text("Distance: \(distance * 3.28084, specifier: "%.0f") ft") + .foregroundColor(themeColors.detailColor) + Spacer() + } + } +} +``` + +#### New Travel Time Cell +```swift +struct DetailTravelTimeCell: View { + let distance: CLLocationDistance + @Environment(\.themeColors) var themeColors + + var body: some View { + if let attributedString = TTTLocationFormatter.brc_humanizedString(forDistance: distance) { + HStack { + Text(AttributedString(attributedString)) + .frame(maxWidth: .infinity, alignment: .leading) + Spacer() + } + } + } +} +``` + +#### All Day Event Fix +```swift +if event.isAllDay { + let start = timeFormatter.string(from: startDate) + let end = timeFormatter.string(from: endDate) + timeString = "All Day (\(start) - \(end))" +} else { + let start = timeFormatter.string(from: startDate) + let end = timeFormatter.string(from: endDate) + timeString = "\(start) - \(end)" +} +``` + +## Testing +- Build succeeded with only expected warnings +- Changes are isolated to SwiftUI detail view +- No impact on legacy Objective-C detail view +- Maintains consistency with existing app patterns + +## Expected Outcomes +- Users will see distance in feet (more familiar unit for Burning Man context) +- Walk/bike time estimates help with planning navigation at the event +- "All Day" events now show specific hours for better planning + +## Notes +- The conversion factor 3.28084 is the standard meters to feet conversion +- TTTLocationFormatter already provides walking/biking time calculations with color coding +- These changes only affect the new SwiftUI detail screen, not the legacy implementation \ No newline at end of file diff --git a/iBurn/Detail/Models/DetailCellType.swift b/iBurn/Detail/Models/DetailCellType.swift index c02fa5ce..fe9b5f47 100644 --- a/iBurn/Detail/Models/DetailCellType.swift +++ b/iBurn/Detail/Models/DetailCellType.swift @@ -39,6 +39,7 @@ enum DetailCellType { case allHostEvents(count: Int, hostName: String) case playaAddress(String, tappable: Bool) case distance(CLLocationDistance) + case travelTime(CLLocationDistance) case audio(BRCArtObject, isPlaying: Bool) case userNotes(String) case date(Date, format: String) diff --git a/iBurn/Detail/ViewModels/DetailViewModel.swift b/iBurn/Detail/ViewModels/DetailViewModel.swift index 65e3dc2d..c7e43631 100644 --- a/iBurn/Detail/ViewModels/DetailViewModel.swift +++ b/iBurn/Detail/ViewModels/DetailViewModel.swift @@ -510,7 +510,9 @@ class DetailViewModel: ObservableObject { var timeString: String if event.isAllDay { - timeString = "All Day" + let start = timeFormatter.string(from: startDate) + let end = timeFormatter.string(from: endDate) + timeString = "All Day (\(start) - \(end))" } else { let start = timeFormatter.string(from: startDate) let end = timeFormatter.string(from: endDate) @@ -618,6 +620,7 @@ class DetailViewModel: ObservableObject { // Distance if let distance = locationService.distanceToObject(dataObject) { cells.append(.distance(distance)) + cells.append(.travelTime(distance)) } // User notes diff --git a/iBurn/Detail/Views/DetailView.swift b/iBurn/Detail/Views/DetailView.swift index 66fc8b53..e23a75fe 100644 --- a/iBurn/Detail/Views/DetailView.swift +++ b/iBurn/Detail/Views/DetailView.swift @@ -189,6 +189,9 @@ struct DetailCellView: View { case .distance(let distance): DetailDistanceCell(distance: distance) + case .travelTime(let distance): + DetailTravelTimeCell(distance: distance) + case .userNotes(let notes): DetailUserNotesCell(notes: notes) @@ -247,7 +250,7 @@ struct DetailCellView: View { return true case .playaAddress(_, let tappable): return tappable - case .text, .distance, .schedule, .date, .landmark, .eventType: + case .text, .distance, .travelTime, .schedule, .date, .landmark, .eventType: return false case .image: return true @@ -401,13 +404,28 @@ struct DetailDistanceCell: View { HStack { Image(systemName: "ruler") .foregroundColor(themeColors.detailColor) - Text("Distance: \(distance, specifier: "%.0f") meters") + Text("Distance: \(distance * 3.28084, specifier: "%.0f") ft") .foregroundColor(themeColors.detailColor) Spacer() } } } +struct DetailTravelTimeCell: View { + let distance: CLLocationDistance + @Environment(\.themeColors) var themeColors + + var body: some View { + if let attributedString = TTTLocationFormatter.brc_humanizedString(forDistance: distance) { + HStack { + Text(AttributedString(attributedString)) + .frame(maxWidth: .infinity, alignment: .leading) + Spacer() + } + } + } +} + struct DetailUserNotesCell: View { let notes: String @Environment(\.themeColors) var themeColors From 53b803457ba4fd616ab314be44f5e2002a63e47b Mon Sep 17 00:00:00 2001 From: Chris Ballinger Date: Thu, 21 Aug 2025 17:50:30 -0700 Subject: [PATCH 2/2] Use MeasurementFormatter for proper distance conversion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Replace hardcoded conversion factor with Foundation's MeasurementFormatter - Provides proper iOS patterns and locale-aware formatting - More maintainable and follows iOS best practices πŸ€– Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude --- ...2-fix-detail-screen-distance-and-events.md | 19 ++++++++++++++++--- iBurn/Detail/Views/DetailView.swift | 14 +++++++++++++- 2 files changed, 29 insertions(+), 4 deletions(-) diff --git a/Docs/2025-08-22-fix-detail-screen-distance-and-events.md b/Docs/2025-08-22-fix-detail-screen-distance-and-events.md index f6ac4b4d..93817548 100644 --- a/Docs/2025-08-22-fix-detail-screen-distance-and-events.md +++ b/Docs/2025-08-22-fix-detail-screen-distance-and-events.md @@ -51,11 +51,23 @@ struct DetailDistanceCell: View { HStack { Image(systemName: "ruler") .foregroundColor(themeColors.detailColor) - Text("Distance: \(distance * 3.28084, specifier: "%.0f") ft") + Text("Distance: \(formattedDistance)") .foregroundColor(themeColors.detailColor) Spacer() } } + + private var formattedDistance: String { + let meters = Measurement(value: distance, unit: UnitLength.meters) + let feet = meters.converted(to: .feet) + + let formatter = MeasurementFormatter() + formatter.unitStyle = .short + formatter.unitOptions = .providedUnit + formatter.numberFormatter.maximumFractionDigits = 0 + + return formatter.string(from: feet) + } } ``` @@ -102,6 +114,7 @@ if event.isAllDay { - "All Day" events now show specific hours for better planning ## Notes -- The conversion factor 3.28084 is the standard meters to feet conversion +- Uses Foundation's MeasurementFormatter for proper unit conversion instead of hardcoded factor - TTTLocationFormatter already provides walking/biking time calculations with color coding -- These changes only affect the new SwiftUI detail screen, not the legacy implementation \ No newline at end of file +- These changes only affect the new SwiftUI detail screen, not the legacy implementation +- MeasurementFormatter provides locale-aware formatting and proper iOS patterns \ No newline at end of file diff --git a/iBurn/Detail/Views/DetailView.swift b/iBurn/Detail/Views/DetailView.swift index e23a75fe..b8b6124b 100644 --- a/iBurn/Detail/Views/DetailView.swift +++ b/iBurn/Detail/Views/DetailView.swift @@ -404,11 +404,23 @@ struct DetailDistanceCell: View { HStack { Image(systemName: "ruler") .foregroundColor(themeColors.detailColor) - Text("Distance: \(distance * 3.28084, specifier: "%.0f") ft") + Text("Distance: \(formattedDistance)") .foregroundColor(themeColors.detailColor) Spacer() } } + + private var formattedDistance: String { + let meters = Measurement(value: distance, unit: UnitLength.meters) + let feet = meters.converted(to: .feet) + + let formatter = MeasurementFormatter() + formatter.unitStyle = .short + formatter.unitOptions = .providedUnit + formatter.numberFormatter.maximumFractionDigits = 0 + + return formatter.string(from: feet) + } } struct DetailTravelTimeCell: View {