const IMAGE_REGEXP = /(.gif|.jpg|.jpeg|.png)$/gi;
var HootStream = View.extend({
el: "#hootstream",
initialize: function ({ parent }) {
this.parent = parent;
this.$hootevents = this.$("#hootevents");
this.hootTemplate = this.$(".hootTemplate").html();
this.threadTemplate = this.$(".threadTemplate").html();
this.lastlogTemplate = this.$(".lastlogTemplate").html();
this.fileTemplate = this.$(".fileTemplate").html();
},
load: function (data) {
this.$hootevents.empty();
const { order, threadLookup } = this.agglutinate(data);
console.log(data, threadLookup, order);
const $els = order.map(
function (item) {
return item.type === "thread"
? this.renderThread(threadLookup[item.thread_id]).reduce(
($el, $item) => $el.append($item),
$("
")
)
: item.type === "hoot"
? this.renderHoot(item.data)
: item.type === "lastlog"
? this.renderLastlog(item.data)
: "Unknown item";
}.bind(this)
);
this.$hootevents.append($els);
},
render: (template, object) => {
const rendered = Object.entries(object).reduce(
(newTemplate, [key, value]) =>
newTemplate.replace(new RegExp(`{{${key}}}`, "g"), value),
template
);
return $(rendered);
},
renderLastlog: function ({ username, lastseen }) {
const age = get_age(lastseen);
const age_ago = age === "now" ? age : `${age} ago`;
return this.render(this.lastlogTemplate, {
className: "hoot streamLastlog",
username,
age,
opacity: 0.6,
showAvatar: 0,
hoot: "last seen " + age_ago,
});
},
renderHoot: function ({
id,
thread,
date,
username,
hoot,
comment,
hidden,
className,
showAvatar,
template,
...options
}) {
// console.log(hoot, comment);
return this.render(template || this.hootTemplate, {
username,
className: className ? `hoot ${className}` : "hoot",
image: profile_image(username),
showAvatar: showAvatar === false ? 0 : 1,
hoot:
hoot || "
" + tidy_urls(comment, true) + "
",
age: get_age(date),
age_opacity: get_age_opacity(date),
...options,
});
},
renderHoots: function ({ hoots, className }) {
const els = [];
for (hoot of hoots) {
els.push(this.renderHoot({ ...hoot, className }));
}
return els;
},
renderThread: function ({ thread, comments, files, images }) {
thread = thread.shift();
// console.log(thread, comments, files, images);
const postedToday = +new Date() / 1000 - thread.lastmodified < 86400;
const age_opacity = get_age_opacity(thread.lastmodified);
return [
"
",
this.renderHoot({
template: this.threadTemplate,
hoot: `
${thread.title}`,
keyword_link: thread.keyword
? `
${thread.keyword}`
: "",
username: thread.username,
className: postedToday ? "isRecent" : "",
date: thread.lastmodified,
file_count: `${files.length || 0} f.`,
file_opacity: age_opacity * get_size_opacity(files.length),
comment_count: `${comments.length || 0} c.`,
comment_opacity: age_opacity * get_size_opacity(files.length),
}),
this.renderFiles(postedToday ? files : files.slice(0, 10)),
...this.renderHoots({ hoots: comments.slice(0, 1), tag: "first_post" }),
...this.renderHoots({
hoots: postedToday ? comments.slice(1) : comments.slice(1).slice(-5),
}),
"
",
];
// say "in ... "
// audio player OR recent file list
// recent 3 comments
},
renderFiles: function (files) {
if (!files.length) {
return null;
}
const $table = $("
");
for (const file of files) {
const $el = this.renderFile(file);
$table.append($el);
}
return $table;
},
renderFile: function (file) {
var size = hush_size(file.size);
var datetime = verbose_date(file.date, true);
var date_class = carbon_date(file.date);
var link = make_link(file);
return this.render(this.fileTemplate, {
id: file.id,
username: file.username,
link,
filename: file.filename,
age: get_age(file.date),
age_opacity: get_age_opacity(file.date),
date_class,
date: datetime[0],
// time: datetime[1],
// size_class: size[0],
size: size[1],
});
},
agglutinate: ({ threads, comments, files, hootbox, lastlog }) =>
[
...threads.map((thread) => [
thread.id,
thread.createdate,
"thread",
thread,
]),
...comments
.filter((comment) => comment.thread !== 1)
.map((comment) => [comment.thread, comment.date, "comments", comment]),
...files.map((file) => [
file.thread,
file.date,
IMAGE_REGEXP.test(file.filename) ? "images" : "files",
file,
]),
...hootbox.map((hoot) => [1, hoot.date, "hoot", hoot]),
...lastlog.map((user) => [1, user.lastseen, "lastlog", user]),
]
.sort((a, b) => b[1] - a[1])
.reduce(
({ threadLookup, order }, [thread_id, date, type, data]) => {
if (type === "hoot") {
order.push({ type: "hoot", date, data });
} else if (type === "lastlog") {
order.push({ type: "lastlog", date, data });
} else if (thread_id !== 1) {
if (!(thread_id in threadLookup)) {
threadLookup[thread_id] = {
thread: [],
comments: [],
files: [],
images: [],
};
order.push({ type: "thread", date, thread_id });
}
threadLookup[thread_id][type].push(data);
}
return { threadLookup, order };
},
{ threadLookup: {}, order: [] }
),
});