diff --git a/MIGRATIONS.md b/MIGRATIONS.md index fea896c1bdc3..cfa402cc5560 100644 --- a/MIGRATIONS.md +++ b/MIGRATIONS.md @@ -3,6 +3,10 @@ This file documents changes in the data model. Please explain any changes to the data model as well as any custom migrations. +## WordPress 77 +- @aerych 2018-07-27 +- `SharingService` added `externalUsersOnly` (bool) property. A new field returned by the API. + ## WordPress 76 - @frosty 2018-05-16 diff --git a/Podfile b/Podfile index 402cf8a8f5ee..477d6b46af81 100644 --- a/Podfile +++ b/Podfile @@ -23,7 +23,7 @@ def shared_with_networking_pods pod 'AFNetworking', '3.2.1' pod 'Alamofire', '4.7.2' pod 'wpxmlrpc', '0.8.3' - pod 'WordPressKit', '~> 1.2' + pod 'WordPressKit', '1.2.1' end def shared_test_pods diff --git a/Podfile.lock b/Podfile.lock index d1cb8069784f..c5cb0d31fddb 100644 --- a/Podfile.lock +++ b/Podfile.lock @@ -119,7 +119,7 @@ PODS: - WordPressShared (~> 1.0) - WordPressUI (~> 1.0) - wpxmlrpc (~> 0.8) - - WordPressKit (1.2): + - WordPressKit (1.2.1): - Alamofire (~> 4.7) - CocoaLumberjack (= 3.4.2) - NSObject-SafeExpectations (= 0.0.3) @@ -167,7 +167,7 @@ DEPENDENCIES: - WordPress-Aztec-iOS (= 1.0.0-beta.24) - WordPress-Editor-iOS (= 1.0.0-beta.24) - WordPressAuthenticator (= 1.0.4) - - WordPressKit (~> 1.2) + - WordPressKit (= 1.2.1) - WordPressShared (= 1.0.9) - WordPressUI (from `https://github.com/wordpress-mobile/WordPressUI-iOS.git`, commit `7a5b1a3fb44f62416fbc2e5f0de623b87b613aae`) - WPMediaPicker (= 1.1) @@ -256,13 +256,13 @@ SPEC CHECKSUMS: WordPress-Aztec-iOS: b019a2ee94d7a7c300b463776b5009682cd13e9c WordPress-Editor-iOS: d110040c64267ab002c3551cc343b8dfe6f59f3a WordPressAuthenticator: 2825f0c56f83a17470564dbec427991fa5cac5af - WordPressKit: 68eaa8df5ceedeed03ba796afc4b825f0bed4fe2 + WordPressKit: a4a3849684f631a3abf579f6d3f15a32677cbb30 WordPressShared: e5ea8a1ed3329735e40bd6623830960f63dd10fd WordPressUI: af141587ec444f9af753a00605bd0d3f14d8d8a3 WPMediaPicker: 5cc9386a4720f906d8fb79c7c4090d216b9f2348 wpxmlrpc: bfc572f62ce7ee897f6f38b098d2ba08732ecef4 ZendeskSDK: 2cda4db2ba6b10ba89aeb8dddaa94e97c85946a0 -PODFILE CHECKSUM: 2234776d14f86b13e13804654ce8178d74ac866d +PODFILE CHECKSUM: 6c257291bab7089dda9372c0fc53feda5f8b5f3a COCOAPODS: 1.5.3 diff --git a/WordPress/Classes/Models/PublicizeConnection.swift b/WordPress/Classes/Models/PublicizeConnection.swift index bcd11ed39db2..cf0be9c6db1a 100644 --- a/WordPress/Classes/Models/PublicizeConnection.swift +++ b/WordPress/Classes/Models/PublicizeConnection.swift @@ -28,4 +28,16 @@ open class PublicizeConnection: NSManagedObject { @objc open func isBroken() -> Bool { return status == "broken" } + + @objc open func mustDisconnect() -> Bool { + return status == "must-disconnect" + } + + @objc open func requiresUserAction() -> Bool { + return isBroken() || mustDisconnect() + } + + @objc open func mustDisconnectFacebook() -> Bool { + return mustDisconnect() && service == PublicizeService.facebookServiceID + } } diff --git a/WordPress/Classes/Models/PublicizeService.swift b/WordPress/Classes/Models/PublicizeService.swift index a5532d5b93fe..a11ea153b9f8 100644 --- a/WordPress/Classes/Models/PublicizeService.swift +++ b/WordPress/Classes/Models/PublicizeService.swift @@ -3,9 +3,11 @@ import CoreData open class PublicizeService: NSManagedObject { @objc static let googlePlusServiceID = "google_plus" + @objc static let facebookServiceID = "facebook" @NSManaged open var connectURL: String @NSManaged open var detail: String + @NSManaged open var externalUsersOnly: Bool @NSManaged open var icon: String @NSManaged open var jetpackSupport: Bool @NSManaged open var jetpackModuleRequired: String diff --git a/WordPress/Classes/Services/SharingService.swift b/WordPress/Classes/Services/SharingService.swift index a9069b1362ce..77a42704a5b7 100644 --- a/WordPress/Classes/Services/SharingService.swift +++ b/WordPress/Classes/Services/SharingService.swift @@ -358,6 +358,7 @@ open class SharingService: LocalCoreDataService { } pubService?.connectURL = remoteService.connectURL pubService?.detail = remoteService.detail + pubService?.externalUsersOnly = remoteService.externalUsersOnly pubService?.icon = remoteService.icon pubService?.jetpackModuleRequired = remoteService.jetpackModuleRequired pubService?.jetpackSupport = remoteService.jetpackSupport diff --git a/WordPress/Classes/ViewRelated/Blog/SharingAccountViewController.swift b/WordPress/Classes/ViewRelated/Blog/SharingAccountViewController.swift index 012b600e97d6..28dddb932b8c 100644 --- a/WordPress/Classes/ViewRelated/Blog/SharingAccountViewController.swift +++ b/WordPress/Classes/ViewRelated/Blog/SharingAccountViewController.swift @@ -12,6 +12,15 @@ import WordPressShared @objc var immutableHandler: ImmuTableViewHandler! @objc var delegate: SharingAccountSelectionDelegate? + fileprivate lazy var noResultsViewController: NoResultsViewController = { + let controller = NoResultsViewController.controller() + controller.view.frame = view.frame + addChildViewController(controller) + view.addSubview(controller.view) + controller.didMove(toParentViewController: self) + return controller + }() + // MARK: - Lifecycle Methods @@ -72,6 +81,25 @@ import WordPressShared } + fileprivate func showNoResultsViewController() { + let title = NSLocalizedString("No Accounts Found", + comment: "Title of an error message. There were no third-party service accounts found to setup sharing.") + let message = NSLocalizedString("Sorry. The social service did not tell us which account could be used for sharing.", + comment: "An error message shown if a third-party social service does not specify any accounts that an be used with publicize sharing.") + noResultsViewController.configure(title: title, buttonTitle: nil, subtitle: message, image: nil, accessoryView: nil) + } + + + fileprivate func showFacebookNotice() { + let message = NSLocalizedString("The Facebook connection could not be made because this account does not have access to any pages. Facebook supports sharing connections to Facebook Pages, but not to Facebook Profiles.", + comment: "Error message shown to a user who is trying to share to Facebook but does not have any available Facebook Pages.") + + let buttonTitle = NSLocalizedString("Learn more", comment: "A button title.") + noResultsViewController.configure(title: "", buttonTitle: buttonTitle, subtitle: message, image: nil, accessoryView: nil) + noResultsViewController.delegate = self + } + + // MARK: - View Model Wrangling @@ -84,6 +112,15 @@ import WordPressShared var connectedAccounts = [KeyringAccount]() var accounts = keyringAccountsFromKeyringConnections(keyringConnections) + if accounts.count == 0 { + if publicizeService.serviceID == PublicizeService.facebookServiceID { + showFacebookNotice() + } else { + showNoResultsViewController() + } + return ImmuTable(sections: []) + } + // Filter out connected accounts into a different Array for (idx, acct) in accounts.enumerated() { if accountIsConnected(acct) { @@ -196,7 +233,11 @@ import WordPressShared for connection in connections { let acct = KeyringAccount(name: connection.externalDisplay, externalID: nil, externalIDForConnection: connection.externalID, keyringConnection: connection) - accounts.append(acct) + + // Do not include the service if it only supports external users. + if !publicizeService.externalUsersOnly { + accounts.append(acct) + } for externalUser in connection.additionalExternalUsers { let acct = KeyringAccount(name: externalUser.externalName, externalID: externalUser.externalID, externalIDForConnection: externalUser.externalID, keyringConnection: connection) @@ -283,3 +324,13 @@ import WordPressShared func didDismissSharingAccountViewController(_ controller: SharingAccountViewController) func sharingAccountViewController(_ controller: SharingAccountViewController, selectedKeyringConnection keyringConnection: KeyringConnection, externalID: String?) } + + +extension SharingAccountViewController: NoResultsViewControllerDelegate { + func actionButtonPressed() { + if let url = URL(string: "https://en.support.wordpress.com/publicize/#facebook-pages") { + UIApplication.shared.open(url) + } + dismiss(animated: true, completion: nil) + } +} diff --git a/WordPress/Classes/ViewRelated/Blog/SharingConnectionsViewController.m b/WordPress/Classes/ViewRelated/Blog/SharingConnectionsViewController.m index 58cf3b33084e..a4eecdc249be 100644 --- a/WordPress/Classes/ViewRelated/Blog/SharingConnectionsViewController.m +++ b/WordPress/Classes/ViewRelated/Blog/SharingConnectionsViewController.m @@ -196,7 +196,7 @@ - (void)configurePublicizeCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath PublicizeConnection *connection = [[self connectionsForService] objectAtIndex:indexPath.row]; cell.textLabel.text = connection.externalDisplay; - if ([connection isBroken]) { + if ([connection requiresUserAction]) { cell.accessoryView = [WPStyleGuide sharingCellWarningAccessoryImageView]; } } diff --git a/WordPress/Classes/ViewRelated/Blog/SharingDetailViewController.m b/WordPress/Classes/ViewRelated/Blog/SharingDetailViewController.m index b99c81fca7f3..922ced0a20fc 100644 --- a/WordPress/Classes/ViewRelated/Blog/SharingDetailViewController.m +++ b/WordPress/Classes/ViewRelated/Blog/SharingDetailViewController.m @@ -60,6 +60,46 @@ - (void)viewDidLoad #pragma mark - Instance Methods +- (void)openFacebookFAQ +{ + NSURL *url = [NSURL URLWithString:@"https://en.blog.wordpress.com/2018/07/23/sharing-options-from-wordpress-com-to-facebook-are-changing/"]; + [[UIApplication sharedApplication] openURL:url options:[NSDictionary new] completionHandler:nil]; +} + +- (NSString *)textForFacebookFooter +{ + NSString *title = NSLocalizedString(@"As of August 1, 2018, Facebook no longer allows direct sharing of posts to Facebook Profiles. Connections to Facebook Pages remain unchanged.", @"Message shown to users who have an old publicize connection to a facebook profile."); + return [NSString stringWithFormat:title, self.publicizeConnection.label]; +} + +- (NSString *)textForBrokenConnectionFooter +{ + NSString *title = NSLocalizedString(@"There is an issue connecting to %@. Reconnect to continue publicizing.", @"Informs the user about an issue connecting to the third-party sharing service. The `%@` is a placeholder for the service name."); + return [NSString stringWithFormat:title, self.publicizeConnection.label]; +} + +- (void)configureReconnectCell: (UITableViewCell *)cell +{ + cell.textLabel.text = NSLocalizedString(@"Reconnect", @"Verb. Text label. Tapping attempts to reconnect a third-party sharing service to the user's blog."); + [WPStyleGuide configureTableViewActionCell:cell]; + cell.textLabel.textAlignment = NSTextAlignmentCenter; + cell.textLabel.textColor = [WPStyleGuide jazzyOrange]; +} + +- (void)configureLearnMoreCell: (UITableViewCell *)cell +{ + cell.textLabel.text = NSLocalizedString(@"Learn More", @"Title of a button. Tapping allows the user to learn more about the specific error."); + [WPStyleGuide configureTableViewActionCell:cell]; + cell.textLabel.textAlignment = NSTextAlignmentCenter; + cell.textLabel.textColor = [WPStyleGuide wordPressBlue]; +} + +- (void)configureDisconnectCell: (UITableViewCell *)cell +{ + cell.textLabel.text = NSLocalizedString(@"Disconnect", @"Verb. Text label. Tapping disconnects a third-party sharing service from the user's blog."); + [WPStyleGuide configureTableViewDestructiveActionCell:cell]; +} + - (NSManagedObjectContext *)managedObjectContext { return self.blog.managedObjectContext; @@ -70,7 +110,7 @@ - (NSManagedObjectContext *)managedObjectContext - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { - if ([self.publicizeConnection isBroken]) { + if ([self.publicizeConnection requiresUserAction]) { return 3; } @@ -96,10 +136,17 @@ - (NSString *)tableView:(UITableView *)tableView titleForFooterInSection:(NSInte if (section == 0) { return NSLocalizedString(@"Allow this connection to be used by all admins and users of your site.", @""); } - if (section == 1 && [self.publicizeConnection isBroken]) { - NSString *title = NSLocalizedString(@"There is an issue connecting to %@. Reconnect to continue publicizing.", @"Informs the user about an issue connecting to the third-party sharing service. The `%@` is a placeholder for the service name."); - return [NSString stringWithFormat:title, self.publicizeConnection.label]; + + if (section == 1) { + if ([self.publicizeConnection mustDisconnectFacebook]) { + return [self textForFacebookFooter]; + } + + if ([self.publicizeConnection isBroken]) { + return [self textForBrokenConnectionFooter]; + } } + return nil; } @@ -120,14 +167,13 @@ - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(N cell = [self switchTableViewCell]; } else if (indexPath.section == 1 && [self.publicizeConnection isBroken]) { - cell.textLabel.text = NSLocalizedString(@"Reconnect", @"Verb. Text label. Tapping attempts to reconnect a third-party sharing service to the user's blog."); - [WPStyleGuide configureTableViewActionCell:cell]; - cell.textLabel.textAlignment = NSTextAlignmentCenter; - cell.textLabel.textColor = [WPStyleGuide jazzyOrange]; + [self configureReconnectCell:cell]; + + } else if (indexPath.section == 1 && [self.publicizeConnection mustDisconnectFacebook]) { + [self configureLearnMoreCell:cell]; } else { - cell.textLabel.text = NSLocalizedString(@"Disconnect", @"Verb. Text label. Tapping disconnects a third-party sharing service from the user's blog."); - [WPStyleGuide configureTableViewDestructiveActionCell:cell]; + [self configureDisconnectCell:cell]; } return cell; @@ -139,7 +185,8 @@ - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath if (indexPath.section == 1 && [self.publicizeConnection isBroken]) { [self reconnectPublicizeConnection]; - + } else if (indexPath.section == 1 && [self.publicizeConnection mustDisconnectFacebook]) { + [self openFacebookFAQ]; } else { [self promptToConfirmDisconnect]; } diff --git a/WordPress/Classes/ViewRelated/Blog/SharingViewController.m b/WordPress/Classes/ViewRelated/Blog/SharingViewController.m index 3c23e9762b49..e4307cccd5ba 100644 --- a/WordPress/Classes/ViewRelated/Blog/SharingViewController.m +++ b/WordPress/Classes/ViewRelated/Blog/SharingViewController.m @@ -193,7 +193,7 @@ - (void)configurePublicizeCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath // Check if any of the connections are broken. for (PublicizeConnection *pubConn in connections) { - if ([pubConn isBroken]) { + if ([pubConn requiresUserAction]) { cell.accessoryView = [WPStyleGuide sharingCellWarningAccessoryImageView]; break; } diff --git a/WordPress/Classes/WordPress.xcdatamodeld/.xccurrentversion b/WordPress/Classes/WordPress.xcdatamodeld/.xccurrentversion index 099cde710486..cd0bfbbbbc89 100644 --- a/WordPress/Classes/WordPress.xcdatamodeld/.xccurrentversion +++ b/WordPress/Classes/WordPress.xcdatamodeld/.xccurrentversion @@ -3,6 +3,6 @@ _XCCurrentVersionName - WordPress 76.xcdatamodel + WordPress 77.xcdatamodel diff --git a/WordPress/Classes/WordPress.xcdatamodeld/WordPress 77.xcdatamodel/contents b/WordPress/Classes/WordPress.xcdatamodeld/WordPress 77.xcdatamodel/contents new file mode 100644 index 000000000000..81c556997fb5 --- /dev/null +++ b/WordPress/Classes/WordPress.xcdatamodeld/WordPress 77.xcdatamodel/contents @@ -0,0 +1,712 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/WordPress/WordPress.xcodeproj/project.pbxproj b/WordPress/WordPress.xcodeproj/project.pbxproj index 29bf6e144349..9926a832fd41 100644 --- a/WordPress/WordPress.xcodeproj/project.pbxproj +++ b/WordPress/WordPress.xcodeproj/project.pbxproj @@ -2824,6 +2824,7 @@ E6805D2F1DCD399600168E4F /* WPRichTextMediaAttachment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = WPRichTextMediaAttachment.swift; path = WPRichText/WPRichTextMediaAttachment.swift; sourceTree = ""; }; E68580F51E0D91470090EE63 /* WPHorizontalRuleAttachment.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = WPHorizontalRuleAttachment.swift; sourceTree = ""; }; E69551F51B8B6AE200CB8E4F /* ReaderStreamViewController+Helper.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "ReaderStreamViewController+Helper.swift"; sourceTree = ""; }; + E699E530210BB719008ED8A7 /* WordPress 77.xcdatamodel */ = {isa = PBXFileReference; lastKnownFileType = wrapper.xcdatamodel; path = "WordPress 77.xcdatamodel"; sourceTree = ""; }; E69BA1961BB5D7D300078740 /* WPStyleGuide+ReadableMargins.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "WPStyleGuide+ReadableMargins.h"; sourceTree = ""; }; E69BA1971BB5D7D300078740 /* WPStyleGuide+ReadableMargins.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "WPStyleGuide+ReadableMargins.m"; sourceTree = ""; }; E69EF9D21BFA539F00ED0554 /* ReaderDetailViewController.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = ReaderDetailViewController.swift; sourceTree = ""; }; @@ -10261,6 +10262,7 @@ E125443B12BF5A7200D87A0A /* WordPress.xcdatamodeld */ = { isa = XCVersionGroup; children = ( + E699E530210BB719008ED8A7 /* WordPress 77.xcdatamodel */, 17F2A5D020ACC70D00F0BE10 /* WordPress 76.xcdatamodel */, 17E553B520910791000D3005 /* WordPress 75.xcdatamodel */, FFEECFFE20875329009B8CDB /* WordPress 74.xcdatamodel */, @@ -10338,7 +10340,7 @@ 8350E15911D28B4A00A7B073 /* WordPress.xcdatamodel */, E125443D12BF5A7200D87A0A /* WordPress 2.xcdatamodel */, ); - currentVersion = 17F2A5D020ACC70D00F0BE10 /* WordPress 76.xcdatamodel */; + currentVersion = E699E530210BB719008ED8A7 /* WordPress 77.xcdatamodel */; name = WordPress.xcdatamodeld; path = Classes/WordPress.xcdatamodeld; sourceTree = "";