function Metadata(modules) { var comments = modules.cache.make(function(threadId) { return modules.async.bind( modules.async.parallel( getJSON(url(threadId)), getJSON(url(threadId) + '/context'), ), modules.async.map(function(t) { return [renderLink(t[0]), renderAnswers(t[1])]; }) ); }); return { get: get, getComments: getComments }; function url(threadId) { return blog.path.commentsAt + '/api/v1/statuses/' + threadId; } function getJSON(url) { return modules.async.bind( modules.async.http({method: 'GET', url: url}), function(queryResult) { if(queryResult.status == 200) { try { return modules.async.wrap(JSON.parse(queryResult.responseText)); } catch(e) { return modules.async.fail('Server returned invalid JSON for ' + url); } } else { return modules.async.fail('Could not load page ' + url); } } ); } function getComments(articleKey) { var threadId = blog.articles[articleKey].metadata.comments; if(blog.path.commentsAt != undefined && threadId != undefined) { var ul = modules.dom.make('ul'); var div = emptySection(ul); modules.async.run( modules.async.bind( comments.get(threadId), modules.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 modules.dom.make('div', {class: 'comments'}, [ modules.dom.make('h2', {innerText: blog.wording.commentsSection}), ul ]); } function renderLink(post) { return modules.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 [ ', shortcode, ' ].join('"'); } else { return pattern; } }); } function renderAnswers(comments) { return comments.descendants.map(function(descendant) { return modules.dom.make('li', {}, [ modules.dom.make('a', {href: descendant.account.url}, [ modules.dom.make('img', { src: descendant.account.avatar, alt: descendant.account.username + "'s profile picture" }) ]), modules.dom.make('div', { class: "metadata", innerHTML: modules.template.render('metadata', { author: author(descendant.account.url, descendant.account.username), date: date(descendant.created_at) }) }), modules.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 '' + author + ''; } } 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 '' + tag + ''; }).join(', '); } function get(key) { return modules.dom.make('div', { class: "metadata", innerHTML: modules.template.render('metadata', { author: author(key), date: date(key), tags: tags(key) }) }); } }