feat: speed controls in collapsed tab bar via safeAreaBar
All checks were successful
Security Checks / dependency-audit (push) Successful in 27s
Security Checks / secret-scanning (push) Successful in 7s
Security Checks / dockerfile-lint (push) Successful in 6s

Uses .safeAreaBar(edge: .bottom) on the Reader content — the iOS 26
API that places content in the collapsed tab bar area, same position
as the Now Playing mini bar. Speed controls [ - ] 1.50x [ + ] appear
in the glass bar when auto-scrolling.

Removed the floating speed pill overlay from ContentView.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Yusuf Suleman
2026-04-04 09:00:42 -05:00
parent e37444c62e
commit 61cd78e080
2 changed files with 31 additions and 40 deletions

View File

@@ -73,53 +73,18 @@ struct MainTabView: View {
.tint(Color.accentWarm)
.tabBarMinimizeBehavior(.onScrollDown)
// Bottom floating controls
VStack(spacing: 10) {
Spacer()
// Speed pill (only when auto-scrolling on Reader)
if isAutoScrolling && selectedTab == 2 {
HStack(spacing: 12) {
Button {
scrollSpeed = max(0.25, scrollSpeed - 0.25)
} label: {
Image(systemName: "minus")
.font(.caption.weight(.bold))
.foregroundStyle(Color.accentWarm)
.frame(width: 32, height: 32)
}
Text(String(format: "%.2fx", scrollSpeed))
.font(.system(size: 13, weight: .bold, design: .monospaced))
.foregroundStyle(Color.textPrimary)
Button {
scrollSpeed = min(3.0, scrollSpeed + 0.25)
} label: {
Image(systemName: "plus")
.font(.caption.weight(.bold))
.foregroundStyle(Color.accentWarm)
.frame(width: 32, height: 32)
}
}
.padding(.horizontal, 16)
.padding(.vertical, 10)
.background(.regularMaterial, in: Capsule())
.shadow(color: .black.opacity(0.15), radius: 12, y: 4)
.transition(.move(edge: .bottom).combined(with: .opacity))
}
// Feedback button (not on Reader)
if selectedTab != 2 {
// Feedback button (not on Reader)
if selectedTab != 2 {
VStack {
Spacer()
HStack {
FeedbackButton()
.padding(.leading, 20)
Spacer()
}
.padding(.bottom, 70)
}
}
.padding(.bottom, 70)
.animation(.spring(duration: 0.3), value: isAutoScrolling)
}
.confettiCannon(
trigger: $confettiTrigger,

View File

@@ -140,6 +140,32 @@ struct ReaderTabView: View {
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(Color.canvas)
.navigationBarHidden(true)
.safeAreaBar(edge: .bottom) {
if isAutoScrolling {
HStack(spacing: 16) {
Button {
scrollSpeed = max(0.25, scrollSpeed - 0.25)
} label: {
Image(systemName: "minus")
.font(.caption.weight(.bold))
.foregroundStyle(Color.accentWarm)
}
Text(String(format: "%.2fx", scrollSpeed))
.font(.system(size: 13, weight: .bold, design: .monospaced))
.foregroundStyle(Color.textPrimary)
Button {
scrollSpeed = min(3.0, scrollSpeed + 0.25)
} label: {
Image(systemName: "plus")
.font(.caption.weight(.bold))
.foregroundStyle(Color.accentWarm)
}
}
.padding(.horizontal, 20)
}
}
.sheet(isPresented: $showFeedSheet) {
AddFeedSheet(vm: vm)
}