FEATURE: Show time gap between posts if more than a few days
This commit is contained in:
parent
4e898c604e
commit
42bd9b6199
|
@ -0,0 +1,20 @@
|
|||
export default Ember.Component.extend({
|
||||
classNameBindings: [':time-gap'],
|
||||
|
||||
render(buffer) {
|
||||
const gapDays = this.get('gapDays');
|
||||
|
||||
let timeGapWords;
|
||||
if (gapDays < 30) {
|
||||
timeGapWords = I18n.t('dates.later.x_days', {count: gapDays});
|
||||
} else if (gapDays < 365) {
|
||||
const gapMonths = Math.floor(gapDays / 30);
|
||||
timeGapWords = I18n.t('dates.later.x_months', {count: gapMonths});
|
||||
} else {
|
||||
const gapYears = Math.floor(gapDays / 365);
|
||||
timeGapWords = I18n.t('dates.later.x_years', {count: gapYears});
|
||||
}
|
||||
|
||||
buffer.push("<div class='time-gap-words'>" + timeGapWords + "</div>");
|
||||
}
|
||||
});
|
|
@ -1,5 +1,21 @@
|
|||
import RestModel from 'discourse/models/rest';
|
||||
|
||||
function calcDayDiff(p1, p2) {
|
||||
if (!p1) { return; }
|
||||
|
||||
const date = p1.get('created_at');
|
||||
if (date) {
|
||||
if (p2) {
|
||||
const lastDate = p2.get('created_at');
|
||||
if (lastDate) {
|
||||
const delta = new Date(date).getTime() - new Date(lastDate).getTime();
|
||||
const days = Math.round(delta / (1000 * 60 * 60 * 24));
|
||||
|
||||
p1.set('daysSincePrevious', days);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
const PostStream = RestModel.extend({
|
||||
loading: Em.computed.or('loadingAbove', 'loadingBelow', 'loadingFilter', 'stagingPost'),
|
||||
notLoading: Em.computed.not('loading'),
|
||||
|
@ -367,14 +383,22 @@ const PostStream = RestModel.extend({
|
|||
},
|
||||
|
||||
prependPost(post) {
|
||||
this.get('posts').unshiftObject(this.storePost(post));
|
||||
const stored = this.storePost(post);
|
||||
if (stored) {
|
||||
const posts = this.get('posts');
|
||||
calcDayDiff(posts.get('firstObject'), stored);
|
||||
posts.unshiftObject(stored);
|
||||
}
|
||||
|
||||
return post;
|
||||
},
|
||||
|
||||
appendPost(post) {
|
||||
const stored = this.storePost(post);
|
||||
if (stored) {
|
||||
this.get('posts').addObject(stored);
|
||||
const posts = this.get('posts');
|
||||
calcDayDiff(stored, posts.get('lastObject'));
|
||||
posts.addObject(stored);
|
||||
}
|
||||
return post;
|
||||
},
|
||||
|
|
|
@ -27,6 +27,10 @@ const Post = RestModel.extend({
|
|||
notDeleted: Em.computed.not('deleted'),
|
||||
userDeleted: Em.computed.empty('user_id'),
|
||||
|
||||
hasTimeGap: function() {
|
||||
return (this.get('daysSincePrevious') || 0) > Discourse.SiteSettings.show_time_gap_days;
|
||||
}.property('daysSincePrevious'),
|
||||
|
||||
showName: function() {
|
||||
const name = this.get('name');
|
||||
return name && (name !== this.get('username')) && Discourse.SiteSettings.display_name_on_posts;
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
<div class='time-gap'>
|
||||
<div class='time-gap-days'>
|
||||
{{gapInWords}}
|
||||
</div>
|
||||
</div>
|
|
@ -1,5 +1,9 @@
|
|||
{{post-gap post=this postStream=controller.model.postStream before="true"}}
|
||||
|
||||
{{#if hasTimeGap}}
|
||||
{{time-gap gapDays=daysSincePrevious}}
|
||||
{{/if}}
|
||||
|
||||
<div class='row'>
|
||||
{{view 'reply-history' content=replyHistory}}
|
||||
</div>
|
||||
|
|
|
@ -717,6 +717,21 @@ $topic-avatar-width: 45px;
|
|||
width: calc(#{$topic-avatar-width} + #{$topic-body-width} + 2 * #{$topic-body-width-padding});
|
||||
}
|
||||
|
||||
.time-gap {
|
||||
width: 755px;
|
||||
border-top: 1px solid dark-light-diff($primary, $secondary, 90%, -60%);
|
||||
}
|
||||
.time-gap-words {
|
||||
display: inline-block;
|
||||
padding: 0.5em 1em;
|
||||
margin: 0.5em 0 0.5em 56px;
|
||||
text-transform: uppercase;
|
||||
font-weight: bold;
|
||||
font-size: 0.8em;
|
||||
background-color: dark-light-diff($primary, $secondary, 90%, -60%);
|
||||
color: lighten($primary, 30%);
|
||||
}
|
||||
|
||||
.posts-wrapper {
|
||||
position: relative;
|
||||
-webkit-font-smoothing: subpixel-antialiased;
|
||||
|
|
|
@ -92,6 +92,16 @@ en:
|
|||
x_days:
|
||||
one: "1 day ago"
|
||||
other: "%{count} days ago"
|
||||
later:
|
||||
x_days:
|
||||
one: "1 day layer"
|
||||
other: "%{count} days later"
|
||||
x_months:
|
||||
one: "1 month layer"
|
||||
other: "%{count} months later"
|
||||
x_years:
|
||||
one: "1 year layer"
|
||||
other: "%{count} years later"
|
||||
share:
|
||||
topic: 'share a link to this topic'
|
||||
post: 'post #%{postNumber}'
|
||||
|
|
|
@ -1120,6 +1120,7 @@ en:
|
|||
full_name_required: "Full name is a required field of a user's profile."
|
||||
enable_names: "Show the user's full name on their profile, user card, and emails. Disable to hide full name everywhere."
|
||||
display_name_on_posts: "Show a user's full name on their posts in addition to their @username."
|
||||
show_time_gap_days: "If two posts are made this many days apart, display the time gap in the topic."
|
||||
invites_per_page: "Default invites shown on the user page."
|
||||
short_progress_text_threshold: "After the number of posts in a topic goes above this number, the progress bar will only show the current post number. If you change the progress bar's width, you may need to change this value."
|
||||
default_code_lang: "Default programming language syntax highlighting applied to GitHub code blocks (lang-auto, ruby, python etc.)"
|
||||
|
|
|
@ -415,6 +415,9 @@ posting:
|
|||
display_name_on_posts:
|
||||
client: true
|
||||
default: false
|
||||
show_time_gap_days:
|
||||
default: 4
|
||||
client: true
|
||||
short_progress_text_threshold:
|
||||
client: true
|
||||
default: 10000
|
||||
|
|
|
@ -26,6 +26,40 @@ test('defaults', function() {
|
|||
present(postStream.get('topic'));
|
||||
});
|
||||
|
||||
test('daysSincePrevious when appending', function(assert) {
|
||||
const postStream = buildStream(10000001, [1,2,3]);
|
||||
const store = postStream.store;
|
||||
|
||||
const p1 = store.createRecord('post', {id: 1, post_number: 1, created_at: "2015-05-29T18:17:35.868Z"}),
|
||||
p2 = store.createRecord('post', {id: 2, post_number: 2, created_at: "2015-06-01T01:07:25.761Z"}),
|
||||
p3 = store.createRecord('post', {id: 3, post_number: 3, created_at: "2015-06-02T01:07:25.761Z"});
|
||||
|
||||
postStream.appendPost(p1);
|
||||
postStream.appendPost(p2);
|
||||
postStream.appendPost(p3);
|
||||
|
||||
assert.ok(!p1.get('daysSincePrevious'));
|
||||
assert.equal(p2.get('daysSincePrevious'), 2);
|
||||
assert.equal(p3.get('daysSincePrevious'), 1);
|
||||
});
|
||||
|
||||
test('daysSincePrevious when prepending', function(assert) {
|
||||
const postStream = buildStream(10000001, [1,2,3]);
|
||||
const store = postStream.store;
|
||||
|
||||
const p1 = store.createRecord('post', {id: 1, post_number: 1, created_at: "2015-05-29T18:17:35.868Z"}),
|
||||
p2 = store.createRecord('post', {id: 2, post_number: 2, created_at: "2015-06-01T01:07:25.761Z"}),
|
||||
p3 = store.createRecord('post', {id: 3, post_number: 3, created_at: "2015-06-02T01:07:25.761Z"});
|
||||
|
||||
postStream.prependPost(p3);
|
||||
postStream.prependPost(p2);
|
||||
postStream.prependPost(p1);
|
||||
|
||||
assert.ok(!p1.get('daysSincePrevious'));
|
||||
assert.equal(p2.get('daysSincePrevious'), 2);
|
||||
assert.equal(p3.get('daysSincePrevious'), 1);
|
||||
});
|
||||
|
||||
test('appending posts', function() {
|
||||
const postStream = buildStream(4567, [1, 3, 4]);
|
||||
const store = postStream.store;
|
||||
|
|
Loading…
Reference in New Issue