Skip to content

Commit

Permalink
Merge pull request wordpress-mobile#21074 from wordpress-mobile/task/…
Browse files Browse the repository at this point in the history
…20783-prepublishing-no-social-connection
  • Loading branch information
dvdchr authored Jul 13, 2023
2 parents 300547d + b0850b0 commit 4431ec7
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -34,16 +34,16 @@ struct JetpackSocialNoConnectionView: View {
}
}
.padding(viewModel.padding)
.background(Color(UIColor.listForeground))
.background(Color(viewModel.preferredBackgroundColor))
}

func iconImage(_ image: UIImage) -> some View {
Image(uiImage: image)
.resizable()
.frame(width: 32.0, height: 32.0)
.background(Color(UIColor.listForeground))
.background(Color(viewModel.preferredBackgroundColor))
.clipShape(Circle())
.overlay(Circle().stroke(Color(UIColor.listForeground), lineWidth: 2.0))
.overlay(Circle().stroke(Color(viewModel.preferredBackgroundColor), lineWidth: 2.0))
}
}

Expand All @@ -53,7 +53,7 @@ extension JetpackSocialNoConnectionView {
static func createHostController(with viewModel: JetpackSocialNoConnectionViewModel = JetpackSocialNoConnectionViewModel()) -> UIHostingController<JetpackSocialNoConnectionView> {
let hostController = UIHostingController(rootView: JetpackSocialNoConnectionView(viewModel: viewModel))
hostController.view.translatesAutoresizingMaskIntoConstraints = false
hostController.view.backgroundColor = .listForeground
hostController.view.backgroundColor = viewModel.preferredBackgroundColor
return hostController
}
}
Expand All @@ -63,17 +63,20 @@ extension JetpackSocialNoConnectionView {
class JetpackSocialNoConnectionViewModel: ObservableObject {
let padding: EdgeInsets
let hideNotNow: Bool
let preferredBackgroundColor: UIColor
let onConnectTap: (() -> Void)?
let onNotNowTap: (() -> Void)?
@MainActor @Published var icons: [UIImage] = [UIImage()]

init(services: [PublicizeService] = [],
padding: EdgeInsets = Constants.defaultPadding,
hideNotNow: Bool = false,
preferredBackgroundColor: UIColor? = nil,
onConnectTap: (() -> Void)? = nil,
onNotNowTap: (() -> Void)? = nil) {
self.padding = padding
self.hideNotNow = hideNotNow
self.preferredBackgroundColor = preferredBackgroundColor ?? Constants.defaultBackgroundColor
self.onConnectTap = onConnectTap
self.onNotNowTap = onNotNowTap
updateIcons(services)
Expand Down Expand Up @@ -118,6 +121,7 @@ class JetpackSocialNoConnectionViewModel: ObservableObject {

private struct Constants {
static let defaultPadding = EdgeInsets(top: 16.0, leading: 16.0, bottom: 24.0, trailing: 16.0)
static let defaultBackgroundColor = UIColor.listForeground
static let bodyText = NSLocalizedString("social.noconnection.body",
value: "Increase your traffic by auto-sharing your posts with your friends on social media.",
comment: "Body text for the Jetpack Social no connection view")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -84,29 +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) { $0 || $1.enabled }
}

var enabledConnections: [Connection] {
connections.filter { $0.enabled }
}
}

struct Connection: Hashable {
let account: String
let enabled: Bool
}

// MARK: Properties

let services: [Service]
Expand Down Expand Up @@ -154,6 +131,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 {
Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -12,26 +14,46 @@ 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)
}
}
}

// MARK: - Helper Methods

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<PublicizeConnection> 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,
Expand Down Expand Up @@ -70,4 +92,35 @@ 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 {
let context = post.managedObjectContext ?? coreDataStack.mainContext
guard let services = try? PublicizeService.allSupportedServices(in: context) else {
return .init()
}

// TODO: Tap actions
return .init(services: services, preferredBackgroundColor: tableView.backgroundColor)
}

enum Constants {
static let socialCellBackgroundColor = UIColor(light: .listForeground, dark: .listBackground)
}
}

0 comments on commit 4431ec7

Please sign in to comment.