mirror of
https://github.com/discourse/discourse.git
synced 2025-02-25 18:55:32 -06:00
Show the entire history of replies above a post when you expend "in reply to"
This commit is contained in:
@@ -253,10 +253,29 @@ Discourse.TopicController = Discourse.ObjectController.extend(Discourse.Selected
|
||||
},
|
||||
|
||||
// Toggle the star on the topic
|
||||
toggleStar: function(e) {
|
||||
toggleStar: function() {
|
||||
this.get('content').toggleStar();
|
||||
},
|
||||
|
||||
/**
|
||||
Toggle the replies this post is a reply to
|
||||
|
||||
@method showReplyHistory
|
||||
**/
|
||||
toggleReplyHistory: function(post) {
|
||||
var replyHistory = post.get('replyHistory'),
|
||||
topicController = this;
|
||||
|
||||
if (replyHistory.length > 0) {
|
||||
replyHistory.clear();
|
||||
} else {
|
||||
post.set('loadingReplyHistory', true);
|
||||
topicController.get('postStream').findReplyHistory(post).then(function () {
|
||||
post.set('loadingReplyHistory', false);
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Clears the pin from a topic for the currently logged in user
|
||||
|
||||
|
||||
@@ -8,6 +8,10 @@
|
||||
**/
|
||||
Discourse.Post = Discourse.Model.extend({
|
||||
|
||||
init: function() {
|
||||
this.set('replyHistory', []);
|
||||
},
|
||||
|
||||
shareUrl: function() {
|
||||
var user = Discourse.User.current();
|
||||
var userSuffix = user ? '?u=' + user.get('username_lower') : '';
|
||||
@@ -383,12 +387,6 @@ Discourse.Post.reopenClass({
|
||||
});
|
||||
},
|
||||
|
||||
loadByPostNumber: function(topicId, postId) {
|
||||
return Discourse.ajax("/posts/by_number/" + topicId + "/" + postId + ".json").then(function (result) {
|
||||
return Discourse.Post.create(result);
|
||||
});
|
||||
},
|
||||
|
||||
loadQuote: function(postId) {
|
||||
return Discourse.ajax("/posts/" + postId + ".json").then(function(result) {
|
||||
var post = Discourse.Post.create(result);
|
||||
|
||||
@@ -459,6 +459,26 @@ Discourse.PostStream = Em.Object.extend({
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
Returns the "thread" of posts in the history of a post.
|
||||
|
||||
@method findReplyHistory
|
||||
@param {Discourse.Post} post the post whose history we want
|
||||
@returns {Array} the posts in the history.
|
||||
**/
|
||||
findReplyHistory: function(post) {
|
||||
var postStream = this,
|
||||
url = "/posts/" + post.get('id') + "/reply-history.json";
|
||||
|
||||
return Discourse.ajax(url).then(function(result) {
|
||||
return result.map(function (p) {
|
||||
return postStream.storePost(Discourse.Post.create(p));
|
||||
});
|
||||
}).then(function (replyHistory) {
|
||||
post.set('replyHistory', replyHistory);
|
||||
});
|
||||
},
|
||||
|
||||
/**
|
||||
Returns the closest post number given a postNumber that may not exist in the stream.
|
||||
For example, if the user asks for a post that's deleted or otherwise outside the range.
|
||||
|
||||
@@ -10,9 +10,9 @@
|
||||
<div class='span11 topic-body'>
|
||||
<div class="topic-meta-data-inside">
|
||||
<div class='post-info post-date'>{{unboundAgeWithTooltip created_at}}</div>
|
||||
{{#if view.previousPost}}<a href='{{unbound url}}' class="post-info arrow" title="{{i18n topic.jump_reply_up}}"><i class='icon icon-arrow-up'></i></a>{{/if}}
|
||||
{{#if view.parentView.previousPost}}<a href='{{unbound url}}' class="post-info arrow" title="{{i18n topic.jump_reply_up}}"><i class='icon icon-arrow-up'></i></a>{{/if}}
|
||||
</div>
|
||||
{{{unbound cooked}}}
|
||||
{{#unless view.previousPost}}<a href='{{unbound url}}' class="arrow" title="{{i18n topic.jump_reply_down}}"><i class='icon icon-arrow-down'></i></a>{{/unless}}
|
||||
{{#unless view.parentView.previousPost}}<a href='{{unbound url}}' class="arrow" title="{{i18n topic.jump_reply_down}}"><i class='icon icon-arrow-down'></i></a>{{/unless}}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -1,16 +1,12 @@
|
||||
<div class='row'>
|
||||
<section class='embedded-posts top parent-post span14 offset2' style='display:none'>
|
||||
{{#if view.parentPost}}
|
||||
{{view Discourse.ParentView contentBinding="view.parentPost" postViewBinding="view"}}
|
||||
{{/if}}
|
||||
</section>
|
||||
{{view Discourse.ReplyHistory contentBinding="replyHistory"}}
|
||||
</div>
|
||||
|
||||
<article class='boxed' {{bindAttr id="postElementId"}} {{bindAttr data-post-id="id"}} data-user-id="{{unbound user_id}}">
|
||||
<div class='row'>
|
||||
{{#if showUserReplyTab}}
|
||||
<a href='#' {{action toggleParent target="view"}} class='reply-to-tab'>
|
||||
{{#if loadingParent}}
|
||||
<a href='#' {{action toggleReplyHistory this}} class='reply-to-tab'>
|
||||
{{#if loadingReplyHistory}}
|
||||
{{i18n loading}}
|
||||
{{else}}
|
||||
{{i18n post.in_reply_to}}
|
||||
@@ -31,7 +27,7 @@
|
||||
<div class='topic-body span14'>
|
||||
<button {{action selectPost this}} {{bindAttr class=":post-select controller.multiSelect::hidden"}}>{{view.selectText}}</button>
|
||||
|
||||
<div {{bindAttr class="showUserReplyTab:avoid-tab view.repliesHidden:bottom-round :contents :regular view.extraClass"}}>
|
||||
<div {{bindAttr class="showUserReplyTab:avoid-tab view.repliesShown::bottom-round :contents :regular view.extraClass"}}>
|
||||
{{#unless controller.multiSelect}}
|
||||
<div class='topic-meta-data-inside'>
|
||||
{{#if hasHistory}}
|
||||
|
||||
@@ -0,0 +1 @@
|
||||
the world ain't all sunshine and rainbows
|
||||
@@ -1,29 +0,0 @@
|
||||
/*global Markdown:true*/
|
||||
|
||||
/**
|
||||
A control to support embedding a post as a parent of the current post (in reply to)
|
||||
|
||||
@class ParentView
|
||||
@extends Discourse.EmbeddedPostView
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.ParentView = Discourse.EmbeddedPostView.extend({
|
||||
previousPost: true,
|
||||
|
||||
// Nice animation for when the replies appear
|
||||
didInsertElement: function() {
|
||||
this._super();
|
||||
|
||||
var $parentPost = this.get('postView').$('section.parent-post');
|
||||
|
||||
// Animate unless we're on a touch device
|
||||
if (Discourse.get('touch')) {
|
||||
$parentPost.show();
|
||||
} else {
|
||||
$parentPost.slideDown();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -19,7 +19,8 @@ Discourse.PostMenuView = Discourse.View.extend({
|
||||
'post.bookmarkClass',
|
||||
'post.bookmarkTooltip',
|
||||
'post.shareUrl',
|
||||
'post.topic.deleted_at'),
|
||||
'post.topic.deleted_at',
|
||||
'post.replies.length'),
|
||||
|
||||
render: function(buffer) {
|
||||
var post = this.get('post');
|
||||
@@ -55,12 +56,16 @@ Discourse.PostMenuView = Discourse.View.extend({
|
||||
buffer.push("<span class='badge-posts'>" + reply_count + "</span>");
|
||||
buffer.push(I18n.t("post.has_replies", { count: reply_count }));
|
||||
|
||||
var icon = this.get('postView.repliesShown') ? 'icon-chevron-up' : 'icon-chevron-down';
|
||||
var icon = (this.get('post.replies.length') > 0) ? 'icon-chevron-up' : 'icon-chevron-down';
|
||||
return buffer.push("<i class='icon " + icon + "'></i></button>");
|
||||
},
|
||||
|
||||
clickReplies: function() {
|
||||
this.get('postView').showReplies();
|
||||
if (this.get('post.replies.length') > 0) {
|
||||
this.set('post.replies', []);
|
||||
} else {
|
||||
this.get('post').loadReplies();
|
||||
}
|
||||
},
|
||||
|
||||
// Delete button
|
||||
|
||||
@@ -12,8 +12,7 @@ Discourse.PostView = Discourse.GroupedView.extend({
|
||||
classNameBindings: ['postTypeClass',
|
||||
'selected',
|
||||
'post.hidden:hidden',
|
||||
'post.deleted',
|
||||
'parentPost:replies-above'],
|
||||
'post.deleted'],
|
||||
postBinding: 'content',
|
||||
|
||||
postTypeClass: function() {
|
||||
@@ -44,56 +43,7 @@ Discourse.PostView = Discourse.GroupedView.extend({
|
||||
return this.get('selected') ? I18n.t('topic.multi_select.selected', { count: this.get('controller.selectedPostsCount') }) : I18n.t('topic.multi_select.select');
|
||||
}.property('selected', 'controller.selectedPostsCount'),
|
||||
|
||||
repliesHidden: Em.computed.not('repliesShown'),
|
||||
|
||||
// Click on the replies button
|
||||
showReplies: function() {
|
||||
var postView = this;
|
||||
if (this.get('repliesShown')) {
|
||||
this.set('repliesShown', false);
|
||||
} else {
|
||||
this.get('post').loadReplies().then(function() {
|
||||
postView.set('repliesShown', true);
|
||||
});
|
||||
}
|
||||
return false;
|
||||
},
|
||||
|
||||
// Toggle visibility of parent post
|
||||
toggleParent: function(e) {
|
||||
var postView = this;
|
||||
var post = this.get('post');
|
||||
var $parent = this.$('.parent-post');
|
||||
var inReplyTo = post.get('reply_to_post_number');
|
||||
|
||||
if (post.get('post_number') - 1 === inReplyTo) {
|
||||
// true means ... avoid scroll if possible
|
||||
Discourse.TopicView.jumpToPost(post.get('topic_id'), inReplyTo, true);
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.get('parentPost')) {
|
||||
$('nav', $parent).removeClass('toggled');
|
||||
// Don't animate on touch
|
||||
if (Discourse.get('touch')) {
|
||||
$parent.hide();
|
||||
this.set('parentPost', null);
|
||||
} else {
|
||||
$parent.slideUp(function() { postView.set('parentPost', null); });
|
||||
}
|
||||
} else {
|
||||
this.set('loadingParent', true);
|
||||
$('nav', $parent).addClass('toggled');
|
||||
|
||||
Discourse.Post.loadByPostNumber(post.get('topic_id'), inReplyTo).then(function(result) {
|
||||
postView.set('loadingParent', false);
|
||||
// Give the post a reference back to the topic
|
||||
result.topic = postView.get('post.topic');
|
||||
postView.set('parentPost', result);
|
||||
});
|
||||
}
|
||||
return false;
|
||||
},
|
||||
repliesShown: Em.computed.gt('post.replies.length', 0),
|
||||
|
||||
updateQuoteElements: function($aside, desc) {
|
||||
var navLink = "";
|
||||
@@ -143,7 +93,7 @@ Discourse.PostView = Discourse.GroupedView.extend({
|
||||
if ($aside.data('topic')) {
|
||||
topic_id = $aside.data('topic');
|
||||
}
|
||||
Discourse.ajax("/posts/by_number/" + topic_id + "/" + ($aside.data('post'))).then(function (result) {
|
||||
Discourse.ajax("/posts/by_number/" + topic_id + "/" + $aside.data('post')).then(function (result) {
|
||||
var parsed = $(result.cooked);
|
||||
parsed.replaceText(originalText, "<span class='highlighted'>" + originalText + "</span>");
|
||||
$blockQuote.showHtml(parsed);
|
||||
|
||||
@@ -7,24 +7,10 @@
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.RepliesView = Ember.CollectionView.extend({
|
||||
templateName: 'replies',
|
||||
tagName: 'section',
|
||||
classNames: ['replies-list', 'embedded-posts', 'bottom'],
|
||||
classNameBindings: [':embedded-posts', ':bottom', 'hidden'],
|
||||
itemViewClass: Discourse.EmbeddedPostView,
|
||||
|
||||
repliesShownChanged: function() {
|
||||
var $this = this.$();
|
||||
if (this.get('parentView.repliesShown')) {
|
||||
Em.run.schedule('afterRender', function() {
|
||||
$this.slideDown();
|
||||
});
|
||||
} else {
|
||||
Em.run.schedule('afterRender', function() {
|
||||
$this.slideUp();
|
||||
});
|
||||
}
|
||||
}.observes('parentView.repliesShown')
|
||||
|
||||
hidden: Em.computed.equal('content.length', 0)
|
||||
});
|
||||
|
||||
|
||||
|
||||
17
app/assets/javascripts/discourse/views/reply_history.js
Normal file
17
app/assets/javascripts/discourse/views/reply_history.js
Normal file
@@ -0,0 +1,17 @@
|
||||
/**
|
||||
Lists previous posts in the history of a post.
|
||||
|
||||
@class ReplyHistory
|
||||
@extends Discourse.EmbeddedPostView
|
||||
@namespace Discourse
|
||||
@module Discourse
|
||||
**/
|
||||
Discourse.ReplyHistory = Em.CollectionView.extend({
|
||||
tagName: 'section',
|
||||
classNameBindings: [':embedded-posts', ':top', ':span14', ':offset2', 'hidden'],
|
||||
itemViewClass: Discourse.EmbeddedPostView,
|
||||
hidden: Em.computed.equal('content.length', 0),
|
||||
previousPost: true
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user