diff --git a/mobile/ios-app/Features/Round/RoundView.swift b/mobile/ios-app/Features/Round/RoundView.swift index e1c51c9..0f82132 100644 --- a/mobile/ios-app/Features/Round/RoundView.swift +++ b/mobile/ios-app/Features/Round/RoundView.swift @@ -47,39 +47,10 @@ struct RoundView: View { ) ZStack { - HermesTheme.surface - .ignoresSafeArea() - - if round != nil { - HermesVideoPlayerView(coordinator: playerCoordinator, cornerRadius: 0, fixedHeight: nil) - .ignoresSafeArea() - } - - LinearGradient( - colors: [.black.opacity(0.72), .black.opacity(0.12), .black.opacity(0.78)], - startPoint: .top, - endPoint: .bottom - ) - .ignoresSafeArea() - sideSelectionOverlay(round: round) - if let feedback = swipeFeedback { - swipeFeedbackOverlay(feedback) - } - - VStack(spacing: 0) { - header(round: round, remaining: remaining) - Spacer() - if let bannerMessage { - banner(message: bannerMessage) - .padding(.horizontal, HermesTheme.screenPadding) - .padding(.bottom, 16) - } - bottomOverlay(round: round, timerLocked: timerLocked) - } + swipeSurface(round: round, remaining: remaining, timerLocked: timerLocked, bannerMessage: bannerMessage) } - .offset(x: dragOffset.width * 0.12) .contentShape(Rectangle()) .gesture(swipeGesture(round: round, timerLocked: timerLocked)) .onAppear { @@ -113,6 +84,43 @@ struct RoundView: View { } } + private func swipeSurface(round: HermesRound?, remaining: TimeInterval, timerLocked: Bool, bannerMessage: String?) -> some View { + ZStack { + HermesTheme.surface + .ignoresSafeArea() + + if round != nil { + HermesVideoPlayerView(coordinator: playerCoordinator, cornerRadius: 0, fixedHeight: nil) + .ignoresSafeArea() + } + + LinearGradient( + colors: [.black.opacity(0.72), .black.opacity(0.12), .black.opacity(0.78)], + startPoint: .top, + endPoint: .bottom + ) + .ignoresSafeArea() + + if let feedback = swipeFeedback { + swipeFeedbackOverlay(feedback) + } + + VStack(spacing: 0) { + header(round: round, remaining: remaining) + Spacer() + if let bannerMessage { + banner(message: bannerMessage) + .padding(.horizontal, HermesTheme.screenPadding) + .padding(.bottom, 16) + } + bottomOverlay(round: round, timerLocked: timerLocked) + } + } + .offset(x: dragOffset.width * 0.72) + .rotationEffect(.degrees(max(min(Double(dragOffset.width / 40.0), 6), -6))) + .shadow(color: .black.opacity(0.28), radius: 22, x: 0, y: 10) + } + private func header(round: HermesRound?, remaining: TimeInterval) -> some View { HStack(alignment: .top, spacing: 16) { VStack(alignment: .leading, spacing: 10) { @@ -243,7 +251,7 @@ struct RoundView: View { @ViewBuilder private func sideSelectionOverlay(round: HermesRound?) -> some View { if let round, phase == .preview { - let dragThreshold: CGFloat = 18 + let dragThreshold: CGFloat = 10 let isDraggingRight = dragOffset.width > dragThreshold let isDraggingLeft = dragOffset.width < -dragThreshold @@ -252,13 +260,13 @@ struct RoundView: View { title: sortedOutcomes(for: round).dropFirst().first.map(outcomeTitle) ?? localization.string(for: "round.no"), subtitle: localization.string(for: "round.swipe_left"), color: .red, - opacity: isDraggingLeft ? min(abs(dragOffset.width) / 180.0, 0.78) : 0 + opacity: isDraggingLeft ? min(abs(dragOffset.width) / 240.0, 0.95) : 0 ) sideTint( title: sortedOutcomes(for: round).first.map(outcomeTitle) ?? localization.string(for: "round.yes"), subtitle: localization.string(for: "round.swipe_right"), color: HermesTheme.positive, - opacity: isDraggingRight ? min(abs(dragOffset.width) / 180.0, 0.78) : 0 + opacity: isDraggingRight ? min(abs(dragOffset.width) / 240.0, 0.95) : 0 ) } .ignoresSafeArea() @@ -287,7 +295,7 @@ struct RoundView: View { } private func swipeGesture(round: HermesRound?, timerLocked: Bool) -> some Gesture { - DragGesture(minimumDistance: 24) + DragGesture(minimumDistance: 12) .onChanged { value in dragOffset = value.translation } @@ -298,7 +306,7 @@ struct RoundView: View { return } - guard abs(value.translation.width) > 72, abs(value.translation.width) > abs(value.translation.height) else { + guard abs(value.translation.width) > 145, abs(value.translation.width) > abs(value.translation.height) else { swipeFeedback = nil return } diff --git a/mobile/ios-app/HermesApp.xcodeproj/project.pbxproj b/mobile/ios-app/HermesApp.xcodeproj/project.pbxproj index 2d7356a..b0617e9 100644 --- a/mobile/ios-app/HermesApp.xcodeproj/project.pbxproj +++ b/mobile/ios-app/HermesApp.xcodeproj/project.pbxproj @@ -322,7 +322,7 @@ SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HermesPrediction.app/HermesApp"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HermesPrediction.app/HermesPrediction"; }; name = Debug; }; @@ -344,7 +344,7 @@ SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_VERSION = 5.0; TARGETED_DEVICE_FAMILY = 1; - TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HermesPrediction.app/HermesApp"; + TEST_HOST = "$(BUILT_PRODUCTS_DIR)/HermesPrediction.app/HermesPrediction"; }; name = Release; }; diff --git a/mobile/ios-app/Tests/HermesAppTests/LocalizationStoreTests.swift b/mobile/ios-app/Tests/HermesAppTests/LocalizationStoreTests.swift index 8c129ae..95cfb42 100644 --- a/mobile/ios-app/Tests/HermesAppTests/LocalizationStoreTests.swift +++ b/mobile/ios-app/Tests/HermesAppTests/LocalizationStoreTests.swift @@ -1,5 +1,5 @@ import XCTest -@testable import HermesApp +@testable import HermesPrediction private struct TestFailure: Error, CustomStringConvertible { let description: String