From 046e6e5d86db59016999dd0c4081fcf68278f791 Mon Sep 17 00:00:00 2001 From: Robin Ward <robin.ward@gmail.com> Date: Mon, 20 May 2013 16:52:37 -0400 Subject: [PATCH] Simplified grouping on user views, fixed issue with messages not loading on initial load. Really simplified the restricted user route. --- .../user_private_messages_controller.js | 7 +- .../javascripts/discourse/models/user.js | 167 ++++-------------- .../discourse/models/user_action.js | 20 +-- .../discourse/models/user_action_stat.js | 21 ++- .../routes/discourse_restricted_user_route.js | 20 +-- .../discourse/routes/user_activity_route.js | 14 +- .../routes/user_private_messages_route.js | 11 +- .../discourse/routes/user_route.js | 7 +- .../templates/user/activity.js.handlebars | 1 - app/serializers/user_serializer.rb | 24 +-- 10 files changed, 92 insertions(+), 200 deletions(-) diff --git a/app/assets/javascripts/discourse/controllers/user_private_messages_controller.js b/app/assets/javascripts/discourse/controllers/user_private_messages_controller.js index 83d44e1e6..6607de7f9 100644 --- a/app/assets/javascripts/discourse/controllers/user_private_messages_controller.js +++ b/app/assets/javascripts/discourse/controllers/user_private_messages_controller.js @@ -8,13 +8,8 @@ **/ Discourse.UserPrivateMessagesController = Discourse.ObjectController.extend({ - editPreferences: function() { - Discourse.URL.routeTo("/users/" + (this.get('content.username_lower')) + "/preferences"); - }, - composePrivateMessage: function() { - var composerController; - composerController = Discourse.get('router.composerController'); + var composerController = Discourse.get('router.composerController'); return composerController.open({ action: Discourse.Composer.PRIVATE_MESSAGE, archetypeId: 'private_message', diff --git a/app/assets/javascripts/discourse/models/user.js b/app/assets/javascripts/discourse/models/user.js index 9fa45098f..f9eb8f511 100644 --- a/app/assets/javascripts/discourse/models/user.js +++ b/app/assets/javascripts/discourse/models/user.js @@ -187,6 +187,7 @@ Discourse.User = Discourse.Model.extend({ if (Discourse.UserAction.statGroups[filter]) { filter = Discourse.UserAction.statGroups[filter].join(","); } + this.set('streamFilter', filter); this.set('stream', Em.A()); this.set('totalItems', 0); @@ -254,17 +255,12 @@ Discourse.User = Discourse.Model.extend({ @property statsCountNonPM @type {Integer} **/ - statsCountNonPM: (function() { - var stats, total; - total = 0; - if (!(stats = this.get('stats'))) return 0; - this.get('stats').each(function(s) { - if (!s.get("isPM")) { - total += parseInt(s.count, 10); - } + statsCountNonPM: function() { + if (this.blank('statsExcludingPms')) return 0; + return this.get('statsExcludingPms').getEach('count').reduce(function (accum, val) { + return accum + val; }); - return total; - }).property('stats.@each'), + }.property('statsExcludingPms.@each.count'), /** The user's stats, excluding PMs. @@ -272,17 +268,10 @@ Discourse.User = Discourse.Model.extend({ @property statsExcludingPms @type {Array} **/ - statsExcludingPms: (function() { - var r; - r = []; - if (this.blank('stats')) return r; - this.get('stats').each(function(s) { - if (!s.get('isPM')) { - return r.push(s); - } - }); - return r; - }).property('stats.@each'), + statsExcludingPms: function() { + if (this.blank('stats')) return []; + return this.get('stats').rejectProperty('isPM'); + }.property('stats.@each.isPM'), /** This user's stats, only including PMs. @@ -290,66 +279,10 @@ Discourse.User = Discourse.Model.extend({ @property statsPmsOnly @type {Array} **/ - statsPmsOnly: (function() { - var r; - r = []; - if (this.blank('stats')) return r; - this.get('stats').each(function(s) { - if (s.get('isPM')) return r.push(s); - }); - return r; - }).property('stats.@each'), - - /** - Number of items in this user's inbox. - - @property inboxCount - @type {Integer} - **/ - inboxCount: (function() { - var r; - r = 0; - this.get('stats').each(function(s) { - if (s.action_type === Discourse.UserAction.GOT_PRIVATE_MESSAGE) { - r = s.count; - return false; - } - }); - return r; - }).property('stats.@each'), - - /** - Number of items this user has sent. - - @property sentItemsCount - @type {Integer} - **/ - sentItemsCount: function() { - var r; - r = 0; - this.get('stats').each(function(s) { - if (s.action_type === Discourse.UserAction.NEW_PRIVATE_MESSAGE) { - r = s.count; - return false; - } - }); - return r; - }.property('stats.@each'), - - onDetailsLoaded: function(callback){ - var _this = this; - this.set("loading",false); - - if(callback){ - this.onDetailsLoadedCallbacks = this.onDetailsLoadedCallbacks || []; - this.onDetailsLoadedCallbacks.push(callback); - } else { - var callbacks = this.onDetailsLoadedCallbacks; - $.each(callbacks, function(){ - this.apply(_this); - }); - } - }, + statsPmsOnly: function() { + if (this.blank('stats')) return []; + return this.get('stats').filterProperty('isPM'); + }.property('stats.@each.isPM'), /** Load extra details for the user @@ -358,33 +291,25 @@ Discourse.User = Discourse.Model.extend({ **/ loadDetails: function() { - this.set("loading",true); + this.set('loading', true); + // Check the preload store first var user = this; - var username = this.get('username'); - PreloadStore.getAndRemove("user_" + username, function() { + var username = user.get('username'); + + return PreloadStore.getAndRemove("user_" + username, function() { return Discourse.ajax("/users/" + username + '.json'); }).then(function (json) { + // Create a user from the resulting JSON json.user.stats = Discourse.User.groupStats(json.user.stats.map(function(s) { - var stat = Em.Object.create(s); - stat.set('isPM', stat.get('action_type') === Discourse.UserAction.NEW_PRIVATE_MESSAGE || - stat.get('action_type') === Discourse.UserAction.GOT_PRIVATE_MESSAGE); - stat.set('description', Em.String.i18n('user_action_groups.' + stat.get('action_type'))); - return stat; + if (s.count) s.count = parseInt(s.count, 10); + return Discourse.UserActionStat.create(s); })); - var count = 0; - if (json.user.stream) { - count = json.user.stream.length; - json.user.stream = Discourse.UserAction.collapseStream(json.user.stream.map(function(ua) { - return Discourse.UserAction.create(ua); - })); - } - user.setProperties(json.user); - user.set('totalItems', count); - user.onDetailsLoaded(); + user.set('loading', false); + return user; }); } @@ -412,41 +337,19 @@ Discourse.User.reopenClass({ @returns {Object} **/ groupStats: function(stats) { - var g, - _this = this; - g = {}; - stats.each(function(s) { - var c, found, k, v, _ref; - found = false; - _ref = Discourse.UserAction.statGroups; - for (k in _ref) { - v = _ref[k]; - if (v.contains(s.action_type)) { - found = true; - if (!g[k]) { - g[k] = Em.Object.create({ - description: Em.String.i18n("user_action_groups." + k), - count: 0, - action_type: parseInt(k, 10) - }); - } - g[k].count += parseInt(s.count, 10); - c = g[k].count; - if (s.action_type === k) { - g[k] = s; - s.count = c; - } - } - } - if (!found) { - g[s.action_type] = s; - } + var responses = Discourse.UserActionStat.create({ + count: 0, + action_type: Discourse.UserAction.RESPONSE }); - return stats.map(function(s) { - return g[s.action_type]; - }).exclude(function(s) { - return !s; + + stats.filterProperty('isResponse').forEach(function (stat) { + responses.set('count', responses.get('count') + stat.get('count')); }); + + var result = Em.A(); + result.pushObject(responses); + result.pushObjects(stats.rejectProperty('isResponse')); + return(result); }, /** diff --git a/app/assets/javascripts/discourse/models/user_action.js b/app/assets/javascripts/discourse/models/user_action.js index bfbc15939..8713b052f 100644 --- a/app/assets/javascripts/discourse/models/user_action.js +++ b/app/assets/javascripts/discourse/models/user_action.js @@ -69,7 +69,7 @@ Discourse.UserAction = Discourse.Model.extend({ } } } else { - Ember.debug("Invalid user action: " + action); + return ""; } return new Handlebars.SafeString(icon + " " + sentence); @@ -87,20 +87,19 @@ Discourse.UserAction = Discourse.Model.extend({ return Discourse.Utilities.postUrl(this.get('slug'), this.get('topic_id'), this.get('post_number')); }).property(), - replyUrl: (function() { + replyUrl: function() { return Discourse.Utilities.postUrl(this.get('slug'), this.get('topic_id'), this.get('reply_to_post_number')); - }).property(), + }.property(), - isPM: (function() { + isPM: function() { var a = this.get('action_type'); return a === Discourse.UserAction.NEW_PRIVATE_MESSAGE || a === Discourse.UserAction.GOT_PRIVATE_MESSAGE; - }).property(), + }.property(), - isPostAction: (function() { - var a; - a = this.get('action_type'); + isPostAction: function() { + var a = this.get('action_type'); return a === Discourse.UserAction.RESPONSE || a === Discourse.UserAction.POST || a === Discourse.UserAction.NEW_TOPIC; - }).property(), + }.property(), addChild: function(action) { var bucket, current, groups, ua; @@ -215,8 +214,7 @@ Discourse.UserAction.reopenClass({ Discourse.UserAction.reopenClass({ statGroups: (function() { - var g; - g = {}; + var g = {}; g[Discourse.UserAction.RESPONSE] = [Discourse.UserAction.RESPONSE, Discourse.UserAction.MENTION, Discourse.UserAction.QUOTE]; return g; })() diff --git a/app/assets/javascripts/discourse/models/user_action_stat.js b/app/assets/javascripts/discourse/models/user_action_stat.js index 78566adb5..c00be91ee 100644 --- a/app/assets/javascripts/discourse/models/user_action_stat.js +++ b/app/assets/javascripts/discourse/models/user_action_stat.js @@ -6,6 +6,25 @@ @namespace Discourse @module Discourse **/ -Discourse.UserActionStat = Discourse.Model.extend({}); +Discourse.UserActionStat = Discourse.Model.extend({ + + isPM: function() { + var actionType = this.get('action_type'); + return actionType === Discourse.UserAction.NEW_PRIVATE_MESSAGE || + actionType === Discourse.UserAction.GOT_PRIVATE_MESSAGE; + }.property('action_type'), + + description: function() { + return Em.String.i18n('user_action_groups.' + this.get('action_type')); + }.property('description'), + + isResponse: function() { + var actionType = this.get('action_type'); + return actionType === Discourse.UserAction.RESPONSE || + actionType === Discourse.UserAction.MENTION || + actionType === Discourse.UserAction.QUOTE; + }.property('action_type') + +}); diff --git a/app/assets/javascripts/discourse/routes/discourse_restricted_user_route.js b/app/assets/javascripts/discourse/routes/discourse_restricted_user_route.js index cbb75976f..dbd73f4b9 100644 --- a/app/assets/javascripts/discourse/routes/discourse_restricted_user_route.js +++ b/app/assets/javascripts/discourse/routes/discourse_restricted_user_route.js @@ -8,23 +8,9 @@ **/ Discourse.RestrictedUserRoute = Discourse.Route.extend({ - enter: function(router, context) { - var _this = this; - - // a bit hacky, but we don't have a fully loaded user at this point - // so we need to wait for it - var user = this.controllerFor('user').get('content'); - - if(user.can_edit === undefined) { - user.onDetailsLoaded(function(){ - if (this.get('can_edit') === false) { - _this.transitionTo('user.activity'); - } - }); - } - - if(user.can_edit === false) { - this.transitionTo('user.activity'); + redirect: function(user) { + if (user.get('can_edit') === false) { + this.transitionTo('user.activity', user); } } diff --git a/app/assets/javascripts/discourse/routes/user_activity_route.js b/app/assets/javascripts/discourse/routes/user_activity_route.js index f07d84a47..6e5427e7c 100644 --- a/app/assets/javascripts/discourse/routes/user_activity_route.js +++ b/app/assets/javascripts/discourse/routes/user_activity_route.js @@ -8,18 +8,16 @@ **/ Discourse.UserActivityRoute = Discourse.Route.extend({ + model: function() { + return this.modelFor('user'); + }, + renderTemplate: function() { this.render({ into: 'user', outlet: 'userOutlet' }); }, - setupController: function(controller) { - var userController = this.controllerFor('user'); - var user = userController.get('content'); - controller.set('content', user); - user.set('filter', null); - if (user.get('streamFilter')) { - user.filterStream(null); - } + setupController: function(controller, user) { + user.filterStream(null); } }); diff --git a/app/assets/javascripts/discourse/routes/user_private_messages_route.js b/app/assets/javascripts/discourse/routes/user_private_messages_route.js index 740fa84bd..318a6a2ee 100644 --- a/app/assets/javascripts/discourse/routes/user_private_messages_route.js +++ b/app/assets/javascripts/discourse/routes/user_private_messages_route.js @@ -8,18 +8,21 @@ **/ Discourse.UserPrivateMessagesRoute = Discourse.RestrictedUserRoute.extend({ + model: function() { + return this.modelFor('user'); + }, + renderTemplate: function() { this.render({ into: 'user', outlet: 'userOutlet' }); }, setupController: function(controller, user) { - var _this = this; - user = this.controllerFor('user').get('content'); - controller.set('content', user); user.filterStream(Discourse.UserAction.GOT_PRIVATE_MESSAGE); + + var composerController = this.controllerFor('composer'); Discourse.Draft.get('new_private_message').then(function(data) { if (data.draft) { - _this.controllerFor('composer').open({ + composerController.open({ draft: data.draft, draftKey: 'new_private_message', ignoreIfChanged: true, diff --git a/app/assets/javascripts/discourse/routes/user_route.js b/app/assets/javascripts/discourse/routes/user_route.js index 33da69294..2b5b9d62e 100644 --- a/app/assets/javascripts/discourse/routes/user_route.js +++ b/app/assets/javascripts/discourse/routes/user_route.js @@ -7,16 +7,13 @@ @module Discourse **/ Discourse.UserRoute = Discourse.Route.extend({ + model: function(params) { - return Discourse.User.create({username: params.username}); + return Discourse.User.create({username: params.username}).loadDetails(); }, serialize: function(params) { return { username: Em.get(params, 'username').toLowerCase() }; - }, - - setupController: function(controller, model) { - model.loadDetails(); } }); diff --git a/app/assets/javascripts/discourse/templates/user/activity.js.handlebars b/app/assets/javascripts/discourse/templates/user/activity.js.handlebars index 30b886f68..815eb8d66 100644 --- a/app/assets/javascripts/discourse/templates/user/activity.js.handlebars +++ b/app/assets/javascripts/discourse/templates/user/activity.js.handlebars @@ -1,4 +1,3 @@ - <div id='user-info'> <nav class='buttons'> {{#if can_edit}} diff --git a/app/serializers/user_serializer.rb b/app/serializers/user_serializer.rb index 50ee13bbe..8dea623af 100644 --- a/app/serializers/user_serializer.rb +++ b/app/serializers/user_serializer.rb @@ -9,7 +9,6 @@ class UserSerializer < BasicUserSerializer :created_at, :website, :can_edit, - :stream, :stats, :can_send_private_message_to_user, :bio_excerpt, @@ -41,15 +40,15 @@ class UserSerializer < BasicUserSerializer end private_attributes :email, - :email_digests, - :email_private_messages, - :email_direct, - :digest_after_days, - :auto_track_topics_after_msecs, - :new_topic_duration_minutes, - :external_links_in_new_tab, - :enable_quoting - + :email_digests, + :email_private_messages, + :email_direct, + :digest_after_days, + :auto_track_topics_after_msecs, + :new_topic_duration_minutes, + :external_links_in_new_tab, + :enable_quoting + def auto_track_topics_after_msecs object.auto_track_topics_after_msecs || SiteSetting.auto_track_topics_after @@ -67,11 +66,6 @@ class UserSerializer < BasicUserSerializer UserAction.stats(object.id, scope) end - def stream - UserAction.stream(user_id: object.id, offset: 0, limit: 60, - guardian: scope, ignore_private_messages: true) - end - def can_edit scope.can_edit?(object) end