Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
54 changes: 47 additions & 7 deletions Where/WhereUI/Sources/Primary/PresenceTimelineList.swift
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,17 @@ struct PresenceTimelineList: View {
Text(String(localized: .timelineEmptyDescription))
}
} else {
let pinsOverview = stylesheet.timeline.overview.pinsToViewport

ScrollView {
LazyVStack(spacing: stylesheet.spacing.large) {
YearRibbon(
days: yearReport?.days ?? [],
year: report.selectedYear,
calendar: report.calendar,
)
LazyVStack(spacing: pinsOverview ? 0 : stylesheet.spacing.large) {
if !pinsOverview {
YearRibbon(
days: yearReport?.days ?? [],
year: report.selectedYear,
calendar: report.calendar,
)
}

LazyVStack(spacing: 0) {
ForEach(stints.enumerated(), id: \.element.id) { index, stint in
Expand All @@ -50,8 +54,26 @@ struct PresenceTimelineList: View {
}
}
.padding(.horizontal, stylesheet.spacing.xxLarge)
.padding(.vertical, stylesheet.spacing.large)
.padding(.top, pinsOverview ? 0 : stylesheet.spacing.large)
.padding(.bottom, stylesheet.spacing.large)
}
.safeAreaInset(
edge: .top,
spacing: 0,
) {
if pinsOverview {
YearRibbon(
days: yearReport?.days ?? [],
year: report.selectedYear,
calendar: report.calendar,
)
.padding(.horizontal, stylesheet.spacing.xxLarge)
.padding(.top, stylesheet.spacing.large)
.padding(.bottom, stylesheet.spacing.large)
}
}
.defaultScrollAnchor(.bottom, for: .initialOffset)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Posted by an AI agent on kve's behalf.

Review focus: using the .initialOffset role here is deliberate. It starts each newly entered or newly selected year at the latest stint without turning the timeline into a follow-mode that overrides manual scrolling after same-year refreshes.

.id(report.selectedYear)
}
}
}
Expand All @@ -65,6 +87,11 @@ struct PresenceTimelineList: View {
PresenceTimelineList(report: PreviewSupport.loadedYearReportModel())
}
},
whereSnapshot(name: "InitialBottom", configurations: .screenDefaults) {
NavigationStack {
PresenceTimelineList(report: PreviewSupport.loadedYearReportModel())
}
},
whereSnapshot(
name: "DifferentiateWithoutColor",
configurations: .fullContentPhoneLightDark,
Expand All @@ -78,6 +105,19 @@ struct PresenceTimelineList: View {
overrides.accessibility = accessibility
}
},
whereSnapshot(
name: "DifferentiateWithoutColorInitialBottom",
configurations: .phoneLightDark,
) {
NavigationStack {
PresenceTimelineList(report: PreviewSupport.loadedYearReportModel())
}
.bTraitOverrides { traits, overrides in
var accessibility = traits.accessibility
accessibility.shouldDifferentiateWithoutColor = true
overrides.accessibility = accessibility
}
},
]
}
}
Expand Down
8 changes: 6 additions & 2 deletions Where/WhereUI/Sources/Primary/YearRibbon.swift
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,12 @@ struct YearRibbon: View {
}
.padding(overview.padding)
.background {
RoundedRectangle(cornerRadius: overview.cornerRadius)
.fill(overview.background)
ZStack {
RoundedRectangle(cornerRadius: overview.cornerRadius)
.fill(.background)

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Posted by an AI agent on kve's behalf.

Review focus: this base fill intentionally makes only the ribbon’s rounded shape opaque. The existing translucent tint remains above it, while the parent inset stays clear so journey content can pass through the corner cutouts without showing through the ribbon itself.

RoundedRectangle(cornerRadius: overview.cornerRadius)
.fill(overview.background)
}
}
.overlay {
RoundedRectangle(cornerRadius: overview.cornerRadius)
Expand Down
5 changes: 5 additions & 0 deletions Where/WhereUI/Sources/Shared/WhereStylesheet.swift
Original file line number Diff line number Diff line change
Expand Up @@ -42,13 +42,15 @@ struct WhereStylesheet: BStylesheet {
// Grow day-grid tap targets at accessibility Dynamic Type sizes.
if traits.contentSizeCategory.isAccessibilitySize {
calendar.day.minHeight = 56
timeline.overview.pinsToViewport = false
timeline.row.stacksDayCount = true
featureDiscovery.siri.bubble.indent = 0
}

// Give every region a consistently labeled ribbon band when tint
// alone is not an acceptable differentiator.
if traits.accessibility.shouldDifferentiateWithoutColor {
timeline.overview.pinsToViewport = false
timeline.ribbon.separatesRegions = true
}

Expand Down Expand Up @@ -1163,6 +1165,8 @@ extension WhereStylesheet {
var border: Color
var borderWidth: CGFloat
var yearFont: Font
/// Keep the compact overview visible while the journey scrolls.
var pinsToViewport: Bool
}

struct Ribbon: Equatable {
Expand Down Expand Up @@ -1219,6 +1223,7 @@ extension WhereStylesheet {
border: Color.primary.opacity(0.1),
borderWidth: 1,
yearFont: .system(.title2, design: .serif).bold(),
pinsToViewport: true,
),
ribbon: Ribbon(
monthLabelSpacing: 6,
Expand Down
3 changes: 3 additions & 0 deletions Where/WhereUI/Tests/WhereStylesheetTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -295,6 +295,7 @@ struct WhereStylesheetTests {
#expect(overview.border == Color.primary.opacity(0.1))
#expect(overview.borderWidth == 1)
#expect(overview.yearFont == .system(.title2, design: .serif).bold())
#expect(overview.pinsToViewport)

let ribbon = timeline.ribbon
#expect(ribbon.monthLabelSpacing == 6)
Expand Down Expand Up @@ -604,6 +605,7 @@ struct WhereStylesheetTests {
context.traitOverrides.contentSizeCategory = .accessibilityLarge
let resolved = try context.stylesheets.get(WhereStylesheet.self)
#expect(resolved.calendar.day.minHeight == 56)
#expect(resolved.timeline.overview.pinsToViewport == false)
#expect(resolved.timeline.row.stacksDayCount)
#expect(resolved.featureDiscovery.siri.bubble.indent == 0)
#expect(resolved.featureDiscovery.widgets.contentWidth(in: 834) == 320)
Expand All @@ -627,6 +629,7 @@ struct WhereStylesheetTests {
shouldDifferentiateWithoutColor: true,
)
let resolved = try context.stylesheets.get(WhereStylesheet.self)
#expect(resolved.timeline.overview.pinsToViewport == false)
#expect(resolved.timeline.ribbon.separatesRegions)
}

Expand Down
Loading