FEATURE: Show user popup when clicking on an @mention in a post.
This commit is contained in:
parent
04c6733ae7
commit
27f786e06a
|
@ -34,8 +34,6 @@ var PosterNameComponent = Em.Component.extend({
|
|||
}
|
||||
buffer.push("</span>");
|
||||
|
||||
|
||||
|
||||
// Are we showing full names?
|
||||
if (name && this.get('displayNameOnPosts') && (this.sanitizeName(name) !== this.sanitizeName(username))) {
|
||||
name = Handlebars.Utils.escapeExpression(name);
|
||||
|
|
|
@ -2,7 +2,9 @@ export default Discourse.ObjectController.extend({
|
|||
needs: ['topic'],
|
||||
visible: false,
|
||||
user: null,
|
||||
username: null,
|
||||
participant: null,
|
||||
avatar: null,
|
||||
|
||||
postStream: Em.computed.alias('controllers.topic.postStream'),
|
||||
enoughPostsForFiltering: Em.computed.gte('participant.post_count', 2),
|
||||
|
@ -20,22 +22,25 @@ export default Discourse.ObjectController.extend({
|
|||
|
||||
showMoreBadges: Em.computed.gt('moreBadgesCount', 0),
|
||||
|
||||
show: function(post) {
|
||||
show: function(username, uploadedAvatarId) {
|
||||
var url = "/users/" + username;
|
||||
|
||||
// Don't show on mobile
|
||||
if (Discourse.Mobile.mobileView) {
|
||||
Discourse.URL.routeTo(post.get('usernameUrl'));
|
||||
Discourse.URL.routeTo(url);
|
||||
return;
|
||||
}
|
||||
|
||||
var currentPostId = this.get('id'),
|
||||
var currentUsername = this.get('username'),
|
||||
wasVisible = this.get('visible');
|
||||
|
||||
this.setProperties({model: post, visible: true});
|
||||
this.set('avatar', {username: username, uploaded_avatar_id: uploadedAvatarId});
|
||||
|
||||
this.setProperties({visible: true, username: username});
|
||||
|
||||
// If we click the avatar again, close it.
|
||||
if (post.get('id') === currentPostId && wasVisible) {
|
||||
this.setProperties({ visible: false, model: null });
|
||||
if (username === currentUsername && wasVisible) {
|
||||
this.setProperties({ visible: false, username: null, avatar: null });
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -44,13 +49,14 @@ export default Discourse.ObjectController.extend({
|
|||
// Retrieve their participants info
|
||||
var participants = this.get('topic.details.participants');
|
||||
if (participants) {
|
||||
this.set('participant', participants.findBy('username', post.get('username')));
|
||||
this.set('participant', participants.findBy('username', username));
|
||||
}
|
||||
|
||||
var self = this;
|
||||
self.set('user', null);
|
||||
Discourse.User.findByUsername(post.get('username')).then(function (user) {
|
||||
Discourse.User.findByUsername(username).then(function (user) {
|
||||
self.set('user', user);
|
||||
self.set('avatar', user);
|
||||
});
|
||||
},
|
||||
|
||||
|
|
|
@ -189,7 +189,7 @@ Handlebars.registerHelper('avatar', function(user, options) {
|
|||
@for Handlebars
|
||||
**/
|
||||
Em.Handlebars.helper('bound-avatar', function(user, size, uploadId) {
|
||||
|
||||
if (Em.isEmpty(user)) { return; }
|
||||
var username = Em.get(user, 'username');
|
||||
|
||||
if(arguments.length < 4){
|
||||
|
|
|
@ -14,8 +14,15 @@ Discourse.TopicRoute = Discourse.Route.extend({
|
|||
|
||||
actions: {
|
||||
// Modals that can pop up within a topic
|
||||
showPosterExpansion: function(post) {
|
||||
this.controllerFor('poster-expansion').show(post);
|
||||
expandPostUser: function(post) {
|
||||
this.controllerFor('poster-expansion').show(post.get('username'), post.get('uploaded_avatar_id'));
|
||||
},
|
||||
|
||||
expandPostUsername: function(username) {
|
||||
username = username.replace(/^@/, '');
|
||||
if (!Em.isEmpty(username)) {
|
||||
this.controllerFor('poster-expansion').show(username);
|
||||
}
|
||||
},
|
||||
|
||||
composePrivateMessage: function(user) {
|
||||
|
|
|
@ -2,13 +2,13 @@
|
|||
<div class='topic-avatar'>
|
||||
<div class='contents'>
|
||||
<div>
|
||||
{{poster-avatar action="showPosterExpansion" post=this classNames="main-avatar"}}
|
||||
{{poster-avatar action="expandPostUser" post=this classNames="main-avatar"}}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class='topic-body'>
|
||||
<div class="topic-meta-data">
|
||||
{{poster-name post=this expandAction="showPosterExpansion"}}
|
||||
{{poster-name post=this expandAction="expandPostUser"}}
|
||||
{{#if view.parentView.previousPost}}<a href='{{unbound url}}' class="post-info arrow" title="{{i18n topic.jump_reply_up}}"><i class='fa fa-arrow-up'></i></a>{{/if}}
|
||||
<div class='post-info post-date'>{{age-with-tooltip created_at}}</div>
|
||||
</div>
|
||||
|
|
|
@ -20,7 +20,7 @@
|
|||
<div class='topic-avatar'>
|
||||
{{#unless userDeleted}}
|
||||
<div {{bind-attr class=":contents byTopicCreator:topic-creator"}}>
|
||||
{{poster-avatar action="showPosterExpansion" post=this classNames="main-avatar"}}
|
||||
{{poster-avatar action="expandPostUser" post=this classNames="main-avatar"}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="contents">
|
||||
|
@ -34,7 +34,7 @@
|
|||
|
||||
<div class='topic-body'>
|
||||
<div class='topic-meta-data'>
|
||||
{{poster-name post=this expandAction="showPosterExpansion"}}
|
||||
{{poster-name post=this expandAction="expandPostUser"}}
|
||||
<div class='post-info'>
|
||||
<a class='post-date' {{bind-attr href="shareUrl" data-share-url="shareUrl" data-post-number="post_number"}}>{{age-with-tooltip created_at}}</a>
|
||||
</div>
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
{{#if model}}
|
||||
{{#link-to 'user' user}}{{bound-avatar model "huge"}}{{/link-to}}
|
||||
{{#if username}}
|
||||
{{#link-to 'user' user}}{{bound-avatar avatar "huge"}}{{/link-to}}
|
||||
|
||||
<div class="names">
|
||||
<h1 {{bind-attr class="staff new_user"}}><a {{bind-attr href="usernameUrl"}}>{{username}}</a></h1>
|
||||
<h1 {{bind-attr class="staff new_user"}}>
|
||||
{{#link-to 'user' user}}{{username}}{{/link-to}}
|
||||
</h1>
|
||||
{{#if showName}}
|
||||
<h2><a {{bind-attr href="usernameUrl"}}>{{name}}</a></h2>
|
||||
<h2>{{#link-to 'user' user}}{{name}}{{/link-to}}</h2>
|
||||
{{/if}}
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
{{#if showBadges}}
|
||||
|
@ -22,6 +22,7 @@
|
|||
{{/if}}
|
||||
</div>
|
||||
{{/if}}
|
||||
|
||||
{{#if user}}
|
||||
<div class="metadata">
|
||||
{{#if user.location}}<h3><i class="fa fa-map-marker"></i> {{user.location}}</h3>{{/if}}
|
||||
|
@ -30,7 +31,6 @@
|
|||
{{groups-list groups=user.custom_groups}}
|
||||
</div>
|
||||
|
||||
|
||||
<div class='bottom'>
|
||||
{{#if user.bio_cooked}}<div class='bio'>{{{user.bio_cooked}}}</div>{{/if}}
|
||||
|
||||
|
|
|
@ -1,11 +1,3 @@
|
|||
/**
|
||||
This view renders a post.
|
||||
|
||||
@class PostView
|
||||
@extends Discourse.GroupedView
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.PostView = Discourse.GroupedView.extend(Ember.Evented, {
|
||||
classNames: ['topic-post', 'clearfix'],
|
||||
templateName: 'post',
|
||||
|
@ -36,7 +28,7 @@ Discourse.PostView = Discourse.GroupedView.extend(Ember.Evented, {
|
|||
|
||||
// If the cooked content changed, add the quote controls
|
||||
cookedChanged: function() {
|
||||
Em.run.scheduleOnce('afterRender', this, 'insertQuoteControls');
|
||||
Em.run.scheduleOnce('afterRender', this, '_insertQuoteControls');
|
||||
}.observes('post.cooked'),
|
||||
|
||||
mouseUp: function(e) {
|
||||
|
@ -66,7 +58,7 @@ Discourse.PostView = Discourse.GroupedView.extend(Ember.Evented, {
|
|||
|
||||
repliesShown: Em.computed.gt('post.replies.length', 0),
|
||||
|
||||
updateQuoteElements: function($aside, desc) {
|
||||
_updateQuoteElements: function($aside, desc) {
|
||||
var navLink = "",
|
||||
quoteTitle = I18n.t("post.follow_quote"),
|
||||
postNumber = $aside.data('post');
|
||||
|
@ -100,42 +92,39 @@ Discourse.PostView = Discourse.GroupedView.extend(Ember.Evented, {
|
|||
$('.quote-controls', $aside).html(expandContract + navLink);
|
||||
},
|
||||
|
||||
toggleQuote: function($aside) {
|
||||
$aside.data('expanded',!$aside.data('expanded'));
|
||||
_toggleQuote: function($aside) {
|
||||
$aside.data('expanded', !$aside.data('expanded'));
|
||||
if ($aside.data('expanded')) {
|
||||
this.updateQuoteElements($aside, 'chevron-up');
|
||||
this._updateQuoteElements($aside, 'chevron-up');
|
||||
// Show expanded quote
|
||||
var $blockQuote = $('blockquote', $aside);
|
||||
$aside.data('original-contents',$blockQuote.html());
|
||||
|
||||
var originalText = $blockQuote.text().trim();
|
||||
$blockQuote.html(I18n.t("loading"));
|
||||
var topic_id = this.get('post.topic_id');
|
||||
var topicId = this.get('post.topic_id');
|
||||
if ($aside.data('topic')) {
|
||||
topic_id = $aside.data('topic');
|
||||
topicId = $aside.data('topic');
|
||||
}
|
||||
|
||||
var post_id = $aside.data('post');
|
||||
var postId = parseInt($aside.data('post'), 10);
|
||||
topicId = parseInt(topicId, 10);
|
||||
|
||||
topic_id = parseInt(topic_id,10);
|
||||
post_id = parseInt(post_id,10);
|
||||
|
||||
Discourse.ajax("/posts/by_number/" + topic_id + "/" + post_id).then(function (result) {
|
||||
Discourse.ajax("/posts/by_number/" + topicId + "/" + postId).then(function (result) {
|
||||
var parsed = $(result.cooked);
|
||||
parsed.replaceText(originalText, "<span class='highlighted'>" + originalText + "</span>");
|
||||
$blockQuote.showHtml(parsed);
|
||||
});
|
||||
} else {
|
||||
// Hide expanded quote
|
||||
this.updateQuoteElements($aside, 'chevron-down');
|
||||
this._updateQuoteElements($aside, 'chevron-down');
|
||||
$('blockquote', $aside).showHtml($aside.data('original-contents'));
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
// Show how many times links have been clicked on
|
||||
showLinkCounts: function() {
|
||||
|
||||
_showLinkCounts: function() {
|
||||
var self = this,
|
||||
link_counts = this.get('post.link_counts');
|
||||
|
||||
|
@ -194,7 +183,7 @@ Discourse.PostView = Discourse.GroupedView.extend(Ember.Evented, {
|
|||
},
|
||||
|
||||
// Add the quote controls to a post
|
||||
insertQuoteControls: function() {
|
||||
_insertQuoteControls: function() {
|
||||
var self = this,
|
||||
$quotes = this.$('aside.quote');
|
||||
|
||||
|
@ -204,14 +193,14 @@ Discourse.PostView = Discourse.GroupedView.extend(Ember.Evented, {
|
|||
$quotes.each(function(i, e) {
|
||||
var $aside = $(e);
|
||||
if ($aside.data('post')) {
|
||||
self.updateQuoteElements($aside, 'chevron-down');
|
||||
self._updateQuoteElements($aside, 'chevron-down');
|
||||
var $title = $('.title', $aside);
|
||||
|
||||
// Unless it's a full quote, allow click to expand
|
||||
if (!($aside.data('full') || $title.data('has-quote-controls'))) {
|
||||
$title.on('click', function(e) {
|
||||
if ($(e.target).is('a')) return true;
|
||||
self.toggleQuote($aside);
|
||||
self._toggleQuote($aside);
|
||||
});
|
||||
$title.data('has-quote-controls', true);
|
||||
}
|
||||
|
@ -219,16 +208,17 @@ Discourse.PostView = Discourse.GroupedView.extend(Ember.Evented, {
|
|||
});
|
||||
},
|
||||
|
||||
willDestroyElement: function() {
|
||||
_destroyedPostView: function() {
|
||||
Discourse.ScreenTrack.current().stopTracking(this.get('elementId'));
|
||||
},
|
||||
this._unbindExpandMentions();
|
||||
}.on('willDestroyElement'),
|
||||
|
||||
didInsertElement: function() {
|
||||
_postViewInserted: function() {
|
||||
var $post = this.$(),
|
||||
post = this.get('post'),
|
||||
postNumber = post.get('post_number');
|
||||
|
||||
this.showLinkCounts();
|
||||
this._showLinkCounts();
|
||||
|
||||
// Track this post
|
||||
Discourse.ScreenTrack.current().track(this.$().prop('id'), postNumber);
|
||||
|
@ -245,12 +235,27 @@ Discourse.PostView = Discourse.GroupedView.extend(Ember.Evented, {
|
|||
this.trigger('postViewInserted', $post);
|
||||
|
||||
// Find all the quotes
|
||||
Em.run.scheduleOnce('afterRender', this, 'insertQuoteControls');
|
||||
Em.run.scheduleOnce('afterRender', this, '_insertQuoteControls');
|
||||
|
||||
this.applySearchHighlight();
|
||||
this._applySearchHighlight();
|
||||
this._bindExpandMentions();
|
||||
}.on('didInsertElement'),
|
||||
|
||||
_bindExpandMentions: function() {
|
||||
var self = this;
|
||||
this.$('.cooked').on('click.discourse-mention', 'a.mention', function(e) {
|
||||
var $target = $(e.target);
|
||||
self.appEvents.trigger('poster:expand', $target);
|
||||
self.get('controller').send('expandPostUsername', $target.text());
|
||||
return false;
|
||||
});
|
||||
},
|
||||
|
||||
applySearchHighlight: function(){
|
||||
_unbindExpandMentions: function() {
|
||||
this.$('.cooked').off('click.discourse-mention');
|
||||
},
|
||||
|
||||
_applySearchHighlight: function() {
|
||||
var highlight = this.get('controller.searchHighlight');
|
||||
var cooked = this.$('.cooked');
|
||||
|
||||
|
|
|
@ -5,14 +5,22 @@ export default Discourse.View.extend({
|
|||
classNameBindings: ['controller.visible::hidden', 'controller.showBadges'],
|
||||
|
||||
_setup: function() {
|
||||
var self = this;
|
||||
var self = this,
|
||||
width = this.$().width();
|
||||
|
||||
this.appEvents.on('poster:expand', function(target) {
|
||||
if (!target) { return; }
|
||||
Em.run.schedule('afterRender', function() {
|
||||
if (target) {
|
||||
var position = target.offset();
|
||||
if (position) {
|
||||
position.left += target.width() + 5;
|
||||
position.left += target.width() + 10;
|
||||
|
||||
var overage = ($(window).width() - 50) - (position.left + width);
|
||||
if (overage < 0) {
|
||||
position.left += overage;
|
||||
position.top += target.height() + 5;
|
||||
}
|
||||
self.$().css(position);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue