From 64bae0a657c903d16335491d98d2ec7aef10dbdd Mon Sep 17 00:00:00 2001 From: wenlei Date: Mon, 11 Mar 2024 12:46:30 +0800 Subject: [PATCH] Home refresh component optimization --- .../IndieMusic.xcodeproj/project.pbxproj | 4 +- .../Common/CollectionViewController.swift | 2 +- .../Common/RefreshLoadingView.swift | 62 +++++++++++++------ IndieMusic/IndieMusic/Configs/Configs.swift | 7 ++- .../Extensions/UIImage+IndieMusic.swift | 28 +++++++++ IndieMusic/IndieMusic/Models/Search.swift | 14 ++++- .../Modules/Home/HomeTabBarController.swift | 20 ++++++ .../Modules/Home/HomeTabBarViewModel.swift | 44 ++++++------- .../Modules/Home/HomeViewController.swift | 23 +++++++ .../Modules/Home/HomeViewModel.swift | 6 +- .../Modules/Home/SongViewCell.swift | 58 +---------------- .../JournalDetail/CommentViewController.swift | 2 + .../JournalDetailController.swift | 8 ++- .../JournalDetail/JournalDetailView.swift | 2 +- .../Mine/MineDownloadViewController.swift | 36 ++--------- .../PersonalViewController.swift | 12 ++-- .../Modules/Search/SearchViewController.swift | 2 +- .../Modules/Setting/CacheViewController.swift | 2 +- .../Modules/Setting/CacheViewModel.swift | 11 +++- .../EditInfo/EditInfoViewController.swift | 43 ++++++++++++- .../Setting/EditInfo/EditInfoViewModel.swift | 5 +- IndieMusic/IndieMusic/Networking/Api.swift | 2 +- .../Networking/Rest/APIConfig.swift | 4 +- .../IndieMusic/Networking/Rest/RestApi.swift | 6 +- IndieMusic/Podfile | 1 + 25 files changed, 241 insertions(+), 163 deletions(-) diff --git a/IndieMusic/IndieMusic.xcodeproj/project.pbxproj b/IndieMusic/IndieMusic.xcodeproj/project.pbxproj index c9c1e9f..fe26e88 100644 --- a/IndieMusic/IndieMusic.xcodeproj/project.pbxproj +++ b/IndieMusic/IndieMusic.xcodeproj/project.pbxproj @@ -1924,7 +1924,7 @@ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 15; + CURRENT_PROJECT_VERSION = 18; DEVELOPMENT_TEAM = AY569L2R6W; ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; @@ -1965,7 +1965,7 @@ ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES; CLANG_ENABLE_MODULES = YES; CODE_SIGN_STYLE = Automatic; - CURRENT_PROJECT_VERSION = 15; + CURRENT_PROJECT_VERSION = 18; DEVELOPMENT_TEAM = AY569L2R6W; ENABLE_USER_SCRIPT_SANDBOXING = NO; GENERATE_INFOPLIST_FILE = YES; diff --git a/IndieMusic/IndieMusic/Common/CollectionViewController.swift b/IndieMusic/IndieMusic/Common/CollectionViewController.swift index 9bd057c..0b4d6f1 100644 --- a/IndieMusic/IndieMusic/Common/CollectionViewController.swift +++ b/IndieMusic/IndieMusic/Common/CollectionViewController.swift @@ -60,7 +60,7 @@ class CollectionViewController: ViewController { make.edges.equalTo(view) } - collectionView.mj_header = MJRefreshNormalHeader.init(refreshingBlock: {[weak self] in + collectionView.mj_header = RefreshHeader.init(refreshingBlock: {[weak self] in self?.headerRefreshTrigger.onNext(()) }) collectionView.mj_footer = MJRefreshAutoStateFooter.init(refreshingBlock: {[weak self] in diff --git a/IndieMusic/IndieMusic/Common/RefreshLoadingView.swift b/IndieMusic/IndieMusic/Common/RefreshLoadingView.swift index 1cfb319..d3d79aa 100644 --- a/IndieMusic/IndieMusic/Common/RefreshLoadingView.swift +++ b/IndieMusic/IndieMusic/Common/RefreshLoadingView.swift @@ -155,20 +155,7 @@ class HomeRefreshHeader: MJRefreshStateHeader { return refreshLoadingView }() - let tipsLabel: PaddingLabel = { - let tipsLabel = PaddingLabel.init(padding: .init(top: 5, left: 15, bottom: 5, right: 15), frame: .zero) - tipsLabel.font = UIFont.systemFont(ofSize: 15) - tipsLabel.textColor = .tertiaryText() - tipsLabel.text = "已刷新完成" - tipsLabel.backgroundColor = .red - - tipsLabel.textColor = .primaryText() - tipsLabel.alpha = 1 - tipsLabel.isHidden = true - return tipsLabel - }() - override init(frame: CGRect) { @@ -177,7 +164,6 @@ class HomeRefreshHeader: MJRefreshStateHeader { stateLabel?.isHidden = true addSubview(self.gifLoadingView) - addSubview(tipsLabel) } required init?(coder aDecoder: NSCoder) { @@ -214,7 +200,7 @@ class HomeRefreshHeader: MJRefreshStateHeader { override func placeSubviews() { super.placeSubviews() - backgroundColor = .red + gifLoadingView.backgroundColor = .blue gifLoadingView.frame = CGRect.init(x: 0, y: 0, width: 60, height: 60) @@ -224,12 +210,7 @@ class HomeRefreshHeader: MJRefreshStateHeader { let centerY = mj_h + 18 gifLoadingView.center = CGPoint(x: centerX, y: centerY) - tipsLabel.snp.makeConstraints { make in - make.centerX.equalTo(gifLoadingView) - make.centerY.equalTo(gifLoadingView) - } // tipsLabel.sizeToFit() -// tipsLabel.center = CGPoint(x: centerX, y: centerY) } override func scrollViewContentOffsetDidChange(_ change: [AnyHashable : Any]?) { @@ -280,6 +261,20 @@ class RefreshHeader: MJRefreshStateHeader { return refreshLoadingView }() + let tipsLabel: PaddingLabel = { + let tipsLabel = PaddingLabel.init(padding: .init(top: 5, left: 15, bottom: 5, right: 15), frame: .zero) + tipsLabel.font = UIFont.systemFont(ofSize: 15) + tipsLabel.textColor = .tertiaryText() + tipsLabel.text = "已刷新完成" +// tipsLabel.backgroundColor = .red + tipsLabel.textAlignment = .center + + tipsLabel.textColor = .primaryText() + tipsLabel.isHidden = true + tipsLabel.alpha = 0 + + return tipsLabel + }() override init(frame: CGRect) { super.init(frame: frame) @@ -287,6 +282,8 @@ class RefreshHeader: MJRefreshStateHeader { stateLabel?.isHidden = true addSubview(self.gifLoadingView) + addSubview(self.tipsLabel) + } required init?(coder aDecoder: NSCoder) { @@ -331,6 +328,9 @@ class RefreshHeader: MJRefreshStateHeader { let centerY = mj_h * 0.5 gifLoadingView.center = CGPoint(x: centerX, y: centerY) + tipsLabel.frame = CGRect.init(x: 0, y: 0, width: mj_w, height: 60) + tipsLabel.center = CGPoint(x: centerX, y: centerY) + } func calculateOpacity(withOffset offset: CGFloat) -> CGFloat { @@ -401,5 +401,27 @@ class RefreshHeader: MJRefreshStateHeader { // Implement the initialization state logic here } + func endRefreshingWithMessage(_ message: String) { + tipsLabel.isHidden = false + tipsLabel.text = message + gifLoadingView.isHidden = true + + UIView.animate(withDuration: 0.3) { + self.tipsLabel.alpha = 1 + } + } + func hidenTipsLabel() { + + UIView.animate(withDuration: 1) { + self.tipsLabel.alpha = 0 + + } completion: { _ in + self.gifLoadingView.isHidden = false + self.tipsLabel.isHidden = true + + } + + } + } diff --git a/IndieMusic/IndieMusic/Configs/Configs.swift b/IndieMusic/IndieMusic/Configs/Configs.swift index 8c49608..33d5605 100644 --- a/IndieMusic/IndieMusic/Configs/Configs.swift +++ b/IndieMusic/IndieMusic/Configs/Configs.swift @@ -17,16 +17,17 @@ extension EnvironmentType { var baseUrl: String { switch self { case .production: - return "http://39.103.180.196:9012" + return "http://api.indie.cn:9012" case .development: - return "http://testapi.indie.cn:9012" + return "http://39.103.180.196:9012" +// return "http://testapi.indie.cn:9012" } } } struct Configs { struct App { - static let environmentType: EnvironmentType = .production + static let environmentType: EnvironmentType = .development static let aggrementUrl = environmentType.baseUrl + "" static let universalLink = "" static let bundleIdentifier = "cn.indie.queyue" diff --git a/IndieMusic/IndieMusic/Extensions/UIImage+IndieMusic.swift b/IndieMusic/IndieMusic/Extensions/UIImage+IndieMusic.swift index 60dc76e..92cc95e 100644 --- a/IndieMusic/IndieMusic/Extensions/UIImage+IndieMusic.swift +++ b/IndieMusic/IndieMusic/Extensions/UIImage+IndieMusic.swift @@ -38,6 +38,29 @@ extension UIImage { UIGraphicsEndImageContext(); return img! } + + func resizeImage(targetSize: CGSize) -> UIImage { + let size = self.size + + let widthRatio = targetSize.width / size.width + let heightRatio = targetSize.height / size.height + + var newSize: CGSize + if(widthRatio > heightRatio) { + newSize = CGSize(width: size.width * heightRatio, height: size.height * heightRatio) + } else { + newSize = CGSize(width: size.width * widthRatio, height: size.height * widthRatio) + } + + let rect = CGRect(x: 0, y: 0, width: newSize.width, height: newSize.height) + + UIGraphicsBeginImageContextWithOptions(newSize, false, 1.0) + self.draw(in: rect) + let newImage = UIGraphicsGetImageFromCurrentImageContext() + UIGraphicsEndImageContext() + + return newImage ?? self + } } extension UIImageView { @@ -53,4 +76,9 @@ extension UIImageView { currentURL = url // 更新当前URL self.kf.setImage(with: url) } + + + + + } diff --git a/IndieMusic/IndieMusic/Models/Search.swift b/IndieMusic/IndieMusic/Models/Search.swift index c9bc367..47ab54c 100644 --- a/IndieMusic/IndieMusic/Models/Search.swift +++ b/IndieMusic/IndieMusic/Models/Search.swift @@ -62,14 +62,24 @@ extension SearchResultsSection: SectionModelType { -struct SearchCategory: Codable { - let id: String? +struct SearchCategory: Codable, IdentifiableType, Equatable { + let id: String let nameCh: String? let nameEn: String? let image: String? let description: String? + let thumbnail: String? var isExpand: Bool? + + + var identity: String { + return id + } + + static func == (lhs: SearchCategory, rhs: SearchCategory) -> Bool { + return lhs.id == rhs.id && lhs.nameCh == rhs.nameCh && lhs.nameEn == rhs.nameEn && lhs.image == rhs.image && lhs.description == rhs.description && lhs.thumbnail == rhs.thumbnail && lhs.isExpand == rhs.isExpand + } } diff --git a/IndieMusic/IndieMusic/Modules/Home/HomeTabBarController.swift b/IndieMusic/IndieMusic/Modules/Home/HomeTabBarController.swift index bd5c5b0..afacfea 100644 --- a/IndieMusic/IndieMusic/Modules/Home/HomeTabBarController.swift +++ b/IndieMusic/IndieMusic/Modules/Home/HomeTabBarController.swift @@ -382,8 +382,28 @@ class HomeTabBarController: UITabBarController, Navigatable { extension HomeTabBarController: UITabBarControllerDelegate { func tabBarController(_ tabBarController: UITabBarController, shouldSelect viewController: UIViewController) -> Bool { + + if tabBarController.selectedViewController === viewController && viewController is UINavigationController { + if let navigationController = viewController as? UINavigationController, + let topViewController = navigationController.viewControllers.first as? TableViewController { + topViewController.tableView.mj_header?.beginRefreshing() + let feedbackGenerator = UIImpactFeedbackGenerator(style: .light) + feedbackGenerator.impactOccurred() + + } else if let navigationController = viewController as? UINavigationController, + let topViewController = navigationController.viewControllers.first as? CollectionViewController { + topViewController.collectionView.mj_header?.beginRefreshing() + let feedbackGenerator = UIImpactFeedbackGenerator(style: .light) + feedbackGenerator.impactOccurred() + + } + } return viewController != tabBarController.selectedViewController } + func tabBarController(_ tabBarController: UITabBarController, didSelect viewController: UIViewController) { + + + } } diff --git a/IndieMusic/IndieMusic/Modules/Home/HomeTabBarViewModel.swift b/IndieMusic/IndieMusic/Modules/Home/HomeTabBarViewModel.swift index 1d3e344..b54d655 100644 --- a/IndieMusic/IndieMusic/Modules/Home/HomeTabBarViewModel.swift +++ b/IndieMusic/IndieMusic/Modules/Home/HomeTabBarViewModel.swift @@ -46,26 +46,12 @@ class HomeTabBarViewModel: ViewModel, ViewModelType { func transform(input: Input) -> Output { let tabBarItems = Observable.just([HomeTabBarItem.home, HomeTabBarItem.search, HomeTabBarItem.mine]).asDriver(onErrorJustReturn: []) -// -// -// if authorized { -// renewalToken() -// } -// -// -// -// -// AudioManager.sharedInstance.progressObserver.subscribe { (time, duration, progress) in -// -// }.disposed(by: rx.disposeBag) -// -// -// input.notiPlayAudioTrack.subscribe { [weak self] noti in -// guard let track = noti.element?.object as? AudioTrack else { return } -// -// }.disposed(by: rx.disposeBag) -// - + + + if authorized { + renewalToken() + } + return Output.init(tabBarItems: tabBarItems, notiPlayAudioTrack: input.notiPlayAudioTrack, @@ -93,15 +79,23 @@ class HomeTabBarViewModel: ViewModel, ViewModelType { func renewalToken() { - self.provider.autoLogin().subscribe { token in + self.provider.autoLogin(deviceId: AuthManager.shared.getUUID(), deviceBrand: AuthManager.shared.getDevice()).subscribe { token in print("autoLogin: success") - AuthManager.setToken(token: Token.init(isValid: true, basicToken: token)) + if token != "" { + AuthManager.setToken(token: Token.init(isValid: true, basicToken: token)) + } else { + AuthManager.removeToken() + } } onFailure: { error in + print("autoLogin: error") -// if case HTTPServiceError.errorJudge(let err) = error { -// SVProgressHUD.showText(withStatus: err.message) -// } + if case HTTPServiceError.errorJudge(let err) = error, err.code == 200 { + AuthManager.removeToken() + } else if case MoyaError.objectMapping(let err, let response) = error { + AuthManager.removeToken() + + } }.disposed(by: rx.disposeBag) } diff --git a/IndieMusic/IndieMusic/Modules/Home/HomeViewController.swift b/IndieMusic/IndieMusic/Modules/Home/HomeViewController.swift index 0bbc65f..3801e4d 100644 --- a/IndieMusic/IndieMusic/Modules/Home/HomeViewController.swift +++ b/IndieMusic/IndieMusic/Modules/Home/HomeViewController.swift @@ -255,8 +255,31 @@ class HomeViewController: TableViewController, ScrollableNavBar { }.disposed(by: rx.disposeBag) + viewModel.showReFreshTips.subscribe { [weak self] tips in + + if let header = self?.tableView.mj_header as? RefreshHeader { + header.endRefreshingWithMessage("数据刷新完毕") + + print("state123 :\(header.state)") + if header.state == .idle { + header.hidenTipsLabel() + } else { + DispatchQueue.main.asyncAfter(deadline: .now() + 1) { + viewModel.endHeaderRefresh.accept(false) + header.hidenTipsLabel() + } + } + + } + + + + }.disposed(by: rx.disposeBag) + } + + override func viewDidLayoutSubviews() { super.viewDidLayoutSubviews() diff --git a/IndieMusic/IndieMusic/Modules/Home/HomeViewModel.swift b/IndieMusic/IndieMusic/Modules/Home/HomeViewModel.swift index a0f5c15..0335190 100644 --- a/IndieMusic/IndieMusic/Modules/Home/HomeViewModel.swift +++ b/IndieMusic/IndieMusic/Modules/Home/HomeViewModel.swift @@ -50,6 +50,8 @@ class HomeViewModel: ViewModel, ViewModelType { let loginTrigger: PublishRelay = .init() + let showReFreshTips: PublishRelay = .init() + func transform(input: Input) -> Output { let carouselItems = BehaviorRelay<[Carousel]>(value: []) @@ -105,7 +107,9 @@ class HomeViewModel: ViewModel, ViewModelType { } - self.endHeaderRefresh.accept(false) + self.showReFreshTips.accept("刷新完毕") + +// self.endHeaderRefresh.accept(false) }).disposed(by: rx.disposeBag) diff --git a/IndieMusic/IndieMusic/Modules/Home/SongViewCell.swift b/IndieMusic/IndieMusic/Modules/Home/SongViewCell.swift index 639086f..1da10a0 100644 --- a/IndieMusic/IndieMusic/Modules/Home/SongViewCell.swift +++ b/IndieMusic/IndieMusic/Modules/Home/SongViewCell.swift @@ -63,12 +63,6 @@ class SongViewCell: UITableViewCell { return musicIndicator }() - - var downloadButton: DownloadButton = { - let downloadButton = DownloadButton.init() - - return downloadButton - }() var buttonTapCallback: ((AudioTrack) -> ())? @@ -101,9 +95,7 @@ class SongViewCell: UITableViewCell { }.disposed(by: disposeBag) - downloadButton.changeDownloadState(to: audioTrack.downloadState ?? .no) - updateDownloadButton() } } @@ -134,7 +126,6 @@ class SongViewCell: UITableViewCell { contentView.addSubview(detailLabel) contentView.addSubview(moreButtin) contentView.addSubview(musicIndicator) - contentView.addSubview(downloadButton) contentView.addSubview(lineView) @@ -164,35 +155,13 @@ class SongViewCell: UITableViewCell { make.bottom.equalTo(coverView.snp.centerY).offset(-2) make.right.equalTo(moreButtin.snp.left).offset(-10) } -// -// detailLabel.snp.makeConstraints { make in -// make.left.equalTo(coverView.snp.right).offset(15) -// make.top.equalTo(titleLabel.snp.bottom).offset(10) -// make.right.equalTo(musicIndicator.snp.left).offset(-6) -// } + - downloadButton.snp.makeConstraints { make in + detailLabel.snp.makeConstraints { make in make.left.equalTo(coverView.snp.right).offset(15) make.top.equalTo(coverView.snp.centerY).offset(2) - make.size.equalTo(CGSize.init(width: 24, height: 24)) - } - - - if downloadButton.isHidden { - detailLabel.snp.makeConstraints { make in - make.left.equalTo(downloadButton.snp.left) - make.centerY.equalTo(downloadButton) - make.right.equalTo(musicIndicator.snp.left).offset(-6) - } - } else { - detailLabel.snp.makeConstraints { make in - make.left.equalTo(downloadButton.snp.right).offset(3) - make.centerY.equalTo(downloadButton) - make.right.equalTo(musicIndicator.snp.left).offset(-6) - } + make.right.equalTo(musicIndicator.snp.left).offset(-6) } - - lineView.snp.makeConstraints { make in @@ -210,26 +179,5 @@ class SongViewCell: UITableViewCell { buttonTapCallback(audioTrack) } } - - - func updateDownloadButton() { - if downloadButton.downloadState == DownloadState.no { - self.downloadButton.isHidden = true - detailLabel.snp.remakeConstraints { make in - make.left.equalTo(downloadButton.snp.left) - make.centerY.equalTo(downloadButton) - make.right.equalTo(musicIndicator.snp.left).offset(-6) - } - } else { - self.downloadButton.isHidden = false - detailLabel.snp.remakeConstraints { make in - make.left.equalTo(downloadButton.snp.right).offset(3) - make.centerY.equalTo(downloadButton) - make.right.equalTo(musicIndicator.snp.left).offset(-6) - } - } - - } - } diff --git a/IndieMusic/IndieMusic/Modules/JournalDetail/CommentViewController.swift b/IndieMusic/IndieMusic/Modules/JournalDetail/CommentViewController.swift index b224242..0ae9d85 100644 --- a/IndieMusic/IndieMusic/Modules/JournalDetail/CommentViewController.swift +++ b/IndieMusic/IndieMusic/Modules/JournalDetail/CommentViewController.swift @@ -298,6 +298,8 @@ class CommentViewController: TableViewController { viewModel.selectedItem.subscribe { comment in + + }.disposed(by: rx.disposeBag) diff --git a/IndieMusic/IndieMusic/Modules/JournalDetail/JournalDetailController.swift b/IndieMusic/IndieMusic/Modules/JournalDetail/JournalDetailController.swift index 6ba1388..f816a9a 100644 --- a/IndieMusic/IndieMusic/Modules/JournalDetail/JournalDetailController.swift +++ b/IndieMusic/IndieMusic/Modules/JournalDetail/JournalDetailController.swift @@ -108,14 +108,18 @@ class JournalDetailController: TableViewController { .bind(to: viewModel.moreButtonTapped) .disposed(by: cell.disposeBag) - cell.doubleTapGesture.rx.event.subscribe { tap in + cell.doubleTapGesture.rx.event + .filter { _ in !tableView.isDragging } + .subscribe { tap in if audioTrack.src == AudioManager.sharedInstance.currentTrack.value?.src { viewModel.doubleTapTrigger.accept(audioTrack) } }.disposed(by: cell.disposeBag) - cell.tapGesture.rx.event.subscribe { tap in + cell.tapGesture.rx.event + .filter { _ in !tableView.isDragging } + .subscribe { tap in guard let tap = tap.element else { return } let location = tap.location(in: cell) diff --git a/IndieMusic/IndieMusic/Modules/JournalDetail/JournalDetailView.swift b/IndieMusic/IndieMusic/Modules/JournalDetail/JournalDetailView.swift index c262b05..c2bccc2 100644 --- a/IndieMusic/IndieMusic/Modules/JournalDetail/JournalDetailView.swift +++ b/IndieMusic/IndieMusic/Modules/JournalDetail/JournalDetailView.swift @@ -953,7 +953,7 @@ class JournalContainerViewCell: UITableViewCell { disposeBag = DisposeBag() // 重置DisposeBag以避免重用问题 let dataSource = JournalContainerViewCell.dataSource() - let header = SearchCategory.init(id: nil, nameCh: nil, nameEn: nil, image: nil, description: nil) + let header = SearchCategory.init(id: "", nameCh: nil, nameEn: nil, image: nil, description: nil, thumbnail: nil) let sections = [MusicStyleSection.init(header: header, items: journals)] let items = Driver.just(sections) diff --git a/IndieMusic/IndieMusic/Modules/Mine/MineDownloadViewController.swift b/IndieMusic/IndieMusic/Modules/Mine/MineDownloadViewController.swift index e1aa63b..de6beb2 100644 --- a/IndieMusic/IndieMusic/Modules/Mine/MineDownloadViewController.swift +++ b/IndieMusic/IndieMusic/Modules/Mine/MineDownloadViewController.swift @@ -154,13 +154,6 @@ class MineDownloadViewController: TableViewController { }.disposed(by: rx.disposeBag) - - tableView.rx.willDisplayCell - .subscribe { [weak self] cell, indexPath in - guard let cell = cell as? MineDownloadViewCell else { return } - cell.downloadButton.changeDownloadState(to: .finished) - }.disposed(by: rx.disposeBag) - } @@ -270,12 +263,6 @@ class MineDownloadViewCell: UITableViewCell { return moreButton }() - var downloadButton: DownloadButton = { - let downloadButton = DownloadButton.init() - - return downloadButton - }() - let musicIndicator: ESTMusicIndicatorView = { let musicIndicator = ESTMusicIndicatorView.init() musicIndicator.tintColor = .primary() @@ -381,7 +368,6 @@ class MineDownloadViewCell: UITableViewCell { contentView.addSubview(titleLabel) contentView.addSubview(detailLabel) contentView.addSubview(moreButton) - contentView.addSubview(downloadButton) contentView.addSubview(musicIndicator) @@ -410,27 +396,13 @@ class MineDownloadViewCell: UITableViewCell { make.bottom.equalTo(coverView.snp.centerY).offset(-2) make.right.equalTo(moreButton.snp.left).offset(-10) } - - downloadButton.snp.makeConstraints { make in + + detailLabel.snp.makeConstraints { make in make.left.equalTo(coverView.snp.right).offset(15) make.top.equalTo(coverView.snp.centerY).offset(2) - make.size.equalTo(CGSize.init(width: 24, height: 24)) - } - - - if downloadButton.isHidden { - detailLabel.snp.makeConstraints { make in - make.left.equalTo(downloadButton.snp.left) - make.centerY.equalTo(downloadButton) - make.right.equalTo(musicIndicator.snp.left).offset(-6) - } - } else { - detailLabel.snp.makeConstraints { make in - make.left.equalTo(downloadButton.snp.right).offset(3) - make.centerY.equalTo(downloadButton) - make.right.equalTo(musicIndicator.snp.left).offset(-6) - } + make.right.equalTo(musicIndicator.snp.left).offset(-6) } + } diff --git a/IndieMusic/IndieMusic/Modules/Personal/PersonalDetail/PersonalViewController.swift b/IndieMusic/IndieMusic/Modules/Personal/PersonalDetail/PersonalViewController.swift index 79ea983..8205c35 100644 --- a/IndieMusic/IndieMusic/Modules/Personal/PersonalDetail/PersonalViewController.swift +++ b/IndieMusic/IndieMusic/Modules/Personal/PersonalDetail/PersonalViewController.swift @@ -188,13 +188,11 @@ class PersonalHeaderView: UIView, ShazamHeaderView { } - var blurEffectView: UIImageView = { - let titleImageView = UIImageView.init() - let blurEffect = UIBlurEffect(style: .regular) - let blurEffectView = UIVisualEffectView(effect: blurEffect) + var blurEffectView: BlurEffectView = { + let titleImageView = BlurEffectView.init(style: .systemUltraThinMaterialDark, frame: CGRect.zero) + titleImageView.imageView.contentMode = .scaleAspectFill + titleImageView.layer.masksToBounds = true - - titleImageView.addSubview(blurEffectView) return titleImageView }() @@ -324,7 +322,7 @@ class PersonalHeaderView: UIView, ShazamHeaderView { var user: User? { didSet { guard let user = user else { return } - blurEffectView.kf.setImage(with: URL.init(string: user.avatar ?? "")) + blurEffectView.imageView.kf.setImage(with: URL.init(string: user.avatar ?? "")) avatarView.kf.setImage(with: URL.init(string: user.avatar ?? "")) nameLabel.text = user.nickName diff --git a/IndieMusic/IndieMusic/Modules/Search/SearchViewController.swift b/IndieMusic/IndieMusic/Modules/Search/SearchViewController.swift index a3aa7c2..43cd16c 100644 --- a/IndieMusic/IndieMusic/Modules/Search/SearchViewController.swift +++ b/IndieMusic/IndieMusic/Modules/Search/SearchViewController.swift @@ -204,7 +204,7 @@ class SearchViewCell: UICollectionViewCell { var searchCategory: SearchCategory? { didSet { guard let searchCategory = searchCategory else { return } - backgroudnView.kf.setImage(with: URL.init(string: searchCategory.image ?? "")) + backgroudnView.kf.setImage(with: URL.init(string: searchCategory.thumbnail ?? "")) titleLabel.text = searchCategory.nameCh subTitleLabel.text = searchCategory.nameEn diff --git a/IndieMusic/IndieMusic/Modules/Setting/CacheViewController.swift b/IndieMusic/IndieMusic/Modules/Setting/CacheViewController.swift index 4fd74f7..a32046b 100644 --- a/IndieMusic/IndieMusic/Modules/Setting/CacheViewController.swift +++ b/IndieMusic/IndieMusic/Modules/Setting/CacheViewController.swift @@ -72,7 +72,7 @@ class CacheViewController: TableViewController { case .file: let mineDownloadViewModel = MineDownloadViewModel.init(provider: viewModel.provider) self?.navigator.show(segue: .mineDownload(viewModel: mineDownloadViewModel), sender: self) - + default: break } diff --git a/IndieMusic/IndieMusic/Modules/Setting/CacheViewModel.swift b/IndieMusic/IndieMusic/Modules/Setting/CacheViewModel.swift index 2df0f8e..8ae0a09 100644 --- a/IndieMusic/IndieMusic/Modules/Setting/CacheViewModel.swift +++ b/IndieMusic/IndieMusic/Modules/Setting/CacheViewModel.swift @@ -46,7 +46,12 @@ class CacheViewModel: ViewModel, ViewModelType { let cachePath = PINCacheAssetDataManager.Cache.diskCache.cacheURL.path FileManager.default.deleteContentsOfFolder(atPath: cachePath) self.reloadData() - + + case .other: + KingfisherManager.shared.cache.clearDiskCache { + print("磁盘缓存已清理完毕") + self.reloadData() + } default: break } @@ -91,7 +96,7 @@ class CacheViewModel: ViewModel, ViewModelType { let cache = Cache.init(title: "听歌缓存", detail: "\(cacheSizeString)", buttonTitle: "清理") let file = Cache.init(title: "音乐下载", detail: "\(downloadSizeString)", buttonTitle: "管理") - let other = Cache.init(title: "其他缓存(图片…)", detail: "\(otherSizeString)", buttonTitle: "") + let other = Cache.init(title: "其他缓存(图片…)", detail: "\(otherSizeString)", buttonTitle: "清理") self.items.accept([CacheSection.init(items: [.cache(cache), .file(file), .other(other)])]) @@ -113,7 +118,7 @@ class CacheViewModel: ViewModel, ViewModelType { let cache = Cache.init(title: "听歌缓存", detail: "\(cacheSizeString)", buttonTitle: "清理") let file = Cache.init(title: "音乐下载", detail: "\(downloadSizeString)", buttonTitle: "管理") - let other = Cache.init(title: "其他缓存(图片…)", detail: "\(otherSizeString)", buttonTitle: "") + let other = Cache.init(title: "其他缓存(图片…)", detail: "\(otherSizeString)", buttonTitle: "清理") self.items.accept([CacheSection.init(items: [.cache(cache), .file(file), .other(other)])]) diff --git a/IndieMusic/IndieMusic/Modules/Setting/EditInfo/EditInfoViewController.swift b/IndieMusic/IndieMusic/Modules/Setting/EditInfo/EditInfoViewController.swift index 5d6df8b..2499634 100644 --- a/IndieMusic/IndieMusic/Modules/Setting/EditInfo/EditInfoViewController.swift +++ b/IndieMusic/IndieMusic/Modules/Setting/EditInfo/EditInfoViewController.swift @@ -12,6 +12,7 @@ import RxDataSources import RxGesture import PhotosUI import RxModal +import RSKImageCropper class EditInfoViewController: TableViewController { let headerView: EditInfoHeaderView = { @@ -100,6 +101,8 @@ class EditInfoViewController: TableViewController { output.avatar.subscribe { [weak self] url in self?.headerView.avatarView.kf.setImage(with: URL.init(string: url)) + + }.disposed(by: rx.disposeBag) let avatarViewTap = headerView.avatarView.rx.tapGesture().when(.recognized) @@ -109,6 +112,10 @@ class EditInfoViewController: TableViewController { .subscribe { [weak self] gestureRecognizer in guard let self = self else { return } + + + + RxModal.photoPicker(presenter: .viewController(self)) { config in config.filter = .images config.selectionLimit = 1 @@ -120,7 +127,7 @@ class EditInfoViewController: TableViewController { DispatchQueue.main.async { if let image = image as? UIImage, let imageData = image.pngData() { - viewModel.editAvatar.onNext(imageData) + viewModel.showEditAvatar.onNext(imageData) } } } @@ -133,6 +140,18 @@ class EditInfoViewController: TableViewController { }.disposed(by: rx.disposeBag) + + + viewModel.showEditAvatar.subscribe { [weak self] imageData in + guard let image = UIImage.init(data: imageData) else { return } + + let imageCropViewController = RSKImageCropViewController.init(image: image, cropMode: .circle) + imageCropViewController.delegate = self + + self?.navigationController?.pushViewController(imageCropViewController, animated: true) + + }.disposed(by: rx.disposeBag) + tableView.mj_header = nil tableView.mj_footer = nil @@ -141,6 +160,28 @@ class EditInfoViewController: TableViewController { } +extension EditInfoViewController: RSKImageCropViewControllerDelegate { + func imageCropViewControllerDidCancelCrop(_ controller: RSKImageCropViewController) { + self.navigationController?.popViewController(animated: true) + } + + + func imageCropViewController(_ controller: RSKImageCropViewController, didCropImage croppedImage: UIImage, usingCropRect cropRect: CGRect, rotationAngle: CGFloat) { + guard let viewModel = self.viewModel as? EditInfoViewModel else { return } + if let data = croppedImage.resizeImage(targetSize: CGSize.init(width: 512, height: 512)).pngData() { + viewModel.editAvatar.onNext(data) + self.navigationController?.popViewController(animated: true) + } + + } + + + func imageCropViewController(_ controller: RSKImageCropViewController, willCropImage originalImage: UIImage) { + + } + +} + extension EditInfoViewController { static func dataSource() -> RxTableViewSectionedReloadDataSource { diff --git a/IndieMusic/IndieMusic/Modules/Setting/EditInfo/EditInfoViewModel.swift b/IndieMusic/IndieMusic/Modules/Setting/EditInfo/EditInfoViewModel.swift index 3d60553..9421a2e 100644 --- a/IndieMusic/IndieMusic/Modules/Setting/EditInfo/EditInfoViewModel.swift +++ b/IndieMusic/IndieMusic/Modules/Setting/EditInfo/EditInfoViewModel.swift @@ -39,6 +39,7 @@ class EditInfoViewModel: ViewModel, ViewModelType { let sexType = PublishRelay() let editAvatar = PublishSubject() + let showEditAvatar = PublishSubject() let avatar = PublishSubject() func transform(input: Input) -> Output { @@ -111,11 +112,13 @@ class EditInfoViewModel: ViewModel, ViewModelType { editAvatar.subscribe { imageData in + SVProgressHUD.show() self.editAvatar(imageData: imageData) .subscribe { [weak self] url in - + SVProgressHUD.showText(withStatus: "上传成功") self?.avatar.onNext(url) } onError: { error in + SVProgressHUD.showText(withStatus: "上传失败") print("error: \(error)") }.disposed(by: self.rx.disposeBag) }.disposed(by: rx.disposeBag) diff --git a/IndieMusic/IndieMusic/Networking/Api.swift b/IndieMusic/IndieMusic/Networking/Api.swift index 8fe1e17..5e8d96c 100644 --- a/IndieMusic/IndieMusic/Networking/Api.swift +++ b/IndieMusic/IndieMusic/Networking/Api.swift @@ -23,7 +23,7 @@ protocol IndieMusicAPI { /// 退出登录 func logout() -> Single /// Token续期 - func autoLogin() -> Single + func autoLogin(deviceId: String, deviceBrand: String) -> Single /// 个人信息 func getUserInfo() -> Single /// 修改个人信息 diff --git a/IndieMusic/IndieMusic/Networking/Rest/APIConfig.swift b/IndieMusic/IndieMusic/Networking/Rest/APIConfig.swift index 5b3642d..399cbaa 100644 --- a/IndieMusic/IndieMusic/Networking/Rest/APIConfig.swift +++ b/IndieMusic/IndieMusic/Networking/Rest/APIConfig.swift @@ -206,10 +206,10 @@ extension APIConfig: TargetType { var parameterEncoding: ParameterEncoding { switch self { - case .wechatAccessToken, .journalList, .journalMusic, .countryCode, .sendsms, .imageCheckCode, .login, .getUserInfo, .carousel, .otherUserInfo, .single, .journal, .messageList, .like, .cancelLike, .collectSongList, .journalCollectList, .followingList, .followerList, .blackList, .hotCommentList, .latestCommentList, .subCommentList, .filterMenu, .journalRecommend, .searchCategory, .searchSong, .searchJournal, .randomAudioTrack, .myThumbupList, .myCommentReplyList, .suggestions, .commentReport, .deleteComment, .thanks, .collectJournalSongList, .otherMessageList, .otherMessageDetail, .checkVersion, .journalDetail, .commentDetail, .lastJournalCover, .journalDetailByID: + case .wechatAccessToken, .journalList, .journalMusic, .countryCode, .sendsms, .imageCheckCode, .login, .getUserInfo, .carousel, .otherUserInfo, .single, .journal, .messageList, .like, .cancelLike, .collectSongList, .journalCollectList, .followingList, .followerList, .blackList, .hotCommentList, .latestCommentList, .subCommentList, .filterMenu, .journalRecommend, .searchCategory, .searchSong, .searchJournal, .randomAudioTrack, .myThumbupList, .myCommentReplyList, .suggestions, .commentReport, .deleteComment, .thanks, .collectJournalSongList, .otherMessageList, .otherMessageDetail, .checkVersion, .journalDetail, .commentDetail, .lastJournalCover, .journalDetailByID, .autoLogin: return URLEncoding.default - case .autoLogin, .editUserInfo, .editAvatar, .logout, .commentLike, .sendComment, .feedback: + case .editUserInfo, .editAvatar, .logout, .commentLike, .sendComment, .feedback: return JSONEncoding.default } } diff --git a/IndieMusic/IndieMusic/Networking/Rest/RestApi.swift b/IndieMusic/IndieMusic/Networking/Rest/RestApi.swift index ba3ab15..b0d4994 100644 --- a/IndieMusic/IndieMusic/Networking/Rest/RestApi.swift +++ b/IndieMusic/IndieMusic/Networking/Rest/RestApi.swift @@ -104,8 +104,10 @@ extension RestApi { return requestWithoutMapping(.logout(["": ""])).map { _ in } } - func autoLogin() -> Single { - return requestObject(.autoLogin(["": ""]), with: "data", type: String.self) + func autoLogin(deviceId: String, deviceBrand: String) -> Single { + let dic = ["deviceId": deviceId, "deviceBrand": deviceBrand] + + return requestObject(.autoLogin(dic), with: "data", type: String.self) } func sendsms(countryCode: String, mobile: String, imageCheckCode: String?, deviceId: String) -> Single { diff --git a/IndieMusic/Podfile b/IndieMusic/Podfile index 3fd06c5..dee97c2 100644 --- a/IndieMusic/Podfile +++ b/IndieMusic/Podfile @@ -35,6 +35,7 @@ target 'IndieMusic' do pod 'EFQRCode' pod 'GrowingTextView', '0.7.2' pod 'Tiercel' + pod 'RSKImageCropper' pod 'NSObject+Rx'