diff --git a/KkuMulKum/Source/AddPromise/ViewController/AddPromiseCompleteViewController.swift b/KkuMulKum/Source/AddPromise/ViewController/AddPromiseCompleteViewController.swift index aaa7a028..93233626 100644 --- a/KkuMulKum/Source/AddPromise/ViewController/AddPromiseCompleteViewController.swift +++ b/KkuMulKum/Source/AddPromise/ViewController/AddPromiseCompleteViewController.swift @@ -17,7 +17,6 @@ final class AddPromiseCompleteViewController: BaseViewController { private let disposeBag = DisposeBag() - // MARK: - Initializer init(promiseID: Int) { diff --git a/KkuMulKum/Source/Promise/EditPromise/ViewController/ChooseContentViewController.swift b/KkuMulKum/Source/Promise/EditPromise/ViewController/ChooseContentViewController.swift index 282cfd30..435db9f3 100644 --- a/KkuMulKum/Source/Promise/EditPromise/ViewController/ChooseContentViewController.swift +++ b/KkuMulKum/Source/Promise/EditPromise/ViewController/ChooseContentViewController.swift @@ -85,6 +85,15 @@ private extension ChooseContentViewController { button.isSelected = (button.identifier == penalty) } }) + + viewModel.isSuccess.bindOnMain(with: self) { owner, success in + let viewController = AddPromiseCompleteViewController(promiseID: self.viewModel.promiseID) + + viewController.setupNavigationBarTitle(with: "약속 수정하기") + viewController.rootView.titleLabel.text = "약속이 수정되었어요!" + + self.navigationController?.pushViewController(viewController, animated: true) + } } @objc @@ -99,31 +108,6 @@ private extension ChooseContentViewController { @objc func confirmButtonDidTap() { - guard let participantList = viewModel.participantList?.value else { return } - let participants = participantList.filter { $0.isParticipant }.map { $0.memberID } - - viewModel.putPromiseInfo( - request: EditPromiseRequestModel( - name: viewModel.promiseName?.value ?? "", - placeName: viewModel.placeName?.value ?? "", - address: viewModel.address ?? "", - roadAddress: viewModel.roadAddress ?? "", - time: viewModel.time ?? "", - dressUpLevel: viewModel.dressUpLevel?.value ?? "", - penalty: viewModel.penalty?.value ?? "", - x: viewModel.xCoordinate ?? 0, - y: viewModel.yCoordinate ?? 0, - participants: participants - ) - ) { - DispatchQueue.main.async { - let viewController = AddPromiseCompleteViewController(promiseID: self.viewModel.promiseID) - - viewController.setupNavigationBarTitle(with: "약속 수정하기") - viewController.rootView.titleLabel.text = "약속이 수정되었어요!" - - self.navigationController?.pushViewController(viewController, animated: true) - } - } + viewModel.putPromiseInfo() } } diff --git a/KkuMulKum/Source/Promise/EditPromise/ViewController/ChooseMemberViewController.swift b/KkuMulKum/Source/Promise/EditPromise/ViewController/ChooseMemberViewController.swift index 65f17afb..92c5fc92 100644 --- a/KkuMulKum/Source/Promise/EditPromise/ViewController/ChooseMemberViewController.swift +++ b/KkuMulKum/Source/Promise/EditPromise/ViewController/ChooseMemberViewController.swift @@ -39,9 +39,7 @@ class ChooseMemberViewController: BaseViewController { setupBinding() - viewModel.fetchPromiseAvailableMember() { - self.setupSelectInitialCells() - } + viewModel.fetchPromiseAvailableMember() } override func viewWillAppear(_ animated: Bool) { @@ -82,23 +80,6 @@ private extension ChooseMemberViewController { }) } - // TODO: 셀 초기 선택 안되는 문제 해결 - func setupSelectInitialCells() { - DispatchQueue.main.async { - guard let members = self.viewModel.participantList?.value else { return } - - for index in 0 ..< members.count { - let indexPath = IndexPath(item: index, section: 0) - - if members[index].isParticipant { - (self.rootView.memberListView.cellForItem(at: indexPath) as? SelectMemberCell)?.isSelected = true - } - } - - self.rootView.memberListView.reloadData() - } - } - @objc func confirmButtonDidTap() { let viewController = ChooseContentViewController(viewModel: viewModel) @@ -139,6 +120,13 @@ extension ChooseMemberViewController: UICollectionViewDataSource { ) ) + if let isParticipant = viewModel.participantList?.value[indexPath.row].isParticipant, isParticipant { + collectionView.selectItem(at: indexPath, animated: false, scrollPosition: []) + } else { + return cell + } + + return cell } } diff --git a/KkuMulKum/Source/Promise/EditPromise/ViewModel/EditPromiseViewModel.swift b/KkuMulKum/Source/Promise/EditPromise/ViewModel/EditPromiseViewModel.swift index ad67d131..2c78b758 100644 --- a/KkuMulKum/Source/Promise/EditPromise/ViewModel/EditPromiseViewModel.swift +++ b/KkuMulKum/Source/Promise/EditPromise/ViewModel/EditPromiseViewModel.swift @@ -15,6 +15,7 @@ class EditPromiseViewModel { let participantList: ObservablePattern<[AvailableMember]>? let dressUpLevel: ObservablePattern? let penalty: ObservablePattern? + let isSuccess = ObservablePattern(false) var xCoordinate: Double? var yCoordinate: Double? @@ -120,33 +121,49 @@ extension EditPromiseViewModel { } extension EditPromiseViewModel { - func putPromiseInfo(request: EditPromiseRequestModel, completion: @escaping () -> Void) { + func putPromiseInfo() { + let participants = participantList?.value.filter { $0.isParticipant }.map { $0.memberID } ?? [] + + let request = EditPromiseRequestModel( + name: promiseName?.value ?? "", + placeName: placeName?.value ?? "", + address: address ?? "", + roadAddress: roadAddress ?? "", + time: time ?? "", + dressUpLevel: dressUpLevel?.value ?? "", + penalty: penalty?.value ?? "", + x: xCoordinate ?? 0, + y: yCoordinate ?? 0, + participants: participants + ) + Task { do { let result = try await service.putPromiseInfo(with: promiseID, request: request) guard let success = result?.success, - success == true else { + success == true + else { return } - completion() + isSuccess.value = success } } } - func fetchPromiseAvailableMember(completion: @escaping () -> Void) { + func fetchPromiseAvailableMember() { Task { do { let result = try await service.fetchPromiseAvailableMember(with: promiseID) - guard let success = result?.success, success == true else { + guard let success = result?.success, + success == true + else { return } participantList?.value = result?.data?.members ?? [] - - completion() } } } diff --git a/KkuMulKum/Source/Promise/PagePromise/ViewController/PromiseViewController.swift b/KkuMulKum/Source/Promise/PagePromise/ViewController/PromiseViewController.swift index 9ae3aa69..a0a8cad8 100644 --- a/KkuMulKum/Source/Promise/PagePromise/ViewController/PromiseViewController.swift +++ b/KkuMulKum/Source/Promise/PagePromise/ViewController/PromiseViewController.swift @@ -57,7 +57,7 @@ class PromiseViewController: BaseViewController { super.viewDidLoad() setupNavigationBarBackButton() - setupPromiseEditButton() + setupPromiseEditButton(isHidden: false) setupBindings() } @@ -154,18 +154,19 @@ private extension PromiseViewController { owner.promiseInfoViewController.setupContent() owner.promiseInfoViewController.setUpTimeContent() owner.removePromiseViewContoller.promiseNameLabel.text = info?.promiseName ?? "" + owner.setupPromiseEditButton(isHidden: !(info?.isParticipant ?? false)) } } - func setupPromiseEditButton() { + func setupPromiseEditButton(isHidden: Bool) { let moreButton = UIBarButtonItem( image: .imgMore.withRenderingMode(.alwaysOriginal), style: .plain, target: self, action: #selector(self.moreButtonDidTap) ) - - navigationItem.rightBarButtonItem = moreButton + + navigationItem.rightBarButtonItem = isHidden ? nil : moreButton } @objc @@ -193,9 +194,9 @@ private extension PromiseViewController { @objc func finishMeetingButtonDidTap() { - promiseTardyViewController.viewModel.updatePromiseCompletion() - - navigationController?.popViewController(animated: true) + promiseTardyViewController.viewModel.updatePromiseCompletion { + self.navigationController?.popViewController(animated: true) + } } @objc diff --git a/KkuMulKum/Source/Promise/PromiseInfo/ViewController/PromiseInfoViewController.swift b/KkuMulKum/Source/Promise/PromiseInfo/ViewController/PromiseInfoViewController.swift index da732df0..17999ad0 100644 --- a/KkuMulKum/Source/Promise/PromiseInfo/ViewController/PromiseInfoViewController.swift +++ b/KkuMulKum/Source/Promise/PromiseInfo/ViewController/PromiseInfoViewController.swift @@ -45,6 +45,7 @@ class PromiseInfoViewController: BaseViewController { viewModel.fetchPromiseParticipantList() viewModel.fetchPromiseInfo() + viewModel.fetchTardyInfo() } @@ -86,22 +87,25 @@ extension PromiseInfoViewController { } func setupBinding() { - viewModel.participantsInfo.bind(with: self) { owner, participantsInfo in - DispatchQueue.main.async { - owner.rootView.participantNumberLabel.setText( - "약속 참여 인원 \(participantsInfo?.count ?? 0)명", - style: .body05, - color: .maincolor - ) - - owner.rootView.participantNumberLabel.setHighlightText( - "\(participantsInfo?.count ?? 0)명", - style: .body05, - color: .gray3 - ) - - owner.rootView.participantCollectionView.reloadData() - } + viewModel.isPastDue.bindOnMain(with: self) { owner, isPastDue in + + owner.rootView.editButton.isHidden = isPastDue + } + + viewModel.participantsInfo.bindOnMain(with: self) { owner, participantsInfo in + owner.rootView.participantNumberLabel.setText( + "약속 참여 인원 \(participantsInfo?.count ?? 0)명", + style: .body05, + color: .maincolor + ) + + owner.rootView.participantNumberLabel.setHighlightText( + "\(participantsInfo?.count ?? 0)명", + style: .body05, + color: .gray3 + ) + + owner.rootView.participantCollectionView.reloadData() } } @@ -130,41 +134,41 @@ extension PromiseInfoViewController { dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" dateFormatter.locale = Locale(identifier: "ko_KR") dateFormatter.timeZone = TimeZone(identifier: "Asia/Seoul") - - guard let date = dateFormatter.date(from: viewModel.promiseInfo.value?.time ?? "") else { + + guard let dateWithTime = dateFormatter.date(from: viewModel.promiseInfo.value?.time ?? "") else { return } - - dateFormatter.dateFormat = "M월 d일 a h:mm" - dateFormatter.amSymbol = "AM" - dateFormatter.pmSymbol = "PM" - - let time = dateFormatter.string(from: date) - - let currentDate = Calendar.current - - let components = currentDate.dateComponents([.day], from: Date(), to: date) + + let calendar = Calendar.current + + let dateOnly = calendar.startOfDay(for: dateWithTime) + let today = calendar.startOfDay(for: Date()) + + let components = calendar.dateComponents([.day], from: today, to: dateOnly) guard let remainDay = components.day else { return } - - rootView.timeContentLabel.setText(time, style: .body04) - + if remainDay == 0 { - rootView.dDayLabel.setText("D-DAY" ,style: .body05, color: .mainorange) + rootView.dDayLabel.setText("D-DAY", style: .body05, color: .mainorange) rootView.promiseImageView.image = .imgPromise rootView.promiseNameLabel.textColor = .gray7 - } - else if remainDay < 0 { - rootView.dDayLabel.setText("D+\(remainDay)" ,style: .body05, color: .gray4) + } else if remainDay < 0 { + rootView.dDayLabel.setText("D+\(-remainDay)", style: .body05, color: .gray4) rootView.promiseImageView.image = .imgPromiseGray rootView.promiseNameLabel.textColor = .gray4 - } - else { - rootView.dDayLabel.setText("D-\(remainDay)" ,style: .body05, color: .gray5) + } else { + rootView.dDayLabel.setText("D-\(remainDay)", style: .body05, color: .gray5) rootView.promiseImageView.image = .imgPromise rootView.promiseNameLabel.textColor = .gray7 } + + dateFormatter.dateFormat = "M월 d일 a h:mm" + dateFormatter.amSymbol = "AM" + dateFormatter.pmSymbol = "PM" + let time = dateFormatter.string(from: dateWithTime) + + rootView.timeContentLabel.setText(time, style: .body04) } } diff --git a/KkuMulKum/Source/Promise/Tardy/ViewController/TardyViewController.swift b/KkuMulKum/Source/Promise/Tardy/ViewController/TardyViewController.swift index 3e0bf761..ee81651e 100644 --- a/KkuMulKum/Source/Promise/Tardy/ViewController/TardyViewController.swift +++ b/KkuMulKum/Source/Promise/Tardy/ViewController/TardyViewController.swift @@ -41,6 +41,10 @@ class TardyViewController: BaseViewController { override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) + + viewModel.fetchPromiseParticipantList() + viewModel.fetchPromiseInfo() + viewModel.fetchTardyInfo() } @@ -57,24 +61,18 @@ class TardyViewController: BaseViewController { private extension TardyViewController { func setupBinding() { /// 시간이 지나고 지각자가 없을 때 arriveView로 띄워짐 - viewModel.isPastDue.bind(with: self) { owner, isPastDue in - DispatchQueue.main.async { - owner.tardyView.tardyCollectionView.isHidden = !isPastDue - owner.tardyView.tardyEmptyView.isHidden = isPastDue - owner.tardyView.finishMeetingButton.isEnabled = isPastDue - } + viewModel.isPastDue.bindOnMain(with: self) { owner, isPastDue in + owner.tardyView.tardyCollectionView.isHidden = !isPastDue + owner.tardyView.tardyEmptyView.isHidden = isPastDue + owner.tardyView.finishMeetingButton.isEnabled = isPastDue } - viewModel.penalty.bind(with: self) { - owner, - penalty in - DispatchQueue.main.async { - owner.tardyView.tardyPenaltyView.contentLabel.setText( - penalty, - style: .body03, - color: .gray8 - ) - } + viewModel.penalty.bindOnMain(with: self) { owner, penalty in + owner.tardyView.tardyPenaltyView.contentLabel.setText( + penalty, + style: .body03, + color: .gray8 + ) } viewModel.hasTardy.bind(with: self) { owner, hasTardy in @@ -88,6 +86,20 @@ private extension TardyViewController { owner.tardyView.tardyCollectionView.reloadData() } } + + viewModel.promiseInfo.bindOnMain(with: self) { owner, info in + owner.tardyView.finishMeetingButton.isEnabled = (info?.isParticipant ?? false) + } + + viewModel.errorMessage.bindOnMain(with: self) { owner, error in + let toast = Toast() + toast.show( + message: error, + view: owner.view, + position: .bottom, + inset: 100 + ) + } } } diff --git a/KkuMulKum/Source/Promise/ViewModel/PromiseViewModel.swift b/KkuMulKum/Source/Promise/ViewModel/PromiseViewModel.swift index df7282b7..20a4d32d 100644 --- a/KkuMulKum/Source/Promise/ViewModel/PromiseViewModel.swift +++ b/KkuMulKum/Source/Promise/ViewModel/PromiseViewModel.swift @@ -318,7 +318,7 @@ extension PromiseViewModel { } /// 약속 완료 API 구현 함수 - func updatePromiseCompletion() { + func updatePromiseCompletion(completion: @escaping () -> Void) { Task { do { let responseBody = try await service.updatePromiseCompletion(with: promiseID) @@ -330,6 +330,8 @@ extension PromiseViewModel { return } + + completion() } catch { print(">>>>> \(error.localizedDescription) : \(#function)") }