diff --git a/Projects/Feature/GoalDetail/Sources/Detail/GoalDetailView.swift b/Projects/Feature/GoalDetail/Sources/Detail/GoalDetailView.swift index 3b6921ed..9eede9a2 100644 --- a/Projects/Feature/GoalDetail/Sources/Detail/GoalDetailView.swift +++ b/Projects/Feature/GoalDetail/Sources/Detail/GoalDetailView.swift @@ -280,19 +280,23 @@ private extension GoalDetailView { } @ViewBuilder var reactionBar: some View { - ReactionBarView( - selectedEmoji: store.selectedReactionEmoji, - onSelect: { emoji in - store.send(.view(.reactionEmojiTapped(emoji))) - } - ) - .padding(.horizontal, Constants.reactionBarHorizontalPadding) - .position( - x: rectFrame.midX, - y: rectFrame.maxY - + Constants.reactionBarTopPadding - + Constants.reactionBarHeight / 2 - ) + GeometryReader { rootGeo in + let rootFrame = rootGeo.frame(in: .global) + + ReactionBarView( + selectedEmoji: store.selectedReactionEmoji, + onSelect: { emoji in + store.send(.view(.reactionEmojiTapped(emoji))) + } + ) + .padding(.horizontal, Constants.reactionBarHorizontalPadding) + .frame(maxWidth: .infinity, alignment: .top) + .offset( + y: rectFrame.maxY + - rootFrame.minY + + Constants.reactionBarTopPadding + ) + } } var backgroundCard: some View { @@ -626,11 +630,10 @@ private extension GoalDetailView { static let minimumDragResistance: CGFloat = 0.35 static let pullToRefreshThreshold: CGFloat = 80 static let maxPullToRefreshOffset: CGFloat = 120 - static var cardTopPadding: CGFloat { isSEDevice ? 34 : 89 } + static var cardTopPadding: CGFloat { isSEDevice ? 46 : 103 } static var cardSize: CGFloat { isSEDevice ? 321 : 336 } - static let reactionBarHeight: CGFloat = 77 static let reactionBarHorizontalPadding: CGFloat = 20 - static var reactionBarTopPadding: CGFloat { isSEDevice ? 19 : 69 } + static var reactionBarTopPadding: CGFloat { isSEDevice ? 55 : 105 } } } diff --git a/Projects/Feature/Home/Sources/Root/HomeCoordinator+Impl.swift b/Projects/Feature/Home/Sources/Root/HomeCoordinator+Impl.swift index 12dc9b3b..0d6f5478 100644 --- a/Projects/Feature/Home/Sources/Root/HomeCoordinator+Impl.swift +++ b/Projects/Feature/Home/Sources/Root/HomeCoordinator+Impl.swift @@ -72,6 +72,15 @@ extension HomeCoordinator { state.makeGoal = .init(mode: .edit(goalData)) return .none + case let .statsDetail(.delegate(.goToGoalDetail(id, owner, date))): + return .send( + .navigateToGoalDetail( + id: id, + owner: owner, + date: date + ) + ) + case .statsDetail(.view(.onDisappear)): if !state.routes.contains(.statsDetail) { state.statsDetail = nil diff --git a/Projects/Feature/ProofPhoto/Interface/Sources/ProofPhotoReducer.swift b/Projects/Feature/ProofPhoto/Interface/Sources/ProofPhotoReducer.swift index 7eedd7fc..cca2a18a 100644 --- a/Projects/Feature/ProofPhoto/Interface/Sources/ProofPhotoReducer.swift +++ b/Projects/Feature/ProofPhoto/Interface/Sources/ProofPhotoReducer.swift @@ -40,6 +40,7 @@ public struct ProofPhotoReducer { public var isCapturing: Bool = false public var isUploading: Bool = false public var hasImage: Bool { imageData != nil } + public var shouldShowComment: Bool = false public var toast: TXToastType? public var goalId: Int64 public var verificationDate: String diff --git a/Projects/Feature/ProofPhoto/Sources/ProofPhoto/ProofPhotoReducer+Impl.swift b/Projects/Feature/ProofPhoto/Sources/ProofPhoto/ProofPhotoReducer+Impl.swift index fd66f089..e4f2969c 100644 --- a/Projects/Feature/ProofPhoto/Sources/ProofPhoto/ProofPhotoReducer+Impl.swift +++ b/Projects/Feature/ProofPhoto/Sources/ProofPhoto/ProofPhotoReducer+Impl.swift @@ -229,6 +229,7 @@ extension ProofPhotoReducer { // MARK: - Update State case let .response(.setupCaptureSessionCompleted(session)): state.captureSession = session + state.shouldShowComment = true return .none case .response(.cameraSwitched): @@ -278,7 +279,9 @@ extension ProofPhotoReducer { case .binding: return .none - default: return .none + case .delegate: + state.shouldShowComment = false + return .none } } // swiftlint: enable closure_body_length diff --git a/Projects/Feature/ProofPhoto/Sources/ProofPhoto/ProofPhotoView.swift b/Projects/Feature/ProofPhoto/Sources/ProofPhoto/ProofPhotoView.swift index 25066860..bc8821d1 100644 --- a/Projects/Feature/ProofPhoto/Sources/ProofPhoto/ProofPhotoView.swift +++ b/Projects/Feature/ProofPhoto/Sources/ProofPhoto/ProofPhotoView.swift @@ -113,7 +113,7 @@ private extension ProofPhotoView { } var shouldShowCommentOverlay: Bool { - (store.captureSession != nil || store.hasImage) && rectFrame != .zero + store.shouldShowComment && rectFrame != .zero } var topBar: some View { diff --git a/Projects/Feature/Stats/Interface/Sources/Detail/StatsDetailReducer.swift b/Projects/Feature/Stats/Interface/Sources/Detail/StatsDetailReducer.swift index 637d5e60..ff7f9d02 100644 --- a/Projects/Feature/Stats/Interface/Sources/Detail/StatsDetailReducer.swift +++ b/Projects/Feature/Stats/Interface/Sources/Detail/StatsDetailReducer.swift @@ -92,9 +92,10 @@ public struct StatsDetailReducer { public init(goalId: Int64, initialMonth: TXCalendarDate) { self.goalId = goalId - self.currentMonth = initialMonth + let month = TXCalendarDate(year: initialMonth.year, month: initialMonth.month) + self.currentMonth = month self.monthlyData = TXCalendarDataGenerator.generateMonthData( - for: initialMonth, + for: month, hideAdjacentDates: true ) } @@ -150,7 +151,7 @@ public struct StatsDetailReducer { public enum Delegate { case navigateBack - case goToGoalDetail(goalId: Int64, isCompletedPartner: Bool, date: String) + case goToGoalDetail(goalId: Int64, owner: GoalDetail.Owner, date: String) case goToGoalEdit(EditableGoal) } diff --git a/Projects/Feature/Stats/Sources/Coordinator/StatsCoordinator+Impl.swift b/Projects/Feature/Stats/Sources/Coordinator/StatsCoordinator+Impl.swift index 9e964d3a..0130a3f8 100644 --- a/Projects/Feature/Stats/Sources/Coordinator/StatsCoordinator+Impl.swift +++ b/Projects/Feature/Stats/Sources/Coordinator/StatsCoordinator+Impl.swift @@ -38,10 +38,10 @@ extension StatsCoordinator { state.statsDetail = .init(goalId: goalId, initialMonth: calendarDate) return .none - case let .statsDetail(.delegate(.goToGoalDetail(goalId, isCompletedPartner, date))): + case let .statsDetail(.delegate(.goToGoalDetail(goalId, owner, date))): state.routes.append(.goalDetail) state.goalDetail = .init( - currentUser: isCompletedPartner ? .you : .mySelf, + currentUser: owner, id: goalId, verificationDate: date ) diff --git a/Projects/Feature/Stats/Sources/Detail/StatsDetailReducer+Impl.swift b/Projects/Feature/Stats/Sources/Detail/StatsDetailReducer+Impl.swift index c1332655..2a33b331 100644 --- a/Projects/Feature/Stats/Sources/Detail/StatsDetailReducer+Impl.swift +++ b/Projects/Feature/Stats/Sources/Detail/StatsDetailReducer+Impl.swift @@ -91,13 +91,13 @@ extension StatsDetailReducer { else { return .none } let dateString = txDate.formattedAPIDateString() let completedItem = state.completedDateByKey[dateString] - let isCompletedPartner = completedItem?.partnerImageUrl != nil + let owner: GoalDetail.Owner = completedItem?.partnerImageUrl != nil ? .you : .mySelf return .send( .delegate( .goToGoalDetail( goalId: state.goalId, - isCompletedPartner: isCompletedPartner, + owner: owner, date: dateString ) )