Update follow-button-state after (un)following a person

This commit is contained in:
Nathan Mattes 2023-10-24 15:42:23 +02:00
parent 02207d1b1f
commit 242f351e10
4 changed files with 54 additions and 28 deletions

View File

@ -21,6 +21,7 @@ extension UserView {
self.delegate = delegate self.delegate = delegate
viewModel.user = user viewModel.user = user
viewModel.account = nil viewModel.account = nil
viewModel.relationship = nil
Publishers.CombineLatest( Publishers.CombineLatest(
user.publisher(for: \.avatar), user.publisher(for: \.avatar),
@ -67,9 +68,11 @@ extension UserView {
.store(in: &disposeBag) .store(in: &disposeBag)
} }
func configure(with account: Mastodon.Entity.Account) { func configure(with account: Mastodon.Entity.Account, relationship: Mastodon.Entity.Relationship?, delegate: UserViewDelegate?) {
viewModel.account = account viewModel.account = account
viewModel.relationship = relationship
viewModel.user = nil viewModel.user = nil
self.delegate = delegate
let authorUsername = PlaintextMetaContent(string: "@\(account.username)") let authorUsername = PlaintextMetaContent(string: "@\(account.username)")
authorUsernameLabel.configure(content: authorUsername) authorUsernameLabel.configure(content: authorUsername)

View File

@ -38,28 +38,12 @@ extension UserTableViewCell {
relationship: Mastodon.Entity.Relationship?, relationship: Mastodon.Entity.Relationship?,
delegate: UserTableViewCellDelegate? delegate: UserTableViewCellDelegate?
) { ) {
userView.configure(with: account) userView.configure(with: account, relationship: relationship, delegate: delegate)
let buttonState: UserView.ButtonState
if let relationship {
let isMe = account.id == me.id let isMe = account.id == me.id
if isMe { userView.updateButtonState(with: relationship, isMe: isMe)
buttonState = .none
} else if relationship.following {
buttonState = .unfollow
} else if relationship.blocking || (relationship.domainBlocking ?? false) {
buttonState = .blocked
} else if relationship.requested ?? false {
buttonState = .pending
} else {
buttonState = .follow
}
} else {
buttonState = .none
}
userView.setButtonState(buttonState)
self.delegate = delegate
} }
func configure( func configure(
@ -117,15 +101,30 @@ extension UserTableViewCellDelegate where Self: NeedsDependency & AuthContextPro
) )
} }
} }
func userView(_ view: UserView, didTapButtonWith state: UserView.ButtonState, for account: Mastodon.Entity.Account, me: MastodonUser?) {
func userView(_ view: UserView, didTapButtonWith state: UserView.ButtonState, for user: Mastodon.Entity.Account) {
Task { Task {
await MainActor.run { view.setButtonState(.loading) }
try await DataSourceFacade.responseToUserViewButtonAction( try await DataSourceFacade.responseToUserViewButtonAction(
dependency: self, dependency: self,
user: user, user: account,
buttonState: state buttonState: state
) )
}
let relationship = try await self.context.apiService.relationship(forAccounts: [account], authenticationBox: authContext.mastodonAuthenticationBox).value.first
let isMe: Bool
if let me {
isMe = account.id == me.id
} else {
isMe = false
} }
await MainActor.run {
view.viewModel.relationship = relationship
view.updateButtonState(with: relationship, isMe: isMe)
}
}
}
} }

View File

@ -28,6 +28,7 @@ extension UserView {
@Published public var authorVerifiedLink: String? @Published public var authorVerifiedLink: String?
@Published public var user: MastodonUser? @Published public var user: MastodonUser?
@Published public var account: Mastodon.Entity.Account? @Published public var account: Mastodon.Entity.Account?
@Published public var relationship: Mastodon.Entity.Relationship?
} }
} }

View File

@ -16,7 +16,7 @@ import MastodonSDK
public protocol UserViewDelegate: AnyObject { public protocol UserViewDelegate: AnyObject {
func userView(_ view: UserView, didTapButtonWith state: UserView.ButtonState, for user: MastodonUser) func userView(_ view: UserView, didTapButtonWith state: UserView.ButtonState, for user: MastodonUser)
func userView(_ view: UserView, didTapButtonWith state: UserView.ButtonState, for user: Mastodon.Entity.Account) func userView(_ view: UserView, didTapButtonWith state: UserView.ButtonState, for user: Mastodon.Entity.Account, me: MastodonUser?)
} }
public final class UserView: UIView { public final class UserView: UIView {
@ -258,10 +258,33 @@ public extension UserView {
if let user = viewModel.user { if let user = viewModel.user {
delegate?.userView(self, didTapButtonWith: currentButtonState, for: user) delegate?.userView(self, didTapButtonWith: currentButtonState, for: user)
} else if let account = viewModel.account { } else if let account = viewModel.account {
delegate?.userView(self, didTapButtonWith: currentButtonState, for: account) delegate?.userView(self, didTapButtonWith: currentButtonState, for: account, me: nil)
} }
} }
func updateButtonState(with relationship: Mastodon.Entity.Relationship?, isMe: Bool) {
let buttonState: UserView.ButtonState
if let relationship {
if isMe {
buttonState = .none
} else if relationship.following {
buttonState = .unfollow
} else if relationship.blocking || (relationship.domainBlocking ?? false) {
buttonState = .blocked
} else if relationship.requested ?? false {
buttonState = .pending
} else {
buttonState = .follow
}
} else {
buttonState = .none
}
setButtonState(buttonState)
}
func setButtonState(_ state: ButtonState) { func setButtonState(_ state: ButtonState) {
currentButtonState = state currentButtonState = state
prepareButtonStateLayout(for: state) prepareButtonStateLayout(for: state)