Skip to content

Commit

Permalink
[#74]Feat: report 버튼 클릭 시, 타이머를 멈추고 info view를 hidden하고 alert를 표시
Browse files Browse the repository at this point in the history
- 현재는 차단하기를 했을 떄, 데이터 또는 dataSource에서 item을 삭제하지 않고, 0.5초 후에 scroll하는 방식으로 구현
- dimview를 클릭하면 타이머가 다시 시작되도록 이벤트 전달
- reject 버튼 이벤트는 애니메이션 1초여서 1초후에 다음 유저로 넘어가도록 구현
  • Loading branch information
Minny27 authored and ibcylon committed Jun 5, 2024
1 parent 9922d0a commit 6dc528e
Show file tree
Hide file tree
Showing 2 changed files with 134 additions and 14 deletions.
116 changes: 106 additions & 10 deletions Projects/Features/Falling/Src/Home/FallingHomeViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,24 @@ enum FallingCellButtonAction {
case like(IndexPath)
}

enum TimerActiveAction {
case viewWillDisAppear(Bool)
case profileDoubleTap(Bool)
case reportButtonTap(Bool)
case DimViewTap(Bool)

var state: Bool {
switch self {
case .viewWillDisAppear(let flag), .profileDoubleTap(let flag), .reportButtonTap(let flag), .DimViewTap(let flag):
return flag
}
}
}

enum AnimationAction {
case scroll, delete
}

final class FallingHomeViewController: TFBaseViewController {
private let viewModel: FallingHomeViewModel
private var dataSource: DataSource!
Expand Down Expand Up @@ -49,28 +67,46 @@ final class FallingHomeViewController: TFBaseViewController {
}

override func bindViewModel() {
let timeOverSubject = PublishSubject<Void>()
let timeOverSubject = PublishSubject<AnimationAction>()

let initialTrigger = Driver<Void>.just(())
let timerOverTrigger = timeOverSubject.asDriverOnErrorJustEmpty()
let fallingCellButtonAction = PublishSubject<FallingCellButtonAction>()

let viewWillDisAppearTrigger = self.rx.viewWillDisAppear.map { _ in false }.asDriverOnErrorJustEmpty()
let timerActiveRelay = BehaviorRelay(value: true)
let profileDoubleTapTriggerObserver = PublishSubject<Void>()
let viewWillDisAppearTrigger = self.rx.viewWillDisAppear.map { _ in
return TimerActiveAction.viewWillDisAppear(false)
}.asDriverOnErrorJustEmpty()

let timerActiveRelay = BehaviorRelay<TimerActiveAction>(value: .profileDoubleTap(true))

let profileDoubleTapTriggerObserver = PublishSubject<Void>()
let profileDoubleTapTrigger = profileDoubleTapTriggerObserver
.withLatestFrom(timerActiveRelay) { !$1 }
.withLatestFrom(timerActiveRelay) {
return TimerActiveAction.profileDoubleTap(!$1.state)
}
.asDriverOnErrorJustEmpty()

let reportButtonTapTriggerObserver = PublishSubject<Void>()

let reportButtonTapTrigger = reportButtonTapTriggerObserver
.withLatestFrom(timerActiveRelay) { _, _ in
return TimerActiveAction.reportButtonTap(false)
}
.asDriverOnErrorJustEmpty()

Driver.merge(profileDoubleTapTrigger, viewWillDisAppearTrigger)
Driver.merge(reportButtonTapTrigger, profileDoubleTapTrigger, viewWillDisAppearTrigger)
.drive(timerActiveRelay)
.disposed(by: disposeBag)

let complaintsButtonTapTrigger = PublishRelay<Void>()
let blockButtonTapTrigger = PublishRelay<Void>()

let input = FallingHomeViewModel.Input(
initialTrigger: initialTrigger,
timeOverTrigger: timerOverTrigger,
cellButtonAction: fallingCellButtonAction.asDriverOnErrorJustEmpty()
cellButtonAction: fallingCellButtonAction.asDriverOnErrorJustEmpty(),
complaintsButtonTapTrigger: complaintsButtonTapTrigger.asDriverOnErrorJustEmpty(),
blockButtonTapTrigger: blockButtonTapTrigger.asDriverOnErrorJustEmpty()
)

let output = viewModel.transform(input: input)
Expand All @@ -88,7 +124,8 @@ final class FallingHomeViewController: TFBaseViewController {
timerActiveTrigger: timerActiveTrigger,
timeOverSubject: timeOverSubject,
profileDoubleTapTriggerObserver: profileDoubleTapTriggerObserver,
fallingCellButtonAction: fallingCellButtonAction
fallingCellButtonAction: fallingCellButtonAction,
reportButtonTapTriggerObserver: reportButtonTapTriggerObserver
)
}

Expand Down Expand Up @@ -124,7 +161,8 @@ final class FallingHomeViewController: TFBaseViewController {
at: indexPath,
at: .top,
animated: true
)})
)
})
.disposed(by: self.disposeBag)

output.infoButtonAction
Expand All @@ -142,10 +180,53 @@ final class FallingHomeViewController: TFBaseViewController {
cell.rejectLottieView.isHidden = false
cell.rejectLottieView.play()

DispatchQueue.main.asyncAfter(deadline: .now() + 1.0) {
timeOverSubject.onNext(.scroll)
}
}
.disposed(by: disposeBag)

reportButtonTapTriggerObserver.asDriverOnErrorJustEmpty()
.do { _ in
self.showAlert(
leftActionTitle: "신고하기",
rightActionTitle: "차단하기",
leftActionCompletion: {
self.showAlert(action: .complaints)
},
rightActionCompletion: {
self.showAlert(
action: .block,
leftActionCompletion: {
blockButtonTapTrigger.accept(())
},
rightActionCompletion: {
timerActiveRelay.accept(.DimViewTap(true))
}
)
},
dimActionCompletion: {
timerActiveRelay.accept(.DimViewTap(true))
}
)
}
.drive()
.disposed(by: disposeBag)

Driver.merge(output.complaintsAction, output.blockAction)
.do { indexPath in
// timerActiveRelay.accept(.DimViewTap(true))
self.deleteItems(indexPath)
DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) {
timeOverSubject.onNext(())
timeOverSubject.onNext(.delete)
timerActiveRelay.accept(.DimViewTap(true))
}

// timerActiveRelay.accept(.DimViewTap(true))


}
.drive()
.disposed(by: disposeBag)
}
}
Expand All @@ -158,6 +239,21 @@ extension FallingHomeViewController {
typealias SectionType = FallingProfileSection
typealias DataSource = UICollectionViewDiffableDataSource<SectionType, ModelType>
typealias Snapshot = NSDiffableDataSourceSnapshot<SectionType, ModelType>

private func deleteItems(_ indexPath: IndexPath) {
guard
let item = self.dataSource.itemIdentifier(for: indexPath),
let cell = self.homeView.collectionView.cellForItem(at: indexPath) as? FallingUserCollectionViewCell else { return }
var snapshot = self.dataSource.snapshot()
snapshot.deleteItems([item])
UIView.animate(withDuration: 0.5, delay: 0, options: .curveEaseOut) {
cell.transform = cell.transform.rotated(by: -.pi / 6).concatenating(cell.transform.translatedBy(x: cell.frame.minX - self.homeView.collectionView.frame.width, y: 37.62))
} completion: { [weak self] _ in
guard let self = self else { return }

// self.dataSource.apply(snapshot)
}
}
}

//#if DEBUG
Expand Down
32 changes: 28 additions & 4 deletions Projects/Features/Falling/Src/Home/FallingHomeViewModel.swift
Original file line number Diff line number Diff line change
Expand Up @@ -22,15 +22,19 @@ final class FallingHomeViewModel: ViewModelType {

struct Input {
let initialTrigger: Driver<Void>
let timeOverTrigger: Driver<Void>
let timeOverTrigger: Driver<AnimationAction>
let cellButtonAction: Driver<FallingCellButtonAction>
let complaintsButtonTapTrigger: Driver<Void>
let blockButtonTapTrigger: Driver<Void>
}

struct Output {
let userList: Driver<[FallingUser]>
let nextCardIndexPath: Driver<IndexPath>
let infoButtonAction: Driver<IndexPath>
let rejectButtonAction: Driver<IndexPath>
let complaintsAction: Driver<IndexPath>
let blockAction: Driver<IndexPath>
}

init(fallingUseCase: FallingUseCaseInterface) {
Expand All @@ -57,8 +61,11 @@ final class FallingHomeViewModel: ViewModelType {
currentIndexRelay.accept(currentIndexRelay.value)
}

let updateScrollIndexTrigger = timeOverTrigger.withLatestFrom(currentIndexRelay.asDriver(onErrorJustReturn: 0)) { _, index in
currentIndexRelay.accept(index + 1)
let updateScrollIndexTrigger = timeOverTrigger.withLatestFrom(currentIndexRelay.asDriver(onErrorJustReturn: 0)) { action, index in
switch action {
case .scroll: currentIndexRelay.accept(index + 1)
case .delete: currentIndexRelay.accept(index + 1)
}
}

let nextCardIndexPath = Driver.merge(
Expand All @@ -82,11 +89,28 @@ final class FallingHomeViewModel: ViewModelType {
return nil
}

let complaintsAction = input.complaintsButtonTapTrigger.withLatestFrom(currentIndexRelay.asDriver()).map { IndexPath(item: $0, section: 0) }

let blockAction = input.blockButtonTapTrigger
.withLatestFrom(currentIndexRelay.asDriver()).map { index in
let indexPath = IndexPath(item: index, section: 0)
// var mutable = snapshot.value
// if indexPath.item >= mutable.count {
// fatalError("index range")
// }
// let deleted = mutable[indexPath.item]
// mutable.remove(at: indexPath.item)
// snapshot.accept(mutable)
return indexPath
}

return Output(
userList: userList,
nextCardIndexPath: nextCardIndexPath,
infoButtonAction: infoButtonAction,
rejectButtonAction: rejectButtonAction
rejectButtonAction: rejectButtonAction,
complaintsAction: complaintsAction,
blockAction: blockAction
)
}
}

0 comments on commit 6dc528e

Please sign in to comment.