Skip to content

refactor(repository-screen): switch to GraphQL #775

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 8 commits into from
Apr 24, 2018

Conversation

machour
Copy link
Member

@machour machour commented Apr 17, 2018

Question Response
Version? v1.4.1
Devices tested? iPhone 7
Bug fix? no
New feature? yes
Includes tests? no
All Tests pass? no
Related ticket? #761

Description

Introducing GraphQL in the new Redux API 🎉

Rewrote the repo screen to be loaded with only two requests:

  • A GraphQL query to load all the displayed information on the screen
  • A REST list query to load the contributors (not provided by GitHub v4 yet)

I also ported star/unstar watch/unwatch & fork to the new API.

For now, the GraphQL query also returns 50 issues & 50 pull requests, to avoid making any changes to the issues/pulls list screens. We will get rid of that once these two screens are rewritten to the new API.

Even with that little performance annoyance, the new screen is blazing fast!

UX changes

  • Starring/Unstarring or Watching/Unwatching are immediately reflected on the UI :
watching unwatching not watching
simulator screen shot - iphone 7 - 2018-04-17 at 02 58 52 simulator screen shot - iphone 7 - 2018-04-17 at 02 58 56 simulator screen shot - iphone 7 - 2018-04-17 at 02 58 58

This is possible with the new Client.delete() and Client.put() methods, that allow us to patch the entity in our Store. This logic already showcased for REST in #770, is also compatible with GraphQL.

  • Error Page (to be discussed)

When a repository doesn't exist, we currently display a Toast with an error message, and an incomplete Repository screen.

I wanted to simplify things, a create a nicer user experience, so I tweaked this part a bit.

My first approach was to immediately navigate back & display the toast, but the toast length was really limited.

So for now I'm displaying this error page:

simulator screen shot - iphone 7 - 2018-04-17 at 02 48 29

Come to think about it, we already have an ErrorPage component, but with a hardcoded message for now. We could definitely refactor it a bit:

  • Allow for a custom message to be passed as a prop
  • Give it some UI ❤️
  • Allow the user to provide us some feedback about how he got to the error (if it's a GitPoint app error) and have that feedback posted as a new issue in the GitPoint repository ✨

And icing on the cake, we would use that from the new componentDidCatch React lifecycle method and spread that in all our screens.

Any opinions on that ? If accepted, this would have to be done in a separate PR.

NB: For now the new API displays an additional (ugly) alert message meant for debugging.

@coveralls
Copy link

coveralls commented Apr 17, 2018

Coverage Status

Coverage decreased (-1.6%) to 41.564% when pulling dc6be2f on machour:refactor/repo-screen into 8f8f229 on gitpoint:master.

Copy link
Member

@housseindjirdeh housseindjirdeh left a comment

Choose a reason for hiding this comment

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

So so great that we actually don't have to change much at all when porting to GraphQL :) It's literally a matter of adding the queries and mapping them correct?

I love this and everything looks great, feel free to merge whenever ✅


Regarding the error screen - I agree that it might be nicer to have one instead of a toast. But I also agree that the current implementation is a little much, and we can definitely come to a better decision to have a better ErrorComponent or ErrorScreen that is used everywhere and is a little more flexible. When we do that, we can apply some better UI changes. For now, this is not a problem :)

id: repoId,
updater: gqlRepo => ({
isSubscribed: true,
watchersCount: gqlRepo.watchersCount + 1,
Copy link
Member

Choose a reason for hiding this comment

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

Good stuff :)

Copy link
Member Author

Choose a reason for hiding this comment

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

this was almost already in #770, but changed it to take a callback with the modified elements, for way more flexibility.

}

return Promise.resolve();
}
Copy link
Member

Choose a reason for hiding this comment

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

No worries about doing it now, we can chat about this much later - but because this single method is getting so long we can spend a little time separating these to separate methods

Copy link
Member Author

Choose a reason for hiding this comment

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

This is something that have been puzzling me for a while, but I can't seem to find a good code splitting approach, without passing a zillion of parameters to the separate methods.

Would love if you can lay a fresh pair of eyes on this 🙌

}
}

`;
Copy link
Member

Choose a reason for hiding this comment

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

👏 👏 👏 👏

@@ -7,6 +7,7 @@ export const entities = (
orgs: {},
repos: {},
users: {},
gqlRepos: {},
Copy link
Member

Choose a reason for hiding this comment

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

Why are we separating it into it's own entity instead of just using repos? I'm assuming this is because other parts of the app still reference the original repos object (and if that's the case -> not a big deal for now)

Copy link
Member Author

Choose a reason for hiding this comment

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

repos here is from our new store architecture. It holds v3 repositories found in the Search screen, or starred by a user for example.

I needed to separate repositories retrieved via GraphQL , from the one retrieved from the Rest API, because they don't share the same structure / field names.


If you get back to #761, you'll see that I've mentioned adapting GraphQL entities structure to match the ones from Rest.

But now that I've experimented a bit with GraphQL, I think that we should be doing exactly the opposite: Adapt REST entities to the GraphQL structure in our store. We will do that once we migrated everything to the new API, because it will require updates in most of our components (avatar_url => avatarUrl).


Furthermore, since we're retrieving exactly what we need from GraphQL, I think that we should be storing the response structure as-is in the store. I'll be updating this PR accordingly to reflect that (and loose the ugly code in gqlRepos schema)

});
};
};

Copy link
Member

Choose a reason for hiding this comment

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

Love it <3

),
contents_url: `https://api.github.com/repos/${
repository.nameWithOwner
}/contents`,
Copy link
Member Author

Choose a reason for hiding this comment

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

This is the file I just called ugly. We're receiving a structure that correspond exactly to the current GitHub data model & relation, and I'm just breaking everything to try to mimic the old Rest structure. Sounds totally illogic.

@machour
Copy link
Member Author

machour commented Apr 18, 2018

Thanks for the feedback buddy. As mentioned in the comments, I think I'll be tweaking the data structure a bit more before merging this one.

Currently experimenting with GraphQL on the Issue/Pull Request screen to gain more hindsight about how we should store the data from v4.

@machour
Copy link
Member Author

machour commented Apr 22, 2018

Reverted to a nicer error screen (the one that was put in place by #726).

Also, as mentioned in the conversation, I've changed the structure of our data in store to closely match the data structure of GitHub & the new Repository screen accept only a repoId as entry parameter.

@machour machour merged commit 9eeb5a9 into gitpoint:master Apr 24, 2018
@machour
Copy link
Member Author

machour commented Apr 24, 2018

@housseindjirdeh merged this PR as I had your okay. Changes since your comment only enhanced it.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants