Skip to content

Add JetpackSocial module skeleton with models, strings, and assets#25537

Open
crazytonyli wants to merge 4 commits intotrunkfrom
task/jetpack-social-code-format
Open

Add JetpackSocial module skeleton with models, strings, and assets#25537
crazytonyli wants to merge 4 commits intotrunkfrom
task/jetpack-social-code-format

Conversation

@crazytonyli
Copy link
Copy Markdown
Contributor

Context: phcsdm-1z8-p2


Introduces a new JetpackSocial Swift package and registers it with the shared Modules/Package.swift and the Xcode plugin alias list.

Includes the wire-format models (SocialConnection, SocialService, SocialKeyringAccount, SocialKeyringConnection, ConnectionStatus, AdditionalExternalUser, SocialSharingError), the localized Strings catalog, and the publicize-* asset catalog used by the connection rows and service picker.

Registers JetpackSocialTests in WordPressUnitTests.xctestplan and adds unit tests covering the model layer.

Introduces a new JetpackSocial Swift package and registers it with the
shared Modules/Package.swift and the Xcode plugin alias list.

Includes the wire-format models (SocialConnection, SocialService,
SocialKeyringAccount, SocialKeyringConnection, ConnectionStatus,
AdditionalExternalUser, SocialSharingError), the localized Strings
catalog, and the publicize-* asset catalog used by the connection rows
and service picker.

Registers JetpackSocialTests in WordPressUnitTests.xctestplan and adds
unit tests covering the model layer.
@crazytonyli crazytonyli added this to the 26.9 milestone May 6, 2026
@crazytonyli crazytonyli requested review from jkmassel and mokagio May 6, 2026 03:26
@dangermattic
Copy link
Copy Markdown
Collaborator

2 Warnings
⚠️ Modules/Package.swift was changed without updating its corresponding Package.resolved.

If the change includes adding, removing, or editing a dependency please resolve the Swift packages as appropriate to your project setup (e.g. in Xcode or by running swift package resolve).

If the change to the Package.swift did not modify dependencies, ignoring this warning should be safe, but we recommend double checking and running the package resolution just in case.
.

⚠️ This PR is larger than 500 lines of changes. Please consider splitting it into smaller PRs for easier and faster reviews.

Generated by 🚫 Danger

@wpmobilebot
Copy link
Copy Markdown
Contributor

wpmobilebot commented May 6, 2026

App Icon📲 You can test the changes from this Pull Request in Jetpack by scanning the QR code below to install the corresponding build.
App NameJetpack
ConfigurationRelease-Alpha
Build Number32151
VersionPR #25537
Bundle IDcom.jetpack.alpha
Commitf636640
Installation URL6f7e73dr365vg
Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new JetpackSocial SwiftPM module to the shared Modules package, introducing initial “wire-to-model” mappings, localized string constants, and the icon assets needed for future Social Sharing UI, plus a new unit test target.

Changes:

  • Register JetpackSocial (library + test target) in Modules/Package.swift and add JetpackSocialTests to the shared unit test plan.
  • Add initial model layer types (connections, services, keyring accounts, status, errors) with mapping initializers from WordPressAPI wire responses.
  • Add Strings constants and a publicize-* icon asset catalog for connection rows / service picker.

Reviewed changes

Copilot reviewed 29 out of 42 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
Tests/KeystoneTests/WordPressUnitTests.xctestplan Adds JetpackSocialTests to the unit test plan.
Modules/Package.swift Registers JetpackSocial target + JetpackSocialTests and adds module to Xcode support list.
Modules/Tests/JetpackSocialTests/SocialSharingErrorTests.swift Tests SocialSharingError localized descriptions.
Modules/Tests/JetpackSocialTests/SocialServiceTests.swift Tests mapping from PublicizeServiceResponse to SocialService.
Modules/Tests/JetpackSocialTests/SocialKeyringConnectionTests.swift Tests mapping from KeyringConnectionResponse to SocialKeyringConnection.
Modules/Tests/JetpackSocialTests/SocialKeyringAccountTests.swift Tests SocialKeyringAccount.flatten behavior and ID composition.
Modules/Tests/JetpackSocialTests/SocialConnectionTests.swift Tests mapping/fallback logic from PublicizeConnectionResponse to SocialConnection.
Modules/Tests/JetpackSocialTests/ConnectionStatusTests.swift Tests ConnectionStatus wire mapping and isBroken.
Modules/Sources/JetpackSocial/Strings/Strings.swift Defines localized string keys + default fallback values for Social Sharing UI.
Modules/Sources/JetpackSocial/Models/SocialSharingError.swift Introduces SocialSharingError with LocalizedError descriptions.
Modules/Sources/JetpackSocial/Models/SocialService.swift Introduces SocialService model + wire mapping initializer.
Modules/Sources/JetpackSocial/Models/SocialKeyringConnection.swift Introduces SocialKeyringConnection model + wire mapping + fallback for empty display.
Modules/Sources/JetpackSocial/Models/SocialKeyringAccount.swift Adds flattened “account row” model derived from keyring connections.
Modules/Sources/JetpackSocial/Models/SocialConnection.swift Introduces SocialConnection model + wire mapping + display/handle fallbacks.
Modules/Sources/JetpackSocial/Models/ConnectionStatus.swift Adds connection status enum + wire mapping + broken/healthy classification.
Modules/Sources/JetpackSocial/Models/AdditionalExternalUser.swift Adds additional external user model + wire mapping.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/Contents.json Root asset catalog metadata for JetpackSocial icons.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-wordpress.imageset/Contents.json Registers WordPress service icon asset.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-wordpress.imageset/publicize-wordpress.pdf WordPress service icon PDF asset.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-twitter.imageset/Contents.json Registers Twitter service icon asset.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-twitter.imageset/publicize-twitter.svg Twitter service icon SVG asset.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-tumblr.imageset/Contents.json Registers Tumblr service icon asset (incl. dark appearance).
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-tumblr.imageset/publicize-tumblr.svg Tumblr service icon SVG asset.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-tumblr.imageset/publicize-tumblr-dark.svg Tumblr dark-mode icon SVG asset.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-threads.imageset/Contents.json Registers Threads service icon asset.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-threads.imageset/publicize-threads.png Threads service icon PNG asset.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-nextdoor.imageset/Contents.json Registers Nextdoor service icon asset.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-nextdoor.imageset/publicize-nextdoor.svg Nextdoor service icon SVG asset.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-mastodon.imageset/Contents.json Registers Mastodon service icon asset.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-mastodon.imageset/publicize-mastodon.svg Mastodon service icon SVG asset.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-linkedin.imageset/Contents.json Registers LinkedIn service icon asset.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-linkedin.imageset/publicize-linkedin.svg LinkedIn service icon SVG asset.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-instagram-business.imageset/Contents.json Registers Instagram Business service icon asset.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-instagram-business.imageset/publicize-instagram-business.svg Instagram Business icon SVG asset.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-google-plus.imageset/Contents.json Registers Google Plus legacy icon asset.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-google-plus.imageset/publicize-google-plus.pdf Google Plus legacy icon PDF asset.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-facebook.imageset/Contents.json Registers Facebook service icon asset.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-facebook.imageset/publicize-facebook.svg Facebook service icon SVG asset.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-default.imageset/Contents.json Registers default fallback service icon asset.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-default.imageset/publicize-default.pdf Default fallback icon PDF asset.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-bluesky.imageset/Contents.json Registers Bluesky service icon asset.
Modules/Sources/JetpackSocial/Resources/Icons.xcassets/publicize-bluesky.imageset/publicize-bluesky.svg Bluesky service icon SVG asset.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread Modules/Sources/JetpackSocial/Models/SocialSharingError.swift
Comment on lines +7 to +16
@Test("every case produces a non-empty localized description")
func everyCaseHasDescription() {
let cases: [SocialSharingError] = [
.network(NSError(domain: "t", code: 1)),
.notAuthenticated,
.connectionNotFound(id: "42"),
.keyringNotFound(id: 99),
.decoding(NSError(domain: "t", code: 2)),
.unknown(NSError(domain: "t", code: 3))
]
Comment thread Modules/Package.swift
Comment on lines +62 to +66
public static let footer = NSLocalizedString(
"jetpackSocial.manageConnections.footer",
value: "Connect your favourite social media services to automatically share new posts with friends.",
comment: "Footer caption under the list of services in the Connect Account picker modal."
)
@wpmobilebot
Copy link
Copy Markdown
Contributor

wpmobilebot commented May 6, 2026

App Icon📲 You can test the changes from this Pull Request in WordPress by scanning the QR code below to install the corresponding build.
App NameWordPress
ConfigurationRelease-Alpha
Build Number32151
VersionPR #25537
Bundle IDorg.wordpress.alpha
Commitf636640
Installation URL7q7un5d3hm2o8
Automatticians: You can use our internal self-serve MC tool to give yourself access to those builds if needed.

Comment on lines +8 to +32
public let supportsAdditionalUsers: Bool
public let isActive: Bool
public let connectURL: URL?

public init(
id: String,
label: String,
description: String,
supportsAdditionalUsers: Bool,
isActive: Bool,
connectURL: URL? = nil
) {
self.id = id
self.label = label
self.description = description
self.supportsAdditionalUsers = supportsAdditionalUsers
self.isActive = isActive
self.connectURL = connectURL
}

init(from wire: PublicizeServiceResponse) {
self.init(
id: wire.id,
label: wire.label,
description: wire.description,
Copy link
Copy Markdown
Contributor

@mokagio mokagio May 6, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note

Sent the PR to GPT first and Opus next to verify. Here's the only relevant comment. @crazytonyli was the slight change in domain model intentional?

The wire model exposes both wire.supports.additionalUsers and wire.supports.additionalUsersOnly (see PublicizeServiceSupports), but SocialService collapses them to a single supportsAdditionalUsers.

The pre-JetpackSocial sharing stack preserved that distinction:

The two bits aren't equivalent:

  • additionalUsers == true means “you can add more accounts under the parent keyring.”
  • additionalUsersOnly == true means “this service can only be reached as an additional user” (e.g. Facebook Pages, Instagram Business — there is no standalone primary connect path).

The service picker needs the second bit to suppress the primary “Connect” affordance for those services.
Dropping it here means downstream UI logic will either need a breaking model change later or will have to infer it from service IDs.
Worth keeping the field while the model layer is still new.


Posted by Claude (Opus 4.7) on behalf of @mokagio with approval.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a great finding, actually. I happened to find an issue caused by this during review this afternoon. f636640 adds the missing property, which will be used in a future PR.

Copy link
Copy Markdown
Contributor

@mokagio mokagio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For reference, here's the new tests running in CI

Image

The wire `PublicizeServiceSupports` exposes both `additionalUsers` and
`additionalUsersOnly`. The two are not equivalent: `additionalUsersOnly`
flags services like Facebook Pages or Instagram Business that can only
be reached via additional accounts under the keyring, never as the
keyring's primary external account. The legacy stack tracked this as
`externalUsersOnly` (RemotePublicizeService, PublicizeService) and the
account picker uses it to suppress the primary "Connect" affordance.
@crazytonyli crazytonyli requested a review from mokagio May 6, 2026 09:51
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants