hablo/share/js/Metadata.js

160 lines
4 KiB
JavaScript
Raw Permalink Normal View History

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)
})
});
}