diff --git a/Projects/Features/MusicDetailFeature/Sources/MusicDetail/MusicDetailReactor.swift b/Projects/Features/MusicDetailFeature/Sources/MusicDetail/MusicDetailReactor.swift index 0d990f4b3..fe88aeb4d 100644 --- a/Projects/Features/MusicDetailFeature/Sources/MusicDetail/MusicDetailReactor.swift +++ b/Projects/Features/MusicDetailFeature/Sources/MusicDetail/MusicDetailReactor.swift @@ -111,7 +111,7 @@ final class MusicDetailReactor: Reactor { case .playListButtonDidTap: return playListButtonDidTap() case .dismissButtonDidTap: - return .just(.navigate(.dismiss)) + return navigateMutation(navigate: .dismiss) } } @@ -179,10 +179,7 @@ private extension MusicDetailReactor { ) LogManager.analytics(log) } - return .concat( - .just(.navigate(.youtube(id: song.videoID))), - .just(.navigate(nil)) - ) + return navigateMutation(navigate: .youtube(id: song.videoID)) } func nextButtonDidTap() -> Observable { @@ -219,17 +216,14 @@ private extension MusicDetailReactor { title: song.title, artist: song.artistString ) - return .concat( - .just(.navigate(.lyricsHighlighting(model: lyricHighlightingModel))), - .just(.navigate(nil)) - ) + return navigateMutation(navigate: .lyricsHighlighting(model: lyricHighlightingModel)) } func creditButtonDidTap() -> Observable { guard let song = currentState.selectedSong else { return .empty() } let log = Log.clickCreditButton(id: song.videoID) LogManager.analytics(log) - return .just(.navigate(.credit(id: song.videoID))) + return navigateMutation(navigate: .credit(id: song.videoID)) } func likeButtonDidTap() -> Observable { @@ -269,34 +263,35 @@ private extension MusicDetailReactor { guard let song = currentState.selectedSong else { return .empty() } let log = Log.clickMusicPickButton(id: song.videoID) LogManager.analytics(log) - return .concat( - .just(.navigate(.musicPick(id: song.videoID))), - .just(.navigate(nil)) - ) + return navigateMutation(navigate: .musicPick(id: song.videoID)) } func playListButtonDidTap() -> Observable { guard let song = currentState.selectedSong else { return .empty() } let log = Log.clickPlaylistButton(id: song.videoID) LogManager.analytics(log) - return .concat( - .just(.navigate(.playlist)), - .just(.navigate(nil)) - ) + return navigateMutation(navigate: .playlist) } } // MARK: - Private Methods private extension MusicDetailReactor { + func navigateMutation(navigate: NavigateType) -> Observable { + return .concat( + .just(.navigate(navigate)), + .just(.navigate(nil)) + ) + } + func prefetchThumbnailImage(index: Int) { - if let songID = currentState.songIDs[safe: index], - let thumbnailPrefetchingSongID = currentState.songDictionary[songID]?.videoID, - let thumbnailURL = URL( - string: youtubeURLGenerator.generateHDThumbnailURL(id: thumbnailPrefetchingSongID) - ) { - ImagePrefetcher(urls: [thumbnailURL]).start() - } + let prefetchingSongImageURLs = [ + currentState.songIDs[safe: index - 1], + currentState.songIDs[safe: index], + currentState.songIDs[safe: index + 1] + ].compactMap { $0 } + .compactMap { URL(string: youtubeURLGenerator.generateHDThumbnailURL(id: $0)) } + ImagePrefetcher(urls: prefetchingSongImageURLs).start() } func fetchSongDetailWith(index: Int) -> Observable { diff --git a/Projects/Features/MusicDetailFeature/Sources/MusicDetail/MusicDetailView.swift b/Projects/Features/MusicDetailFeature/Sources/MusicDetail/MusicDetailView.swift index a7dcdbc70..aa0b77228 100644 --- a/Projects/Features/MusicDetailFeature/Sources/MusicDetail/MusicDetailView.swift +++ b/Projects/Features/MusicDetailFeature/Sources/MusicDetail/MusicDetailView.swift @@ -129,7 +129,7 @@ private extension MusicDetailView { func setLayout() { thumbnailCollectionView.snp.makeConstraints { - $0.top.lessThanOrEqualTo(self.safeAreaLayoutGuide.snp.top).offset(52) + $0.top.lessThanOrEqualTo(wmNavigationbarView.snp.bottom).offset(44) $0.centerX.equalToSuperview() $0.leading.trailing.equalToSuperview() $0.height.equalTo(thumbnailCollectionView.snp.width).multipliedBy(9.0 / 16.0) @@ -148,7 +148,7 @@ private extension MusicDetailView { wmNavigationbarView.setRightViews([creditButton]) musicControlView.snp.makeConstraints { - $0.top.equalTo(thumbnailCollectionView.snp.bottom).offset(36) + $0.top.equalTo(thumbnailCollectionView.snp.bottom).offset(20).priority(.required) $0.leading.trailing.equalToSuperview().inset(36) $0.bottom.lessThanOrEqualTo(musicToolbarView.snp.top) $0.height.equalTo(musicControlView.snp.width).multipliedBy(1.0 / 1.0) diff --git a/Projects/Features/MusicDetailFeature/Sources/MusicDetail/Views/MusicHeartButton/MusicHeartButton.swift b/Projects/Features/MusicDetailFeature/Sources/MusicDetail/Views/MusicHeartButton/MusicHeartButton.swift index 602024dc1..56754e6c1 100644 --- a/Projects/Features/MusicDetailFeature/Sources/MusicDetail/Views/MusicHeartButton/MusicHeartButton.swift +++ b/Projects/Features/MusicDetailFeature/Sources/MusicDetail/Views/MusicHeartButton/MusicHeartButton.swift @@ -20,25 +20,11 @@ final class MusicHeartButton: VerticalAlignButton { } func setIsLike(isLike: Bool, animated: Bool = true) { - let heartImage: UIImage - if isLike { - heartImage = DesignSystemAsset.MusicDetail.heartFill.image + let heartImage: UIImage = if isLike { + DesignSystemAsset.MusicDetail.heartFill.image } else { - heartImage = DesignSystemAsset.MusicDetail.heart.image - } - - self.isLike = isLike - guard animated else { - self.setImage(heartImage, for: .normal) - self.setIsLikeTextColor(isLike: isLike) - return - } - - self.imageView?.transform = .init(scaleX: 1.25, y: 1.25) - UIViewPropertyAnimator(duration: 0.3, curve: .easeIn) { - self.imageView?.transform = .identity + DesignSystemAsset.MusicDetail.heart.image } - .startAnimation() self.setImage(heartImage, for: .normal) self.setIsLikeTextColor(isLike: isLike) @@ -46,13 +32,9 @@ final class MusicHeartButton: VerticalAlignButton { private func setIsLikeTextColor(isLike: Bool) { if isLike { - self.setTitleColor(DesignSystemAsset.PrimaryColorV2.increase.color, for: .normal) - self.setTitleColor(DesignSystemAsset.PrimaryColorV2.increase.color, for: .selected) - self.setTitleColor(DesignSystemAsset.PrimaryColorV2.increase.color, for: .highlighted) + self.setTextColor(color: DesignSystemAsset.PrimaryColorV2.increase.color) } else { - self.setTitleColor(DesignSystemAsset.NewGrayColor.gray400.color, for: .normal) - self.setTitleColor(DesignSystemAsset.NewGrayColor.gray400.color, for: .selected) - self.setTitleColor(DesignSystemAsset.NewGrayColor.gray400.color, for: .highlighted) + self.setTextColor(color: DesignSystemAsset.NewGrayColor.gray400.color) } } } diff --git a/Projects/Features/MusicDetailFeature/Sources/MusicDetail/Views/MusicToolbarView.swift b/Projects/Features/MusicDetailFeature/Sources/MusicDetail/Views/MusicToolbarView.swift index b80f2f8e7..ae923fc92 100644 --- a/Projects/Features/MusicDetailFeature/Sources/MusicDetail/Views/MusicToolbarView.swift +++ b/Projects/Features/MusicDetailFeature/Sources/MusicDetail/Views/MusicToolbarView.swift @@ -64,7 +64,15 @@ extension MusicToolbarView: MusicToolbarStateProtocol { func updateIsLike(likes: Int, isLike: Bool) { heartButton.setTitle("\(likes.toUnitNumber)", for: .normal) - heartButton.setIsLike(isLike: isLike) + +// let textColor = isLike +// ? DesignSystemAsset.PrimaryColorV2.increase.color +// : DesignSystemAsset.NewGrayColor.gray400.color +// heartButton.setTitleColor( +// textColor, +// for: .normal +// ) + heartButton.setIsLike(isLike: isLike, animated: false) } } diff --git a/Projects/Features/MusicDetailFeature/Sources/MusicDetail/Views/ThumbnailCollectionView/ThumbnailCell.swift b/Projects/Features/MusicDetailFeature/Sources/MusicDetail/Views/ThumbnailCollectionView/ThumbnailCell.swift index be1bf17cf..e53a6ff5c 100644 --- a/Projects/Features/MusicDetailFeature/Sources/MusicDetail/Views/ThumbnailCollectionView/ThumbnailCell.swift +++ b/Projects/Features/MusicDetailFeature/Sources/MusicDetail/Views/ThumbnailCollectionView/ThumbnailCell.swift @@ -51,8 +51,9 @@ private extension ThumbnailCell { func setLayout() { thumbnailImageView.snp.makeConstraints { - $0.top.bottom.equalToSuperview() $0.leading.trailing.equalToSuperview().inset(24) + $0.center.equalToSuperview() + $0.height.equalTo(thumbnailImageView.snp.width).multipliedBy(9.0 / 16.0) } } } diff --git a/Projects/Features/PlaylistFeature/Sources/ViewModels/PlayListViewModel.swift b/Projects/Features/PlaylistFeature/Sources/ViewModels/PlayListViewModel.swift index 9a0f3c1f0..d2e3f8f7d 100644 --- a/Projects/Features/PlaylistFeature/Sources/ViewModels/PlayListViewModel.swift +++ b/Projects/Features/PlaylistFeature/Sources/ViewModels/PlayListViewModel.swift @@ -96,7 +96,11 @@ final class PlaylistViewModel: ViewModelType { }) .withLatestFrom(output.selectedSongIds) { selectedPlaylistItem, selectedSongIds in var mutableSelectedSongIds = selectedSongIds - mutableSelectedSongIds.insert(selectedPlaylistItem.id) + if mutableSelectedSongIds.contains(selectedPlaylistItem.id) { + mutableSelectedSongIds.remove(selectedPlaylistItem.id) + } else { + mutableSelectedSongIds.insert(selectedPlaylistItem.id) + } return mutableSelectedSongIds } .bind(to: output.selectedSongIds) diff --git a/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/heart.fill.imageset/Contents.json b/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/heart.fill.imageset/Contents.json index d762f5dbf..0508a184d 100644 --- a/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/heart.fill.imageset/Contents.json +++ b/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/heart.fill.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "heart.fill.svg", + "filename" : "ic_32_heart_on.svg", "idiom" : "universal" } ], diff --git a/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/heart.fill.imageset/heart.fill.svg b/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/heart.fill.imageset/ic_32_heart_on.svg similarity index 100% rename from Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/heart.fill.imageset/heart.fill.svg rename to Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/heart.fill.imageset/ic_32_heart_on.svg diff --git a/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/heart.imageset/Contents.json b/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/heart.imageset/Contents.json index f32f571e6..bfeac7b31 100644 --- a/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/heart.imageset/Contents.json +++ b/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/heart.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "heart.svg", + "filename" : "ic_32_heart_off.svg", "idiom" : "universal" } ], diff --git a/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/heart.imageset/heart.svg b/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/heart.imageset/heart.svg deleted file mode 100644 index 34f26328f..000000000 --- a/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/heart.imageset/heart.svg +++ /dev/null @@ -1,3 +0,0 @@ - - - diff --git a/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/heart.imageset/ic_32_heart_off.svg b/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/heart.imageset/ic_32_heart_off.svg new file mode 100644 index 000000000..2d6e610f2 --- /dev/null +++ b/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/heart.imageset/ic_32_heart_off.svg @@ -0,0 +1,3 @@ + + + diff --git a/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/music_pick.imageset/Contents.json b/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/music_pick.imageset/Contents.json index 8225b5aed..e4f83e633 100644 --- a/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/music_pick.imageset/Contents.json +++ b/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/music_pick.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "ic_32_playadd_25.svg", + "filename" : "ic_32_playadd_400.svg", "idiom" : "universal" } ], diff --git a/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/music_pick.imageset/ic_32_playadd_25.svg b/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/music_pick.imageset/ic_32_playadd_400.svg similarity index 100% rename from Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/music_pick.imageset/ic_32_playadd_25.svg rename to Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/music_pick.imageset/ic_32_playadd_400.svg diff --git a/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/playlist.imageset/Contents.json b/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/playlist.imageset/Contents.json index 90ab6a707..747144ba0 100644 --- a/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/playlist.imageset/Contents.json +++ b/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/playlist.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "playlist.svg", + "filename" : "ic_32_play_list_400.svg", "idiom" : "universal" } ], diff --git a/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/playlist.imageset/ic_32_play_list_400.svg b/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/playlist.imageset/ic_32_play_list_400.svg new file mode 100644 index 000000000..feb0af5c5 --- /dev/null +++ b/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/playlist.imageset/ic_32_play_list_400.svg @@ -0,0 +1,7 @@ + + + + + + + diff --git a/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/playlist.imageset/playlist.svg b/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/playlist.imageset/playlist.svg deleted file mode 100644 index a6334421b..000000000 --- a/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/playlist.imageset/playlist.svg +++ /dev/null @@ -1,7 +0,0 @@ - - - - - - - diff --git a/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/views.imageset/Contents.json b/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/views.imageset/Contents.json index 7e56c5189..1dc6ee38b 100644 --- a/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/views.imageset/Contents.json +++ b/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/views.imageset/Contents.json @@ -1,7 +1,7 @@ { "images" : [ { - "filename" : "views.svg", + "filename" : "ic_32_views.svg", "idiom" : "universal" } ], diff --git a/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/views.imageset/views.svg b/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/views.imageset/ic_32_views.svg similarity index 68% rename from Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/views.imageset/views.svg rename to Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/views.imageset/ic_32_views.svg index ad7fb15cc..6d0dd05ac 100644 --- a/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/views.imageset/views.svg +++ b/Projects/UsertInterfaces/DesignSystem/Resources/Image/MusicDetail.xcassets/views.imageset/ic_32_views.svg @@ -1,7 +1,7 @@ - - - - - + + + + + diff --git a/Projects/UsertInterfaces/DesignSystem/Sources/VerticalAlignButton.swift b/Projects/UsertInterfaces/DesignSystem/Sources/VerticalAlignButton.swift index 530f74509..81d13eb9f 100644 --- a/Projects/UsertInterfaces/DesignSystem/Sources/VerticalAlignButton.swift +++ b/Projects/UsertInterfaces/DesignSystem/Sources/VerticalAlignButton.swift @@ -37,4 +37,14 @@ open class VerticalAlignButton: UIButton { super.awakeFromNib() self.contentHorizontalAlignment = .left } + + public func setTextColor(color: UIColor) { + self.configuration?.titleTextAttributesTransformer = UIConfigurationTextAttributesTransformer { + var attribute = $0 + attribute.font = UIFont.setFont(.t7(weight: .medium)) + attribute.foregroundColor = color + attribute.kern = -0.5 + return attribute + } + } }