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
viewModel.user = user
viewModel.account = nil
viewModel.relationship = nil
Publishers.CombineLatest(
user.publisher(for: \.avatar),
@ -67,9 +68,11 @@ extension UserView {
.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.relationship = relationship
viewModel.user = nil
self.delegate = delegate
let authorUsername = PlaintextMetaContent(string: "@\(account.username)")
authorUsernameLabel.configure(content: authorUsername)

View File

@ -38,28 +38,12 @@ extension UserTableViewCell {
relationship: Mastodon.Entity.Relationship?,
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
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
}
let isMe = account.id == me.id
userView.updateButtonState(with: relationship, isMe: isMe)
userView.setButtonState(buttonState)
self.delegate = delegate
}
func configure(
@ -117,15 +101,30 @@ extension UserTableViewCellDelegate where Self: NeedsDependency & AuthContextPro
)
}
}
func userView(_ view: UserView, didTapButtonWith state: UserView.ButtonState, for user: Mastodon.Entity.Account) {
func userView(_ view: UserView, didTapButtonWith state: UserView.ButtonState, for account: Mastodon.Entity.Account, me: MastodonUser?) {
Task {
await MainActor.run { view.setButtonState(.loading) }
try await DataSourceFacade.responseToUserViewButtonAction(
dependency: self,
user: user,
user: account,
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 user: MastodonUser?
@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 {
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 {
@ -258,10 +258,33 @@ public extension UserView {
if let user = viewModel.user {
delegate?.userView(self, didTapButtonWith: currentButtonState, for: user)
} 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) {
currentButtonState = state
prepareButtonStateLayout(for: state)