Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
7 changes: 5 additions & 2 deletions app/components/thank-you-container.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
import Ember from 'ember';

const {
Component
Component,
inject: { service }
} = Ember;

export default Component.extend({
classNames: ['thank-you-container']
classNames: ['thank-you-container'],

onboarding: service()
});
3 changes: 2 additions & 1 deletion app/controllers/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import Ember from 'ember';
const {
computed,
Controller,
get,
inject: { service }
} = Ember;

Expand All @@ -22,7 +23,7 @@ export default Controller.extend({

actions: {
invalidateSession() {
this.get('session').invalidate();
get(this, 'session').invalidate();
}
}
});
41 changes: 32 additions & 9 deletions app/mixins/onboarding-controller.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,11 @@ import Ember from 'ember';

const {
computed,
get,
getProperties,
inject: { service },
Mixin
Mixin,
set
} = Ember;

export default Mixin.create({
Expand All @@ -14,14 +17,34 @@ export default Mixin.create({

actions: {
continue() {
let user = this.get('user');
let onboarding = this.get('onboarding');
let nextStateTransition = onboarding.get('nextStateTransition');
let nextRoute = onboarding.get('nextRoute');
user.set('stateTransition', nextStateTransition);
user.save().then(() => {
this.transitionToRoute(nextRoute);
});
let { onboarding, user } = getProperties(this, 'onboarding', 'user');
let { nextStateTransition, shouldTransitionUser } = getProperties(onboarding, 'nextStateTransition', 'shouldTransitionUser');

// We can transition routes without transitioning the user's state
if (shouldTransitionUser) {
set(user, 'stateTransition', nextStateTransition);
}

this._transitionToNextRoute();
},

skip() {
let { onboarding, user } = getProperties(this, 'onboarding', 'user');
let { skipStateTransition, shouldTransitionUser } = getProperties(onboarding, 'skipStateTransition', 'shouldTransitionUser');

// We can transition routes without transitioning the user's state
if (shouldTransitionUser) {
set(user, 'stateTransition', skipStateTransition);
}

this._transitionToNextRoute();
}
},

_transitionToNextRoute() {
let { onboarding, user } = getProperties(this, 'onboarding', 'user');
user.save().then(() => {
this.transitionToRoute(get(onboarding, 'nextRoute'));
});
}
});
34 changes: 0 additions & 34 deletions app/mixins/onboarding-route.js

This file was deleted.

1 change: 1 addition & 0 deletions app/models/user.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ export default Model.extend({
password: attr(),
photoLargeUrl: attr(),
photoThumbUrl: attr(),
signUpContext: attr(),
state: attr(),
twitter: attr(),
username: attr(),
Expand Down
23 changes: 10 additions & 13 deletions app/router.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,12 @@ let AppRouter = Router.extend({
});

AppRouter.map(function() {
this.route('about');

this.route('login');

this.route('oauth-stripe', {
path: '/oauth/stripe'
this.route('organization', function() {
this.route('settings', function() { });
});

this.route('organizations', function() {
Expand All @@ -45,6 +47,8 @@ AppRouter.map(function() {
});
});

this.route('privacy');

this.route('project', { path: '/:slugged_route_slug/:project_slug' }, function() {
this.route('checkout');
this.route('donate');
Expand Down Expand Up @@ -77,25 +81,18 @@ AppRouter.map(function() {

this.route('signup');

this.route('slugged-route', {
path: '/:slugged_route_slug'
});

this.route('start', function() {
this.route('hello');
this.route('interests');
this.route('expertise');
this.route('skills');
});

this.route('slugged-route', {
path: '/:slugged_route_slug'
});

this.route('team');
this.route('about');

this.route('organization', function() {
this.route('settings', function() { });
});

this.route('privacy');
this.route('terms');
});

Expand Down
75 changes: 41 additions & 34 deletions app/routes/application.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export default Route.extend(ApplicationRouteMixin, LoadingBar, {
onboarding: service(),

isOnboarding: computed.alias('onboarding.isOnboarding'),
onboardingRoute: computed.alias('onboarding.currentRoute'),
onboardingRoute: computed.alias('onboarding.routeForCurrentStep'),

headTags: [
{
Expand Down Expand Up @@ -153,60 +153,63 @@ export default Route.extend(ApplicationRouteMixin, LoadingBar, {
],

beforeModel(transition) {
return this._loadCurrentUser().then(() => {
if (this._shouldTransitionToOnboardingRoute(transition)) {
return this.transitionTo(get(this, 'onboardingRoute'));
} else {
return this._super(...arguments);
}
}).catch(() => this._invalidateSession());
return this._loadCurrentUser()
.then(() => {
if (this._shouldRedirectToOnboarding(transition)) {
return this.transitionTo(get(this, 'onboardingRoute'));
} else {
return this._super(...arguments);
}
})
.catch(() => this._invalidateSession());
},

sessionAuthenticated() {
return this._loadCurrentUser()
.then(() => {
this._attemptTransition();
this._attemptTransitionAfterAuthentication();
this._trackAuthentication();
})
.catch(() => this._invalidateSession());
},

actions: {
willTransition(transition) {
if (this._shouldTransitionToOnboardingRoute(transition)) {
this._abortAndFixHistory(transition);
if (this._shouldRedirectToOnboarding(transition)) {
transition.abort();
this.transitionTo(get(this, 'onboardingRoute'));
}
},

// see https://github.com/emberjs/ember.js/issues/12791
// if we don't handle the error action at application level
// te error will continue to be thrown, causing tests to fail
// and the error to be outputed to console, even though we technically
// the error will continue to be thrown, causing tests to fail
// and the error will output to console, even though we technically
// "handled" it with our application_error route/template
error(e) {
console.error(e);
this.intermediateTransitionTo('application_error', e);
}
},

_abortAndFixHistory(transition) {
transition.abort();
if (window.history) {
window.history.forward();
}
},

_attemptTransition() {
if (get(this, 'isOnboarding')) {
// The default beahavior for an ember-simple-auth ApplicationRouteMixin is to
// Either got back to the route the user tried to access before being
// redirected to login/signup, or if there is no such route, go to the default
// route.
//
// This slightly extends this behavior by sending the user to the onboarding
// route if it's determined that should be the case. If there was a stored
// route, for example, if a non-signed-in user tried to donate, then that
// still takes precedence.
_attemptTransitionAfterAuthentication() {
let attemptedTransition = get(this, 'session.attemptedTransition');
if (isPresent(attemptedTransition)) {
attemptedTransition.retry();
set(this, 'session.attemptedTransition', null);
} else if (get(this, 'isOnboarding')) {
this.transitionTo(get(this, 'onboardingRoute'));
} else {
let attemptedTransition = get(this, 'session.attemptedTransition');
if (isPresent(attemptedTransition)) {
attemptedTransition.retry();
set(this, 'session.attemptedTransition', null);
} else {
this.transitionTo('projects-list');
}
this.transitionTo('projects-list');
}
},

Expand All @@ -218,14 +221,18 @@ export default Route.extend(ApplicationRouteMixin, LoadingBar, {
return get(this, 'currentUser').loadCurrentUser();
},

_shouldTransitionToOnboardingRoute(transition) {
// If the user is still in the process of onboarding, they are allowd to visit
// only select routes. Trying to access any other route redirects them to
// their next onboarding route.
//
// This function returns true if that should happen.
_shouldRedirectToOnboarding(transition) {
let isOnboarding = get(this, 'isOnboarding');

let onboardingRoutes = get(this, 'onboarding.routes');
let allowedRoutes = get(this, 'onboarding.allowedRoutes');
let targetRoute = transition.targetName;
let isTransitionToOnboardingRoute = (onboardingRoutes.indexOf(targetRoute) > -1);
let isTransitionToAllowedRoute = (allowedRoutes.indexOf(targetRoute) > -1);

return isOnboarding && !isTransitionToOnboardingRoute;
return isOnboarding && !isTransitionToAllowedRoute;
},

_trackAuthentication() {
Expand Down
4 changes: 2 additions & 2 deletions app/routes/project/checkout.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export default Route.extend({
return this._super(...arguments);
} else {
set(session, 'attemptedTransition', transition);
let queryParams = { donate: true };
let queryParams = { context: 'donation' };
return this.transitionTo('signup', { queryParams });
}
},
Expand All @@ -38,7 +38,7 @@ export default Route.extend({
get(this, 'flashMessages').success(ALREADY_A_SUBSCRIBER);
this.transitionTo('project', project);
} else {
this._super.call(...arguments);
this._super(...arguments);
}
},

Expand Down
29 changes: 27 additions & 2 deletions app/routes/project/donate.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,37 @@
import Ember from 'ember';

const {
Route
get,
inject: { service },
Route,
RSVP
} = Ember;

const ALREADY_A_SUBSCRIBER = "You're already supporting this project.";

export default Route.extend({
flashMessages: service(),
session: service(),
userSubscriptions: service(),

model() {
return this.modelFor('project').reload();
return this.modelFor('project').reload().then((project) => {
let subscription = get(this, 'userSubscriptions').fetchForProject(project);
return RSVP.hash({ project, subscription });
});
},

afterModel({ project, subscription }) {
if (subscription) {
get(this, 'flashMessages').success(ALREADY_A_SUBSCRIBER);
this.transitionTo('project', project);
} else {
this._super(...arguments);
}
},

setupController(controller, models) {
controller.setProperties(models);
},

renderTemplate() {
Expand Down
Loading