Add some actions to Relationship-action-button (IOS-192)

Well, it's basically just unblock, unmute or follow/unfollow
This commit is contained in:
Nathan Mattes 2023-12-27 23:48:16 +01:00
parent 59fe79fe49
commit 6225c50008
9 changed files with 160 additions and 203 deletions

View File

@ -14,27 +14,6 @@ extension DataSourceFacade {
static func responseToUserBlockAction( static func responseToUserBlockAction(
dependency: NeedsDependency & AuthContextProvider, dependency: NeedsDependency & AuthContextProvider,
account: Mastodon.Entity.Account account: Mastodon.Entity.Account
) async throws {
let selectionFeedbackGenerator = await UISelectionFeedbackGenerator()
await selectionFeedbackGenerator.selectionChanged()
let apiService = dependency.context.apiService
let authBox = dependency.authContext.mastodonAuthenticationBox
_ = try await apiService.toggleBlock(
account: account,
authenticationBox: authBox
)
try await dependency.context.apiService.getBlocked(
authenticationBox: authBox
)
dependency.context.authenticationService.fetchFollowingAndBlockedAsync()
}
static func responseToUserBlockAction(
dependency: NeedsDependency & AuthContextProvider,
user: Mastodon.Entity.Account
) async throws -> Mastodon.Entity.Relationship { ) async throws -> Mastodon.Entity.Relationship {
let selectionFeedbackGenerator = await UISelectionFeedbackGenerator() let selectionFeedbackGenerator = await UISelectionFeedbackGenerator()
await selectionFeedbackGenerator.selectionChanged() await selectionFeedbackGenerator.selectionChanged()
@ -43,7 +22,7 @@ extension DataSourceFacade {
let authBox = dependency.authContext.mastodonAuthenticationBox let authBox = dependency.authContext.mastodonAuthenticationBox
let response = try await apiService.toggleBlock( let response = try await apiService.toggleBlock(
user: user, account: account,
authenticationBox: authBox authenticationBox: authBox
) )

View File

@ -229,7 +229,7 @@ extension DataSourceFacade {
Task { Task {
let newRelationship = try await DataSourceFacade.responseToUserBlockAction( let newRelationship = try await DataSourceFacade.responseToUserBlockAction(
dependency: dependency, dependency: dependency,
user: menuContext.author account: menuContext.author
) )
if let completion { if let completion {

View File

@ -35,7 +35,7 @@ extension DataSourceFacade {
dependency.authContext.mastodonAuthenticationBox.inMemoryCache.followingUserIds.removeAll(where: { $0 == account.id }) dependency.authContext.mastodonAuthenticationBox.inMemoryCache.followingUserIds.removeAll(where: { $0 == account.id })
case .blocked: case .blocked:
try await DataSourceFacade.responseToUserBlockAction( _ = try await DataSourceFacade.responseToUserBlockAction(
dependency: dependency, dependency: dependency,
account: account account: account
) )

View File

@ -686,13 +686,16 @@ extension ProfileViewController: ProfileHeaderViewControllerDelegate {
profileHeaderView: ProfileHeaderView, profileHeaderView: ProfileHeaderView,
relationshipButtonDidPressed button: ProfileRelationshipActionButton relationshipButtonDidPressed button: ProfileRelationshipActionButton
) { ) {
// let relationshipActionSet = viewModel.relationshipViewModel.optionSet ?? .none
#warning("TODO: Implement")
// handle edit logic for editable profile
// handle relationship logic for non-editable profile
if viewModel.me == viewModel.account { if viewModel.me == viewModel.account {
// // do nothing when updating editProfile()
} else {
editRelationship()
}
}
private func editProfile() {
// do nothing when updating
guard !viewModel.isUpdating else { return } guard !viewModel.isUpdating else { return }
let profileHeaderViewModel = profileHeaderViewController.viewModel let profileHeaderViewModel = profileHeaderViewController.viewModel
@ -726,7 +729,7 @@ extension ProfileViewController: ProfileHeaderViewControllerDelegate {
// finish updating // finish updating
self.viewModel.isUpdating = false self.viewModel.isUpdating = false
} // end Task }
} else { } else {
// set `updating` then toggle `edit` state // set `updating` then toggle `edit` state
viewModel.isUpdating = true viewModel.isUpdating = true
@ -741,7 +744,7 @@ extension ProfileViewController: ProfileHeaderViewControllerDelegate {
switch completion { switch completion {
case .failure(let error): case .failure(let error):
let alertController = UIAlertController(for: error, title: L10n.Common.Alerts.EditProfileFailure.title, preferredStyle: .alert) let alertController = UIAlertController(for: error, title: L10n.Common.Alerts.EditProfileFailure.title, preferredStyle: .alert)
let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default, handler: nil) let okAction = UIAlertAction(title: L10n.Common.Controls.Actions.ok, style: .default)
alertController.addAction(okAction) alertController.addAction(okAction)
_ = self.coordinator.present( _ = self.coordinator.present(
scene: .alertController(alertController: alertController), scene: .alertController(alertController: alertController),
@ -758,11 +761,76 @@ extension ProfileViewController: ProfileHeaderViewControllerDelegate {
} }
.store(in: &disposeBag) .store(in: &disposeBag)
} }
} else { }
// guard let relationshipAction = relationshipActionSet.highPriorityAction(except: .editOptions) else { return }
private func editRelationship() {
guard let relationship = viewModel.relationship else { return } guard let relationship = viewModel.relationship else { return }
print(relationship) let account = viewModel.account
if relationship.blocking {
let name = account.displayNameWithFallback
let alertController = UIAlertController(
title: L10n.Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.title,
message: L10n.Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.message(name),
preferredStyle: .alert
)
let unblockAction = UIAlertAction(title: L10n.Common.Controls.Friendship.unblock, style: .default) { [weak self] _ in
guard let self else { return }
Task {
let newRelationship = try await DataSourceFacade.responseToUserBlockAction(
dependency: self,
account: account
)
self.viewModel.relationship = newRelationship
}
}
alertController.addAction(unblockAction)
let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel)
alertController.addAction(cancelAction)
coordinator.present(scene: .alertController(alertController: alertController), transition: .alertController(animated: true))
} else if relationship.muting {
let name = account.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.Friendship.unmute, style: .default) { [weak self] _ in
guard let self else { return }
Task {
let newRelationship = try await DataSourceFacade.responseToUserMuteAction(
dependency: self,
account: account
)
self.viewModel.relationship = newRelationship
}
}
alertController.addAction(unmuteAction)
let cancelAction = UIAlertAction(title: L10n.Common.Controls.Actions.cancel, style: .cancel)
alertController.addAction(cancelAction)
coordinator.present(scene: .alertController(alertController: alertController), transition: .alertController(animated: true))
} else {
Task { [weak self] in
guard let self else { return }
let newRelationship = try await DataSourceFacade.responseToUserFollowAction(
dependency: self,
account: viewModel.account
)
self.viewModel.relationship = newRelationship
// update account?
// update me?
}
}
// switch relationshipAction { // switch relationshipAction {
// case .none: // case .none:
// break // break
@ -776,56 +844,10 @@ extension ProfileViewController: ProfileHeaderViewControllerDelegate {
// ) // )
// } // }
// case .muting: // case .muting:
// guard let user = viewModel.user else { return }
// let name = user.displayNameWithFallback
//
// let alertController = UIAlertController(
// title: L10n.Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.title,
// message: L10n.Scene.Profile.RelationshipActionAlert.ConfirmUnmuteUser.message(name),
// preferredStyle: .alert
// )
// let record = ManagedObjectRecord<MastodonUser>(objectID: user.objectID)
// let unmuteAction = UIAlertAction(title: L10n.Common.Controls.Friendship.unmute, style: .default) { [weak self] _ in
// guard let self = self else { return }
// Task {
// try await DataSourceFacade.responseToUserMuteAction(
// dependency: self,
// user: record
// )
// }
// }
// 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 user = viewModel.user else { return }
// let name = user.displayNameWithFallback
//
// let alertController = UIAlertController(
// title: L10n.Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.title,
// message: L10n.Scene.Profile.RelationshipActionAlert.ConfirmUnblockUser.message(name),
// preferredStyle: .alert
// )
// let record = ManagedObjectRecord<MastodonUser>(objectID: user.objectID)
// let unblockAction = UIAlertAction(title: L10n.Common.Controls.Friendship.unblock, style: .default) { [weak self] _ in
// guard let self = self else { return }
// Task {
// try await DataSourceFacade.responseToUserBlockAction(
// dependency: self,
// user: record
// )
// }
// }
// 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, .showReblogs, .isMyself,.followingBy, .blockingBy, .suspended, .edit, .editing, .updating: // case .blocked, .showReblogs, .isMyself,.followingBy, .blockingBy, .suspended, .edit, .editing, .updating:
// break // break
// } // }
} }
}
func profileHeaderViewController( func profileHeaderViewController(
_ profileHeaderViewController: ProfileHeaderViewController, _ profileHeaderViewController: ProfileHeaderViewController,

View File

@ -108,7 +108,7 @@ extension ReportResultViewController {
guard !self.viewModel.isRequestMute else { return } guard !self.viewModel.isRequestMute else { return }
self.viewModel.isRequestMute = true self.viewModel.isRequestMute = true
do { do {
try await DataSourceFacade.responseToUserMuteAction( _ = try await DataSourceFacade.responseToUserMuteAction(
dependency: self, dependency: self,
account: self.viewModel.account account: self.viewModel.account
) )
@ -128,9 +128,9 @@ extension ReportResultViewController {
guard !self.viewModel.isRequestBlock else { return } guard !self.viewModel.isRequestBlock else { return }
self.viewModel.isRequestBlock = true self.viewModel.isRequestBlock = true
do { do {
try await DataSourceFacade.responseToUserBlockAction( _ = try await DataSourceFacade.responseToUserBlockAction(
dependency: self, dependency: self,
user: self.viewModel.account account: self.viewModel.account
) )
} catch { } catch {
// handle error // handle error

View File

@ -147,7 +147,7 @@ extension Persistence.MastodonUser {
let me = context.me let me = context.me
user.update(isFollowing: relationship.following, by: me) user.update(isFollowing: relationship.following, by: me)
relationship.requested.flatMap { user.update(isFollowRequested: $0, by: me) } user.update(isFollowRequested: relationship.requested, by: me)
// relationship.endorsed.flatMap { user.update(isEndorsed: $0, by: me) } // relationship.endorsed.flatMap { user.update(isEndorsed: $0, by: me) }
me.update(isFollowing: relationship.followedBy, by: user) me.update(isFollowing: relationship.followedBy, by: user)
user.update(isMuting: relationship.muting, by: me) user.update(isMuting: relationship.muting, by: me)

View File

@ -64,51 +64,7 @@ extension APIService {
account: Mastodon.Entity.Account, account: Mastodon.Entity.Account,
authenticationBox: MastodonAuthenticationBox authenticationBox: MastodonAuthenticationBox
) async throws -> Mastodon.Response.Content<Mastodon.Entity.Relationship> { ) async throws -> Mastodon.Response.Content<Mastodon.Entity.Relationship> {
guard let relationship = try await relationship(forAccounts: [account], authenticationBox: authenticationBox).value.first else {
guard let me = authenticationBox.authentication.account(),
let relationship = try await relationship(forAccounts: [account], authenticationBox: authenticationBox).value.first
else { throw APIError.implicit(.badRequest) }
let blockContext = MastodonBlockContext(
sourceUserID: me.id,
targetUserID: account.id,
targetUsername: account.username,
isBlocking: relationship.blocking,
isFollowing: relationship.following
)
let result: Result<Mastodon.Response.Content<Mastodon.Entity.Relationship>, Error>
do {
if blockContext.isBlocking {
let response = try await Mastodon.API.Account.unblock(
session: session,
domain: authenticationBox.domain,
accountID: blockContext.targetUserID,
authorization: authenticationBox.userAuthorization
).singleOutput()
result = .success(response)
} else {
let response = try await Mastodon.API.Account.block(
session: session,
domain: authenticationBox.domain,
accountID: blockContext.targetUserID,
authorization: authenticationBox.userAuthorization
).singleOutput()
result = .success(response)
}
} catch {
result = .failure(error)
}
let response = try result.get()
return response
}
public func toggleBlock(
user: Mastodon.Entity.Account,
authenticationBox: MastodonAuthenticationBox
) async throws -> Mastodon.Response.Content<Mastodon.Entity.Relationship> {
guard let relationship = try await relationship(forAccounts: [user], authenticationBox: authenticationBox).value.first else {
throw APIError.implicit(.badRequest) throw APIError.implicit(.badRequest)
} }
@ -118,14 +74,14 @@ extension APIService {
response = try await Mastodon.API.Account.unblock( response = try await Mastodon.API.Account.unblock(
session: session, session: session,
domain: authenticationBox.domain, domain: authenticationBox.domain,
accountID: user.id, accountID: account.id,
authorization: authenticationBox.userAuthorization authorization: authenticationBox.userAuthorization
).singleOutput() ).singleOutput()
} else { } else {
response = try await Mastodon.API.Account.block( response = try await Mastodon.API.Account.block(
session: session, session: session,
domain: authenticationBox.domain, domain: authenticationBox.domain,
accountID: user.id, accountID: account.id,
authorization: authenticationBox.userAuthorization authorization: authenticationBox.userAuthorization
).singleOutput() ).singleOutput()
} }

View File

@ -22,7 +22,7 @@ extension Mastodon.Entity {
/// Are you following this user? /// Are you following this user?
public let following: Bool public let following: Bool
/// Do you have a pending follow request for this user? /// Do you have a pending follow request for this user?
public let requested: Bool? public let requested: Bool
/// Are you featuring this user on your profile? /// Are you featuring this user on your profile?
public let endorsed: Bool public let endorsed: Bool
/// Are you followed by this user? /// Are you followed by this user?

View File

@ -87,7 +87,7 @@ extension ProfileRelationshipActionButton {
setTitle(title, for: .normal) setTitle(title, for: .normal)
if relationship.blocking || account.suspended ?? false { if relationship.blockedBy || account.suspended ?? false {
isEnabled = false isEnabled = false
} else { } else {
isEnabled = true isEnabled = true