forked from zelo72/mastodon-ios
chore: add followAction
This commit is contained in:
parent
c74314ef11
commit
567c2af0ee
|
@ -135,6 +135,7 @@
|
||||||
5DF1057925F88A1D00D6C0D4 /* PlayerContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DF1057825F88A1D00D6C0D4 /* PlayerContainerView.swift */; };
|
5DF1057925F88A1D00D6C0D4 /* PlayerContainerView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DF1057825F88A1D00D6C0D4 /* PlayerContainerView.swift */; };
|
||||||
5DF1057F25F88A4100D6C0D4 /* TouchBlockingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DF1057E25F88A4100D6C0D4 /* TouchBlockingView.swift */; };
|
5DF1057F25F88A4100D6C0D4 /* TouchBlockingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DF1057E25F88A4100D6C0D4 /* TouchBlockingView.swift */; };
|
||||||
5DF1058525F88AE500D6C0D4 /* NeedsDependency+AVPlayerViewControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DF1058425F88AE500D6C0D4 /* NeedsDependency+AVPlayerViewControllerDelegate.swift */; };
|
5DF1058525F88AE500D6C0D4 /* NeedsDependency+AVPlayerViewControllerDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DF1058425F88AE500D6C0D4 /* NeedsDependency+AVPlayerViewControllerDelegate.swift */; };
|
||||||
|
5DFC35DF262068D20045711D /* SearchViewController+Follow.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5DFC35DE262068D20045711D /* SearchViewController+Follow.swift */; };
|
||||||
5E0DEC05797A7E6933788DDB /* Pods_MastodonTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 452147B2903DF38070FE56A2 /* Pods_MastodonTests.framework */; };
|
5E0DEC05797A7E6933788DDB /* Pods_MastodonTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 452147B2903DF38070FE56A2 /* Pods_MastodonTests.framework */; };
|
||||||
5E44BF88AD33646E64727BCF /* Pods_MastodonTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD92E0F10BDE4FE7C4B999F2 /* Pods_MastodonTests.framework */; };
|
5E44BF88AD33646E64727BCF /* Pods_MastodonTests.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD92E0F10BDE4FE7C4B999F2 /* Pods_MastodonTests.framework */; };
|
||||||
87FFDA5D898A5C42ADCB35E7 /* Pods_Mastodon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A4ABE34829701A4496C5BB64 /* Pods_Mastodon.framework */; };
|
87FFDA5D898A5C42ADCB35E7 /* Pods_Mastodon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A4ABE34829701A4496C5BB64 /* Pods_Mastodon.framework */; };
|
||||||
|
@ -506,6 +507,7 @@
|
||||||
5DF1057825F88A1D00D6C0D4 /* PlayerContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerContainerView.swift; sourceTree = "<group>"; };
|
5DF1057825F88A1D00D6C0D4 /* PlayerContainerView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = PlayerContainerView.swift; sourceTree = "<group>"; };
|
||||||
5DF1057E25F88A4100D6C0D4 /* TouchBlockingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TouchBlockingView.swift; sourceTree = "<group>"; };
|
5DF1057E25F88A4100D6C0D4 /* TouchBlockingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TouchBlockingView.swift; sourceTree = "<group>"; };
|
||||||
5DF1058425F88AE500D6C0D4 /* NeedsDependency+AVPlayerViewControllerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NeedsDependency+AVPlayerViewControllerDelegate.swift"; sourceTree = "<group>"; };
|
5DF1058425F88AE500D6C0D4 /* NeedsDependency+AVPlayerViewControllerDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "NeedsDependency+AVPlayerViewControllerDelegate.swift"; sourceTree = "<group>"; };
|
||||||
|
5DFC35DE262068D20045711D /* SearchViewController+Follow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "SearchViewController+Follow.swift"; sourceTree = "<group>"; };
|
||||||
75E3471C898DDD9631729B6E /* Pods-Mastodon.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.release.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.release.xcconfig"; sourceTree = "<group>"; };
|
75E3471C898DDD9631729B6E /* Pods-Mastodon.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Mastodon.release.xcconfig"; path = "Target Support Files/Pods-Mastodon/Pods-Mastodon.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
9780A4C98FFC65B32B50D1C0 /* Pods-MastodonTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonTests.release.xcconfig"; path = "Target Support Files/Pods-MastodonTests/Pods-MastodonTests.release.xcconfig"; sourceTree = "<group>"; };
|
9780A4C98FFC65B32B50D1C0 /* Pods-MastodonTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MastodonTests.release.xcconfig"; path = "Target Support Files/Pods-MastodonTests/Pods-MastodonTests.release.xcconfig"; sourceTree = "<group>"; };
|
||||||
A4ABE34829701A4496C5BB64 /* Pods_Mastodon.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Mastodon.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
A4ABE34829701A4496C5BB64 /* Pods_Mastodon.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Mastodon.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||||
|
@ -1613,6 +1615,7 @@
|
||||||
DB9D6BE825E4F5340051B173 /* SearchViewController.swift */,
|
DB9D6BE825E4F5340051B173 /* SearchViewController.swift */,
|
||||||
2D34D9CA261489930081BFC0 /* SearchViewController+Recommend.swift */,
|
2D34D9CA261489930081BFC0 /* SearchViewController+Recommend.swift */,
|
||||||
2DFAD5262616F9D300F9EE7C /* SearchViewController+Searching.swift */,
|
2DFAD5262616F9D300F9EE7C /* SearchViewController+Searching.swift */,
|
||||||
|
5DFC35DE262068D20045711D /* SearchViewController+Follow.swift */,
|
||||||
2D6DE3FF26141DF600A63F6A /* SearchViewModel.swift */,
|
2D6DE3FF26141DF600A63F6A /* SearchViewModel.swift */,
|
||||||
2D198654261C3C4300F0B013 /* SearchViewModel+LoadOldestState.swift */,
|
2D198654261C3C4300F0B013 /* SearchViewModel+LoadOldestState.swift */,
|
||||||
2D34D9E026149C550081BFC0 /* CollectionViewCell */,
|
2D34D9E026149C550081BFC0 /* CollectionViewCell */,
|
||||||
|
@ -2355,6 +2358,7 @@
|
||||||
2D42FF6B25C817D2004A627A /* MastodonStatusContent.swift in Sources */,
|
2D42FF6B25C817D2004A627A /* MastodonStatusContent.swift in Sources */,
|
||||||
2DF75BA725D10E1000694EC8 /* APIService+Favorite.swift in Sources */,
|
2DF75BA725D10E1000694EC8 /* APIService+Favorite.swift in Sources */,
|
||||||
DB9D6C3825E508BE0051B173 /* Attachment.swift in Sources */,
|
DB9D6C3825E508BE0051B173 /* Attachment.swift in Sources */,
|
||||||
|
5DFC35DF262068D20045711D /* SearchViewController+Follow.swift in Sources */,
|
||||||
DB8AF52E25C13561002E6C99 /* ViewStateStore.swift in Sources */,
|
DB8AF52E25C13561002E6C99 /* ViewStateStore.swift in Sources */,
|
||||||
2DA7D04A25CA52CB00804E11 /* TimelineBottomLoaderTableViewCell.swift in Sources */,
|
2DA7D04A25CA52CB00804E11 /* TimelineBottomLoaderTableViewCell.swift in Sources */,
|
||||||
2D76318325C14E8F00929FB9 /* PublicTimelineViewModel+Diffable.swift in Sources */,
|
2D76318325C14E8F00929FB9 /* PublicTimelineViewModel+Diffable.swift in Sources */,
|
||||||
|
|
|
@ -5,11 +5,11 @@
|
||||||
// Created by sxiaojian on 2021/4/1.
|
// Created by sxiaojian on 2021/4/1.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import CoreData
|
||||||
|
import CoreDataStack
|
||||||
import Foundation
|
import Foundation
|
||||||
import MastodonSDK
|
import MastodonSDK
|
||||||
import UIKit
|
import UIKit
|
||||||
import CoreData
|
|
||||||
import CoreDataStack
|
|
||||||
|
|
||||||
enum RecommendAccountSection: Equatable, Hashable {
|
enum RecommendAccountSection: Equatable, Hashable {
|
||||||
case main
|
case main
|
||||||
|
@ -18,15 +18,14 @@ enum RecommendAccountSection: Equatable, Hashable {
|
||||||
extension RecommendAccountSection {
|
extension RecommendAccountSection {
|
||||||
static func collectionViewDiffableDataSource(
|
static func collectionViewDiffableDataSource(
|
||||||
for collectionView: UICollectionView,
|
for collectionView: UICollectionView,
|
||||||
context: AppContext!
|
delegate: SearchRecommendAccountsCollectionViewCellDelegate,
|
||||||
|
managedObjectContext: NSManagedObjectContext
|
||||||
) -> UICollectionViewDiffableDataSource<RecommendAccountSection, NSManagedObjectID> {
|
) -> UICollectionViewDiffableDataSource<RecommendAccountSection, NSManagedObjectID> {
|
||||||
UICollectionViewDiffableDataSource(collectionView: collectionView) { collectionView, indexPath, objectID -> UICollectionViewCell? in
|
UICollectionViewDiffableDataSource(collectionView: collectionView) { [weak delegate] collectionView, indexPath, objectID -> UICollectionViewCell? in
|
||||||
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: SearchRecommendAccountsCollectionViewCell.self), for: indexPath) as! SearchRecommendAccountsCollectionViewCell
|
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: String(describing: SearchRecommendAccountsCollectionViewCell.self), for: indexPath) as! SearchRecommendAccountsCollectionViewCell
|
||||||
let user = context.managedObjectContext.object(with: objectID) as! MastodonUser
|
let user = managedObjectContext.object(with: objectID) as! MastodonUser
|
||||||
|
cell.delegate = delegate
|
||||||
cell.config(with: user)
|
cell.config(with: user)
|
||||||
if let currentUser = context.authenticationService.activeMastodonAuthentication.value?.user {
|
|
||||||
cell.configFollowButton(with: user, currentMastodonUser: currentUser)
|
|
||||||
}
|
|
||||||
return cell
|
return cell
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,16 +5,23 @@
|
||||||
// Created by sxiaojian on 2021/4/1.
|
// Created by sxiaojian on 2021/4/1.
|
||||||
//
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
|
import CoreDataStack
|
||||||
import Foundation
|
import Foundation
|
||||||
import MastodonSDK
|
import MastodonSDK
|
||||||
import UIKit
|
import UIKit
|
||||||
import CoreDataStack
|
|
||||||
import Combine
|
protocol SearchRecommendAccountsCollectionViewCellDelegate: NSObject {
|
||||||
|
func followButtonDidPressed(clickedUser: MastodonUser)
|
||||||
|
|
||||||
|
func configFollowButton(with mastodonUser: MastodonUser, followButton: HighlightDimmableButton)
|
||||||
|
}
|
||||||
|
|
||||||
class SearchRecommendAccountsCollectionViewCell: UICollectionViewCell {
|
class SearchRecommendAccountsCollectionViewCell: UICollectionViewCell {
|
||||||
|
|
||||||
var disposeBag = Set<AnyCancellable>()
|
var disposeBag = Set<AnyCancellable>()
|
||||||
|
|
||||||
|
weak var delegate: SearchRecommendAccountsCollectionViewCellDelegate?
|
||||||
|
|
||||||
let avatarImageView: UIImageView = {
|
let avatarImageView: UIImageView = {
|
||||||
let imageView = UIImageView()
|
let imageView = UIImageView()
|
||||||
imageView.layer.cornerRadius = 8.4
|
imageView.layer.cornerRadius = 8.4
|
||||||
|
@ -52,8 +59,8 @@ class SearchRecommendAccountsCollectionViewCell: UICollectionViewCell {
|
||||||
return label
|
return label
|
||||||
}()
|
}()
|
||||||
|
|
||||||
let followButton: UIButton = {
|
let followButton: HighlightDimmableButton = {
|
||||||
let button = UIButton(type: .custom)
|
let button = HighlightDimmableButton(type: .custom)
|
||||||
button.setTitleColor(.white, for: .normal)
|
button.setTitleColor(.white, for: .normal)
|
||||||
button.setTitle(L10n.Scene.Search.Recommend.Accounts.follow, for: .normal)
|
button.setTitle(L10n.Scene.Search.Recommend.Accounts.follow, for: .normal)
|
||||||
button.titleLabel?.font = .systemFont(ofSize: 14, weight: .semibold)
|
button.titleLabel?.font = .systemFont(ofSize: 14, weight: .semibold)
|
||||||
|
@ -138,49 +145,22 @@ extension SearchRecommendAccountsCollectionViewCell {
|
||||||
headerImageView.af.setImage(
|
headerImageView.af.setImage(
|
||||||
withURL: URL(string: mastodonUser.header)!,
|
withURL: URL(string: mastodonUser.header)!,
|
||||||
placeholderImage: UIImage.placeholder(color: .systemFill),
|
placeholderImage: UIImage.placeholder(color: .systemFill),
|
||||||
imageTransition: .crossDissolve(0.2)) { [weak self] _ in
|
imageTransition: .crossDissolve(0.2)
|
||||||
|
) { [weak self] _ in
|
||||||
guard let self = self else { return }
|
guard let self = self else { return }
|
||||||
self.headerImageView.addSubview(self.visualEffectView)
|
self.headerImageView.addSubview(self.visualEffectView)
|
||||||
self.visualEffectView.pin(top: 0, left: 0, bottom: 0, right: 0)
|
self.visualEffectView.pin(top: 0, left: 0, bottom: 0, right: 0)
|
||||||
}
|
}
|
||||||
}
|
delegate?.configFollowButton(with: mastodonUser, followButton: followButton)
|
||||||
|
followButton.publisher(for: .touchUpInside)
|
||||||
func configFollowButton(with mastodonUser: MastodonUser, currentMastodonUser: MastodonUser) {
|
.sink { [weak self] _ in
|
||||||
self._configFollowButton(with: mastodonUser, currentMastodonUser: currentMastodonUser)
|
self?.followButtonDidPressed(mastodonUser: mastodonUser)
|
||||||
ManagedObjectObserver.observe(object: currentMastodonUser)
|
|
||||||
.sink { _ in
|
|
||||||
|
|
||||||
} receiveValue: { change in
|
|
||||||
guard case .update(let object) = change.changeType,
|
|
||||||
let newUser = object as? MastodonUser else { return }
|
|
||||||
self._configFollowButton(with: mastodonUser, currentMastodonUser: newUser)
|
|
||||||
}
|
}
|
||||||
.store(in: &disposeBag)
|
.store(in: &disposeBag)
|
||||||
}
|
}
|
||||||
|
|
||||||
func _configFollowButton(with mastodonUser: MastodonUser, currentMastodonUser: MastodonUser) {
|
func followButtonDidPressed(mastodonUser: MastodonUser) {
|
||||||
var relationshipActionSet = ProfileViewModel.RelationshipActionOptionSet([.follow])
|
delegate?.followButtonDidPressed(clickedUser: mastodonUser)
|
||||||
|
|
||||||
let isFollowing = mastodonUser.followingBy.flatMap { $0.contains(currentMastodonUser) } ?? false
|
|
||||||
if isFollowing {
|
|
||||||
relationshipActionSet.insert(.following)
|
|
||||||
}
|
|
||||||
|
|
||||||
let isPending = mastodonUser.followRequestedBy.flatMap { $0.contains(currentMastodonUser) } ?? false
|
|
||||||
if isPending {
|
|
||||||
relationshipActionSet.insert(.pending)
|
|
||||||
}
|
|
||||||
|
|
||||||
let isBlocking = mastodonUser.blockingBy.flatMap { $0.contains(currentMastodonUser) } ?? false
|
|
||||||
if isBlocking {
|
|
||||||
relationshipActionSet.insert(.blocking)
|
|
||||||
}
|
|
||||||
|
|
||||||
let isBlockedBy = currentMastodonUser.blockingBy.flatMap { $0.contains(mastodonUser) } ?? false
|
|
||||||
if isBlockedBy {
|
|
||||||
relationshipActionSet.insert(.blocked)
|
|
||||||
}
|
|
||||||
self.followButton.setTitle(relationshipActionSet.title, for: .normal)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,137 @@
|
||||||
|
//
|
||||||
|
// SearchViewController+Follow.swift
|
||||||
|
// Mastodon
|
||||||
|
//
|
||||||
|
// Created by xiaojian sun on 2021/4/9.
|
||||||
|
//
|
||||||
|
|
||||||
|
import Combine
|
||||||
|
import CoreDataStack
|
||||||
|
import Foundation
|
||||||
|
import UIKit
|
||||||
|
|
||||||
|
extension SearchViewController: UserProvider {
|
||||||
|
func mastodonUser() -> Future<MastodonUser?, Never> {
|
||||||
|
Future { promise in
|
||||||
|
promise(.success(self.viewModel.mastodonUser.value))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SearchViewController: SearchRecommendAccountsCollectionViewCellDelegate {
|
||||||
|
func followButtonDidPressed(clickedUser: MastodonUser) {
|
||||||
|
viewModel.mastodonUser.value = clickedUser
|
||||||
|
guard let currentMastodonUser = viewModel.currentMastodonUser.value else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
let relationshipAction = relationShipActionSet(mastodonUser: clickedUser, currentMastodonUser: currentMastodonUser)
|
||||||
|
switch relationshipAction {
|
||||||
|
case .none:
|
||||||
|
break
|
||||||
|
case .follow, .following:
|
||||||
|
UserProviderFacade.toggleUserFollowRelationship(provider: self)
|
||||||
|
.sink { _ in
|
||||||
|
|
||||||
|
} receiveValue: { _ in
|
||||||
|
}
|
||||||
|
.store(in: &disposeBag)
|
||||||
|
case .pending:
|
||||||
|
break
|
||||||
|
case .muting:
|
||||||
|
guard let mastodonUser = viewModel.mastodonUser.value else { return }
|
||||||
|
let name = mastodonUser.displayNameWithFallback
|
||||||
|
let alertController = UIAlertController(
|
||||||
|
title: L10n.Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.title,
|
||||||
|
message: L10n.Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.message(name),
|
||||||
|
preferredStyle: .alert
|
||||||
|
)
|
||||||
|
let unmuteAction = UIAlertAction(title: L10n.Common.Controls.Firendship.unmute, style: .default) { [weak self] _ in
|
||||||
|
guard let self = self else { return }
|
||||||
|
UserProviderFacade.toggleUserMuteRelationship(provider: self)
|
||||||
|
.sink { _ in
|
||||||
|
// do nothing
|
||||||
|
} receiveValue: { _ in
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
.store(in: &self.context.disposeBag)
|
||||||
|
}
|
||||||
|
alertController.addAction(unmuteAction)
|
||||||
|
let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel, handler: nil)
|
||||||
|
alertController.addAction(cancelAction)
|
||||||
|
present(alertController, animated: true, completion: nil)
|
||||||
|
case .blocking:
|
||||||
|
guard let mastodonUser = viewModel.mastodonUser.value else { return }
|
||||||
|
let name = mastodonUser.displayNameWithFallback
|
||||||
|
let alertController = UIAlertController(
|
||||||
|
title: L10n.Scene.Profile.RelationshipActionAlert.ConfirmUnblockUsre.title,
|
||||||
|
message: L10n.Scene.Profile.RelationshipActionAlert.ConfirmUnblockUsre.message(name),
|
||||||
|
preferredStyle: .alert
|
||||||
|
)
|
||||||
|
let unblockAction = UIAlertAction(title: L10n.Common.Controls.Firendship.unblock, style: .default) { [weak self] _ in
|
||||||
|
guard let self = self else { return }
|
||||||
|
UserProviderFacade.toggleUserBlockRelationship(provider: self)
|
||||||
|
.sink { _ in
|
||||||
|
// do nothing
|
||||||
|
} receiveValue: { _ in
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
.store(in: &self.context.disposeBag)
|
||||||
|
}
|
||||||
|
alertController.addAction(unblockAction)
|
||||||
|
let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel, handler: nil)
|
||||||
|
alertController.addAction(cancelAction)
|
||||||
|
present(alertController, animated: true, completion: nil)
|
||||||
|
case .blocked:
|
||||||
|
break
|
||||||
|
default:
|
||||||
|
assertionFailure()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func configFollowButton(with mastodonUser: MastodonUser, followButton: HighlightDimmableButton) {
|
||||||
|
guard let currentMastodonUser = viewModel.currentMastodonUser.value else {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
_configFollowButton(with: mastodonUser, currentMastodonUser: currentMastodonUser, followButton: followButton)
|
||||||
|
ManagedObjectObserver.observe(object: currentMastodonUser)
|
||||||
|
.sink { _ in
|
||||||
|
|
||||||
|
} receiveValue: { change in
|
||||||
|
guard case .update(let object) = change.changeType,
|
||||||
|
let newUser = object as? MastodonUser else { return }
|
||||||
|
self._configFollowButton(with: mastodonUser, currentMastodonUser: newUser, followButton: followButton)
|
||||||
|
}
|
||||||
|
.store(in: &disposeBag)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
extension SearchViewController {
|
||||||
|
func _configFollowButton(with mastodonUser: MastodonUser, currentMastodonUser: MastodonUser, followButton: HighlightDimmableButton) {
|
||||||
|
let relationshipActionSet = relationShipActionSet(mastodonUser: mastodonUser, currentMastodonUser: currentMastodonUser)
|
||||||
|
followButton.setTitle(relationshipActionSet.title, for: .normal)
|
||||||
|
}
|
||||||
|
|
||||||
|
func relationShipActionSet(mastodonUser: MastodonUser, currentMastodonUser: MastodonUser) -> ProfileViewModel.RelationshipActionOptionSet {
|
||||||
|
var relationshipActionSet = ProfileViewModel.RelationshipActionOptionSet([.follow])
|
||||||
|
let isFollowing = mastodonUser.followingBy.flatMap { $0.contains(currentMastodonUser) } ?? false
|
||||||
|
if isFollowing {
|
||||||
|
relationshipActionSet.insert(.following)
|
||||||
|
}
|
||||||
|
|
||||||
|
let isPending = mastodonUser.followRequestedBy.flatMap { $0.contains(currentMastodonUser) } ?? false
|
||||||
|
if isPending {
|
||||||
|
relationshipActionSet.insert(.pending)
|
||||||
|
}
|
||||||
|
|
||||||
|
let isBlocking = mastodonUser.blockingBy.flatMap { $0.contains(currentMastodonUser) } ?? false
|
||||||
|
if isBlocking {
|
||||||
|
relationshipActionSet.insert(.blocking)
|
||||||
|
}
|
||||||
|
|
||||||
|
let isBlockedBy = currentMastodonUser.blockingBy.flatMap { $0.contains(mastodonUser) } ?? false
|
||||||
|
if isBlockedBy {
|
||||||
|
relationshipActionSet.insert(.blocked)
|
||||||
|
}
|
||||||
|
return relationshipActionSet
|
||||||
|
}
|
||||||
|
}
|
|
@ -150,7 +150,7 @@ extension SearchViewController {
|
||||||
|
|
||||||
func setupDataSource() {
|
func setupDataSource() {
|
||||||
viewModel.hashtagDiffableDataSource = RecommendHashTagSection.collectionViewDiffableDataSource(for: hashtagCollectionView)
|
viewModel.hashtagDiffableDataSource = RecommendHashTagSection.collectionViewDiffableDataSource(for: hashtagCollectionView)
|
||||||
viewModel.accountDiffableDataSource = RecommendAccountSection.collectionViewDiffableDataSource(for: accountsCollectionView, context: context)
|
viewModel.accountDiffableDataSource = RecommendAccountSection.collectionViewDiffableDataSource(for: accountsCollectionView, delegate: self, managedObjectContext: context.managedObjectContext)
|
||||||
viewModel.searchResultDiffableDataSource = SearchResultSection.tableViewDiffableDataSource(for: searchingTableView, dependency: self)
|
viewModel.searchResultDiffableDataSource = SearchResultSection.tableViewDiffableDataSource(for: searchingTableView, dependency: self)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,9 @@ final class SearchViewModel: NSObject {
|
||||||
let context: AppContext
|
let context: AppContext
|
||||||
weak var coordinator: SceneCoordinator!
|
weak var coordinator: SceneCoordinator!
|
||||||
|
|
||||||
|
let mastodonUser = CurrentValueSubject<MastodonUser?, Never>(nil)
|
||||||
|
let currentMastodonUser = CurrentValueSubject<MastodonUser?, Never>(nil)
|
||||||
|
|
||||||
// output
|
// output
|
||||||
let searchText = CurrentValueSubject<String, Never>("")
|
let searchText = CurrentValueSubject<String, Never>("")
|
||||||
let searchScope = CurrentValueSubject<Mastodon.API.Search.SearchType, Never>(Mastodon.API.Search.SearchType.default)
|
let searchScope = CurrentValueSubject<Mastodon.API.Search.SearchType, Never>(Mastodon.API.Search.SearchType.default)
|
||||||
|
@ -60,6 +63,19 @@ final class SearchViewModel: NSObject {
|
||||||
guard let activeMastodonAuthenticationBox = self.context.authenticationService.activeMastodonAuthenticationBox.value else {
|
guard let activeMastodonAuthenticationBox = self.context.authenticationService.activeMastodonAuthenticationBox.value else {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// bind active authentication
|
||||||
|
context.authenticationService.activeMastodonAuthentication
|
||||||
|
.sink { [weak self] activeMastodonAuthentication in
|
||||||
|
guard let self = self else { return }
|
||||||
|
guard let activeMastodonAuthentication = activeMastodonAuthentication else {
|
||||||
|
self.currentMastodonUser.value = nil
|
||||||
|
return
|
||||||
|
}
|
||||||
|
self.currentMastodonUser.value = activeMastodonAuthentication.user
|
||||||
|
}
|
||||||
|
.store(in: &disposeBag)
|
||||||
|
|
||||||
Publishers.CombineLatest(
|
Publishers.CombineLatest(
|
||||||
searchText
|
searchText
|
||||||
.debounce(for: .milliseconds(300), scheduler: DispatchQueue.main).removeDuplicates(),
|
.debounce(for: .milliseconds(300), scheduler: DispatchQueue.main).removeDuplicates(),
|
||||||
|
|
Loading…
Reference in New Issue