mirror of
https://github.com/codeninjasllc/discourse.git
synced 2024-11-30 10:58:31 -05:00
FEATURE: Show time gap between posts if more than a few days
This commit is contained in:
parent
4e898c604e
commit
42bd9b6199
10 changed files with 125 additions and 5 deletions
20
app/assets/javascripts/discourse/components/time-gap.js.es6
Normal file
20
app/assets/javascripts/discourse/components/time-gap.js.es6
Normal file
|
@ -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';
|
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({
|
const PostStream = RestModel.extend({
|
||||||
loading: Em.computed.or('loadingAbove', 'loadingBelow', 'loadingFilter', 'stagingPost'),
|
loading: Em.computed.or('loadingAbove', 'loadingBelow', 'loadingFilter', 'stagingPost'),
|
||||||
notLoading: Em.computed.not('loading'),
|
notLoading: Em.computed.not('loading'),
|
||||||
|
@ -367,14 +383,22 @@ const PostStream = RestModel.extend({
|
||||||
},
|
},
|
||||||
|
|
||||||
prependPost(post) {
|
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;
|
return post;
|
||||||
},
|
},
|
||||||
|
|
||||||
appendPost(post) {
|
appendPost(post) {
|
||||||
const stored = this.storePost(post);
|
const stored = this.storePost(post);
|
||||||
if (stored) {
|
if (stored) {
|
||||||
this.get('posts').addObject(stored);
|
const posts = this.get('posts');
|
||||||
|
calcDayDiff(stored, posts.get('lastObject'));
|
||||||
|
posts.addObject(stored);
|
||||||
}
|
}
|
||||||
return post;
|
return post;
|
||||||
},
|
},
|
||||||
|
|
|
@ -27,6 +27,10 @@ const Post = RestModel.extend({
|
||||||
notDeleted: Em.computed.not('deleted'),
|
notDeleted: Em.computed.not('deleted'),
|
||||||
userDeleted: Em.computed.empty('user_id'),
|
userDeleted: Em.computed.empty('user_id'),
|
||||||
|
|
||||||
|
hasTimeGap: function() {
|
||||||
|
return (this.get('daysSincePrevious') || 0) > Discourse.SiteSettings.show_time_gap_days;
|
||||||
|
}.property('daysSincePrevious'),
|
||||||
|
|
||||||
showName: function() {
|
showName: function() {
|
||||||
const name = this.get('name');
|
const name = this.get('name');
|
||||||
return name && (name !== this.get('username')) && Discourse.SiteSettings.display_name_on_posts;
|
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"}}
|
{{post-gap post=this postStream=controller.model.postStream before="true"}}
|
||||||
|
|
||||||
|
{{#if hasTimeGap}}
|
||||||
|
{{time-gap gapDays=daysSincePrevious}}
|
||||||
|
{{/if}}
|
||||||
|
|
||||||
<div class='row'>
|
<div class='row'>
|
||||||
{{view 'reply-history' content=replyHistory}}
|
{{view 'reply-history' content=replyHistory}}
|
||||||
</div>
|
</div>
|
||||||
|
|
|
@ -717,6 +717,21 @@ $topic-avatar-width: 45px;
|
||||||
width: calc(#{$topic-avatar-width} + #{$topic-body-width} + 2 * #{$topic-body-width-padding});
|
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 {
|
.posts-wrapper {
|
||||||
position: relative;
|
position: relative;
|
||||||
-webkit-font-smoothing: subpixel-antialiased;
|
-webkit-font-smoothing: subpixel-antialiased;
|
||||||
|
|
|
@ -92,6 +92,16 @@ en:
|
||||||
x_days:
|
x_days:
|
||||||
one: "1 day ago"
|
one: "1 day ago"
|
||||||
other: "%{count} days 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:
|
share:
|
||||||
topic: 'share a link to this topic'
|
topic: 'share a link to this topic'
|
||||||
post: 'post #%{postNumber}'
|
post: 'post #%{postNumber}'
|
||||||
|
|
|
@ -1120,6 +1120,7 @@ en:
|
||||||
full_name_required: "Full name is a required field of a user's profile."
|
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."
|
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."
|
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."
|
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."
|
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.)"
|
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:
|
display_name_on_posts:
|
||||||
client: true
|
client: true
|
||||||
default: false
|
default: false
|
||||||
|
show_time_gap_days:
|
||||||
|
default: 4
|
||||||
|
client: true
|
||||||
short_progress_text_threshold:
|
short_progress_text_threshold:
|
||||||
client: true
|
client: true
|
||||||
default: 10000
|
default: 10000
|
||||||
|
|
|
@ -26,6 +26,40 @@ test('defaults', function() {
|
||||||
present(postStream.get('topic'));
|
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() {
|
test('appending posts', function() {
|
||||||
const postStream = buildStream(4567, [1, 3, 4]);
|
const postStream = buildStream(4567, [1, 3, 4]);
|
||||||
const store = postStream.store;
|
const store = postStream.store;
|
||||||
|
|
Loading…
Reference in a new issue