Skip to content
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 @@ -16,7 +16,7 @@ extension DreamSearchResponse {
}

extension DreamSearchResponse.Records {
func toDomain() -> DreamSearchEntity.Records {
func toDomain() -> DreamSearchEntity.Record {
return .init(id: self.id, emotion: self.emotion, date: self.date, title: self.title, genre: self.genre)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,16 @@ import Foundation

public struct DreamSearchEntity: Equatable {
public let recordsCount: Int
public let records: [Records]
public let records: [Record]

public init(recordsCount: Int, records: [Records]) {
public init(recordsCount: Int, records: [Record]) {
self.recordsCount = recordsCount
self.records = records
}
}

extension DreamSearchEntity {
public struct Records: Equatable {
public struct Record: Hashable {
public let id: String?
public let emotion: Int?
public let date: String?
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,6 @@ extension DramSearchTextField {
.disposed(by: disposeBag)
self.shouldLoadResult = returnKeyTapped
.withLatestFrom(self.rx.text) { $1 ?? "" }
.filter { !$0.isEmpty }
.distinctUntilChanged()
}
private func setupView() {
self.backgroundColor = .white.withAlphaComponent(0.05)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,31 +114,8 @@ extension DependencyContainer: MainTabBarControllerFactory {
let viewModel = DreamSearchViewModel(useCase: useCase)
let dreamSearchVC = DreamSearchVC()
dreamSearchVC.viewModel = viewModel
dreamSearchVC.factory = self

return dreamSearchVC
}

// MARK: - Examples
// 아래에 예시를 첨부합니다
// func makeFeedListVC(isMyPage: Bool) -> FeedListVC {
// let feedRepository = DefaultFeedListRepository(service: BaseService.default)
// let myPageRepository = DefaultMyPageRepository(service: BaseService.default)
// let useCase = DefaultFeedListUseCase(
// myPageRepository: myPageRepository,
// feedrepository: feedRepository)
// let viewModel = FeedListViewModel(useCase: useCase,
// isMyPage: isMyPage)
// let feedListVC = FeedListVC.controllerFromStoryboard(.feedList)
// feedListVC.viewModel = viewModel
// return feedListVC
// }
//
// func makeFeedReportVC(isMyPage: Bool) -> FeedReportVC {
// let repository = DefaultFeedReportRepository()
// let useCase = DefaultFeedReportUseCase(repository: repository)
// let viewModel = FeedReportViewModel(useCase: useCase, isMyPage: isMyPage)
// let feedReportVC = FeedReportVC.controllerFromStoryboard(.feedReport)
// feedReportVC.viewModel = viewModel
// return feedReportVC
// }
}
Original file line number Diff line number Diff line change
Expand Up @@ -146,11 +146,13 @@ extension HomeVC {
.withUnretained(self)
.subscribe(onNext: { (owner, _) in
let searchVC = owner.factory.instantiateSearchVC()
searchVC.modalPresentationStyle = .fullScreen
searchVC.modalTransitionStyle = .coverVertical
let navigation = UINavigationController(rootViewController: searchVC)
navigation.modalTransitionStyle = .coverVertical
navigation.modalPresentationStyle = .fullScreen
navigation.isNavigationBarHidden = true
guard let rdtabbarController = owner.tabBarController as? RDTabBarController else { return }
rdtabbarController.rdTabBar.isHidden = true
owner.present(searchVC, animated: true)
owner.present(navigation, animated: true)
}).disposed(by: disposeBag)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ extension DreamSearchVC {
let item = NSCollectionLayoutItem(layoutSize: itemSize)
let groupSize = NSCollectionLayoutSize(
widthDimension: .fractionalWidth(1.0),
heightDimension: .estimated(88.adjustedHeight)
heightDimension: .estimated(400.adjustedHeight)
)
let group = NSCollectionLayoutGroup.vertical(
layoutSize: groupSize, subitems: [item])
let section = NSCollectionLayoutSection(group: group)
let sectionFooter = self.createSectionFooter()
section.orthogonalScrollingBehavior = .continuous
section.orthogonalScrollingBehavior = .none
section.boundarySupplementaryItems = [sectionFooter]
section.contentInsets = .init(
top: 8, leading: 20, bottom: 0, trailing: 21
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ public class DreamSearchVC: UIViewController {

// MARK: - Reactive Properties
private let searchKeyword = PublishRelay<String>()
private let fetchedCount = PublishRelay<Int>()
private let fetchedCount = BehaviorRelay<Int>(value: 0)
private var disposeBag = DisposeBag()
public var factory: ViewControllerFactory!
public var viewModel: DreamSearchViewModel!
Expand All @@ -46,8 +46,11 @@ public class DreamSearchVC: UIViewController {
public override func viewDidLoad() {
super.viewDidLoad()

self.setDelegate()
self.bindCollectionView()
self.bindDismissButton()
self.bindTextField()
self.bindViewModels()
self.setupView()
self.setupConstraint()
self.setDataSource()
Expand All @@ -60,8 +63,14 @@ extension DreamSearchVC {
public func setupView() {
self.view.backgroundColor = .black
self.view.addSubviews(navigationBar, searchLabel, searchTextField, dreamSearchCollectionView)
self.searchTextField.addTarget(self, action: #selector(bindViewModels), for: .editingChanged)
}

private func setDelegate() {
self.dreamSearchCollectionView.rx
.setDelegate(self)
.disposed(by: self.disposeBag)
}

public func setupConstraint() {
navigationBar.snp.makeConstraints { make in
make.top.equalTo(view.safeAreaLayoutGuide.snp.top)
Expand Down Expand Up @@ -91,40 +100,28 @@ extension DreamSearchVC {
}
}
// MARK: - DataSource
extension DreamSearchVC {
extension DreamSearchVC: UICollectionViewDelegate {
private func setDataSource() {
self.dataSource = UICollectionViewDiffableDataSource<DreamSearchResultType, AnyHashable>(collectionView: dreamSearchCollectionView, cellProvider: { collectionView, indexPath, itemIdentifier in
if let model = itemIdentifier as? DreamSearchEntity {
switch DreamSearchResultType.type(indexPath.section) {
case .non:
guard let emptyCell = collectionView.dequeueReusableCell(withReuseIdentifier: DreamSearchEmptyCVC.reuseIdentifier, for: indexPath) as? DreamSearchEmptyCVC else { return UICollectionViewCell() }
self.fetchedCount.accept(0)
return emptyCell
case .exist:
guard let resultCell = collectionView.dequeueReusableCell(withReuseIdentifier: StorageExistCVC.reuseIdentifier, for: indexPath) as? StorageExistCVC else { return UICollectionViewCell() }
resultCell.setData(emotion: model.records[indexPath.row].emotion ?? 0, date: model.records[indexPath.row].date ?? "", title: model.records[indexPath.row].title ?? "", tag: model.records[indexPath.row].genre ?? [])
self.searchTextField.shouldLoadResult
.bind(to: self.searchKeyword)
.disposed(by: self.disposeBag)
self.fetchedCount.accept(model.recordsCount)
return resultCell
}
if let model = itemIdentifier as? DreamSearchEntity.Record {
guard let resultCell = collectionView.dequeueReusableCell(withReuseIdentifier: StorageExistCVC.reuseIdentifier, for: indexPath) as? StorageExistCVC else { return UICollectionViewCell() }
resultCell.setData(emotion: model.emotion ?? 0, date: model.date ?? "", title: model.title ?? "", tag: model.genre ?? [])
return resultCell
}
else {
return UICollectionViewCell()
guard let emptyCell = collectionView.dequeueReusableCell(withReuseIdentifier: DreamSearchEmptyCVC.reuseIdentifier, for: indexPath) as? DreamSearchEmptyCVC else { return UICollectionViewCell() }
return emptyCell
}
})

self.dataSource.supplementaryViewProvider = { collectionView, kind, indexPath in
switch kind {
case DreamSearchHeaderCVC.className:
case UICollectionView.elementKindSectionHeader:
guard let header = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: DreamSearchHeaderCVC.reuseIdentifier, for: indexPath) as? DreamSearchHeaderCVC else { return UICollectionReusableView() }
self.fetchedCount.subscribe(onNext: { counts in
header.configureCell(counts: counts)
}).disposed(by: self.disposeBag)
header.configureCell(counts: self.fetchedCount.value)
return header
case DreamSearchEmptyCVC.className:
guard let footer = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: DreamSearchEmptyCVC.reuseIdentifier, for: indexPath) as? DreamSearchEmptyCVC else { return UICollectionReusableView() }
case UICollectionView.elementKindSectionFooter:
guard let footer = collectionView.dequeueReusableSupplementaryView(ofKind: kind, withReuseIdentifier: DreamSearchBottomCVC.reuseIdentifier, for: indexPath) as? DreamSearchBottomCVC else { return UICollectionReusableView() }
return footer
default:
return UICollectionReusableView()
Expand All @@ -133,27 +130,24 @@ extension DreamSearchVC {
}
private func applySnapShot(model: DreamSearchEntity) {
var snapshot = NSDiffableDataSourceSnapshot<DreamSearchResultType, AnyHashable>()
let previousItems = snapshot.itemIdentifiers(inSection: .non)

snapshot.appendSections([.exist, .non])

self.fetchedCount.accept(model.recordsCount)
if model.recordsCount == 0 {
snapshot.appendItems([], toSection: .non)
snapshot.deleteItems(previousItems)
snapshot.appendSections([.non])
snapshot.appendItems([1], toSection: .non)
} else {
snapshot.appendItems([], toSection: .exist)
snapshot.appendSections([.exist])
print(model.records)
snapshot.appendItems(model.records, toSection: .exist)
}

self.dataSource.apply(snapshot)
self.view.setNeedsLayout()
}
}
// MARK: - Bind
extension DreamSearchVC {
@objc
private func bindViewModels(_ sender: Any?) {
private func bindViewModels() {
let input = DreamSearchViewModel.Input(currentSearchQuery: self.searchTextField.shouldLoadResult, returnButtonTapped: self.searchTextField.returnKeyTapped.asObservable())

let output = self.viewModel.transform(from: input, disposeBag: self.disposeBag)

output.searchResultModelFetched
Expand All @@ -162,7 +156,7 @@ extension DreamSearchVC {
.subscribe(onNext: { owner, entity in
owner.applySnapShot(model: entity)
}).disposed(by: self.disposeBag)

output.loadingStatus
.bind(to: self.rx.isLoading)
.disposed(by: disposeBag)
Expand All @@ -171,9 +165,9 @@ extension DreamSearchVC {
private func bindCollectionView() {
self.dreamSearchCollectionView.rx.itemSelected
.withUnretained(self)
.subscribe(onNext: { (owner, _) in
.subscribe(onNext: { (owner, item) in
let detailVC = owner.factory.instantiateDetailVC()
owner.navigationController?.pushViewController(detailVC, animated: true)
owner.present(detailVC, animated: true)
}).disposed(by: disposeBag)
}
private func bindDismissButton() {
Expand All @@ -183,4 +177,10 @@ extension DreamSearchVC {
self.dismiss(animated: true)
}).disposed(by: disposeBag)
}

private func bindTextField() {
self.searchTextField.shouldLoadResult
.bind(to: self.searchKeyword)
.disposed(by: self.disposeBag)
}
}