From 0af5d51feaf3d040876c2048a9b5f1dee37582ed Mon Sep 17 00:00:00 2001 From: Izak Burger Date: Fri, 10 Jan 2014 16:18:12 +0200 Subject: [PATCH 01/12] Add login modal options to hide details, callback When invoking the logInModal, you can now request that the anonymous option and the extra info be hidden, for when you require a login for a specific change. Use case in mind: Forking while not logged in. The logInModal method now returns a promise that is resolved upon login, or rejected otherwise, so that you can hang a follow-up onto a login. --- scripts/gh-book/auth-template.html | 2 +- scripts/gh-book/auth.coffee | 29 +++++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/scripts/gh-book/auth-template.html b/scripts/gh-book/auth-template.html index db4f3013..22e66692 100644 --- a/scripts/gh-book/auth-template.html +++ b/scripts/gh-book/auth-template.html @@ -51,7 +51,7 @@

Sign in to Book Editor

To be able to save your changes, you must provide us with your github username and password.

-

If you refresh this page you may need to re-enter this information.

+

If you refresh this page you may need to re-enter this information.

diff --git a/scripts/gh-book/auth.coffee b/scripts/gh-book/auth.coffee index be7f4e1e..df72d0bb 100644 --- a/scripts/gh-book/auth.coffee +++ b/scripts/gh-book/auth.coffee @@ -75,18 +75,39 @@ define [ @isDirty = true @render() - signInModal: () -> + signInModal: (options) -> $modal = @$el.find('#sign-in-modal') # The hidden event on #login-advanced should not propagate $modal.find('#login-advanced').on 'hidden', (e) => e.stopPropagation() + # We'll return a promise, and resolve it upon login or close. + promise = $.Deferred() + $modal.data('login-promise', promise) + # attach a close listener - $modal.on 'hidden', () => @trigger 'close' + $modal.on 'hidden', () => + if promise.state() == 'pending' + promise.reject() + @trigger 'close' + + # Hide parts of the modal, if requested, for a simpler UI. + if options + if options.anonymous != undefined and options.anonymous == false + $modal.find('#login-anonymous').hide() + else + $modal.find('#login-anonymous').show() + + if options.info != undefined and options.info == false + $modal.find('#login-info-wrapper').hide() + else + $modal.find('#login-info-wrapper').show() # Show the modal $modal.modal {show:true} + return promise + # Show a diff of all unsaved models showDiffsModal: () -> $modal = @$el.find('#diffs-modal') @@ -154,6 +175,9 @@ define [ token: @$el.find('#github-token').val() password: @$el.find('#github-password').val() + # signInModal persists the promise on the modal + promise = @$el.find('#sign-in-modal').data('login-promise') + if not (attrs.password or attrs.token) alert 'We are terribly sorry but github recently changed so you must login to use their API.\nPlease refresh and provide a password or an OAuth token.' else @@ -164,6 +188,7 @@ define [ # The 1st time the editor loads up it waits for the modal to close # but `render` will hide the modal without triggering 'close' @trigger 'close' + promise.resolve() .fail (err) => alert 'Login failed. Did you use the correct credentials?' From d6ed734e65d9d07a82480cc885e667ee6d1088a8 Mon Sep 17 00:00:00 2001 From: Izak Burger Date: Fri, 10 Jan 2014 17:02:24 +0200 Subject: [PATCH 02/12] Prompt for login when forking as anonymous. --- scripts/gh-book/auth.coffee | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/scripts/gh-book/auth.coffee b/scripts/gh-book/auth.coffee index df72d0bb..78ef974b 100644 --- a/scripts/gh-book/auth.coffee +++ b/scripts/gh-book/auth.coffee @@ -156,9 +156,14 @@ define [ forkContent: () -> if not (@model.get('password') or @model.get('token')) - alert 'Please Sign In before trying to fork a book' + @signInModal + anonymous: false + info: false + .done () => @_forkContent() return + @_forkContent() + _forkContent: () -> @model.getClient().getLogin().done (login) => @model.getRepo()?.fork().done () => @model.set 'repoUser', login From 15e89dace67a9425a27f1e17d21670412915351e Mon Sep 17 00:00:00 2001 From: Izak Burger Date: Tue, 28 Jan 2014 11:01:50 +0200 Subject: [PATCH 03/12] Use correct terminology: copying the book shelf. --- scripts/gh-book/auth-template.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/gh-book/auth-template.html b/scripts/gh-book/auth-template.html index 22e66692..28de2600 100644 --- a/scripts/gh-book/auth-template.html +++ b/scripts/gh-book/auth-template.html @@ -80,7 +80,7 @@

Sign in to Book Editor

+ diff --git a/scripts/gh-book/auth.coffee b/scripts/gh-book/auth.coffee index 54adf234..00e1c5d7 100644 --- a/scripts/gh-book/auth.coffee +++ b/scripts/gh-book/auth.coffee @@ -206,11 +206,16 @@ define [ @__forkContent(info.login) __forkContent: (login) -> + $modal = @$el.find('#fork-progress-modal') + $body = $modal.find('.modal-body') + $body.html('Creating a Fork...') + $modal.modal {show: true} @model.getRepo()?.fork(login).done () => + $body.html('Waiting for Fork to become available...') + # Change upstream repo wait = 2000 @model.set 'repoUser', login - # TODO: Some feedback here would be nice # Poll until repo becomes available pollRepo = () => @@ -227,6 +232,8 @@ define [ wait = wait * 2 # exponential backoff else alert('Fork failed') + .always () => + $modal.modal('hide') pollRepo() From c6238d4a98e7a44c8d7db950be5942ed3d0279da Mon Sep 17 00:00:00 2001 From: Izak Burger Date: Tue, 28 Jan 2014 14:09:07 +0200 Subject: [PATCH 06/12] Check for duplicate repo also in organisation The previous version only checked for duplicates in the user area. --- scripts/gh-book/auth.coffee | 38 ++++++++++++++++++++++++------------- 1 file changed, 25 insertions(+), 13 deletions(-) diff --git a/scripts/gh-book/auth.coffee b/scripts/gh-book/auth.coffee index 00e1c5d7..93046319 100644 --- a/scripts/gh-book/auth.coffee +++ b/scripts/gh-book/auth.coffee @@ -156,7 +156,7 @@ define [ organisationModal: (info, orgs) -> - $modal = @$el.find('#fork-book-modal') + $modal = @$el.find('#fork-book-modal').data('userinfo', info) $body = $modal.find('.modal-body').empty() # Own account @@ -175,10 +175,11 @@ define [ $modal.modal {show:true} selectOrg: (e) -> + userinfo = @$el.find('#fork-book-modal').data('userinfo') $block = $(e.target).addBack().closest('.organisation-block') org = $block.data('org-name') or null @$el.find('#fork-book-modal').modal('hide') - @__forkContent(org) + @__forkContent(userinfo, org) forkContent: () -> if not (@model.get('password') or @model.get('token')) @@ -190,22 +191,34 @@ define [ @_forkContent() _forkContent: () -> + # If user has more than one organisation, ask which one. + @model.getClient().getUser().getInfo().done (userinfo) => + @model.getClient().getUser().getOrgs().done (orgs) => + if orgs.length > 1 + @organisationModal(userinfo, orgs) + else + @__forkContent(userinfo, userinfo.login) + + __forkContent: (userinfo, login) -> + # If repo exists, go to it or cancel. Else fork. + if userinfo.login == login + # Forking into own space + promise = @model.getClient().getUser().getRepos() + else + # Forking into organisation + promise = @model.getClient().getOrg(login).getRepos() + + # Check if repo exists reponame = @model.getRepo().git.repoName - @model.getClient().getUser().getRepos().done (repos) => - # Check if repo exists + promise.done (repos) => existing = _.findWhere(repos, {name: reponame}) if existing # TODO: Present choice of cancel, or take me there alert('You already have a copy of this bookshelf') else - @model.getClient().getUser().getInfo().done (info) => - @model.getClient().getUser().getOrgs().done (orgs) => - if orgs.length > 1 - @organisationModal(info, orgs) - else - @__forkContent(info.login) - - __forkContent: (login) -> + @___forkContent(login) + + ___forkContent: (login) -> $modal = @$el.find('#fork-progress-modal') $body = $modal.find('.modal-body') $body.html('Creating a Fork...') @@ -220,7 +233,6 @@ define [ # Poll until repo becomes available pollRepo = () => @model.getRepo()?.getInfo('').done (info) => - # TODO: Clear feedback require ['backbone', 'cs!controllers/routing'], (bb, controller) => # Filter out the view bit, then set the url to reflect the fork v = RegExp('repo/[^/]*/[^/]*(/branch/[^/]*)?/(.*)').exec( From 57853cfb0cd2f5ac94f5d98704ce23f92626f630 Mon Sep 17 00:00:00 2001 From: Izak Burger Date: Tue, 28 Jan 2014 14:59:11 +0200 Subject: [PATCH 07/12] If there is an existing fork, offer to take me there. --- scripts/gh-book/auth-template.html | 14 ++++++++++++++ scripts/gh-book/auth.coffee | 11 +++++++++-- 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/scripts/gh-book/auth-template.html b/scripts/gh-book/auth-template.html index 0d7e7215..af67f3cd 100644 --- a/scripts/gh-book/auth-template.html +++ b/scripts/gh-book/auth-template.html @@ -106,6 +106,20 @@

Copying in progress

+ +