159 lines
4 KiB
JavaScript
159 lines
4 KiB
JavaScript
import blog from Hablo.Config;
|
|
import Template;
|
|
import * as Async from UnitJS.Async;
|
|
import * as Cache from UnitJS.Cache;
|
|
import * as Dom from UnitJS.Dom;
|
|
|
|
var comments = Cache.make(function(threadId) {
|
|
return Async.bind(
|
|
Async.parallel(
|
|
getJSON(url(threadId)),
|
|
getJSON(url(threadId) + '/context'),
|
|
),
|
|
Async.map(function(t) {
|
|
return [renderLink(t[0]), renderAnswers(t[1])];
|
|
})
|
|
);
|
|
});
|
|
return {
|
|
get: get,
|
|
getComments: getComments
|
|
};
|
|
|
|
function url(threadId) {
|
|
return blog.urls.comments + '/api/v1/statuses/' + threadId;
|
|
}
|
|
|
|
function getJSON(url) {
|
|
return Async.bind(
|
|
Async.http({method: 'GET', url: url}),
|
|
function(queryResult) {
|
|
if(queryResult.status == 200) {
|
|
try {
|
|
return Async.wrap(JSON.parse(queryResult.responseText));
|
|
} catch(e) {
|
|
return Async.fail('Server returned invalid JSON for ' + url);
|
|
}
|
|
} else {
|
|
return Async.fail('Could not load page ' + url);
|
|
}
|
|
}
|
|
);
|
|
}
|
|
|
|
function getComments(articleKey) {
|
|
var threadId = blog.articles[articleKey].metadata.comments;
|
|
if(blog.urls.comments != undefined && threadId != undefined) {
|
|
var ul = Dom.make('ul');
|
|
var div = emptySection(ul);
|
|
Async.run(
|
|
Async.bind(
|
|
comments.get(threadId), Async.map(populateComments(div, ul))
|
|
)
|
|
);
|
|
return [div];
|
|
} else {
|
|
return [];
|
|
}
|
|
}
|
|
|
|
function populateComments(div, ul) {
|
|
return function(apiResults) {
|
|
var post = apiResults[0], comments = apiResults[1];
|
|
div.appendChild(post);
|
|
comments.forEach(function(comment) {ul.appendChild(comment);});
|
|
};
|
|
}
|
|
|
|
function emptySection(ul) {
|
|
return Dom.make('div', {class: 'comments'}, [
|
|
Dom.make('h2', {innerText: blog.wording.commentsSection}),
|
|
ul
|
|
]);
|
|
}
|
|
|
|
function renderLink(post) {
|
|
return Dom.make('a', {
|
|
href: post.url,
|
|
innerText: blog.wording.commentsLink
|
|
});
|
|
}
|
|
|
|
function getContent(descendant) {
|
|
return descendant.content.replace(/:([^: ]+):/g, function(pattern, shortcode) {
|
|
var emoji = descendant.emojis.find(function(e) {return e.shortcode == shortcode;});
|
|
if(emoji) {
|
|
return [
|
|
'<img title=', shortcode, ' alt=', shortcode, ' src=', emoji.url, ' class="emoji"/>'
|
|
].join('"');
|
|
} else {
|
|
return pattern;
|
|
}
|
|
});
|
|
}
|
|
|
|
function renderAnswers(comments) {
|
|
return comments.descendants.map(function(descendant) {
|
|
return Dom.make('li', {}, [
|
|
Dom.make('a', {href: descendant.account.url}, [
|
|
Dom.make('img', {
|
|
src: descendant.account.avatar,
|
|
alt: descendant.account.username + "'s profile picture"
|
|
})
|
|
]),
|
|
Dom.make('div', {
|
|
class: "metadata",
|
|
innerHTML: Template.render('metadata', {
|
|
author: author(descendant.account.url, descendant.account.username),
|
|
date: date(descendant.created_at)
|
|
})
|
|
}),
|
|
Dom.make('div', {innerHTML: getContent(descendant)})
|
|
]);
|
|
});
|
|
}
|
|
|
|
function author(key, name) {
|
|
var authorUrl = key;
|
|
if(blog.articles[key] != undefined) {
|
|
authorUrl = blog.articles[key].metadata.author;
|
|
}
|
|
if(authorUrl) {
|
|
var author = name || authorUrl.replace(/.*\//, '');
|
|
return '<a href="' + authorUrl + '">' + author + '</a>';
|
|
}
|
|
}
|
|
|
|
function date(key) {
|
|
if(blog.articles[key] != undefined) {
|
|
var date = new Date(blog.articles[key].metadata.date * 1000);
|
|
} else {
|
|
var date = new Date(key);
|
|
}
|
|
var format = blog.wording.dateFormat;
|
|
if(format[0] != '[') {
|
|
if(format[0] != '"') {
|
|
format = '"' + format + '"';
|
|
}
|
|
format = '[' + format + ']';
|
|
}
|
|
return Date.prototype.toLocaleDateString.apply(date, JSON.parse(format));
|
|
}
|
|
|
|
function tags(key) {
|
|
var tags = blog.articles[key].tagged;
|
|
return tags.length < 1 ? null : tags.map(function(tag) {
|
|
return '<a class="tag" href="/' + tag + '">' + tag + '</a>';
|
|
}).join(', ');
|
|
}
|
|
|
|
function get(key) {
|
|
return Dom.make('div', {
|
|
class: "metadata",
|
|
innerHTML: Template.render('metadata', {
|
|
author: author(key),
|
|
date: date(key),
|
|
tags: tags(key)
|
|
})
|
|
});
|
|
}
|