Move vote animation to Customize tab as persistent user setting

Replace random animation selection with a user-configurable picker on
the Customize tab between Mood Style and Notifications. Confetti is
the default. Selecting a style shows an inline preview that auto-plays
the animation then dismisses itself. Remove Animation Lab from Settings.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Trey t
2026-02-24 11:47:40 -06:00
parent c643feb1d6
commit 36be57e47d
6 changed files with 193 additions and 51 deletions

View File

@@ -10,28 +10,39 @@ import SwiftUI
// MARK: - Animation Type Enum
enum CelebrationAnimationType: String, CaseIterable, Identifiable {
case confettiCannon = "Confetti"
case vortexCheckmark = "Vortex"
case explosionReveal = "Explosion"
case flipReveal = "Flip"
case shatterReform = "Shatter"
case pulseWave = "Pulse Wave"
case fireworks = "Fireworks"
case confettiCannon = "Confetti"
case morphBlob = "Morph"
case zoomTunnel = "Tunnel"
case gravityDrop = "Gravity"
var id: String { rawValue }
/// Int index for AppStorage persistence (enum uses String raw values)
var index: Int {
Self.allCases.firstIndex(of: self) ?? 0
}
/// Restore from persisted Int index
static func fromIndex(_ index: Int) -> CelebrationAnimationType {
guard index >= 0, index < allCases.count else { return .confettiCannon }
return allCases[index]
}
var icon: String {
switch self {
case .confettiCannon: return "party.popper.fill"
case .vortexCheckmark: return "tornado"
case .explosionReveal: return "sparkles"
case .flipReveal: return "rectangle.portrait.rotate"
case .shatterReform: return "square.grid.3x3"
case .pulseWave: return "dot.radiowaves.left.and.right"
case .fireworks: return "fireworks"
case .confettiCannon: return "party.popper.fill"
case .morphBlob: return "drop.fill"
case .zoomTunnel: return "tunnel.circle"
case .gravityDrop: return "arrow.down.to.line"
@@ -40,13 +51,13 @@ enum CelebrationAnimationType: String, CaseIterable, Identifiable {
var description: String {
switch self {
case .confettiCannon: return "Party confetti"
case .vortexCheckmark: return "Sucked into center"
case .explosionReveal: return "Explodes outward"
case .flipReveal: return "3D card flip"
case .shatterReform: return "Shatters & reforms"
case .pulseWave: return "Expanding waves"
case .fireworks: return "Celebration burst"
case .confettiCannon: return "Party confetti"
case .morphBlob: return "Liquid transform"
case .zoomTunnel: return "Warp speed zoom"
case .gravityDrop: return "Falls with bounce"
@@ -55,13 +66,13 @@ enum CelebrationAnimationType: String, CaseIterable, Identifiable {
var accentColor: Color {
switch self {
case .confettiCannon: return .pink
case .vortexCheckmark: return .purple
case .explosionReveal: return .orange
case .flipReveal: return .blue
case .shatterReform: return .red
case .pulseWave: return .green
case .fireworks: return .yellow
case .confettiCannon: return .pink
case .morphBlob: return .cyan
case .zoomTunnel: return .indigo
case .gravityDrop: return .mint
@@ -70,13 +81,13 @@ enum CelebrationAnimationType: String, CaseIterable, Identifiable {
var duration: Double {
switch self {
case .confettiCannon: return 2.2
case .vortexCheckmark: return 2.0
case .explosionReveal: return 1.8
case .flipReveal: return 1.5
case .shatterReform: return 2.2
case .pulseWave: return 1.6
case .fireworks: return 2.5
case .confettiCannon: return 2.2
case .morphBlob: return 2.0
case .zoomTunnel: return 1.8
case .gravityDrop: return 2.0
@@ -84,7 +95,7 @@ enum CelebrationAnimationType: String, CaseIterable, Identifiable {
}
static var random: CelebrationAnimationType {
allCases.randomElement() ?? .pulseWave
allCases.randomElement() ?? .confettiCannon
}
}