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

๐Ÿ”€ :: (#742) ํ”Œ๋ ˆ์ด๋ฆฌ์ŠคํŠธ ๊ธฐ๋ณธ ์ด๋ฏธ์ง€๋ฅผ ๋ถˆ๋Ÿฌ์˜ค๋Š” UseCase๋ฅผ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. #745

Merged
merged 9 commits into from
Jul 7, 2024
Merged
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import BaseFeature
import BaseFeatureInterface
import ImageDomain
import ImageDomainInterface
import PlaylistDomain
import PlaylistDomainInterface
import PlaylistFeature
Expand Down Expand Up @@ -123,4 +125,10 @@ public extension AppComponent {
CheckSubscriptionUseCaseImpl(playlistRepository: playlistRepository)
}
}

var fetchDefaultPlaylistImageUseCase: any FetchDefaultPlaylistImageUseCase {
shared {
FetchDefaultPlaylistImageUseCaseImpl(imageRepository: imageRepository)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ import RxSwift
public protocol RemoteImageDataSource {
func fetchLyricDecoratingBackground() -> Single<[LyricDecoratingBackgroundEntity]>
func fetchProfileList() -> Single<[ProfileListEntity]>
func fetchDefaultPlaylistImage() -> Single<[DefaultImageEntity]>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Foundation

public struct DefaultImageEntity: Hashable, Equatable {
public let name: String
public let url: String

public init(name: String, url: String) {
self.name = name
self.url = url
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,5 @@ import RxSwift
public protocol ImageRepository {
func fetchLyricDecoratingBackground() -> Single<[LyricDecoratingBackgroundEntity]>
func fetchProfileList() -> Single<[ProfileListEntity]>
func fetchDefaultPlaylistImage() -> Single<[DefaultImageEntity]>
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import Foundation
import RxSwift

public protocol FetchDefaultPlaylistImageUseCase {
func execute() -> Single<[DefaultImageEntity]>
}
11 changes: 5 additions & 6 deletions Projects/Domains/ImageDomain/Sources/API/ImageAPI.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import Moya
public enum ImageAPI {
case fetchLyricDecoratingBackground
case fetchProfileList
case fetchDefaultPlaylistImage
}

extension ImageAPI: WMAPI {
Expand All @@ -20,23 +21,21 @@ extension ImageAPI: WMAPI {
return "/lyrics/backgrounds"
case .fetchProfileList:
return "/user/profiles"
case .fetchDefaultPlaylistImage:
return "/playlists"
}
}

public var method: Moya.Method {
switch self {
case .fetchLyricDecoratingBackground:
return .get
case .fetchProfileList:
case .fetchLyricDecoratingBackground, .fetchDefaultPlaylistImage, .fetchProfileList:
return .get
}
}

public var task: Moya.Task {
switch self {
case .fetchLyricDecoratingBackground:
return .requestPlain
case .fetchProfileList:
case .fetchLyricDecoratingBackground, .fetchProfileList, .fetchDefaultPlaylistImage:
return .requestPlain
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,4 +15,10 @@ public final class RemoteImageDataSourceImpl: BaseRemoteDataSource<ImageAPI>, Re
.map([FetchProfileListResponseDTO].self)
.map { $0.map { $0.toDomain() } }
}

public func fetchDefaultPlaylistImage() -> Single<[DefaultImageEntity]> {
return request(.fetchDefaultPlaylistImage)
.map([FetchDefaultImageResponseDTO].self)
.map { $0.map { $0.toDomain() } }
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,8 @@ public final class ImageRepositoryImpl: ImageRepository {
public func fetchProfileList() -> Single<[ProfileListEntity]> {
remoteImageDataSource.fetchProfileList()
}

public func fetchDefaultPlaylistImage() -> Single<[DefaultImageEntity]> {
remoteImageDataSource.fetchDefaultPlaylistImage()
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Foundation
import ImageDomainInterface

public struct FetchDefaultImageResponseDTO: Decodable, Equatable {
public let type: String
public let name: String
public let url: String
}

public extension FetchDefaultImageResponseDTO {
func toDomain() -> DefaultImageEntity {
DefaultImageEntity(
name: name,
url: url
)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import Foundation
import ImageDomainInterface
import RxSwift

public struct FetchDefaultPlaylistImageUseCaseImpl: FetchDefaultPlaylistImageUseCase {
private let imageRepository: any ImageRepository

public init(
imageRepository: ImageRepository
) {
self.imageRepository = imageRepository
}

public func execute() -> Single<[DefaultImageEntity]> {
imageRepository.fetchDefaultPlaylistImage()
}
}
4 changes: 3 additions & 1 deletion Projects/Features/PlaylistFeature/Project.swift
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,15 @@ let project = Project.module(
targets: [
.interface(module: .feature(.PlaylistFeature), dependencies: [
.feature(target: .BaseFeature, type: .interface)

]),
.implements(
module: .feature(.PlaylistFeature), dependencies: [
.feature(target: .BaseFeature),
.feature(target: .PlaylistFeature, type: .interface),
.domain(target: .AuthDomain, type: .interface),
.domain(target: .PlaylistDomain, type: .interface)
.domain(target: .PlaylistDomain, type: .interface),
.domain(target: .ImageDomain, type: .interface)
]
),
.testing(module: .feature(.PlaylistFeature), dependencies: [
Expand Down
Original file line number Diff line number Diff line change
@@ -1,17 +1,20 @@
import BaseFeature
import BaseFeatureInterface
import ImageDomainInterface
import NeedleFoundation
import PlaylistFeatureInterface
import UIKit

public protocol DefaultPlaylistImageDependency: Dependency {
#warning("usecase ์ฃผ์ž…")
//
var fetchDefaultPlaylistImageUseCase: any FetchDefaultPlaylistImageUseCase { get }
}

public final class DefaultPlaylistImageComponent: Component<DefaultPlaylistImageDependency>,
DefaultPlaylistImageFactory {
public func makeView(_ delegate: any DefaultPlaylistImageDelegate) -> UIViewController {
DefaultPlaylistImageViewController(delegate: delegate, reactor: DefaultPlaylistImageReactor())
DefaultPlaylistImageViewController(delegate: delegate, reactor: DefaultPlaylistImageReactor(
fetchDefaultPlaylistImageUseCase: dependency.fetchDefaultPlaylistImageUseCase

))
}
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import DesignSystem
import Foundation
import ImageDomainInterface
import ReactorKit
import RxSwift

final class DefaultPlaylistImageReactor: Reactor {
enum Action {
Expand All @@ -9,25 +11,28 @@ final class DefaultPlaylistImageReactor: Reactor {
}

enum Mutation {
case updateDataSource([String])
case updateDataSource([DefaultImageEntity])
yongbeomkwak marked this conversation as resolved.
Show resolved Hide resolved
case updateSelectedItem(Int)
case updateLoadingState(Bool)
}

struct State {
var dataSource: [String]
var dataSource: [DefaultImageEntity]
var selectedIndex: Int
var isLoading: Bool
}

private let fetchDefaultPlaylistImageUseCase: any FetchDefaultPlaylistImageUseCase
var initialState: State

init() {
init(fetchDefaultPlaylistImageUseCase: any FetchDefaultPlaylistImageUseCase) {
initialState = State(
dataSource: [],
selectedIndex: 0,
isLoading: false
isLoading: true
)

self.fetchDefaultPlaylistImageUseCase = fetchDefaultPlaylistImageUseCase
}

func mutate(action: Action) -> Observable<Mutation> {
Expand Down Expand Up @@ -66,7 +71,11 @@ extension DefaultPlaylistImageReactor {

return .concat([
.just(.updateLoadingState(true)),
.just(.updateDataSource(dataSource)),
fetchDefaultPlaylistImageUseCase.execute()
.asObservable()
.flatMap { data -> Observable<Mutation> in
return Observable.just(.updateDataSource(data))
},
.just(.updateLoadingState(false))
])
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import BaseFeature
import DesignSystem
import ImageDomainInterface
import PlaylistFeatureInterface
import SnapKit
import Then
Expand Down Expand Up @@ -39,12 +40,12 @@ final class DefaultPlaylistImageViewController: BaseReactorViewController<Defaul
private lazy var collectionView: UICollectionView = createCollectionView()

private let thumbnailCellRegistration = UICollectionView.CellRegistration<
DefaultThumbnailCell, String
DefaultThumbnailCell, DefaultImageEntity
> { cell, _, itemIdentifier in
cell.configure(itemIdentifier)
}

private lazy var thumbnailDiffableDataSource = UICollectionViewDiffableDataSource<Int, String>(
private lazy var thumbnailDiffableDataSource = UICollectionViewDiffableDataSource<Int, DefaultImageEntity>(
collectionView: collectionView
) { [thumbnailCellRegistration] collectionView, indexPath, itemIdentifier in
let cell = collectionView.dequeueConfiguredReusableCell(
Expand All @@ -64,8 +65,6 @@ final class DefaultPlaylistImageViewController: BaseReactorViewController<Defaul
super.viewDidLoad()
self.view.backgroundColor = .white
reactor?.action.onNext(.viewDidload)

collectionView.selectItem(at: IndexPath(row: 0, section: 0), animated: false, scrollPosition: .top)
}

override func addView() {
Expand Down Expand Up @@ -138,7 +137,7 @@ final class DefaultPlaylistImageViewController: BaseReactorViewController<Defaul

let (dataSource, index) = (info.0, info.1)

let (name, url) = ("์ž„์‹œ ๋ช…", dataSource[index])
let (name, url) = (dataSource[index].name, dataSource[index].url)

owner.dismiss(animated: true) {
owner.delegate?.receive(name, url)
Expand All @@ -152,22 +151,34 @@ final class DefaultPlaylistImageViewController: BaseReactorViewController<Defaul

sharedState.map(\.dataSource)
.distinctUntilChanged()
.filter { !$0.isEmpty }
.bind(with: self) { owner, dataSource in

var snapShot = NSDiffableDataSourceSnapshot<Int, String>()
var snapShot = NSDiffableDataSourceSnapshot<Int, DefaultImageEntity>()

snapShot.appendSections([0])

snapShot.appendItems(dataSource)

owner.thumbnailDiffableDataSource.apply(snapShot)
owner.thumbnailDiffableDataSource.apply(snapShot) {
owner.collectionView.selectItem(
at: IndexPath(row: 0, section: 0),
animated: false,
scrollPosition: .top
)
}
}
.disposed(by: disposeBag)

sharedState.map(\.isLoading)
.distinctUntilChanged()
.bind(with: self) { owner, flag in
flag == true ? owner.indicator.stopAnimating() : owner.indicator.stopAnimating()

if flag {
owner.indicator.startAnimating()
} else {
owner.indicator.stopAnimating()
}
}
.disposed(by: disposeBag)

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import DesignSystem
import ImageDomainInterface
import Kingfisher
import SnapKit
import Then
Expand Down Expand Up @@ -41,9 +42,7 @@ extension DefaultThumbnailCell {
}
}

public func configure(_ image: String) {
let image = DesignSystemAsset.PlayListTheme.theme0.image

imageView.image = image
public func configure(_ model: DefaultImageEntity) {
imageView.kf.setImage(with: URL(string: model.url), options: [.transition(.fade(0.2))])
}
}
Loading