Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[feat] 약속 상세 API 연결 #247

Merged
merged 2 commits into from
Jul 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ class PagePromiseViewController: BaseViewController {

tardyViewController = TardyViewController(
tardyViewModel: TardyViewModel(
tardyService: MockTardyService(),
tardyService: PromiseService(),
promiseID: promiseViewModel.promiseID
)
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,16 +12,16 @@ class ReadyPlanInfoView: BaseView {

// MARK: Property

private let readyTimeLabel: UILabel = UILabel().then {
let readyTimeLabel: UILabel = UILabel().then {
$0.setText("12시 30분에 준비하고,\n1시에 이동을 시작해야 해요", style: .body03)
$0.setHighlightText("12시 30분", "1시", style: .body03, color: .maincolor)
}

private let requestReadyTimeLabel: UILabel = UILabel().then {
let requestReadyTimeLabel: UILabel = UILabel().then {
$0.setText("준비 소요 시간: 30분", style: .label02, color: .gray8)
}

private let requestMoveTimeLabel: UILabel = UILabel().then {
let requestMoveTimeLabel: UILabel = UILabel().then {
$0.setText("이동 소요 시간: 1시간 30분", style: .label02, color: .gray8)
}

Expand Down Expand Up @@ -69,7 +69,3 @@ class ReadyPlanInfoView: BaseView {
}
}
}

extension ReadyPlanInfoView {
func configure() {}
}
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ class ReadyStatusViewController: BaseViewController {

@objc
func readyStartButtonDidTapped() {
// TODO: 늦었을 때 꾸물거릴 시간이 없어요 팝업 뜨도록 설정
readyStatusViewModel.myReadyProgressStatus.value = .ready
rootView.myReadyStatusProgressView.readyStartButton.isEnabled.toggle()
}
Expand Down Expand Up @@ -174,9 +173,32 @@ private extension ReadyStatusViewController {
owner.updateReadyInfoView(flag: false)
return
}
// TODO: 시간 계산 로직 필요..

owner.updateReadyInfoView(flag: true)
owner.rootView.readyPlanInfoView.configure()
owner.readyStatusViewModel.calculatePrepareTime()
owner.readyStatusViewModel.convertMinute()
}
}

readyStatusViewModel.moveTime.bind(with: self) { owner, moveTime in
owner.rootView.readyPlanInfoView.requestMoveTimeLabel.setText("이동 소요 시간: \(moveTime)", style: .label02, color: .gray8)
}

readyStatusViewModel.readyTime.bind(with: self) { owner, readyTime in
owner.rootView.readyPlanInfoView.requestReadyTimeLabel.setText("준비 소요 시간: \(readyTime)", style: .label02, color: .gray8)
}

readyStatusViewModel.readyStartTime.bind(with: self) { owner, readyStartTime in
DispatchQueue.main.async {
owner.rootView.readyPlanInfoView.readyTimeLabel.setText("\(readyStartTime)에 준비하고,\n\(owner.readyStatusViewModel.moveStartTime.value)에 이동을 시작해야 해요", style: .body03)
owner.rootView.readyPlanInfoView.readyTimeLabel.setHighlightText(readyStartTime, owner.readyStatusViewModel.moveStartTime.value, style: .body03, color: .maincolor)
}
}

readyStatusViewModel.moveStartTime.bind(with: self) { owner, moveStartTime in
DispatchQueue.main.async {
owner.rootView.readyPlanInfoView.readyTimeLabel.setText("\(owner.readyStatusViewModel.readyStartTime.value)에 준비하고,\n\(moveStartTime)에 이동을 시작해야 해요", style: .body03)
owner.rootView.readyPlanInfoView.readyTimeLabel.setHighlightText(owner.readyStatusViewModel.readyStartTime.value, moveStartTime, style: .body03, color: .maincolor)
}
}

Expand Down Expand Up @@ -211,7 +233,7 @@ private extension ReadyStatusViewController {
}

func updateReadyStartButton(status: ReadyProgressStatus) {
/// 버튼 누를 때 서버 통신하게 설정
// TODO: 버튼 누를 때 서버 통신하게 설정
switch status {
case .none:
rootView.myReadyStatusProgressView.readyStartButton.setupButton(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,22 @@ class ReadyStatusViewModel {
/// bind를 사용하라는 말이 아님
let promiseName = ObservablePattern<String>("")

// 준비 정보가 입력되었는지 여부
// let isReadyInfoEntered = ObservablePattern<Bool>(false)

/// 나의 준비현황이 담긴 정보
/// 설령 데이터가 없다하더라도 약속 시간은 담겨있음.
let myReadyStatus = ObservablePattern<MyReadyStatusModel?>(nil)

// 준비 시작 시간
var readyStartTime = ObservablePattern<String>("")

// 준비 소요 시간
var readyTime = ObservablePattern<String>("")

// 이동 시작 시간
var moveStartTime = ObservablePattern<String>("")

// 이동 소요 시간
var moveTime = ObservablePattern<String>("")

// 현재 준비 상태에 대한 버튼 처리
let myReadyProgressStatus = ObservablePattern<ReadyProgressStatus>(.none)

Expand Down Expand Up @@ -63,6 +72,55 @@ class ReadyStatusViewModel {
}

extension ReadyStatusViewModel {
func convertMinute() {
let preparationHours = (self.myReadyStatus.value?.preparationTime ?? 0) / 60
let preparationMinutes = (self.myReadyStatus.value?.preparationTime ?? 0) % 60

readyTime.value = preparationHours == 0 ? "\(preparationMinutes)분" : "\(preparationHours)시간 \(preparationMinutes)분"

let travelHours = (self.myReadyStatus.value?.travelTime ?? 0) / 60
let travelMinutes = (self.myReadyStatus.value?.travelTime ?? 0) % 60

moveTime.value = travelHours == 0 ? "\(travelMinutes)분" : "\(travelHours)시간 \(travelMinutes)분"
}

func calculatePrepareTime() {
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss"
dateFormatter.locale = Locale(identifier: "ko_KR")
dateFormatter.timeZone = TimeZone(identifier: "Asia/Seoul")

let promiseTime = self.myReadyStatus.value?.promiseTime ?? ""
let readyTime = self.myReadyStatus.value?.preparationTime ?? 0
let moveTime = self.myReadyStatus.value?.travelTime ?? 0


guard let promiseDate = dateFormatter.date(from: promiseTime) else {
print("Invalid date format: \(promiseTime)")
return
}

let totalPrepTime = TimeInterval((readyTime + moveTime) * 60)

let timeFormatter = DateFormatter()
timeFormatter.dateFormat = "HH시 mm분"
timeFormatter.timeZone = TimeZone(identifier: "Asia/Seoul")

print("약속 시간: \(timeFormatter.string(from: promiseDate))")
print("준비 시간: \(readyTime) 분")
print("이동 시간: \(moveTime) 분")
print("총 준비 시간: \(totalPrepTime / 60) 분")

let readyStartTime = promiseDate.addingTimeInterval(-TimeInterval(readyTime + moveTime) * 60)
let moveStartTime = promiseDate.addingTimeInterval(-TimeInterval(moveTime) * 60)

self.readyStartTime.value = timeFormatter.string(from: readyStartTime)
print("준비 시작 시간: \(self.readyStartTime.value)")

self.moveStartTime.value = timeFormatter.string(from: moveStartTime)
print("이동 시작 시간: \(self.moveStartTime.value)")
}

func fetchMyReadyStatus() {
Task {
do {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,10 @@ class TardyCollectionViewCell: BaseCollectionViewCell {

// MARK: Property

private let profileImageView: UIImageView = UIImageView().then {
let profileImageView: UIImageView = UIImageView().then {
$0.image = .imgProfile
$0.contentMode = .scaleAspectFill
$0.layer.cornerRadius = 67 / 2
$0.layer.cornerRadius = Screen.height(67) / 2
$0.clipsToBounds = true
}

Expand Down
2 changes: 2 additions & 0 deletions KkuMulKum/Source/Promise/Tardy/View/TardyEmptyView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@ class TardyEmptyView: BaseView {

private let emptyContentLabel: UILabel = UILabel().then {
$0.setText("꾸물이들이 도착하길\n기다리는 중이에요", style: .body05, color: .gray3)
}.then {
$0.textAlignment = .center
}


Expand Down
2 changes: 1 addition & 1 deletion KkuMulKum/Source/Promise/Tardy/View/TardyPenaltyView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ class TardyPenaltyView: BaseView {
$0.setText("벌칙", style: .caption02, color: .gray8)
}

private let contentLabel: UILabel = UILabel().then {
let contentLabel: UILabel = UILabel().then {
$0.setText("탕후루 릴스 찍기", style: .body03, color: .gray8)
}

Expand Down
6 changes: 3 additions & 3 deletions KkuMulKum/Source/Promise/Tardy/View/TardyView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,15 @@ class TardyView: BaseView {

// MARK: Property

private let tardyPenaltyView: TardyPenaltyView = TardyPenaltyView().then {
let tardyPenaltyView: TardyPenaltyView = TardyPenaltyView().then {
$0.layer.cornerRadius = 8
}

private let titleLabel: UILabel = UILabel().then {
$0.setText("이번 약속의 지각 꾸물이는?", style: .head01, color: .gray8)
}

private let tardyEmptyView: TardyEmptyView = TardyEmptyView()
let tardyEmptyView: TardyEmptyView = TardyEmptyView()

let tardyCollectionView: UICollectionView = UICollectionView(
frame: .zero,
Expand Down Expand Up @@ -74,7 +74,7 @@ class TardyView: BaseView {
tardyEmptyView.snp.makeConstraints {
$0.top.equalTo(titleLabel.snp.bottom).offset(108)
$0.centerX.equalToSuperview()
$0.height.equalTo(Screen.height(192))
$0.height.equalTo(Screen.height(210))
$0.width.equalTo(Screen.width(112))
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,14 +33,14 @@ class TardyViewController: BaseViewController {
// MARK: - Setup

override func loadView() {
let state = !tardyViewModel.hasTardy.value && tardyViewModel.isPastDue.value
view = state ? tardyView : arriveView
view = tardyViewModel.isPastDue.value ? arriveView : tardyView
}

override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)

// TODO: 서버 통신하고 데이터 바인딩
tardyViewModel.fetchTardyInfo()
tardyViewModel.updatePromiseCompletion()
}

override func viewDidLoad() {
Expand All @@ -50,7 +50,6 @@ class TardyViewController: BaseViewController {
}

override func setupDelegate() {
tardyView.tardyCollectionView.delegate = self
tardyView.tardyCollectionView.dataSource = self
}
}
Expand All @@ -61,34 +60,48 @@ class TardyViewController: BaseViewController {
private extension TardyViewController {
func setupBinding() {
/// 시간이 지나고 지각자가 없을 때 arriveView로 띄워짐
tardyViewModel.hasTardy.bind(with: self) { owner, flag in
let state = !flag && owner.tardyViewModel.isPastDue.value
owner.view = state ? owner.tardyView : owner.arriveView
tardyViewModel.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
}
}

/// isFinishButtonEnabled에 따라서 버튼 활성화 상태 변경
tardyViewModel.isFinishButtonEnabled.bind(with: self) { owner, flag in
self.tardyView.finishMeetingButton.isEnabled = flag
tardyViewModel.penalty.bind(with: self) {
owner,
penalty in
DispatchQueue.main.async {
owner.tardyView.tardyPenaltyView.contentLabel.setText(
penalty,
style: .body03,
color: .gray8
)
}
}

tardyViewModel.hasTardy.bind(with: self) { owner, hasTardy in
DispatchQueue.main.async {
owner.view = hasTardy && owner.tardyViewModel.isPastDue.value ? owner.arriveView : owner.tardyView
}
}

tardyViewModel.comers.bind(with: self) { owner, comers in
DispatchQueue.main.async {
owner.tardyView.tardyCollectionView.reloadData()
}
}
}
}

// MARK: UICollectionViewDelegate

extension TardyViewController: UICollectionViewDelegate {

}


// MARK: UICollectionViewDataSource

extension TardyViewController: UICollectionViewDataSource {
func collectionView(
_ collectionView: UICollectionView,
numberOfItemsInSection section: Int
) -> Int {
// TODO: 데이터 바인딩
return 10
return tardyViewModel.comers.value?.count ?? 0
}

func collectionView(
Expand All @@ -100,6 +113,18 @@ extension TardyViewController: UICollectionViewDataSource {
for: indexPath
) as? TardyCollectionViewCell else { return UICollectionViewCell() }

guard let data = tardyViewModel.comers.value?[indexPath.row] else { return cell }

cell.nameLabel.setText(data.name, style: .body06, color: .gray6)

guard let image = URL(string: data.profileImageURL) else {
cell.profileImageView.image = .imgProfile

return cell
}

cell.profileImageView.kf.setImage(with: image)

return cell
}
}
Loading