Skip to content

Commit

Permalink
Merge pull request wordpress-mobile#21056 from wordpress-mobile/task/…
Browse files Browse the repository at this point in the history
…20783-social-cell-view-model

Jetpack Social: Add view model for the pre-publishing social cell
  • Loading branch information
dvdchr authored Jul 12, 2023
2 parents 656d68f + 840bb35 commit 84eeabc
Show file tree
Hide file tree
Showing 2 changed files with 147 additions and 32 deletions.
177 changes: 146 additions & 31 deletions WordPress/Classes/ViewRelated/Post/PrepublishingAutoSharingView.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,59 +2,68 @@ import SwiftUI

struct PrepublishingAutoSharingView: View {

// TODO: view model.
let model: PrepublishingAutoSharingViewModel

var body: some View {
HStack {
textStack
Spacer()
iconTrain
if model.connections.count > 0 {
socialIconsView
}
}
}

var textStack: some View {
VStack(alignment: .leading) {
Text(String(format: Strings.primaryLabelActiveConnectionsFormat, 3))
private var textStack: some View {
VStack(alignment: .leading, spacing: .zero) {
Text(model.labelText)
.font(.body)
.foregroundColor(Color(.label))
Text(String(format: Strings.remainingSharesTextFormat, 27, 30))
.font(.subheadline)
.foregroundColor(Color(.secondaryLabel))
if let sharingLimit = model.sharingLimit {
remainingSharesView(sharingLimit: sharingLimit, showsWarning: model.showsWarning)
}
}
}

// TODO: This will be implemented separately.
var iconTrain: some View {
HStack {
if let uiImage = UIImage(named: "icon-tumblr") {
Image(uiImage: uiImage)
private func remainingSharesView(sharingLimit: PublicizeInfo.SharingLimit, showsWarning: Bool) -> some View {
HStack(spacing: 4.0) {
if showsWarning {
Image("icon-warning")
.resizable()
.frame(width: 32.0, height: 32.0)
.background(Color(UIColor.listForeground))
.clipShape(Circle())
.overlay(Circle().stroke(Color(UIColor.listForeground), lineWidth: 2.0))
.frame(width: 16.0, height: 16.0)
.padding(4.0)
}
Text(String(format: Constants.remainingSharesTextFormat, sharingLimit.remaining, sharingLimit.limit))
.font(.subheadline)
.foregroundColor(Color(showsWarning ? Constants.warningColor : .secondaryLabel))
}
}

private var socialIconsView: some View {
HStack(spacing: -2.0) {
ForEach(model.connections, id: \.self) { connection in
iconImage(connection.serviceName.localIconImage, opaque: connection.enabled)
}
}
}

private func iconImage(_ uiImage: UIImage, opaque: Bool) -> some View {
Image(uiImage: uiImage)
.resizable()
.frame(width: 28.0, height: 28.0)
.opacity(opaque ? 1.0 : Constants.disabledSocialIconOpacity)
.background(Color(.listForeground))
.clipShape(Circle())
}
}

// MARK: - Helpers
// MARK: - View Helpers

private extension PrepublishingAutoSharingView {

enum Strings {
static let primaryLabelActiveConnectionsFormat = NSLocalizedString(
"prepublishing.social.text.activeConnections",
value: "Sharing to %1$d accounts",
comment: """
The primary label for the auto-sharing row on the pre-publishing sheet.
Indicates the number of social accounts that will be auto-sharing the blog post.
%1$d is a placeholder for the number of social network accounts that will be auto-shared.
Example: Sharing to 3 accounts
"""
)

// TODO: More text variations.
enum Constants {
static let disabledSocialIconOpacity: CGFloat = 0.36
static let warningColor = UIColor.muriel(color: MurielColor(name: .yellow, shade: .shade50))

static let remainingSharesTextFormat = NSLocalizedString(
"prepublishing.social.remainingShares",
Expand All @@ -68,5 +77,111 @@ private extension PrepublishingAutoSharingView {
"""
)
}
}

// MARK: - View Model

/// The value-type data model that drives the `PrepublishingAutoSharingView`.
struct PrepublishingAutoSharingViewModel {

struct Connection: Hashable {
let serviceName: PublicizeService.ServiceName
let account: String
let enabled: Bool
}

// TODO: Default values are for temporary testing purposes. Will be removed later.
let connections: [Connection] = [.init(serviceName: .facebook, account: "foo", enabled: true),
.init(serviceName: .twitter, account: "bar", enabled: false),
.init(serviceName: .tumblr, account: "baz", enabled: true)]

// TODO: Default values are for temporary testing purposes. Will be removed later.
let sharingLimit: PublicizeInfo.SharingLimit? = .init(remaining: 1, limit: 30)

var enabledConnectionsCount: Int {
connections.filter({ $0.enabled }).count
}

var showsWarning: Bool {
guard let remaining = sharingLimit?.remaining else {
return false
}
return enabledConnectionsCount > remaining
}

var labelText: String {
switch (enabledConnectionsCount, connections.count) {
case (let enabled, _) where enabled == 0:
// not sharing to any social media
return Strings.notSharingText

case (let enabled, let total) where enabled == total && total == 1:
// sharing to the one and only connection
guard let account = connections.first?.account else {
return String()
}
return String(format: Strings.singleConnectionTextFormat, account)

case (let enabled, let total) where enabled == total && total > 1:
// sharing to all connections
return String(format: Strings.multipleConnectionsTextFormat, enabled)

case (let enabled, let total) where enabled < total && total > 1:
// sharing to some connections
return String(format: Strings.partialConnectionsTextFormat, enabled, total)

default:
return String()
}
}
}

private extension PrepublishingAutoSharingViewModel {

enum Strings {
static let notSharingText = NSLocalizedString(
"prepublishing.social.label.notSharing",
value: "Not sharing to social",
comment: """
The primary label for the auto-sharing row on the pre-publishing sheet.
Indicates the blog post will not be shared to any social accounts.
"""
)

static let singleConnectionTextFormat = NSLocalizedString(
"prepublishing.social.label.singleConnection",
value: "Sharing to %1$@",
comment: """
The primary label for the auto-sharing row on the pre-publishing sheet.
Indicates the blog post will be shared to a social media account.
%1$@ is a placeholder for the account name.
Example: Sharing to @wordpress
"""
)

static let multipleConnectionsTextFormat = NSLocalizedString(
"prepublishing.social.label.multipleConnections",
value: "Sharing to %1$d accounts",
comment: """
The primary label for the auto-sharing row on the pre-publishing sheet.
Indicates the number of social accounts that will be sharing the blog post.
%1$d is a placeholder for the number of social network accounts that will be auto-shared.
Example: Sharing to 3 accounts
"""
)

static let partialConnectionsTextFormat = NSLocalizedString(
"prepublishing.social.label.partialConnections",
value: "Sharing to %1$d of %2$d accounts",
comment: """
The primary label for the auto-sharing row on the pre-publishing sheet.
Indicates the number of social accounts that will be sharing the blog post.
This string is displayed when some of the social accounts are turned off for auto-sharing.
%1$d is a placeholder for the number of social media accounts that will be sharing the blog post.
%2$d is a placeholder for the total number of social media accounts connected to the user's blog.
Example: Sharing to 2 of 3 accounts
"""
)
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ extension PrepublishingViewController {
// TODO:
// - Show the NoConnectionView if user has 0 connections.
// - Properly create and configure the view models.
let autoSharingView = UIView.embedSwiftUIView(PrepublishingAutoSharingView())
let autoSharingView = UIView.embedSwiftUIView(PrepublishingAutoSharingView(model: .init()))
cell.contentView.addSubview(autoSharingView)

// Pin constraints to the cell's layoutMarginsGuide so that the content is properly aligned.
Expand Down

0 comments on commit 84eeabc

Please sign in to comment.