From bd6c67181087c6ebe55e1b4bb4c387a94a636b24 Mon Sep 17 00:00:00 2001 From: David Christiandy <1299411+dvdchr@users.noreply.github.com> Date: Wed, 12 Jul 2023 17:01:18 +0700 Subject: [PATCH] Show NoConnectionView for eligible sites with 0 connections --- .../Post/PrepublishingAutoSharingView.swift | 50 ++++++------ ...blishingViewController+JetpackSocial.swift | 80 ++++++++++++++++--- 2 files changed, 92 insertions(+), 38 deletions(-) diff --git a/WordPress/Classes/ViewRelated/Post/PrepublishingAutoSharingView.swift b/WordPress/Classes/ViewRelated/Post/PrepublishingAutoSharingView.swift index 93f1150a7de9..f43c959b9d4d 100644 --- a/WordPress/Classes/ViewRelated/Post/PrepublishingAutoSharingView.swift +++ b/WordPress/Classes/ViewRelated/Post/PrepublishingAutoSharingView.swift @@ -84,31 +84,6 @@ private extension PrepublishingAutoSharingView { /// The value-type data model that drives the `PrepublishingAutoSharingView`. struct PrepublishingAutoSharingViewModel { - // MARK: Helper Models - - /// A value-type representation of `PublicizeService` that's simplified for the needs of the auto-sharing view. - struct Service: Hashable { - let serviceName: PublicizeService.ServiceName - let connections: [Connection] - - /// Whether the icon for this service should be opaque or transparent. - /// If at least one account is enabled, an opaque version should be shown. - var usesOpaqueIcon: Bool { - connections.reduce(false) { partialResult, connection in - return partialResult || connection.enabled - } - } - - var enabledConnections: [Connection] { - connections.filter { $0.enabled } - } - } - - struct Connection: Hashable { - let account: String - let enabled: Bool - } - // MARK: Properties let services: [Service] @@ -160,6 +135,31 @@ struct PrepublishingAutoSharingViewModel { return String() } } + + // MARK: Helper Models + + /// A value-type representation of `PublicizeService` that's simplified for the needs of the auto-sharing view. + struct Service: Hashable { + let serviceName: PublicizeService.ServiceName + let connections: [Connection] + + /// Whether the icon for this service should be opaque or transparent. + /// If at least one account is enabled, an opaque version should be shown. + var usesOpaqueIcon: Bool { + connections.reduce(false) { partialResult, connection in + return partialResult || connection.enabled + } + } + + var enabledConnections: [Connection] { + connections.filter { $0.enabled } + } + } + + struct Connection: Hashable { + let account: String + let enabled: Bool + } } private extension PrepublishingAutoSharingViewModel { diff --git a/WordPress/Classes/ViewRelated/Post/PrepublishingViewController+JetpackSocial.swift b/WordPress/Classes/ViewRelated/Post/PrepublishingViewController+JetpackSocial.swift index a8c13b5fe175..df57694a9618 100644 --- a/WordPress/Classes/ViewRelated/Post/PrepublishingViewController+JetpackSocial.swift +++ b/WordPress/Classes/ViewRelated/Post/PrepublishingViewController+JetpackSocial.swift @@ -1,3 +1,5 @@ +/// Encapsulates logic related to Jetpack Social in the pre-publishing sheet. +/// extension PrepublishingViewController { /// Determines whether the account and the post's blog is eligible to see auto-sharing options. @@ -12,19 +14,11 @@ extension PrepublishingViewController { } func configureSocialCell(_ cell: UITableViewCell) { - // TODO: - // - Show the NoConnectionView if user has 0 connections. - let autoSharingView = UIView.embedSwiftUIView(PrepublishingAutoSharingView(model: makeAutoSharingViewModel())) - cell.contentView.addSubview(autoSharingView) - - // Pin constraints to the cell's layoutMarginsGuide so that the content is properly aligned. - NSLayoutConstraint.activate([ - autoSharingView.leadingAnchor.constraint(equalTo: cell.contentView.layoutMarginsGuide.leadingAnchor), - autoSharingView.topAnchor.constraint(equalTo: cell.contentView.layoutMarginsGuide.topAnchor), - autoSharingView.bottomAnchor.constraint(equalTo: cell.contentView.layoutMarginsGuide.bottomAnchor), - autoSharingView.trailingAnchor.constraint(equalTo: cell.contentView.layoutMarginsGuide.trailingAnchor) - ]) - cell.accessoryType = .disclosureIndicator // TODO: only for autoSharingView. + if hasExistingConnections { + configureAutoSharingView(for: cell) + } else { + configureNoConnectionView(for: cell) + } } } @@ -32,6 +26,34 @@ extension PrepublishingViewController { private extension PrepublishingViewController { + var hasExistingConnections: Bool { + coreDataStack.performQuery { [postObjectID = post.objectID] context in + guard let post = (try? context.existingObject(with: postObjectID)) as? Post, + let connections = post.blog.connections as? Set else { + return false + } + return !connections.isEmpty + } + } + + // MARK: Auto Sharing View + + func configureAutoSharingView(for cell: UITableViewCell) { + let viewModel = makeAutoSharingViewModel() + let viewToEmbed = UIView.embedSwiftUIView(PrepublishingAutoSharingView(model: viewModel)) + cell.contentView.addSubview(viewToEmbed) + + // Pin constraints to the cell's layoutMarginsGuide so that the content is properly aligned. + NSLayoutConstraint.activate([ + viewToEmbed.leadingAnchor.constraint(equalTo: cell.contentView.layoutMarginsGuide.leadingAnchor), + viewToEmbed.topAnchor.constraint(equalTo: cell.contentView.layoutMarginsGuide.topAnchor), + viewToEmbed.bottomAnchor.constraint(equalTo: cell.contentView.layoutMarginsGuide.bottomAnchor), + viewToEmbed.trailingAnchor.constraint(equalTo: cell.contentView.layoutMarginsGuide.trailingAnchor) + ]) + + cell.accessoryType = .disclosureIndicator + } + func makeAutoSharingViewModel() -> PrepublishingAutoSharingViewModel { return coreDataStack.performQuery { [postObjectID = post.objectID] context in guard let post = (try? context.existingObject(with: postObjectID)) as? Post, @@ -70,4 +92,36 @@ private extension PrepublishingViewController { } } + // MARK: - No Connection View + + func configureNoConnectionView(for cell: UITableViewCell) { + let viewModel = makeNoConnectionViewModel() + guard let viewToEmbed = JetpackSocialNoConnectionView.createHostController(with: viewModel).view else { + return + } + + cell.contentView.addSubview(viewToEmbed) + cell.contentView.pinSubviewToSafeArea(viewToEmbed) + } + + func makeNoConnectionView() -> UIView { + let viewModel = makeNoConnectionViewModel() + let controller = JetpackSocialNoConnectionView.createHostController(with: viewModel) + return controller.view + } + + func makeNoConnectionViewModel() -> JetpackSocialNoConnectionViewModel { + return coreDataStack.performQuery { [weak self] context in + guard let services = try? PublicizeService.allSupportedServices(in: context) else { + return .init() + } + + // TODO: Tap actions + return .init(services: services, preferredBackgroundColor: self?.tableView.backgroundColor) + } + } + + enum Constants { + static let socialCellBackgroundColor = UIColor(light: .listForeground, dark: .listBackground) + } }