Skip to content
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

Fork improvements #151

Merged
merged 15 commits into from
Feb 16, 2014
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 28 additions & 2 deletions scripts/gh-book/auth-template.html
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ <h3 id="sign-in-modal-label">Sign in to Book Editor</h3>
<p>To be able to save your changes, you must provide us with your
<a href="http://github.com/">github</a> username and password.</p>

<p>If you refresh this page you may need to re-enter this information.</p>
<p id="login-info-wrapper">If you refresh this page you may need to re-enter this information.</p>
<div id="login-advanced-wrapper">
<div class="form-inline">
<input id="github-id" class="input-small" type="text" required="true" placeholder="Username" value="{{id}}"/>
Expand Down Expand Up @@ -80,7 +80,7 @@ <h3 id="sign-in-modal-label">Sign in to Book Editor</h3>
<div id="fork-book-modal" data-backdrop="false" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="fork-book-modal-label" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="fork-book-modal-label">Copy this book!</h3>
<h3 id="fork-book-modal-label">Copy this shelf!</h3>
</div>
<h4>&#160; Places I have permission to make changes:</h4>
<div class="modal-body">
Expand All @@ -93,6 +93,32 @@ <h4>&#160; Places I have permission to make changes:</h4>
</div>
</div>

<div id="fork-progress-modal" data-backdrop="false" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="fork-progress-modal-label" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="fork-progress-modal-label">Copying in progress</h3>
</div>
<div class="modal-body">
[Progress indicator here]
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
</div>
</div>

<div id="fork-redirect-modal" data-backdrop="false" class="modal hide fade" tabindex="-1" role="dialog" aria-labelledby="fork-redirect-modal-label" aria-hidden="true">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
<h3 id="fork-redirect-modal-label">Existing bookshelf</h3>
</div>
<div class="modal-body">
You already have a copy of this bookshelf.
</div>
<div class="modal-footer">
<button class="btn" data-dismiss="modal" aria-hidden="true">Cancel</button>
<button class="btn btn-primary">Take me there</button>
</div>
</div>


<!-- Edit Repository Modal -->
Expand Down
125 changes: 114 additions & 11 deletions scripts/gh-book/auth.coffee
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
define [
'jquery'
'underscore'
'marionette'
'cs!collections/content'
'cs!session'
Expand All @@ -10,7 +11,7 @@ define [
'cs!configs/github'
'bootstrapModal'
'bootstrapCollapse'
], ($, Marionette, allContent, session, remoteUpdater, authTemplate, difflib, diffview, config) ->
], ($, _, Marionette, allContent, session, remoteUpdater, authTemplate, difflib, diffview, config) ->

return class GithubAuthView extends Marionette.ItemView
template: authTemplate
Expand All @@ -25,6 +26,8 @@ define [
'click #show-diffs': 'showDiffsModal'
'submit #edit-repo-form': 'editRepo'
'click [data-select-repo]': 'selectRepo'
'click #fork-book-modal .organisation-block': 'selectOrg'
'click #fork-redirect-modal .btn-primary': 'selectFork'

initialize: () ->
# When a model has changed (triggered `dirty`) update the Save button
Expand Down Expand Up @@ -75,18 +78,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')
Expand Down Expand Up @@ -132,17 +156,92 @@ define [
$modal.modal {show:true}


forkContent: () ->
organisationModal: (info, orgs) ->
$modal = @$el.find('#fork-book-modal')
$body = $modal.find('.modal-body').empty()

if not (@model.get('password') or @model.get('token'))
alert 'Please Sign In before trying to fork a book'
return
# Own account
$block = $('<div class="organisation-block"></div>')
$avatar = $('<img alt="avatar">').attr('src', info.avatar_url)
$name = $('<span>').html(info.login)
$block.append($avatar).append($name)
$body.append($block)
for org in orgs
$block = $('<div class="organisation-block"></div>')
$avatar = $('<img alt="avatar">').attr('src', org.avatar_url)
$name = $('<span>').html(org.login)
$block.append($avatar).append($name).data('org-name', org.login)
$body.append($block)

@model.getClient().getLogin().done (login) =>
@model.getRepo()?.fork().done () =>
@model.set 'repoUser', login
$modal.modal {show:true}

selectOrg: (e) ->
$block = $(e.target).addBack().closest('.organisation-block')
org = $block.data('org-name') or null
@$el.find('#fork-book-modal').modal('hide')
@__forkContent(org)

selectFork: (e) ->
e.preventDefault()
login = @$el.find('#fork-redirect-modal').modal('hide').data('login')
@_selectRepo(login, @model.get('repoName'))


forkContent: () ->
if not (@model.get('password') or @model.get('token'))
@signInModal
anonymous: false
info: false
.done () => @_forkContent()
return
@_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.login)

__forkContent: (login) ->
# If repo exists, go to it or cancel. Else fork.
@model.getClient().getRepo(login, @model.get('repoName')).getInfo().done () =>
@$el.find('#fork-redirect-modal').data('login', login).modal
show: true
.fail () =>
@___forkContent(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

# Poll until repo becomes available
pollRepo = () =>
@model.getRepo()?.getInfo('').done (info) =>
Copy link
Member

Choose a reason for hiding this comment

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

I do not believe .getInfo() takes an argument, but it's a minor concern ; )

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(
bb.history.getHash())[2]
controller.trigger 'navigate', v
.fail () =>
if wait < 30
setTimeout(pollRepo, wait)
wait = wait * 2 # exponential backoff
else
alert('Fork failed')
.always () =>
$modal.modal('hide')
pollRepo()


signIn: (e) ->
# Prevent form submission
Expand All @@ -154,6 +253,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
Expand All @@ -164,6 +266,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?'

Expand Down
13 changes: 13 additions & 0 deletions scripts/gh-book/gh-book.less
Original file line number Diff line number Diff line change
Expand Up @@ -218,3 +218,16 @@ nav#workspace-sidebar-toc{
font-size: 120%;
}
}

#fork-book-modal {
.organisation-block {
cursor: pointer;
img {
height: 45px;
width: 45px;
}
span {
margin-left: 0.5em;
}
}
}