discourse/app/assets/javascripts/discourse/widgets/post-stream.js.es6

135 lines
3.8 KiB
JavaScript

import { createWidget } from 'discourse/widgets/widget';
import transformPost from 'discourse/lib/transform-post';
import { Placeholder } from 'discourse/lib/posts-with-placeholders';
import { addWidgetCleanCallback } from 'discourse/components/mount-widget';
let transformCallbacks = null;
function postTransformCallbacks(transformed) {
if (transformCallbacks === null) {
return;
}
for(let i=0; i < transformCallbacks.length; i++) {
transformCallbacks[i].call(this, transformed);
}
}
export function addPostTransformCallback(callback){
transformCallbacks = transformCallbacks || [];
transformCallbacks.push(callback);
};
const CLOAKING_ENABLED = !window.inTestEnv;
const DAY = 1000 * 60 * 60 * 24;
const _dontCloak = {};
let _cloaked = {};
let _heights = {};
export function preventCloak(postId) {
_dontCloak[postId] = true;
}
export function cloak(post, component) {
if (!CLOAKING_ENABLED || _cloaked[post.id] || _dontCloak[post.id]) { return; }
const $post = $(`#post_${post.post_number}`);
_cloaked[post.id] = true;
_heights[post.id] = $post.outerHeight();
component.dirtyKeys.keyDirty(`post-${post.id}`);
Ember.run.debounce(component, 'queueRerender', 1000);
}
export function uncloak(post, component) {
if (!CLOAKING_ENABLED || !_cloaked[post.id]) { return; }
_cloaked[post.id] = null;
component.dirtyKeys.keyDirty(`post-${post.id}`);
component.queueRerender();
}
addWidgetCleanCallback('post-stream', () => {
_cloaked = {};
_heights = {};
});
export default createWidget('post-stream', {
tagName: 'div.post-stream',
html(attrs) {
const posts = attrs.posts || [];
const postArray = posts.toArray();
const result = [];
const before = attrs.gaps && attrs.gaps.before ? attrs.gaps.before : {};
const after = attrs.gaps && attrs.gaps.after ? attrs.gaps.after : {};
let prevPost;
let prevDate;
const mobileView = this.site.mobileView;
for (let i=0; i<postArray.length; i++) {
const post = postArray[i];
if (post instanceof Placeholder) {
result.push(this.attach('post-placeholder'));
continue;
}
const nextPost = (i < postArray.length - 1) ? postArray[i+1] : null;
const transformed = transformPost(this.currentUser, this.site, post, prevPost, nextPost);
transformed.canCreatePost = attrs.canCreatePost;
transformed.mobileView = mobileView;
if (transformed.canManage) {
transformed.multiSelect = attrs.multiSelect;
if (attrs.multiSelect) {
transformed.selected = attrs.selectedQuery(post);
}
}
if (attrs.searchService) {
transformed.highlightTerm = attrs.searchService.highlightTerm;
}
// Post gap - before
const beforeGap = before[post.id];
if (beforeGap) {
result.push(this.attach('post-gap', { pos: 'before', postId: post.id, gap: beforeGap }, { model: post }));
}
// Handle time gaps
const curTime = new Date(transformed.created_at).getTime();
if (prevDate) {
const daysSince = Math.floor((curTime - prevDate) / DAY);
if (daysSince > this.siteSettings.show_time_gap_days) {
result.push(this.attach('time-gap', { daysSince }));
}
}
prevDate = curTime;
transformed.height = _heights[post.id];
transformed.cloaked = _cloaked[post.id];
postTransformCallbacks(transformed);
if (transformed.isSmallAction) {
result.push(this.attach('post-small-action', transformed, { model: post }));
} else {
result.push(this.attach('post', transformed, { model: post }));
}
// Post gap - after
const afterGap = after[post.id];
if (afterGap) {
result.push(this.attach('post-gap', { pos: 'after', postId: post.id, gap: afterGap }, { model: post }));
}
prevPost = post;
}
return result;
}
});