From 6106636349e01afe9f36924763fa515593cc959d Mon Sep 17 00:00:00 2001 From: haeseoklee Date: Sun, 24 Nov 2024 22:41:04 +0900 Subject: [PATCH] =?UTF-8?q?feature:=20=EC=A4=91=EB=B3=B5=EC=9D=B8=EC=A6=9D?= =?UTF-8?q?=20=EB=B0=A9=EC=96=B4=EB=A1=9C=EC=A7=81=20=EC=9E=91=EC=84=B1=20?= =?UTF-8?q?&=20=EC=9D=B8=EC=A6=9D=EC=A4=91=EC=97=90=20cta=EB=B2=84?= =?UTF-8?q?=ED=8A=BC=20=EB=A1=9C=EB=94=A9=EC=83=81=ED=83=9C=EB=A1=9C=20?= =?UTF-8?q?=EB=B3=80=EA=B2=BD?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Interface/Sources/Home/HomeFeature.swift | 36 +++++++++++++++---- .../Sources/Home/Views/HomeBottomView.swift | 16 +++++++-- .../ImageUpload/ImageUploadFeature.swift | 35 ++++++++++-------- .../Sources/ImageUpload/ImageUploadView.swift | 7 +++- 4 files changed, 69 insertions(+), 25 deletions(-) diff --git a/Projects/Feature/Home/Interface/Sources/Home/HomeFeature.swift b/Projects/Feature/Home/Interface/Sources/Home/HomeFeature.swift index d9e1faf..0a0dea5 100644 --- a/Projects/Feature/Home/Interface/Sources/Home/HomeFeature.swift +++ b/Projects/Feature/Home/Interface/Sources/Home/HomeFeature.swift @@ -278,12 +278,26 @@ public struct HomeFeature { switch action { case .dismiss: return .none - case .presented(.imageUpload(.delegate(.didFinishImageUpload))): + + case .presented(.imageUpload(.delegate(.didFinishImageUpload(.success)))): guard let myPiece = state.competition?.myPiece else { return .none } state.movingPiece = myPiece state.competition?.board.remove(piece: myPiece) return .none + case .presented(.imageUpload(.delegate(.didFinishImageUpload(.failure)))): + guard let mission = state.mission else { return .none } + state.ctaButtonState = makeCTAButtonState(isMeCertificated: state.competition?.isMeVerified == true, mission: mission) + return .none + + case .presented(.imageUpload(.delegate(.didStartImageUpload))): + state.ctaButtonState = CTAButtonState( + info: state.ctaButtonState.info, + title: "", + status: .loading + ) + return .none + case .presented(.verificationResult(.delegate(.didTapCloseButton))): return .send(.loadData(missionId: state.missionId ?? 0)) @@ -369,10 +383,18 @@ private extension HomeFeature { public extension HomeFeature { struct CTAButtonState { - static let `default`: Self = .init(isEnabled: false, info: "", title: "") - let isEnabled: Bool + enum Status { + case enabled + case disabled + case loading + var isEnabled: Bool { self == .enabled } + var isDisabled: Bool { self == .disabled } + var isLoading: Bool { self == .loading } + } + static let `default`: Self = .init(info: "", title: "", status: .enabled) let info: String let title: String + let status: Status } func makeCTAButtonState(isMeCertificated: Bool, mission: Mission) -> CTAButtonState { @@ -380,17 +402,17 @@ public extension HomeFeature { switch isMeCertificated { case true: return .init( - isEnabled: false, info: info, - title: "오늘 미션 인증 완료!" + title: "오늘 미션 인증 완료!", + status: .disabled ) case false: return .init( - isEnabled: mission.checkIsMissionTime, info: info, title: mission.checkIsMissionDay ? (mission.checkIsMissionTime ? "오늘 미션 인증하기" : "오늘 미션 인증 시간 마감") - : "오늘은 미션일이 아니에요" + : "오늘은 미션일이 아니에요", + status: mission.checkIsMissionTime ? .enabled : .disabled ) } } diff --git a/Projects/Feature/Home/Interface/Sources/Home/Views/HomeBottomView.swift b/Projects/Feature/Home/Interface/Sources/Home/Views/HomeBottomView.swift index 741ec47..cb268e2 100644 --- a/Projects/Feature/Home/Interface/Sources/Home/Views/HomeBottomView.swift +++ b/Projects/Feature/Home/Interface/Sources/Home/Views/HomeBottomView.swift @@ -27,22 +27,32 @@ struct HomeBottomView: View { .padding(.top, 16) .padding(.bottom, 6) - PhotoPickerView(selectedImages: $store.selectedImages.sending(\.didSelectImages), maxSelectedCount: 1) { + PhotoPickerView( + selectedImages: $store.selectedImages.sending(\.didSelectImages), + maxSelectedCount: 1 + ) { Text(store.ctaButtonState.title) .font(.pretendard(kind: .body_lg, type: .bold)) .foregroundColor(SharedDesignSystemAsset.Colors.white.swiftUIColor) .frame(height: 60) .frame(maxWidth: .infinity) .background( - store.ctaButtonState.isEnabled + store.ctaButtonState.status.isEnabled ? SharedDesignSystemAsset.Colors.orange.swiftUIColor : SharedDesignSystemAsset.Colors.disabled.swiftUIColor ) .cornerRadius(30) + .overlay { + VStack(alignment: .center, spacing: 0) { + ProgressView() + .progressViewStyle(CircularProgressViewStyle()) + .isHidden(!store.ctaButtonState.status.isLoading, remove: true) + } + } } .padding(.horizontal, HomeView.Constant.horizontalPadding) .padding(.bottom, 36) - .disabled(!store.ctaButtonState.isEnabled) + .disabled(store.ctaButtonState.status.isDisabled) } .background(.ultraThinMaterial) .cornerRadius(20, corners: [.topLeft, .topRight]) diff --git a/Projects/Feature/Home/Interface/Sources/ImageUpload/ImageUploadFeature.swift b/Projects/Feature/Home/Interface/Sources/ImageUpload/ImageUploadFeature.swift index 2b84931..1dfcaa8 100644 --- a/Projects/Feature/Home/Interface/Sources/ImageUpload/ImageUploadFeature.swift +++ b/Projects/Feature/Home/Interface/Sources/ImageUpload/ImageUploadFeature.swift @@ -25,6 +25,7 @@ public struct ImageUploadFeature { public let updatedDate: Date public let selectedImage: UIImage public var isLoading: Bool = false + public var isButtonDisabled: Bool = false public var formatedDate: String { DateFormatter.yearMonthDayFormatter.string(from: updatedDate) @@ -46,7 +47,8 @@ public struct ImageUploadFeature { } public enum Delegate { - case didFinishImageUpload + case didStartImageUpload + case didFinishImageUpload(Result) } public var body: some ReducerOf { @@ -54,18 +56,22 @@ public struct ImageUploadFeature { switch action { case .didTapUploadButton: state.isLoading = true - return .run { [ - missionId = state.missionId, - selectedImage = state.selectedImage - ] send in - await send(.didFinishImageUpload( - Result { - if let data = selectedImage.jpegData(compressionQuality: 0.5) { - return try await verificationService.postVerificationsMe(missionId, data) + state.isButtonDisabled = true + return .concatenate( + .send(.delegate(.didStartImageUpload)), + .run { [ + missionId = state.missionId, + selectedImage = state.selectedImage + ] send in + await send(.didFinishImageUpload( + Result { + if let data = selectedImage.jpegData(compressionQuality: 0.5) { + return try await verificationService.postVerificationsMe(missionId, data) + } } - } - )) - } + )) + } + ) case .didTapCloseButton: return .run { _ in await self.dismiss() @@ -73,14 +79,15 @@ public struct ImageUploadFeature { case .didFinishImageUpload(.success): state.isLoading = false return .concatenate( - .send(.delegate(.didFinishImageUpload)), + .send(.delegate(.didFinishImageUpload(.success(())))), .run { _ in await self.dismiss() } ) case .didFinishImageUpload(.failure): state.isLoading = false - return .none + state.isButtonDisabled = false + return .send(.delegate(.didFinishImageUpload(.failure(NSError())))) case .delegate: return .none } diff --git a/Projects/Feature/Home/Interface/Sources/ImageUpload/ImageUploadView.swift b/Projects/Feature/Home/Interface/Sources/ImageUpload/ImageUploadView.swift index b1fab40..083a8a0 100644 --- a/Projects/Feature/Home/Interface/Sources/ImageUpload/ImageUploadView.swift +++ b/Projects/Feature/Home/Interface/Sources/ImageUpload/ImageUploadView.swift @@ -77,11 +77,16 @@ public struct ImageUploadView: View { .foregroundColor(SharedDesignSystemAsset.Colors.white.swiftUIColor) .frame(height: 60) .frame(maxWidth: .infinity) - .background(SharedDesignSystemAsset.Colors.orange.swiftUIColor) + .background( + store.state.isButtonDisabled + ? SharedDesignSystemAsset.Colors.disabled.swiftUIColor + : SharedDesignSystemAsset.Colors.orange.swiftUIColor + ) .cornerRadius(30) } .padding(.horizontal, 24) .padding(.bottom, safeAreaInsets.bottom) + .disabled(store.state.isButtonDisabled) } .background(SharedDesignSystemAsset.Colors.white.swiftUIColor) }