Replace page nav arrows with segmented indicator + square chevron
Three amber/gray capsule pills show the current page; a small rounded-square button with an amber border advances to the next page. Positioned below the status message (between heroView and the scroll content), replacing the old left/right chevron bar at the bottom. Co-Authored-By: Kutesir <kutesir@provoc.ug> Co-Authored-By: Sentry <sentry@provoc.ug>
This commit is contained in:
@@ -61,17 +61,16 @@ struct BackupView: View {
|
|||||||
heroView
|
heroView
|
||||||
.animation(.spring(response: 0.4, dampingFraction: 0.85), value: ringPage)
|
.animation(.spring(response: 0.4, dampingFraction: 0.85), value: ringPage)
|
||||||
|
|
||||||
|
// ─── Page indicator ────────────────────────────────────
|
||||||
|
pageIndicator
|
||||||
|
.padding(.bottom, 8)
|
||||||
|
|
||||||
// ─── Scrollable stats / detail ─────────────────────────
|
// ─── Scrollable stats / detail ─────────────────────────
|
||||||
ScrollView(.vertical, showsIndicators: false) {
|
ScrollView(.vertical, showsIndicators: false) {
|
||||||
belowContent
|
belowContent
|
||||||
.padding(.bottom, 16)
|
.padding(.bottom, 24)
|
||||||
}
|
}
|
||||||
.refreshable { await triggerRefreshAndBackup() }
|
.refreshable { await triggerRefreshAndBackup() }
|
||||||
|
|
||||||
// ─── Page navigation ───────────────────────────────────
|
|
||||||
pageNav
|
|
||||||
.padding(.horizontal, AppTheme.hPad)
|
|
||||||
.padding(.bottom, 24)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ─── Menu button — floats above scroll content ─────────────
|
// ─── Menu button — floats above scroll content ─────────────
|
||||||
@@ -679,7 +678,7 @@ struct BackupView: View {
|
|||||||
|
|
||||||
circleStatusRow
|
circleStatusRow
|
||||||
.padding(.horizontal, AppTheme.hPad)
|
.padding(.horizontal, AppTheme.hPad)
|
||||||
.padding(.bottom, 20)
|
.padding(.bottom, 10)
|
||||||
} else {
|
} else {
|
||||||
// Match page 0 spacing so the ring stays at the same Y
|
// Match page 0 spacing so the ring stays at the same Y
|
||||||
Color.clear.frame(height: 60)
|
Color.clear.frame(height: 60)
|
||||||
@@ -929,45 +928,40 @@ struct BackupView: View {
|
|||||||
.padding(.bottom, 8)
|
.padding(.bottom, 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: — Page navigation
|
// MARK: — Page indicator
|
||||||
|
|
||||||
private var pageNav: some View {
|
private var pageIndicator: some View {
|
||||||
HStack {
|
VStack(spacing: 9) {
|
||||||
Button {
|
// Segmented bar — one pill per page, active = amber
|
||||||
withAnimation(.spring(response: 0.4, dampingFraction: 0.85)) {
|
HStack(spacing: 5) {
|
||||||
ringPage = (ringPage - 1 + ringPageCount) % ringPageCount
|
ForEach(0..<ringPageCount, id: \.self) { i in
|
||||||
|
Capsule()
|
||||||
|
.fill(i == ringPage
|
||||||
|
? Color(red: 1.0, green: 0.58, blue: 0.0)
|
||||||
|
: Color(red: 0.78, green: 0.78, blue: 0.78).opacity(0.4))
|
||||||
|
.frame(width: 26, height: 2)
|
||||||
|
.animation(.spring(response: 0.35, dampingFraction: 0.8), value: ringPage)
|
||||||
}
|
}
|
||||||
} label: {
|
|
||||||
Image(systemName: "chevron.left")
|
|
||||||
.font(.system(size: 10, weight: .medium))
|
|
||||||
.foregroundStyle(AppTheme.inkTertiary)
|
|
||||||
.frame(width: 30, height: 30)
|
|
||||||
.background(AppTheme.surfaceSunken)
|
|
||||||
.clipShape(Circle())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Spacer()
|
// Square advance button with amber border
|
||||||
|
|
||||||
Text(ringPageNames[ringPage])
|
|
||||||
.font(.system(size: 8, weight: .regular, design: .monospaced))
|
|
||||||
.foregroundStyle(AppTheme.inkTertiary)
|
|
||||||
.tracking(2)
|
|
||||||
|
|
||||||
Spacer()
|
|
||||||
|
|
||||||
Button {
|
Button {
|
||||||
withAnimation(.spring(response: 0.4, dampingFraction: 0.85)) {
|
withAnimation(.spring(response: 0.4, dampingFraction: 0.85)) {
|
||||||
ringPage = (ringPage + 1) % ringPageCount
|
ringPage = (ringPage + 1) % ringPageCount
|
||||||
}
|
}
|
||||||
} label: {
|
} label: {
|
||||||
Image(systemName: "chevron.right")
|
Image(systemName: "chevron.down")
|
||||||
.font(.system(size: 10, weight: .medium))
|
.font(.system(size: 9, weight: .medium))
|
||||||
.foregroundStyle(AppTheme.inkTertiary)
|
.foregroundStyle(AppTheme.inkSecondary)
|
||||||
.frame(width: 30, height: 30)
|
.frame(width: 30, height: 30)
|
||||||
.background(AppTheme.surfaceSunken)
|
.overlay(
|
||||||
.clipShape(Circle())
|
RoundedRectangle(cornerRadius: 7, style: .continuous)
|
||||||
|
.stroke(Color(red: 1.0, green: 0.58, blue: 0.0).opacity(0.55), lineWidth: 1)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
.buttonStyle(.plain)
|
||||||
}
|
}
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
}
|
}
|
||||||
|
|
||||||
// MARK: — Storage helpers
|
// MARK: — Storage helpers
|
||||||
|
|||||||
Reference in New Issue
Block a user