Configure Profile-button based on relationship and accounts (IOS-192)
Also `me` is not optional anymore as we need it
This commit is contained in:
parent
393722a31d
commit
76304e59e5
|
@ -98,6 +98,7 @@ final public class SceneCoordinator {
|
|||
// show notification related content
|
||||
guard let type = Mastodon.Entity.Notification.NotificationType(rawValue: pushNotification.notificationType) else { return }
|
||||
guard let authContext = self.authContext else { return }
|
||||
guard let me = authContext.mastodonAuthenticationBox.authentication.account() else { return }
|
||||
let notificationID = String(pushNotification.notificationID)
|
||||
|
||||
switch type {
|
||||
|
@ -114,7 +115,8 @@ final public class SceneCoordinator {
|
|||
context: appContext,
|
||||
authContext: authContext,
|
||||
account: account,
|
||||
relationship: relationship
|
||||
relationship: relationship,
|
||||
me: me
|
||||
)
|
||||
_ = self.present(
|
||||
scene: .profile(viewModel: profileViewModel),
|
||||
|
|
|
@ -104,13 +104,15 @@ extension DataSourceFacade {
|
|||
|
||||
Task { @MainActor in
|
||||
|
||||
guard let relationship = try? await provider.context.apiService.relationship(forAccounts: [account], authenticationBox: provider.authContext.mastodonAuthenticationBox).value.first else { return }
|
||||
guard let me = provider.authContext.mastodonAuthenticationBox.authentication.account(),
|
||||
let relationship = try? await provider.context.apiService.relationship(forAccounts: [account], authenticationBox: provider.authContext.mastodonAuthenticationBox).value.first else { return }
|
||||
|
||||
let profileViewModel = ProfileViewModel(
|
||||
context: provider.context,
|
||||
authContext: provider.authContext,
|
||||
account: account,
|
||||
relationship: relationship
|
||||
relationship: relationship,
|
||||
me: me
|
||||
)
|
||||
|
||||
_ = provider.coordinator.present(
|
||||
|
|
|
@ -82,11 +82,11 @@ final class ProfileHeaderViewController: UIViewController, NeedsDependency, Medi
|
|||
return documentPickerController
|
||||
}()
|
||||
|
||||
init(context: AppContext, authContext: AuthContext, account: Mastodon.Entity.Account, coordinator: SceneCoordinator) {
|
||||
init(context: AppContext, authContext: AuthContext, coordinator: SceneCoordinator, profileViewModel: ProfileViewModel) {
|
||||
self.context = context
|
||||
self.coordinator = coordinator
|
||||
self.viewModel = ProfileHeaderViewModel(context: context, authContext: authContext, account: account)
|
||||
self.profileHeaderView = ProfileHeaderView(account: account)
|
||||
self.viewModel = ProfileHeaderViewModel(context: context, authContext: authContext, account: profileViewModel.account, me: profileViewModel.me, relationship: profileViewModel.relationship)
|
||||
self.profileHeaderView = ProfileHeaderView(account: profileViewModel.account, me: profileViewModel.me, relationship: profileViewModel.relationship)
|
||||
|
||||
super.init(nibName: nil, bundle: nil)
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ final class ProfileHeaderViewModel {
|
|||
let context: AppContext
|
||||
let authContext: AuthContext
|
||||
|
||||
@Published var me: Mastodon.Entity.Account
|
||||
@Published var account: Mastodon.Entity.Account
|
||||
@Published var relationship: Mastodon.Entity.Relationship?
|
||||
|
||||
|
@ -44,10 +45,12 @@ final class ProfileHeaderViewModel {
|
|||
@Published var isTitleViewDisplaying = false
|
||||
@Published var isTitleViewContentOffsetSet = false
|
||||
|
||||
init(context: AppContext, authContext: AuthContext, account: Mastodon.Entity.Account) {
|
||||
init(context: AppContext, authContext: AuthContext, account: Mastodon.Entity.Account, me: Mastodon.Entity.Account, relationship: Mastodon.Entity.Relationship?) {
|
||||
self.context = context
|
||||
self.authContext = authContext
|
||||
self.account = account
|
||||
self.me = me
|
||||
self.relationship = relationship
|
||||
|
||||
$accountForEdit
|
||||
.receive(on: DispatchQueue.main)
|
||||
|
|
|
@ -46,13 +46,16 @@ extension ProfileHeaderView {
|
|||
|
||||
@Published var fields: [MastodonField] = []
|
||||
|
||||
@Published var me: Mastodon.Entity.Account
|
||||
@Published var account: Mastodon.Entity.Account
|
||||
@Published var relationship: Mastodon.Entity.Relationship?
|
||||
@Published var isRelationshipActionButtonHidden = false
|
||||
@Published var isMyself = false
|
||||
|
||||
init(account: Mastodon.Entity.Account) {
|
||||
init(account: Mastodon.Entity.Account, me: Mastodon.Entity.Account, relationship: Mastodon.Entity.Relationship?) {
|
||||
self.account = account
|
||||
self.me = me
|
||||
self.relationship = relationship
|
||||
|
||||
#warning("TODO: Implement")
|
||||
// $relationshipActionOptionSet
|
||||
|
@ -103,7 +106,8 @@ extension ProfileHeaderView.ViewModel {
|
|||
// follows you
|
||||
Publishers.CombineLatest($relationship, $isMyself)
|
||||
.map { relationship, isMyself in
|
||||
(relationship?.following ?? false) && (isMyself == false) }
|
||||
return (relationship?.following ?? false) && (isMyself == false)
|
||||
}
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { isFollowing in
|
||||
view.followsYouBlurEffectView.isHidden = (isFollowing == false)
|
||||
|
@ -196,7 +200,9 @@ extension ProfileHeaderView.ViewModel {
|
|||
|
||||
Publishers.CombineLatest($relationship, $account)
|
||||
.compactMap { relationship, account in
|
||||
|
||||
guard let relationship else { return nil }
|
||||
|
||||
let isBlocking = relationship.blocking
|
||||
let isBlockedBy = relationship.blockedBy ?? false
|
||||
let isSuspended = account.suspended ?? false
|
||||
|
@ -263,13 +269,17 @@ extension ProfileHeaderView.ViewModel {
|
|||
.assign(to: \.isHidden, on: view.relationshipActionButtonShadowContainer)
|
||||
.store(in: &disposeBag)
|
||||
#warning("TODO: Implement")
|
||||
// Publishers.CombineLatest2(
|
||||
// $relationshipActionOptionSet,
|
||||
// $isEditing,
|
||||
// $isUpdating
|
||||
// )
|
||||
// .receive(on: DispatchQueue.main)
|
||||
// .sink { relationshipActionOptionSet, isEditing, isUpdating in
|
||||
Publishers.CombineLatest3(
|
||||
Publishers.CombineLatest3($me, $account, $relationship).eraseToAnyPublisher(),
|
||||
$isEditing,
|
||||
$isUpdating
|
||||
)
|
||||
.receive(on: DispatchQueue.main)
|
||||
.sink { tuple, isEditing, isUpdating in
|
||||
let (me, account, relationship) = tuple
|
||||
guard let relationship else { return }
|
||||
|
||||
view.relationshipActionButton.configure(relationship: relationship, between: account, and: me, isEditing: isEditing, isUpdating: isUpdating)
|
||||
// if relationshipActionOptionSet.contains(.edit) {
|
||||
// // check .edit state and set .editing when isEditing
|
||||
// view.relationshipActionButton.configure(actionOptionSet: isUpdating ? .updating : (isEditing ? .editing : .edit))
|
||||
|
@ -277,8 +287,8 @@ extension ProfileHeaderView.ViewModel {
|
|||
// } else {
|
||||
// view.relationshipActionButton.configure(actionOptionSet: relationshipActionOptionSet)
|
||||
// }
|
||||
// }
|
||||
// .store(in: &disposeBag)
|
||||
}
|
||||
.store(in: &disposeBag)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -235,9 +235,9 @@ final class ProfileHeaderView: UIView {
|
|||
return metaText
|
||||
}()
|
||||
|
||||
init(account: Mastodon.Entity.Account) {
|
||||
init(account: Mastodon.Entity.Account, me: Mastodon.Entity.Account, relationship: Mastodon.Entity.Relationship?) {
|
||||
|
||||
viewModel = ViewModel(account: account)
|
||||
viewModel = ViewModel(account: account, me: me, relationship: relationship)
|
||||
|
||||
super.init(frame: .zero)
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ final class ProfileViewController: UIViewController, NeedsDependency, MediaPrevi
|
|||
private(set) lazy var tabBarPagerController = TabBarPagerController()
|
||||
|
||||
private(set) lazy var profileHeaderViewController: ProfileHeaderViewController = {
|
||||
let viewController = ProfileHeaderViewController(context: context, authContext: authContext, account: viewModel.account, coordinator: coordinator)
|
||||
let viewController = ProfileHeaderViewController(context: context, authContext: authContext, coordinator: coordinator, profileViewModel: viewModel)
|
||||
return viewController
|
||||
}()
|
||||
|
||||
|
@ -691,7 +691,7 @@ extension ProfileViewController: ProfileHeaderViewControllerDelegate {
|
|||
#warning("TODO: Implement")
|
||||
// handle edit logic for editable profile
|
||||
// handle relationship logic for non-editable profile
|
||||
if let me = viewModel.me, me == viewModel.account {
|
||||
if viewModel.me == viewModel.account {
|
||||
// // do nothing when updating
|
||||
guard !viewModel.isUpdating else { return }
|
||||
|
||||
|
@ -706,12 +706,13 @@ extension ProfileViewController: ProfileHeaderViewControllerDelegate {
|
|||
Task { @MainActor in
|
||||
do {
|
||||
// TODO: handle error
|
||||
_ = try await viewModel.updateProfileInfo(
|
||||
let updatedAccount = try await viewModel.updateProfileInfo(
|
||||
headerProfileInfo: profileHeaderViewModel.profileInfoEditing,
|
||||
aboutProfileInfo: profileAboutViewModel.profileInfoEditing
|
||||
)
|
||||
).value
|
||||
self.viewModel.isEditing = false
|
||||
|
||||
self.viewModel.account = updatedAccount
|
||||
|
||||
} catch {
|
||||
let alertController = UIAlertController(
|
||||
for: error,
|
||||
|
|
|
@ -34,7 +34,7 @@ class ProfileViewModel: NSObject {
|
|||
let context: AppContext
|
||||
let authContext: AuthContext
|
||||
|
||||
@Published var me: Mastodon.Entity.Account?
|
||||
@Published var me: Mastodon.Entity.Account
|
||||
@Published var account: Mastodon.Entity.Account
|
||||
@Published var relationship: Mastodon.Entity.Relationship?
|
||||
|
||||
|
@ -56,11 +56,12 @@ class ProfileViewModel: NSObject {
|
|||
// let needsPagePinToTop = CurrentValueSubject<Bool, Never>(false)
|
||||
|
||||
@MainActor
|
||||
init(context: AppContext, authContext: AuthContext, account: Mastodon.Entity.Account, relationship: Mastodon.Entity.Relationship?) {
|
||||
init(context: AppContext, authContext: AuthContext, account: Mastodon.Entity.Account, relationship: Mastodon.Entity.Relationship?, me: Mastodon.Entity.Account) {
|
||||
self.context = context
|
||||
self.authContext = authContext
|
||||
self.account = account
|
||||
self.relationship = relationship
|
||||
self.me = me
|
||||
|
||||
self.postsUserTimelineViewModel = UserTimelineViewModel(
|
||||
context: context,
|
||||
|
@ -82,9 +83,6 @@ class ProfileViewModel: NSObject {
|
|||
)
|
||||
self.profileAboutViewModel = ProfileAboutViewModel(context: context, account: account)
|
||||
super.init()
|
||||
|
||||
// bind me
|
||||
self.me = authContext.mastodonAuthenticationBox.authentication.account()
|
||||
|
||||
// bind user
|
||||
$account
|
||||
|
@ -176,7 +174,7 @@ class ProfileViewModel: NSObject {
|
|||
|
||||
// fetch profile info before edit
|
||||
func fetchEditProfileInfo() -> AnyPublisher<Mastodon.Response.Content<Mastodon.Entity.Account>, Error> {
|
||||
guard let me, let domain = me.domain else {
|
||||
guard let domain = me.domain else {
|
||||
return Fail(error: APIService.APIError.implicit(.authenticationMissing)).eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
|
|
|
@ -119,7 +119,7 @@ class MainTabBarController: UITabBarController {
|
|||
let _viewController = ProfileViewController()
|
||||
_viewController.context = context
|
||||
_viewController.coordinator = coordinator
|
||||
_viewController.viewModel = ProfileViewModel(context: context, authContext: authContext, account: me, relationship: nil)
|
||||
_viewController.viewModel = ProfileViewModel(context: context, authContext: authContext, account: me, relationship: nil, me: me)
|
||||
viewController = _viewController
|
||||
}
|
||||
viewController.title = self.title
|
||||
|
|
|
@ -141,6 +141,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||
let domain = authContext.mastodonAuthenticationBox.domain
|
||||
let authenticationBox = authContext.mastodonAuthenticationBox
|
||||
|
||||
guard let me = authenticationBox.authentication.account() else { return }
|
||||
|
||||
guard let account = try await AppContext.shared.apiService.search(
|
||||
query: .init(q: incomingURL.absoluteString, type: .accounts, resolve: true),
|
||||
authenticationBox: authenticationBox
|
||||
|
@ -155,7 +157,8 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
|
|||
context: AppContext.shared,
|
||||
authContext: authContext,
|
||||
account: account,
|
||||
relationship: relationship
|
||||
relationship: relationship,
|
||||
me: me
|
||||
)
|
||||
_ = self.coordinator?.present(
|
||||
scene: .profile(viewModel: profileViewModel),
|
||||
|
@ -285,6 +288,8 @@ extension SceneDelegate {
|
|||
let domain = authContext.mastodonAuthenticationBox.domain
|
||||
let authenticationBox = authContext.mastodonAuthenticationBox
|
||||
|
||||
guard let me = authContext.mastodonAuthenticationBox.authentication.account() else { return }
|
||||
|
||||
guard let account = try await AppContext.shared.apiService.search(
|
||||
query: .init(q: components[1], type: .accounts, resolve: true),
|
||||
authenticationBox: authenticationBox
|
||||
|
@ -299,7 +304,8 @@ extension SceneDelegate {
|
|||
context: AppContext.shared,
|
||||
authContext: authContext,
|
||||
account: account,
|
||||
relationship: relationship
|
||||
relationship: relationship,
|
||||
me: me
|
||||
)
|
||||
|
||||
self.coordinator?.present(
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
import UIKit
|
||||
import MastodonAsset
|
||||
import MastodonSDK
|
||||
import MastodonLocalization
|
||||
|
||||
public final class ProfileRelationshipActionButton: RoundedEdgesButton {
|
||||
|
@ -55,6 +56,32 @@ extension ProfileRelationshipActionButton {
|
|||
}
|
||||
|
||||
extension ProfileRelationshipActionButton {
|
||||
|
||||
public func configure(relationship: Mastodon.Entity.Relationship, between user: Mastodon.Entity.Account, and me: Mastodon.Entity.Account, isEditing: Bool = false, isUpdating: Bool = false) {
|
||||
|
||||
let isMyself = (user == me)
|
||||
let title: String
|
||||
|
||||
if isMyself {
|
||||
if isEditing {
|
||||
title = "SAVE"
|
||||
} else {
|
||||
title = "EDIT"
|
||||
}
|
||||
} else if relationship.following {
|
||||
title = L10n.Common.Controls.Friendship.follow
|
||||
} else {
|
||||
title = "TITLE"
|
||||
}
|
||||
setTitle(title, for: .normal)
|
||||
|
||||
if relationship.blocking || user.suspended ?? false {
|
||||
isEnabled = false
|
||||
} else {
|
||||
isEnabled = true
|
||||
}
|
||||
}
|
||||
|
||||
public func configure(actionOptionSet: RelationshipActionOptionSet) {
|
||||
setTitle(actionOptionSet.title, for: .normal)
|
||||
|
||||
|
|
Loading…
Reference in New Issue