Skip to content

Issues/update facebook sharing#9867

Closed
aerych wants to merge 13 commits intodevelopfrom
issues/update-facebook-sharing
Closed

Issues/update facebook sharing#9867
aerych wants to merge 13 commits intodevelopfrom
issues/update-facebook-sharing

Conversation

@aerych
Copy link
Contributor

@aerych aerych commented Jul 28, 2018

This is an 11th hour patch to address Facebook's privacy changes that affect publicize sharing to Facebook Profiles. As of August 1st, sharing to Facebook Profiles is no longer allowed.

This patch changes how Facebook sharing is handled so only sharing to Facebook Pages is supported. Attempting to share to a profile will result in a notice.
simulator screen shot - iphone 8 plus - 2018-07-28 at 15 50 48

An existing connection to a Facebook profile will show up as broken. On the detail page new messaging is shown.
simulator screen shot - iphone 8 plus - 2018-07-28 at 16 47 33

Clicking Learn More on either screen will open Safari to an FAQ. The destination is different for each button and should match the behavior in calypso.

To test:
You'll want a Facebook account to test with.

Scenario 1:
Attempt to set up a sharing connection to a Facebook profile. You should see the prompt that the connection could not be made because their are no pages.
Confirm clicking the Learn More button opens the support page in Safari.

Scenario 2:
Create a Facebook Page.
Attempt to set up sharing to Facebook again, and this time confirm that your newly created page is shown as an option. Go ahead and make the connection.

Scenario 3:
Edit SharingDetailViewController.m so mustDisconnectFacebook always returns true.
Navigate to the Facebook connection details screen and confirm that instead of a "Reconnect" option, you see a "Learn More" option and the appropriate footer text.
Confirm that the FAQ link opens in Safari.

FYI @loremattei

@ctarda could I trouble you for a review?

cc @kwonye who is wrangling the Android version of this patch.

@aerych aerych added the Sharing label Jul 28, 2018
@aerych aerych added this to the 10.6 milestone Jul 28, 2018
@aerych aerych requested review from ctarda and kwonye July 28, 2018 22:00


extension SharingAccountViewController: NoResultsViewControllerDelegate
{

Choose a reason for hiding this comment

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

Opening Brace Spacing Violation: Opening braces should be preceded by a single space and on the same line as the declaration. (opening_brace)

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.")

Choose a reason for hiding this comment

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

Colon Violation: Colons should be next to the identifier when specifying a type and next to the key in dictionary literals. (colon)


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.")

Choose a reason for hiding this comment

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

Colon Violation: Colons should be next to the identifier when specifying a type and next to the key in dictionary literals. (colon)

@wpmobilebot
Copy link
Contributor

wpmobilebot commented Jul 28, 2018

1 Warning
⚠️ PR has more than 500 lines of code changing. Consider splitting into smaller PRs if possible.

Generated by 🚫 Danger

@kwonye
Copy link
Contributor

kwonye commented Jul 29, 2018

@aerych I believe this should be merged into 10.5 as that's the build going to the app store tomorrow.


extension SharingAccountViewController: NoResultsViewControllerDelegate {
func actionButtonPressed() {
if let url = URL(string: "https://en.support.wordpress.com/publicize/#facebook-pages") {
Copy link
Contributor

Choose a reason for hiding this comment

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

@aerych do you think we should show the blog post instead?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This should match the behavior in Calypso where the support page is linked from the message shown when attempting to link a Facebook account with no pages. The blog post is linked from the message shown for a pre-existing connection that needs to be disconnected.

Unless I somehow got that backwards 😬

@aerych
Copy link
Contributor Author

aerych commented Jul 29, 2018

I believe this should be merged into 10.5 as that's the build going to the app store tomorrow.

This isn't really a trivial patch so I'm not too keen targeting 10.5. The changes include linking to updated pod(s) and adds a new model revision -- things that really need to go through the normal QA cycle.

@kwonye
Copy link
Contributor

kwonye commented Jul 29, 2018

This isn't really a trivial patch so I'm not too keen targeting 10.5. The changes include linking to updated pod(s) and adds a new model revision -- things that really need to go through the normal QA cycle.

@aerych totally fair, but I don't think we should wait the full two weeks to release this after the facebook change. We have 200+ people adding a connection a day (I don't know how many are facebook)

What do you think about a hotfix for 10.5.1 after testing for a couple days?

@aerych
Copy link
Contributor Author

aerych commented Jul 29, 2018

What do you think about a hotfix for 10.5.1 after testing for a couple days?

Sounds good.

@objc var immutableHandler: ImmuTableViewHandler!
@objc var delegate: SharingAccountSelectionDelegate?

lazy var noResultsViewController: NoResultsViewController = {
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it make sense to declare this var as private? Or do we really need it to be fully mutable?



fileprivate func showNoResultsViewController() {
let title = NSLocalizedString("No Accounts Found",
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a completely personal preference, but I tend to declare strings as constants (or as static cases in an enumeration), so that, at the call site, like here, it would read similar to this:

fileprivate func showNoResultsViewController() {
         noResultsViewController.configure(title: "", buttonTitle: NoResults.buttonTitle, subtitle: NoResults.message, image: nil, accessoryView: nil)
         noResultsViewController.delegate = self
}

I have found that makes the code slightly easier to parse for me. What do you think?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm a fan of that when a string is reused. When used only once I like declaring a string in the context of its usage as a way of having as much context as possible in one place.

var accounts = keyringAccountsFromKeyringConnections(keyringConnections)

if accounts.count == 0 {
if publicizeService.externalUsersOnly && publicizeService.serviceID == PublicizeService.facebookServiceID {
Copy link
Contributor

Choose a reason for hiding this comment

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

Would it make sense to encapsulate this boolean check in a method in PublicizeService, named in a way that provides a clear explanation of why we want to call showFacebookNotice()?

If I read this code, without any context, I don't really know what is going on. I mean, I can understand it, but I don't really understand why this boolean check is necessary, what is the meaning of it.

In a way, it's also leaking the abstraction a little bit. This view controller needs to know about the specific internal "state" of the PublicizeService, when it probably should not need to be aware of it.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Looking a bit closer at this. The publicizeService.externalUsersOnly is redundant here so we can remove it. This will make it a check for Facebook to see if it needs special handling which will hopefully make things a bit clearer.

cell.textLabel.text = connection.externalDisplay;

if ([connection isBroken]) {
if ([connection isBroken] || [connection mustDisconnect]) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I tend to encapsulate these boolean checks into a single method. In my experience, that makes the code more readable, in the long term, because it provides a name that can clearly explain what is happening and why it is important.

In this case, also, I think it might make sense to encapsulate that logic in the PublicizeConnection object as well, so this view controller does not need to know about isBroken and / or mustDisconnect.

What do you think?


- (BOOL)mustDisconnectFacebook
{
return [self.publicizeConnection mustDisconnect] && [[self.publicizeConnection service] isEqualToString: [PublicizeService facebookServiceID]];
Copy link
Contributor

Choose a reason for hiding this comment

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

Would this logic belong in the PublicizeConnection object?

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
if ([self.publicizeConnection isBroken]) {
if ([self.publicizeConnection isBroken] || [self mustDisconnectFacebook]) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This boolean check is also done in SharingConnectionsViewController. In my opinion, that also supports moving this logic to the PublicizeConnection object. In this case, also, this boolean check is split in between two classes: part of the logic is defined in the "connection" object, while another part of it is in the mustDisconnectFacebook method, which also pulls properties from the connection. What do you think?

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) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I would suggest extracting each logical branch to a separate method. That way titleForFooterInSection would be easier to read and parse, which might also make it. in the long term, more difficult to get wrong.

cell.textLabel.textAlignment = NSTextAlignmentCenter;
cell.textLabel.textColor = [WPStyleGuide jazzyOrange];
} else if (indexPath.section == 1) {
if ([self.publicizeConnection isBroken]) {
Copy link
Contributor

Choose a reason for hiding this comment

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

I would also suggest extracting each logical branch to a separate method, if possible. That would make this code easier to read, to begin with. Also, there seems to be an issue with this title (more in another comment), so making this code simpler to read might have the extra advantage of fixing that :)

// Check if any of the connections are broken.
for (PublicizeConnection *pubConn in connections) {
if ([pubConn isBroken]) {
if ([pubConn isBroken] || [pubConn mustDisconnect]) {
Copy link
Contributor

Choose a reason for hiding this comment

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

This seems to be the third different place where this boolean check is done, which, in my opinion, supports encapsulating it in the PublicizeConnetion object

@ctarda
Copy link
Contributor

ctarda commented Jul 30, 2018

Hi @aerych! Thanks for attacking this, and thanks also for thinking of me for the review.

The code looks great, I just have a made a few comments to trigger a couple of discussions. 😉

Scenario #1 works great.

Something seems to be slightly off in the "Learn More" button title for the other two scenarios though.

For the Scenario #2, I get a button with an empty label:

simulator screen shot - iphone 8 - 2018-07-30 at 10 24 23

And for Scenario #3, I get a "Reconnect" instead of "Learn More"

simulator screen shot - iphone 8 - 2018-07-30 at 10 26 09

I have tested the feature by upgrading from a previous build, but also after a clean install, and on both cases I get the same results

@aerych
Copy link
Contributor Author

aerych commented Jul 30, 2018

Well, that's embarrassing 😬. I see the issue with the missing button labels now. Not sure how I missed this before. Thanks for spotting it!

@aerych
Copy link
Contributor Author

aerych commented Jul 30, 2018

Hiya @ctarda ! Thanks for the review and suggestions. :) I think I've implemented the changes the way you intended but if I misunderstood let me know and I'll revise.

(The branching logic makes me wish refactoring the table views to use ImmuTable was in scope. It would make things clearer, I think. Something for a future revision.)

Ready for another peek!

@ctarda
Copy link
Contributor

ctarda commented Jul 30, 2018

Hi @aerych ! Thanks for taking the suggestions into consideration.

One thing that I've just noticed (it might be after the latest update, but I am not completely sure it wasn't there before) is that a pod update updates my local Podfile.lock, which I think should not happen.

When it comes to the functionality, something seems to be slightly off. Scenario 1 is always prompting that the connection could not be made because there are no pages (even though there are pages in the testing account I am using)

@aerych
Copy link
Contributor Author

aerych commented Jul 30, 2018

a pod update updates my local Podfile.lock, which I think should not happen.

Nicely spotted. It looks like the Podfile.lock comitted in 620ddb3 pointed to version 1.3, instead of 1.2.1. I've fixed the reference in a79505e

Scenario 1 is always prompting that the connection could not be made because there are no pages (even though there are pages in the testing account I am using)

Hmm... I'm not sure what this could be. This is what I'm seeing with my test Facebook account with a single Facebook page:
facebook

What are you seeing that's different?

@ctarda
Copy link
Contributor

ctarda commented Jul 30, 2018

👋 sorry for the delay, @aerych ! This is what I see:

facebook_split mov

This is a wordpress.com site, in case it is relevant.

@aerych aerych mentioned this pull request Jul 30, 2018
@aerych
Copy link
Contributor Author

aerych commented Jul 30, 2018

Closing this in favor of #9872 so we're not branching off develop.

@aerych aerych closed this Jul 30, 2018
@aerych aerych deleted the issues/update-facebook-sharing branch July 31, 2018 02:19
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