Match page 1 storage layout to design — larger card, black button
Stats card: 26pt semibold values, 18pt corners, full-width gray card with hairline dividers. Legend centered. HOLD TO CLEAN button is full-width black (58pt tall, 18pt radius) replacing PrimaryButtonStyle. storageStat padding/font updated to match screenshot proportions. Co-Authored-By: Kutesir <kutesir@provoc.ug> Co-Authored-By: Sentry <sentry@provoc.ug>
This commit is contained in:
@@ -857,40 +857,51 @@ struct BackupView: View {
|
|||||||
|
|
||||||
@ViewBuilder
|
@ViewBuilder
|
||||||
private var page1BelowContent: some View {
|
private var page1BelowContent: some View {
|
||||||
// 3-col stats
|
// Storage stats card
|
||||||
HStack(spacing: 0) {
|
HStack(spacing: 0) {
|
||||||
storageStat(String(format: "%.0f GB", deviceUsedGB), label: "USED",
|
storageStat(String(format: "%.0f GB", deviceUsedGB), label: "USED",
|
||||||
color: Color(red: 1.0, green: 0.58, blue: 0.0))
|
color: Color(red: 1.0, green: 0.58, blue: 0.0))
|
||||||
thinDivider
|
Rectangle()
|
||||||
|
.fill(AppTheme.separator.opacity(0.35))
|
||||||
|
.frame(width: 0.5)
|
||||||
|
.padding(.vertical, 14)
|
||||||
storageStat(String(format: "%.0f GB", deviceFreeGB), label: "FREE",
|
storageStat(String(format: "%.0f GB", deviceFreeGB), label: "FREE",
|
||||||
color: AppTheme.inkSecondary)
|
color: AppTheme.inkSecondary)
|
||||||
thinDivider
|
Rectangle()
|
||||||
|
.fill(AppTheme.separator.opacity(0.35))
|
||||||
|
.frame(width: 0.5)
|
||||||
|
.padding(.vertical, 14)
|
||||||
storageStat(String(format: "%.1f GB", junkGB), label: "JUNK",
|
storageStat(String(format: "%.1f GB", junkGB), label: "JUNK",
|
||||||
color: AppTheme.positive)
|
color: AppTheme.positive)
|
||||||
}
|
}
|
||||||
.frame(height: 48)
|
.frame(maxWidth: .infinity)
|
||||||
.background(AppTheme.surfaceSunken.opacity(0.85))
|
.background(AppTheme.surfaceSunken)
|
||||||
.clipShape(RoundedRectangle(cornerRadius: 14, style: .continuous))
|
.clipShape(RoundedRectangle(cornerRadius: 18, style: .continuous))
|
||||||
.padding(.horizontal, AppTheme.hPad)
|
.padding(.horizontal, AppTheme.hPad)
|
||||||
.padding(.bottom, 12)
|
.padding(.bottom, 18)
|
||||||
|
|
||||||
// Legend
|
// Legend
|
||||||
HStack(spacing: 16) {
|
HStack(spacing: 20) {
|
||||||
storageLegend(color: Color(red: 1.0, green: 0.58, blue: 0.0), label: "used")
|
storageLegend(color: Color(red: 1.0, green: 0.58, blue: 0.0), label: "used")
|
||||||
storageLegend(color: AppTheme.positive, label: "safe to delete")
|
storageLegend(color: AppTheme.positive, label: "safe to delete")
|
||||||
storageLegend(color: AppTheme.destructive, label: "junk")
|
storageLegend(color: AppTheme.destructive, label: "junk")
|
||||||
}
|
}
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
.padding(.horizontal, AppTheme.hPad)
|
.padding(.horizontal, AppTheme.hPad)
|
||||||
.padding(.bottom, 20)
|
.padding(.bottom, 36)
|
||||||
|
|
||||||
Spacer(minLength: 16).frame(maxHeight: 40)
|
|
||||||
|
|
||||||
|
// HOLD TO CLEAN button
|
||||||
Button(action: { showCleanConfirm = true }) {
|
Button(action: { showCleanConfirm = true }) {
|
||||||
Text("HOLD TO CLEAN")
|
Text("HOLD TO CLEAN")
|
||||||
.font(.system(size: 10, weight: .medium, design: .monospaced))
|
.font(.system(size: 13, weight: .medium, design: .monospaced))
|
||||||
.tracking(2)
|
.tracking(2)
|
||||||
|
.foregroundStyle(.white)
|
||||||
|
.frame(maxWidth: .infinity)
|
||||||
|
.frame(height: 58)
|
||||||
|
.background(Color(red: 0.08, green: 0.08, blue: 0.08))
|
||||||
|
.clipShape(RoundedRectangle(cornerRadius: 18, style: .continuous))
|
||||||
}
|
}
|
||||||
.buttonStyle(PrimaryButtonStyle())
|
.buttonStyle(.plain)
|
||||||
.padding(.horizontal, AppTheme.hPad)
|
.padding(.horizontal, AppTheme.hPad)
|
||||||
.simultaneousGesture(
|
.simultaneousGesture(
|
||||||
LongPressGesture(minimumDuration: 0.8).onEnded { _ in showCleanConfirm = true }
|
LongPressGesture(minimumDuration: 0.8).onEnded { _ in showCleanConfirm = true }
|
||||||
@@ -900,7 +911,8 @@ struct BackupView: View {
|
|||||||
.font(.system(size: 9, weight: .regular, design: .monospaced))
|
.font(.system(size: 9, weight: .regular, design: .monospaced))
|
||||||
.foregroundStyle(AppTheme.inkTertiary)
|
.foregroundStyle(AppTheme.inkTertiary)
|
||||||
.tracking(1.5)
|
.tracking(1.5)
|
||||||
.padding(.top, 6)
|
.frame(maxWidth: .infinity)
|
||||||
|
.padding(.top, 10)
|
||||||
.padding(.bottom, 8)
|
.padding(.bottom, 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -967,18 +979,19 @@ struct BackupView: View {
|
|||||||
// MARK: — Storage helpers
|
// MARK: — Storage helpers
|
||||||
|
|
||||||
private func storageStat(_ value: String, label: String, color: Color) -> some View {
|
private func storageStat(_ value: String, label: String, color: Color) -> some View {
|
||||||
VStack(spacing: 2) {
|
VStack(spacing: 5) {
|
||||||
Text(value)
|
Text(value)
|
||||||
.font(.system(size: 15, weight: .semibold))
|
.font(.system(size: 26, weight: .semibold))
|
||||||
.foregroundStyle(color)
|
.foregroundStyle(color)
|
||||||
.monospacedDigit()
|
.monospacedDigit()
|
||||||
|
.kerning(-0.5)
|
||||||
Text(label)
|
Text(label)
|
||||||
.font(.system(size: 9, weight: .regular, design: .monospaced))
|
.font(.system(size: 9, weight: .regular, design: .monospaced))
|
||||||
.foregroundStyle(AppTheme.inkQuaternary)
|
.foregroundStyle(AppTheme.inkQuaternary)
|
||||||
.tracking(0.5)
|
.tracking(1.5)
|
||||||
}
|
}
|
||||||
.frame(maxWidth: .infinity)
|
.frame(maxWidth: .infinity)
|
||||||
.padding(.vertical, 6)
|
.padding(.vertical, 18)
|
||||||
}
|
}
|
||||||
|
|
||||||
private func storageLegend(color: Color, label: String) -> some View {
|
private func storageLegend(color: Color, label: String) -> some View {
|
||||||
|
|||||||
Reference in New Issue
Block a user