diff --git a/app/assets/javascripts/discourse/ember/resolver.js.es6 b/app/assets/javascripts/discourse/ember/resolver.js.es6 index f4c6e0b11ee..88cf9da9f6a 100644 --- a/app/assets/javascripts/discourse/ember/resolver.js.es6 +++ b/app/assets/javascripts/discourse/ember/resolver.js.es6 @@ -3,6 +3,24 @@ var classify = Ember.String.classify; var get = Ember.get; +var LOADING_WHITELIST = ['badges', 'userActivity', 'userPrivateMessages'], + _dummyRoute, + _loadingView; + +function loadingResolver(cb) { + return function(parsedName) { + var fullNameWithoutType = parsedName.fullNameWithoutType; + if (fullNameWithoutType.indexOf('Loading') > 0) { + fullNameWithoutType = fullNameWithoutType.replace('Loading', ''); + if (LOADING_WHITELIST.indexOf(fullNameWithoutType) !== -1) { + return cb(fullNameWithoutType); + } else { + Ember.warn('consider whitelisting a loading route for: ' + fullNameWithoutType); + } + } + }; +} + function parseName(fullName) { /*jshint validthis:true */ @@ -66,7 +84,7 @@ export default Ember.DefaultResolver.extend({ }, resolveView: function(parsedName) { - return this.customResolve(parsedName) || this._super(parsedName); + return this.findLoadingView(parsedName) || this.customResolve(parsedName) || this._super(parsedName); }, resolveHelper: function(parsedName) { @@ -82,16 +100,9 @@ export default Ember.DefaultResolver.extend({ }, resolveRoute: function(parsedName) { - return this.customResolve(parsedName) || this._super(parsedName); + return this.findLoadingRoute(parsedName) || this.customResolve(parsedName) || this._super(parsedName); }, - /** - Attaches a view and wires up the container properly - - @method resolveTemplate - @param {String} parsedName the name of the template we want to resolve - @returns {Template} the template (if found) - **/ resolveTemplate: function(parsedName) { return this.findPluginTemplate(parsedName) || this.findMobileTemplate(parsedName) || @@ -99,6 +110,19 @@ export default Ember.DefaultResolver.extend({ Ember.TEMPLATES.not_found; }, + findLoadingRoute: loadingResolver(function() { + _dummyRoute = _dummyRoute || Ember.Route.extend(); + return _dummyRoute; + }), + + findLoadingView: loadingResolver(function() { + if (!_loadingView) { + _loadingView = require('discourse/views/loading', null, null, true /* force sync */); + if (_loadingView && _loadingView['default']) { _loadingView = _loadingView['default']; } + } + return _loadingView; + }), + findPluginTemplate: function(parsedName) { var pluginParsedName = this.parseName(parsedName.fullName.replace("template:", "template:javascripts/")); return this.findTemplate(pluginParsedName); diff --git a/app/assets/javascripts/discourse/helpers/loading-spinner.es6 b/app/assets/javascripts/discourse/helpers/loading-spinner.es6 index f82e97a6ecb..fd93335b389 100644 --- a/app/assets/javascripts/discourse/helpers/loading-spinner.es6 +++ b/app/assets/javascripts/discourse/helpers/loading-spinner.es6 @@ -1,7 +1,7 @@ var spinnerHTML = "
"; Handlebars.registerHelper('loading-spinner', function() { - return new Handlebars.SafeString(spinnerHTML); + return new Handlebars.SafeString(spinnerHTML); }); export { spinnerHTML }; diff --git a/app/assets/javascripts/discourse/routes/badges-show.js.es6 b/app/assets/javascripts/discourse/routes/badges-show.js.es6 index a9dbc00f16b..5ee4fa72d8b 100644 --- a/app/assets/javascripts/discourse/routes/badges-show.js.es6 +++ b/app/assets/javascripts/discourse/routes/badges-show.js.es6 @@ -13,6 +13,13 @@ export default Discourse.Route.extend({ } }, + afterModel: function(model) { + var self = this; + return Discourse.UserBadge.findByBadgeId(model.get('id')).then(function(userBadges) { + self.userBadges = userBadges; + }); + }, + titleToken: function() { var model = this.modelFor('badges.show'); if (model) { @@ -21,10 +28,7 @@ export default Discourse.Route.extend({ }, setupController: function(controller, model) { - Discourse.UserBadge.findByBadgeId(model.get('id')).then(function(userBadges) { - controller.set('userBadges', userBadges); - controller.set('userBadgesLoaded', true); - }); controller.set('model', model); + controller.set('userBadges', this.userBadges); } }); diff --git a/app/assets/javascripts/discourse/routes/preferences-about.js.es6 b/app/assets/javascripts/discourse/routes/preferences-about.js.es6 index bf660fa664e..b01c1941e6c 100644 --- a/app/assets/javascripts/discourse/routes/preferences-about.js.es6 +++ b/app/assets/javascripts/discourse/routes/preferences-about.js.es6 @@ -4,7 +4,7 @@ export default Discourse.RestrictedUserRoute.extend({ }, renderTemplate: function() { - this.render({ into: 'user', outlet: 'userOutlet' }); + this.render({ into: 'user' }); }, setupController: function(controller, model) { @@ -14,7 +14,7 @@ export default Discourse.RestrictedUserRoute.extend({ // A bit odd, but if we leave to /preferences we need to re-render that outlet deactivate: function() { this._super(); - this.render('preferences', { into: 'user', outlet: 'userOutlet', controller: 'preferences' }); + this.render('preferences', { into: 'user', controller: 'preferences' }); }, actions: { diff --git a/app/assets/javascripts/discourse/routes/preferences-badge-title.js.es6 b/app/assets/javascripts/discourse/routes/preferences-badge-title.js.es6 index 66eec03ea57..382c61a0f47 100644 --- a/app/assets/javascripts/discourse/routes/preferences-badge-title.js.es6 +++ b/app/assets/javascripts/discourse/routes/preferences-badge-title.js.es6 @@ -4,13 +4,13 @@ export default Discourse.RestrictedUserRoute.extend({ }, renderTemplate: function() { - return this.render('user/badge-title', { into: 'user', outlet: 'userOutlet' }); + return this.render('user/badge-title', { into: 'user' }); }, // A bit odd, but if we leave to /preferences we need to re-render that outlet deactivate: function() { this._super(); - this.render('preferences', { into: 'user', outlet: 'userOutlet', controller: 'preferences' }); + this.render('preferences', { into: 'user', controller: 'preferences' }); }, setupController: function(controller, model) { diff --git a/app/assets/javascripts/discourse/routes/preferences-card-badge.js.es6 b/app/assets/javascripts/discourse/routes/preferences-card-badge.js.es6 index d674c1fdc5f..e75a05092d9 100644 --- a/app/assets/javascripts/discourse/routes/preferences-card-badge.js.es6 +++ b/app/assets/javascripts/discourse/routes/preferences-card-badge.js.es6 @@ -4,13 +4,13 @@ export default Discourse.RestrictedUserRoute.extend({ }, renderTemplate: function() { - return this.render({ into: 'user', outlet: 'userOutlet' }); + return this.render({ into: 'user' }); }, // A bit odd, but if we leave to /preferences we need to re-render that outlet deactivate: function() { this._super(); - this.render('preferences', { into: 'user', outlet: 'userOutlet', controller: 'preferences' }); + this.render('preferences', { into: 'user', controller: 'preferences' }); }, setupController: function(controller, model) { diff --git a/app/assets/javascripts/discourse/routes/preferences-email.js.es6 b/app/assets/javascripts/discourse/routes/preferences-email.js.es6 index da936ee3ebe..4c17b9b2884 100644 --- a/app/assets/javascripts/discourse/routes/preferences-email.js.es6 +++ b/app/assets/javascripts/discourse/routes/preferences-email.js.es6 @@ -4,7 +4,7 @@ export default Discourse.RestrictedUserRoute.extend({ }, renderTemplate: function() { - this.render({ into: 'user', outlet: 'userOutlet' }); + this.render({ into: 'user' }); }, setupController: function(controller, model) { @@ -14,7 +14,7 @@ export default Discourse.RestrictedUserRoute.extend({ // A bit odd, but if we leave to /preferences we need to re-render that outlet deactivate: function() { this._super(); - this.render('preferences', { into: 'user', outlet: 'userOutlet', controller: 'preferences' }); + this.render('preferences', { into: 'user', controller: 'preferences' }); } }); diff --git a/app/assets/javascripts/discourse/routes/preferences-index.js.es6 b/app/assets/javascripts/discourse/routes/preferences-index.js.es6 index 44ee603122c..2d3a66111dd 100644 --- a/app/assets/javascripts/discourse/routes/preferences-index.js.es6 +++ b/app/assets/javascripts/discourse/routes/preferences-index.js.es6 @@ -1,5 +1,5 @@ export default Discourse.RestrictedUserRoute.extend({ renderTemplate: function() { - this.render('preferences', { into: 'user', outlet: 'userOutlet', controller: 'preferences' }); + this.render('preferences', { into: 'user', controller: 'preferences' }); } }); diff --git a/app/assets/javascripts/discourse/routes/preferences-username.js.es6 b/app/assets/javascripts/discourse/routes/preferences-username.js.es6 index 4c983cb2f9d..2a9bbe0fbb5 100644 --- a/app/assets/javascripts/discourse/routes/preferences-username.js.es6 +++ b/app/assets/javascripts/discourse/routes/preferences-username.js.es6 @@ -4,13 +4,13 @@ export default Discourse.RestrictedUserRoute.extend({ }, renderTemplate: function() { - return this.render({ into: 'user', outlet: 'userOutlet' }); + return this.render({ into: 'user' }); }, // A bit odd, but if we leave to /preferences we need to re-render that outlet deactivate: function() { this._super(); - this.render('preferences', { into: 'user', outlet: 'userOutlet', controller: 'preferences' }); + this.render('preferences', { into: 'user', controller: 'preferences' }); }, setupController: function(controller, user) { diff --git a/app/assets/javascripts/discourse/routes/user-badges.js.es6 b/app/assets/javascripts/discourse/routes/user-badges.js.es6 index 2ec062e5809..0ccfa32a0b1 100644 --- a/app/assets/javascripts/discourse/routes/user-badges.js.es6 +++ b/app/assets/javascripts/discourse/routes/user-badges.js.es6 @@ -16,6 +16,6 @@ export default Discourse.Route.extend({ }, renderTemplate: function() { - this.render('user/badges', {into: 'user', outlet: 'userOutlet'}); + this.render('user/badges', {into: 'user'}); } }); diff --git a/app/assets/javascripts/discourse/routes/user-invited.js.es6 b/app/assets/javascripts/discourse/routes/user-invited.js.es6 index 7cb190aa79d..42acec4a2f9 100644 --- a/app/assets/javascripts/discourse/routes/user-invited.js.es6 +++ b/app/assets/javascripts/discourse/routes/user-invited.js.es6 @@ -1,6 +1,6 @@ export default Discourse.Route.extend({ renderTemplate: function() { - this.render({ into: 'user', outlet: 'userOutlet' }); + this.render({ into: 'user' }); }, model: function() { diff --git a/app/assets/javascripts/discourse/routes/user-loading.js.es6 b/app/assets/javascripts/discourse/routes/user-loading.js.es6 new file mode 100644 index 00000000000..9d032c9e3ba --- /dev/null +++ b/app/assets/javascripts/discourse/routes/user-loading.js.es6 @@ -0,0 +1 @@ +export default Ember.Route.extend(); diff --git a/app/assets/javascripts/discourse/routes/user-notifications.js.es6 b/app/assets/javascripts/discourse/routes/user-notifications.js.es6 index 2c40fd8ea88..2abd0f464ac 100644 --- a/app/assets/javascripts/discourse/routes/user-notifications.js.es6 +++ b/app/assets/javascripts/discourse/routes/user-notifications.js.es6 @@ -19,6 +19,6 @@ export default Discourse.Route.extend({ }, renderTemplate: function() { - this.render('user-notification-history', {into: 'user', outlet: 'userOutlet'}); + this.render('user-notification-history', {into: 'user'}); } }); diff --git a/app/assets/javascripts/discourse/routes/user_activity_stream_route.js b/app/assets/javascripts/discourse/routes/user_activity_stream_route.js index cadcdc7359f..62e8228b89f 100644 --- a/app/assets/javascripts/discourse/routes/user_activity_stream_route.js +++ b/app/assets/javascripts/discourse/routes/user_activity_stream_route.js @@ -1,12 +1,4 @@ -/** - The base route for showing an activity stream. - - @class UserActivityStreamRoute - @extends Discourse.Route - @namespace Discourse - @module Discourse -**/ -Discourse.UserActivityStreamRoute = Discourse.Route.extend({ +var UserActivityStreamRoute = Discourse.Route.extend({ model: function() { return this.modelFor('user').get('stream'); }, @@ -16,7 +8,7 @@ Discourse.UserActivityStreamRoute = Discourse.Route.extend({ }, renderTemplate: function() { - this.render('user_stream', {into: 'user', outlet: 'userOutlet'}); + this.render('user_stream'); }, setupController: function(controller, model) { @@ -51,7 +43,7 @@ Discourse.UserActivityStreamRoute = Discourse.Route.extend({ // Build all activity stream routes ['bookmarks', 'edits', 'likes_given', 'likes_received', 'replies', 'posts', 'index'].forEach(function (userAction) { - Discourse["UserActivity" + userAction.classify() + "Route"] = Discourse.UserActivityStreamRoute.extend({ + Discourse["UserActivity" + userAction.classify() + "Route"] = UserActivityStreamRoute.extend({ userActionType: Discourse.UserAction.TYPES[userAction] }); }); diff --git a/app/assets/javascripts/discourse/routes/user_admin_posts_routes.js b/app/assets/javascripts/discourse/routes/user_admin_posts_routes.js index 1440f0ea7f8..0eb874627fd 100644 --- a/app/assets/javascripts/discourse/routes/user_admin_posts_routes.js +++ b/app/assets/javascripts/discourse/routes/user_admin_posts_routes.js @@ -14,7 +14,7 @@ function createAdminPostRoute (filter) { }, renderTemplate: function() { - this.render("user/posts", { into: "user", outlet: "userOutlet" }); + this.render("user/posts", { into: "user" }); } }); } diff --git a/app/assets/javascripts/discourse/routes/user_topic_list_routes.js b/app/assets/javascripts/discourse/routes/user_topic_list_routes.js index 2f9df6fe681..35b4a86ddb5 100644 --- a/app/assets/javascripts/discourse/routes/user_topic_list_routes.js +++ b/app/assets/javascripts/discourse/routes/user_topic_list_routes.js @@ -1,6 +1,6 @@ Discourse.UserTopicListRoute = Discourse.Route.extend({ renderTemplate: function() { - this.render('user_topics_list', {into: 'user', outlet: 'userOutlet'}); + this.render('user_topics_list'); }, setupController: function(controller, model) { diff --git a/app/assets/javascripts/discourse/templates/badges/show.hbs b/app/assets/javascripts/discourse/templates/badges/show.hbs index 0e820abc810..ac3780e1fa7 100644 --- a/app/assets/javascripts/discourse/templates/badges/show.hbs +++ b/app/assets/javascripts/discourse/templates/badges/show.hbs @@ -40,9 +40,5 @@ {{else}} {{custom-html "footer"}} {{/if}} - {{else}} - {{#unless userBadgesLoaded}} - {{loading-spinner}} - {{/unless}} {{/if}} diff --git a/app/assets/javascripts/discourse/templates/loading.hbs b/app/assets/javascripts/discourse/templates/loading.hbs deleted file mode 100644 index 7b998117e8e..00000000000 --- a/app/assets/javascripts/discourse/templates/loading.hbs +++ /dev/null @@ -1 +0,0 @@ -{{loading-spinner}} diff --git a/app/assets/javascripts/discourse/templates/user/activity.hbs b/app/assets/javascripts/discourse/templates/user/activity.hbs index 1d3be0bb127..c24cd68950a 100644 --- a/app/assets/javascripts/discourse/templates/user/activity.hbs +++ b/app/assets/javascripts/discourse/templates/user/activity.hbs @@ -1 +1 @@ -{{outlet activity}} +{{outlet}} diff --git a/app/assets/javascripts/discourse/templates/user/stream.hbs b/app/assets/javascripts/discourse/templates/user/stream.hbs index 3d9ce13b0bd..212361ae661 100644 --- a/app/assets/javascripts/discourse/templates/user/stream.hbs +++ b/app/assets/javascripts/discourse/templates/user/stream.hbs @@ -25,7 +25,3 @@ {{/grouped-each}} {{/grouped-each}} - -{{#if loading}} - {{loading-spinner}} -{{/if}} diff --git a/app/assets/javascripts/discourse/templates/user/user.hbs b/app/assets/javascripts/discourse/templates/user/user.hbs index a6c425c6c4d..14831435178 100644 --- a/app/assets/javascripts/discourse/templates/user/user.hbs +++ b/app/assets/javascripts/discourse/templates/user/user.hbs @@ -3,198 +3,195 @@ {{global-notice}} -{{#unless loading}} -
-
-
-
- {{#if number_of_flags_given}} -
{{number_of_flags_given}} {{i18n user.staff_counters.flags_given}}
- {{/if}} - {{#if number_of_flagged_posts}} -
- {{#link-to 'user.flaggedPosts' this}} - {{number_of_flagged_posts}} {{i18n user.staff_counters.flagged_posts}} - {{/link-to}} -
- {{/if}} - {{#if number_of_deleted_posts}} -
- {{#link-to 'user.deletedPosts' this}} - {{number_of_deleted_posts}} {{i18n user.staff_counters.deleted_posts}} - {{/link-to}} -
- {{/if}} - {{#if number_of_suspensions}} -
{{number_of_suspensions}} {{i18n user.staff_counters.suspensions}}
- {{/if}} - {{#if number_of_warnings}} -
{{number_of_warnings}} {{i18n user.staff_counters.warnings_received}}
- {{/if}} -
-
-
-
- {{bound-avatar model "huge"}} -
- -
- -
-

{{username}} {{{statusIcon}}}

-

{{name}}

-

- {{#if location}}{{fa-icon "map-maker"}}{{location}}{{/if}} - {{#if websiteName}} - {{fa-icon "globe"}} - {{#if linkWebsite}} - {{websiteName}} - {{else}} - {{websiteName}} - {{/if}} +
+
+
+
+ {{#if number_of_flags_given}} +
{{number_of_flags_given}} {{i18n user.staff_counters.flags_given}}
+ {{/if}} + {{#if number_of_flagged_posts}} +
+ {{#link-to 'user.flaggedPosts' this}} + {{number_of_flagged_posts}} {{i18n user.staff_counters.flagged_posts}} + {{/link-to}} +
+ {{/if}} + {{#if number_of_deleted_posts}} +
+ {{#link-to 'user.deletedPosts' this}} + {{number_of_deleted_posts}} {{i18n user.staff_counters.deleted_posts}} + {{/link-to}} +
+ {{/if}} + {{#if number_of_suspensions}} +
{{number_of_suspensions}} {{i18n user.staff_counters.suspensions}}
+ {{/if}} + {{#if number_of_warnings}} +
{{number_of_warnings}} {{i18n user.staff_counters.warnings_received}}
+ {{/if}} +
+
+
+
+ {{bound-avatar model "huge"}} +
+

+ {{#if viewingSelf}} +
  • {{fa-icon "sign-out"}}{{i18n user.log_out}}
  • + {{/if}} + {{#if currentUser.staff}} +
  • {{fa-icon "wrench"}}{{i18n admin.user.show_admin_profile}}
  • + {{/if}} + {{#if can_edit}} +
  • {{#link-to 'preferences' class="btn right"}}{{fa-icon "cog"}}{{i18n user.preferences}}{{/link-to}}
  • + {{/if}} + {{#if canInviteToForum}} +
  • {{#link-to 'user.invited' class="btn right"}}{{fa-icon "envelope-o"}}{{i18n user.invited.title}}{{/link-to}}
  • + {{/if}} + +
    -
    - {{#if isSuspended}} -
    - {{fa-icon "ban"}} - {{i18n user.suspended_notice date="suspendedTillDate"}}
    - {{i18n user.suspended_reason}} {{suspend_reason}} -
    - {{/if}} - {{{bio_cooked}}} -
    - - {{plugin-outlet "user-profile-primary"}} +
    +

    {{username}} {{{statusIcon}}}

    +

    {{name}}

    +

    + {{#if location}}{{fa-icon "map-maker"}}{{location}}{{/if}} + {{#if websiteName}} + {{fa-icon "globe"}} + {{#if linkWebsite}} + {{websiteName}} + {{else}} + {{websiteName}} + {{/if}} + {{/if}} +

    +
    + {{#if isSuspended}} +
    + {{fa-icon "ban"}} + {{i18n user.suspended_notice date="suspendedTillDate"}}
    + {{i18n user.suspended_reason}} {{suspend_reason}} +
    + {{/if}} + {{{bio_cooked}}}
    + + {{plugin-outlet "user-profile-primary"}} +
    -
    +
    + -
    -
    - {{#if created_at}} -
    {{i18n user.created}}
    {{bound-date created_at}}
    - {{/if}} - {{#if last_posted_at}} -
    {{i18n user.last_posted}}
    {{bound-date last_posted_at}}
    - {{/if}} - {{#if last_seen_at}} -
    {{i18n user.last_seen}}
    {{bound-date last_seen_at}}
    - {{/if}} - {{#if invited_by}} -
    {{i18n user.invited_by}}
    {{#link-to 'user' invited_by}}{{invited_by.username}}{{/link-to}}
    - {{/if}} -
    {{i18n user.trust_level}}
    {{trustLevel.name}}
    - {{#if canCheckEmails}} -
    {{i18n user.email.title}}
    -
    - {{#if email}} - {{email}} - {{else}} - - {{/if}} -
    - {{/if}} - {{#if custom_groups}} -
    {{i18n groups.title count=custom_groups.length}}
    -
    - {{#each custom_groups}} - {{#link-to 'group' this class="group-link"}}{{name}}{{/link-to}} - {{/each}} -
    - {{/if}} -
    - {{plugin-outlet "user-profile-secondary"}} -
    - - -
    - - - {{#if canSeePrivateMessages}} -

    {{fa-icon "envelope"}} {{i18n user.private_messages}}

    - - {{/if}} -
    - - {{outlet userOutlet}} - + {{#if last_seen_at}} +
    {{i18n user.last_seen}}
    {{bound-date last_seen_at}}
    + {{/if}} + {{#if invited_by}} +
    {{i18n user.invited_by}}
    {{#link-to 'user' invited_by}}{{invited_by.username}}{{/link-to}}
    + {{/if}} +
    {{i18n user.trust_level}}
    {{trustLevel.name}}
    + {{#if canCheckEmails}} +
    {{i18n user.email.title}}
    +
    + {{#if email}} + {{email}} + {{else}} + + {{/if}} +
    + {{/if}} + {{#if custom_groups}} +
    {{i18n groups.title count=custom_groups.length}}
    +
    + {{#each custom_groups}} + {{#link-to 'group' this class="group-link"}}{{name}}{{/link-to}} + {{/each}} +
    + {{/if}} + + {{plugin-outlet "user-profile-secondary"}} + - - {{#if loadedAllItems}} - {{custom-html "footer"}} - {{/if}} +
    + -{{/unless}} + {{#if canSeePrivateMessages}} +

    {{fa-icon "envelope"}} {{i18n user.private_messages}}

    + + {{/if}} +
    + + {{outlet}} + + + + +{{#if loadedAllItems}} + {{custom-html "footer"}} +{{/if}} diff --git a/app/assets/javascripts/discourse/views/loading.js.es6 b/app/assets/javascripts/discourse/views/loading.js.es6 new file mode 100644 index 00000000000..7b08e628a2c --- /dev/null +++ b/app/assets/javascripts/discourse/views/loading.js.es6 @@ -0,0 +1,7 @@ +import { spinnerHTML } from 'discourse/helpers/loading-spinner'; + +export default Ember.View.extend({ + render: function(buffer) { + buffer.push(spinnerHTML); + } +}); diff --git a/app/assets/javascripts/discourse/views/user-loading.js.es6 b/app/assets/javascripts/discourse/views/user-loading.js.es6 new file mode 100644 index 00000000000..22cc259b248 --- /dev/null +++ b/app/assets/javascripts/discourse/views/user-loading.js.es6 @@ -0,0 +1,3 @@ +import LoadingView from 'discourse/views/loading'; + +export default LoadingView;