diff --git a/iOS/Layover/Layover/Scenes/Profile/ProfileInteractor.swift b/iOS/Layover/Layover/Scenes/Profile/ProfileInteractor.swift index af69f04..401848a 100644 --- a/iOS/Layover/Layover/Scenes/Profile/ProfileInteractor.swift +++ b/iOS/Layover/Layover/Scenes/Profile/ProfileInteractor.swift @@ -10,10 +10,12 @@ import Foundation protocol ProfileBusinessLogic { @discardableResult - func fetchProfile() -> Task + func fetchProfile(with request: ProfileModels.FetchProfile.Request) -> Task @discardableResult - func fetchMorePosts() -> Task + func fetchMorePosts(with request: ProfileModels.FetchMorePosts.Request) -> Task + + func showPostDetail(with request: ProfileModels.ShowPostDetail.Request) } protocol ProfileDataStore { @@ -22,6 +24,9 @@ protocol ProfileDataStore { var profileImageData: Data? { get set } var profileId: Int? { get set } + + var playbackStartIndex: Int? { get set } + var posts: [Post] { get set } } final class ProfileInteractor: ProfileBusinessLogic, ProfileDataStore { @@ -42,10 +47,13 @@ final class ProfileInteractor: ProfileBusinessLogic, ProfileDataStore { var profileImageData: Data? var profileId: Int? + var playbackStartIndex: Int? + var posts: [Post] = [] + // MARK: - Methods @discardableResult - func fetchProfile() -> Task { + func fetchProfile(with request: ProfileModels.FetchProfile.Request) -> Task { Task { guard let userProfile = await userWorker?.fetchProfile(by: profileId) else { return false @@ -75,7 +83,7 @@ final class ProfileInteractor: ProfileBusinessLogic, ProfileDataStore { } @discardableResult - func fetchMorePosts() -> Task { + func fetchMorePosts(with request: ProfileModels.FetchMorePosts.Request) -> Task { Task { guard canFetchMorePosts else { return false } let fetchedPosts = await fetchPosts() @@ -97,13 +105,14 @@ final class ProfileInteractor: ProfileBusinessLogic, ProfileDataStore { } private func fetchPosts() async -> [Models.Post] { - guard let posts = await userWorker?.fetchPosts(at: fetchPostsPage, of: profileId), - posts.count > 0 else { + guard let fetchedPosts = await userWorker?.fetchPosts(at: fetchPostsPage, of: profileId), + fetchedPosts.count > 0 else { return [] } + posts += fetchedPosts var responsePosts = [Models.Post]() - for post in posts { + for post in fetchedPosts { guard let thumbnailURL = post.board.thumbnailImageURL, let profileImageData = await userWorker?.fetchImageData(with: thumbnailURL) else { responsePosts.append(.init(id: post.board.identifier, thumbnailImageData: nil)) @@ -116,4 +125,9 @@ final class ProfileInteractor: ProfileBusinessLogic, ProfileDataStore { return responsePosts } + func showPostDetail(with request: ProfileModels.ShowPostDetail.Request) { + playbackStartIndex = request.startIndex + presenter?.presentPostDetail(with: Models.ShowPostDetail.Response()) + } + } diff --git a/iOS/Layover/Layover/Scenes/Profile/ProfileModels.swift b/iOS/Layover/Layover/Scenes/Profile/ProfileModels.swift index aca8aa5..384bf2e 100644 --- a/iOS/Layover/Layover/Scenes/Profile/ProfileModels.swift +++ b/iOS/Layover/Layover/Scenes/Profile/ProfileModels.swift @@ -38,7 +38,6 @@ enum ProfileModels { } enum FetchMorePosts { - struct Request { } @@ -50,4 +49,16 @@ enum ProfileModels { let posts: [Post] } } + + enum ShowPostDetail { + struct Request { + let startIndex: Int + } + + struct Response { + } + + struct ViewModel { + } + } } diff --git a/iOS/Layover/Layover/Scenes/Profile/ProfilePresenter.swift b/iOS/Layover/Layover/Scenes/Profile/ProfilePresenter.swift index 93be898..88cb0c5 100644 --- a/iOS/Layover/Layover/Scenes/Profile/ProfilePresenter.swift +++ b/iOS/Layover/Layover/Scenes/Profile/ProfilePresenter.swift @@ -11,6 +11,7 @@ import UIKit protocol ProfilePresentationLogic { func presentProfile(with response: ProfileModels.FetchProfile.Response) func presentMorePosts(with response: ProfileModels.FetchMorePosts.Response) + func presentPostDetail(with response: ProfileModels.ShowPostDetail.Response) } final class ProfilePresenter: ProfilePresentationLogic { @@ -33,4 +34,8 @@ final class ProfilePresenter: ProfilePresentationLogic { viewController?.displayMorePosts(viewModel: viewModel) } + func presentPostDetail(with response: ProfileModels.ShowPostDetail.Response) { + viewController?.routeToPostDetail(viewModel: Models.ShowPostDetail.ViewModel()) + } + } diff --git a/iOS/Layover/Layover/Scenes/Profile/ProfileRouter.swift b/iOS/Layover/Layover/Scenes/Profile/ProfileRouter.swift index 2e70ed9..c8920c6 100644 --- a/iOS/Layover/Layover/Scenes/Profile/ProfileRouter.swift +++ b/iOS/Layover/Layover/Scenes/Profile/ProfileRouter.swift @@ -9,15 +9,16 @@ import UIKit protocol ProfileRoutingLogic { - func routeToEditProfileViewController() - func routeToSettingSceneViewController() + func routeToEditProfile() + func routeToSetting() + func routeToPlayback() } protocol ProfileDataPassing { var dataStore: ProfileDataStore? { get } } -final class ProfileRouter: NSObject, ProfileRoutingLogic, ProfileDataPassing { +final class ProfileRouter: ProfileRoutingLogic, ProfileDataPassing { // MARK: - Properties @@ -26,7 +27,7 @@ final class ProfileRouter: NSObject, ProfileRoutingLogic, ProfileDataPassing { // MARK: - Routing - func routeToEditProfileViewController() { + func routeToEditProfile() { let editProfileViewController = EditProfileViewController() guard let source = dataStore, var destination = editProfileViewController.router?.dataStore @@ -38,11 +39,20 @@ final class ProfileRouter: NSObject, ProfileRoutingLogic, ProfileDataPassing { viewController?.navigationController?.pushViewController(editProfileViewController, animated: true) } - func routeToSettingSceneViewController() { + func routeToSetting() { let settingSceneViewController: SettingSceneViewController = SettingSceneViewController() viewController?.navigationController?.pushViewController(settingSceneViewController, animated: true) } + func routeToPlayback() { + let playbackViewController = PlaybackViewController() + guard let source = dataStore, + var destination = playbackViewController.router?.dataStore + else { return } + passDataToPlayback(source: source, destination: &destination) + viewController?.navigationController?.pushViewController(playbackViewController, animated: true) + } + // MARK: - Data Passing private func passDataToEditProfile(source: ProfileDataStore, destination: inout EditProfileDataStore) { @@ -50,4 +60,9 @@ final class ProfileRouter: NSObject, ProfileRoutingLogic, ProfileDataPassing { destination.introduce = source.introduce destination.profileImageData = source.profileImageData } + + private func passDataToPlayback(source: ProfileDataStore, destination: inout PlaybackDataStore) { + destination.posts = source.posts + destination.index = source.playbackStartIndex + } } diff --git a/iOS/Layover/Layover/Scenes/Profile/ProfileViewController.swift b/iOS/Layover/Layover/Scenes/Profile/ProfileViewController.swift index 68b459a..a2af250 100644 --- a/iOS/Layover/Layover/Scenes/Profile/ProfileViewController.swift +++ b/iOS/Layover/Layover/Scenes/Profile/ProfileViewController.swift @@ -11,6 +11,7 @@ import UIKit protocol ProfileDisplayLogic: AnyObject { func displayProfile(viewModel: ProfileModels.FetchProfile.ViewModel) func displayMorePosts(viewModel: ProfileModels.FetchMorePosts.ViewModel) + func routeToPostDetail(viewModel: ProfileModels.ShowPostDetail.ViewModel) } final class ProfileViewController: BaseViewController { @@ -47,7 +48,7 @@ final class ProfileViewController: BaseViewController { // MARK: - Properties typealias Models = ProfileModels - var router: (NSObjectProtocol & ProfileRoutingLogic & ProfileDataPassing)? + var router: (ProfileRoutingLogic & ProfileDataPassing)? var interactor: ProfileBusinessLogic? private let profileType: ProfileType @@ -175,21 +176,21 @@ final class ProfileViewController: BaseViewController { // MARK: - Use Case private func fetchProfile() { - interactor?.fetchProfile() + interactor?.fetchProfile(with: Models.FetchProfile.Request()) } private func fetchPosts() { - interactor?.fetchMorePosts() + interactor?.fetchMorePosts(with: Models.FetchMorePosts.Request()) } // MARK: - Actions @objc private func editbuttonDidTap() { - router?.routeToEditProfileViewController() + router?.routeToEditProfile() } @objc private func settingButtonDidTap() { - router?.routeToSettingSceneViewController() + router?.routeToSetting() } } @@ -211,6 +212,10 @@ extension ProfileViewController: ProfileDisplayLogic { snapshot.append(viewModel.posts) collectionViewDatasource?.apply(snapshot, to: .posts) } + + func routeToPostDetail(viewModel: ProfileModels.ShowPostDetail.ViewModel) { + router?.routeToPlayback() + } } // MARK: - UICollectionViewDelegate @@ -225,4 +230,15 @@ extension ProfileViewController: UICollectionViewDelegate { fetchPosts() } } + + func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) { + guard let section = Section(rawValue: indexPath.section) else { return } + switch section { + case .profile: + return + case .posts: + guard let post = collectionViewDatasource?.itemIdentifier(for: indexPath) as? Models.Post else { return } + interactor?.showPostDetail(with: Models.ShowPostDetail.Request(startIndex: indexPath.item)) + } + } }