Add relationship to ProfileViewModel (IOS-192)

This commit is contained in:
Nathan Mattes 2023-12-14 16:14:16 +01:00
parent 16250b440d
commit 6aea178609
11 changed files with 59 additions and 107 deletions

View File

@ -107,11 +107,14 @@ final public class SceneCoordinator {
notificationID: notificationID,
authenticationBox: authContext.mastodonAuthenticationBox
).value.account
let relationship = try await appContext.apiService.relationship(forAccounts: [account], authenticationBox: authContext.mastodonAuthenticationBox).value.first
let profileViewModel = ProfileViewModel(
context: appContext,
authContext: authContext,
account: account
account: account,
relationship: relationship
)
_ = self.present(
scene: .profile(viewModel: profileViewModel),

View File

@ -102,17 +102,23 @@ extension DataSourceFacade {
account: Mastodon.Entity.Account
) {
let profileViewModel = ProfileViewModel(
context: provider.context,
authContext: provider.authContext,
account: account
)
_ = provider.coordinator.present(
scene: .profile(viewModel: profileViewModel),
from: provider,
transition: .show
)
Task { @MainActor in
guard 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
)
_ = provider.coordinator.present(
scene: .profile(viewModel: profileViewModel),
from: provider,
transition: .show
)
}
}
}

View File

@ -296,16 +296,7 @@ extension NotificationTimelineViewController: TableViewControllerNavigateable {
)
} else {
let profileViewModel = ProfileViewModel(
context: self.context,
authContext: self.viewModel.authContext,
account: notification.account
)
_ = self.coordinator.present(
scene: .profile(viewModel: profileViewModel),
from: self,
transition: .show
)
DataSourceFacade.coordinateToProfileScene(provider: self, account: notification.account)
}
default:
break

View File

@ -56,10 +56,12 @@ class ProfileViewModel: NSObject {
// let needsPagePinToTop = CurrentValueSubject<Bool, Never>(false)
@MainActor
init(context: AppContext, authContext: AuthContext, account: Mastodon.Entity.Account) {
init(context: AppContext, authContext: AuthContext, account: Mastodon.Entity.Account, relationship: Mastodon.Entity.Relationship?) {
self.context = context
self.authContext = authContext
self.account = account
self.relationship = relationship
self.postsUserTimelineViewModel = UserTimelineViewModel(
context: context,
authContext: authContext,

View File

@ -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)
_viewController.viewModel = ProfileViewModel(context: context, authContext: authContext, account: me, relationship: nil)
viewController = _viewController
}
viewController.title = self.title

View File

@ -2,13 +2,18 @@
import UIKit
import MastodonSDK
import MastodonCore
protocol AboutInstanceViewControllerDelegate: AnyObject {
func showAdminAccount(_ viewController: AboutInstanceViewController, account: Mastodon.Entity.Account)
func sendEmailToAdmin(_ viewController: AboutInstanceViewController, emailAddress: String)
}
class AboutInstanceViewController: UIViewController {
class AboutInstanceViewController: UIViewController, NeedsDependency, AuthContextProvider {
var authContext: AuthContext
var context: AppContext!
var coordinator: SceneCoordinator!
weak var delegate: AboutInstanceViewControllerDelegate?
var dataSource: AboutInstanceTableViewDataSource?
@ -19,7 +24,12 @@ class AboutInstanceViewController: UIViewController {
var instance: Mastodon.Entity.V2.Instance?
init() {
init(context: AppContext, authContext: AuthContext, coordinator: SceneCoordinator) {
self.context = context
self.authContext = authContext
self.coordinator = coordinator
tableView = UITableView(frame: .zero, style: .insetGrouped)
tableView.translatesAutoresizingMaskIntoConstraints = false
tableView.register(ContactAdminTableViewCell.self, forCellReuseIdentifier: ContactAdminTableViewCell.reuseIdentifier)

View File

@ -4,6 +4,7 @@ import UIKit
import MastodonSDK
import MastodonLocalization
import MetaTextKit
import MastodonCore
enum ServerDetailsTab: Int, CaseIterable {
case about = 0
@ -36,7 +37,7 @@ class ServerDetailsViewController: UIViewController {
let instanceRulesViewController: InstanceRulesViewController
let containerView: UIView
init(domain: String) {
init(domain: String, appContext: AppContext, authContext: AuthContext, sceneCoordinator: SceneCoordinator) {
segmentedControl = UISegmentedControl()
segmentedControl.translatesAutoresizingMaskIntoConstraints = false
@ -47,7 +48,7 @@ class ServerDetailsViewController: UIViewController {
containerView = UIView()
containerView.translatesAutoresizingMaskIntoConstraints = false
aboutInstanceViewController = AboutInstanceViewController()
aboutInstanceViewController = AboutInstanceViewController(context: appContext, authContext: authContext, coordinator: sceneCoordinator)
instanceRulesViewController = InstanceRulesViewController()
pageController = UIPageViewController(transitionStyle: .scroll, navigationOrientation: .horizontal)

View File

@ -70,7 +70,7 @@ extension SettingsCoordinator: SettingsViewControllerDelegate {
navigationController.pushViewController(notificationViewController, animated: true)
case .serverDetails(let domain):
let serverDetailsViewController = ServerDetailsViewController(domain: domain)
let serverDetailsViewController = ServerDetailsViewController(domain: domain, appContext: appContext, authContext: authContext, sceneCoordinator: sceneCoordinator)
serverDetailsViewController.delegate = self
appContext.apiService.instanceV2(domain: domain)
@ -217,8 +217,7 @@ extension SettingsCoordinator: ServerDetailsViewControllerDelegate {
extension SettingsCoordinator: AboutInstanceViewControllerDelegate {
@MainActor func showAdminAccount(_ viewController: AboutInstanceViewController, account: Mastodon.Entity.Account) {
let profileViewModel = ProfileViewModel(context: appContext, authContext: authContext, account: account)
sceneCoordinator.present(scene: .profile(viewModel: profileViewModel), transition: .show)
DataSourceFacade.coordinateToProfileScene(provider: viewController, account: account)
}
func sendEmailToAdmin(_ viewController: AboutInstanceViewController, emailAddress: String) {

View File

@ -146,10 +146,16 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
authenticationBox: authenticationBox
).value.accounts.first else { return }
guard let relationship = try await AppContext.shared.apiService.relationship(
forAccounts: [account],
authenticationBox: authenticationBox
).value.first else { return }
let profileViewModel = ProfileViewModel(
context: AppContext.shared,
authContext: authContext,
account: account
account: account,
relationship: relationship
)
_ = self.coordinator?.present(
scene: .profile(viewModel: profileViewModel),
@ -284,11 +290,18 @@ extension SceneDelegate {
authenticationBox: authenticationBox
).value.accounts.first else { return }
guard let relationship = try await AppContext.shared.apiService.relationship(
forAccounts: [account],
authenticationBox: authenticationBox
).value.first else { return }
let profileViewModel = ProfileViewModel(
context: AppContext.shared,
authContext: authContext,
account: account
account: account,
relationship: relationship
)
self.coordinator?.present(
scene: .profile(viewModel: profileViewModel),
from: nil,

View File

@ -12,60 +12,6 @@ import CoreDataStack
import MastodonSDK
extension APIService {
public func relationship(
records: [ManagedObjectRecord<MastodonUser>],
authenticationBox: MastodonAuthenticationBox
) async throws -> Mastodon.Response.Content<[Mastodon.Entity.Relationship]> {
let managedObjectContext = backgroundManagedObjectContext
let _query: Mastodon.API.Account.RelationshipQuery? = try? await managedObjectContext.perform {
var ids: [String] = []
for record in records {
guard let user = record.object(in: managedObjectContext) else { continue }
guard user.id != authenticationBox.userID else { continue }
ids.append(user.id)
}
guard !ids.isEmpty else { return nil }
return Mastodon.API.Account.RelationshipQuery(ids: ids)
}
guard let query = _query else {
throw APIError.implicit(.badRequest)
}
let response = try await Mastodon.API.Account.relationships(
session: session,
domain: authenticationBox.domain,
query: query,
authorization: authenticationBox.userAuthorization
).singleOutput()
try await managedObjectContext.performChanges {
guard let me = authenticationBox.authentication.user(in: managedObjectContext) else {
// assertionFailure()
return
}
let relationships = response.value
for record in records {
guard let user = record.object(in: managedObjectContext) else { continue }
guard let relationship = relationships.first(where: { $0.id == user.id }) else { continue }
Persistence.MastodonUser.update(
mastodonUser: user,
context: Persistence.MastodonUser.RelationshipContext(
entity: relationship,
me: me,
networkDate: response.networkDate
)
)
} // end for in
}
return response
}
public func relationship(
forAccounts accounts: [Mastodon.Entity.Account],
authenticationBox: MastodonAuthenticationBox

View File

@ -24,25 +24,6 @@ extension APIService {
query: query,
authorization: authorization
).singleOutput()
let managedObjectContext = self.backgroundManagedObjectContext
try await managedObjectContext.performChanges {
let me = authenticationBox.authentication.user(in: managedObjectContext)
// user
for entity in response.value.accounts {
_ = Persistence.MastodonUser.createOrMerge(
in: managedObjectContext,
context: Persistence.MastodonUser.PersistContext(
domain: domain,
entity: entity,
cache: nil,
networkDate: response.networkDate
)
)
}
} // ent try await managedObjectContext.performChanges { }
return response
}