Simplified grouping on user views, fixed issue with messages not loading on initial load. Really

simplified the restricted user route.
This commit is contained in:
Robin Ward 2013-05-20 16:52:37 -04:00
parent 27828c5ec2
commit 046e6e5d86
10 changed files with 92 additions and 200 deletions

View File

@ -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',

View File

@ -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);
},
/**

View File

@ -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;
})()

View File

@ -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')
});

View File

@ -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);
}
}

View File

@ -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);
}
});

View File

@ -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,

View File

@ -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();
}
});

View File

@ -1,4 +1,3 @@
<div id='user-info'>
<nav class='buttons'>
{{#if can_edit}}

View File

@ -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