diff --git a/js/src/forum/components/PostStream.js b/js/src/forum/components/PostStream.js
index 667d27694..fcff6e723 100644
--- a/js/src/forum/components/PostStream.js
+++ b/js/src/forum/components/PostStream.js
@@ -32,6 +32,13 @@ export default class PostStream extends Component {
const posts = this.stream.posts();
const postIds = this.discussion.postIds();
+ const postFadeIn = (vnode) => {
+ $(vnode.dom).addClass('fadeIn');
+ // 500 is the duration of the fadeIn CSS animation + 100ms,
+ // so the animation has time to complete
+ setTimeout(() => $(vnode.dom).removeClass('fadeIn'), 500);
+ };
+
const items = posts.map((post, i) => {
let content;
const attrs = { 'data-index': this.stream.visibleStart + i };
@@ -42,6 +49,7 @@ export default class PostStream extends Component {
content = PostComponent ? PostComponent.component({ post }) : '';
attrs.key = 'post' + post.id();
+ attrs.oncreate = postFadeIn;
attrs['data-time'] = time.toISOString();
attrs['data-number'] = post.number();
attrs['data-id'] = post.id();
@@ -89,7 +97,7 @@ export default class PostStream extends Component {
// is not already doing so, then show a 'write a reply' placeholder.
if (viewingEnd && (!app.session.user || this.discussion.canReply())) {
items.push(
-
+
{ReplyPlaceholder.component({ discussion: this.discussion })}
);
@@ -389,10 +397,11 @@ export default class PostStream extends Component {
* @param {jQuery} $item
*/
flashItem($item) {
+ // This might execute before the fadeIn class has been removed in PostStreamItem's
+ // oncreate, so we remove it just to be safe and avoid a double animation.
+ $item.removeClass('fadeIn');
$item.addClass('flash').on('animationend webkitAnimationEnd', (e) => {
- if (e.animationName === 'fadeIn') {
- $item.removeClass('flash');
- }
+ $item.removeClass('flash');
});
}
}
diff --git a/less/forum/PostStream.less b/less/forum/PostStream.less
index b4ea701f8..9e649cb3b 100644
--- a/less/forum/PostStream.less
+++ b/less/forum/PostStream.less
@@ -6,18 +6,7 @@
margin-top: 10px;
}
}
-
-@-webkit-keyframes fadeIn {
- 0% {opacity: 0}
- 100% {opacity: 1}
-}
-@keyframes fadeIn {
- 0% {opacity: 0}
- 100% {opacity: 1}
-}
.PostStream-item {
- .animation(fadeIn 0.4s ease-in-out);
-
&:not(:last-child) {
border-bottom: 1px solid @control-bg;
@@ -104,3 +93,16 @@
.animation(pulsate 0.2s ease-in-out);
.animation-iteration-count(1);
}
+
+@-webkit-keyframes fadeIn {
+ 0% {opacity: 0}
+ 100% {opacity: 1}
+}
+@keyframes fadeIn {
+ 0% {opacity: 0}
+ 100% {opacity: 1}
+}
+.fadeIn {
+ .animation(fadeIn 0.4s ease-in-out);
+ .animation-iteration-count(1);
+}