Merge pull request 'Implement full flair functionality' (#72) from StevenNMeza/teddit:flairs into main

Reviewed-on: https://codeberg.org/teddit/teddit/pulls/72
This commit is contained in:
teddit 2020-12-23 11:26:17 +01:00
commit 24b686fe1e
11 changed files with 184 additions and 107 deletions

View File

@ -2,6 +2,7 @@ const config = {
domain: process.env.DOMAIN || '127.0.0.1', // Or for example 'teddit.net' domain: process.env.DOMAIN || '127.0.0.1', // Or for example 'teddit.net'
reddit_app_id: process.env.REDDIT_APP_ID || 'H6-HjZ5pUPjaFQ', // You should obtain your own Reddit app ID. For testing purposes it's okay to use this project's default app ID. Create your Reddit app here: https://old.reddit.com/prefs/apps/. Make sure to create an "installed app" type of app. reddit_app_id: process.env.REDDIT_APP_ID || 'H6-HjZ5pUPjaFQ', // You should obtain your own Reddit app ID. For testing purposes it's okay to use this project's default app ID. Create your Reddit app here: https://old.reddit.com/prefs/apps/. Make sure to create an "installed app" type of app.
cert_dir: process.env.CERT_DIR || '', // For example '/home/teddit/letsencrypt/live/teddit.net', if you are using https. No trailing slash. cert_dir: process.env.CERT_DIR || '', // For example '/home/teddit/letsencrypt/live/teddit.net', if you are using https. No trailing slash.
flairs_enabled: process.env.FLAIRS_ENABLED !== "true" || true, // Enables the rendering of user and link flairs on teddit
api_enabled: process.env.API_ENABLED !== "true" || true, // Teddit API feature. Might increase loads significantly on your instance. api_enabled: process.env.API_ENABLED !== "true" || true, // Teddit API feature. Might increase loads significantly on your instance.
video_enabled: process.env.VIDEO_ENABLED !== "true" || true, video_enabled: process.env.VIDEO_ENABLED !== "true" || true,
redis_enabled: process.env.REDIS_ENABLED !== "true" || true, // If disabled, does not cache Reddit API calls redis_enabled: process.env.REDIS_ENABLED !== "true" || true, // If disabled, does not cache Reddit API calls
@ -34,7 +35,7 @@ const config = {
shorts: 60 * 60 * 24 * 31 shorts: 60 * 60 * 24 * 31
}, },
post_comments_sort: 'confidence', // "confidence" is the default sorting in Reddit. Must be one of: confidence, top, new, controversial, old, random, qa, live. post_comments_sort: 'confidence', // "confidence" is the default sorting in Reddit. Must be one of: confidence, top, new, controversial, old, random, qa, live.
valid_media_domains: ['preview.redd.it', 'external-preview.redd.it', 'i.redd.it', 'v.redd.it', 'a.thumbs.redditmedia.com', 'b.thumbs.redditmedia.com', 'thumbs.gfycat.com', 'i.ytimg.com'], valid_media_domains: ['preview.redd.it', 'external-preview.redd.it', 'i.redd.it', 'v.redd.it', 'a.thumbs.redditmedia.com', 'b.thumbs.redditmedia.com', 'emoji.redditmedia.com', 'thumbs.gfycat.com', 'i.ytimg.com'],
reddit_api_error_text: `Seems like your instance is either blocked (e.g. due to API rate limiting), reddit is currently down, or your API key is expired and not renewd properly. This can also happen for other reasons.` reddit_api_error_text: `Seems like your instance is either blocked (e.g. due to API rate limiting), reddit is currently down, or your API key is expired and not renewd properly. This can also happen for other reasons.`
}; };

49
dist/css/styles.css vendored
View File

@ -172,11 +172,6 @@ body.dark #search form input[type="text"] {
background: #0f0f0f; background: #0f0f0f;
color: white; color: white;
} }
body.dark #links .link .entry .title span.postflair,
body.dark #post .info .title span.postflair {
color: #eaeaea;
background-color: #404040;
}
a { a {
color: var(--linkcolor); color: var(--linkcolor);
text-decoration: none; text-decoration: none;
@ -402,16 +397,6 @@ input[type="submit"]:hover,
cursor: pointer; cursor: pointer;
text-decoration: none; text-decoration: none;
} }
#links .link .entry .title span.postflair,
#post .info .title span.postflair {
display: inline-block;
border-radius: 4px;
color: #404040;
background-color: #e8e8e8;
font-size: x-small;
margin-left: 10px;
padding: 0 2px;
}
/* SUBREDDIT LINKS */ /* SUBREDDIT LINKS */
#links { #links {
float: left; float: left;
@ -994,6 +979,40 @@ input[type="submit"]:hover,
#user .entries .entry a.context { #user .entries .entry a.context {
margin-right: 10px; margin-right: 10px;
} }
/* FLAIR */
.flair,
#links .link .entry .title span.flair,
#post .info .title span.flair {
display: inline-block;
border-radius: 4px;
color: #404040;
background-color: #e8e8e8;
font-size: x-small;
margin-left: 10px;
padding: 0 2px;
}
body.dark .flair {
color: #eaeaea !important;
background-color: #404040 !important;
}
#post .comments .flair,
#user .comment .meta .flair {
margin-left: 0 !important;
}
#links .link .entry .meta p.submitted .flair,
#user .comment .meta .flair,
#user .entries p.submitted .flair {
margin-right: 4px;
}
.flair .emoji {
background-position: center;
background-repeat: no-repeat;
background-size: contain;
display: inline-block;
height: 16px;
width: 16px;
vertical-align: middle;
}
/* SIDEBAR */ /* SIDEBAR */
#sidebar { #sidebar {
float: left; float: left;

View File

@ -1,4 +1,4 @@
module.exports = function(request, fs) { module.exports = function(request, fs) {
const config = require('../config') const config = require('../config')
this.downloadFile = (url) => { this.downloadFile = (url) => {
return new Promise(resolve => { return new Promise(resolve => {
@ -51,7 +51,7 @@ module.exports = function(request, fs) {
if(video_exts.includes(file_ext) || !image_exts.includes(file_ext)) if(video_exts.includes(file_ext) || !image_exts.includes(file_ext))
url = url.replace(u.host, `${config.domain}/vids`) + '.mp4' url = url.replace(u.host, `${config.domain}/vids`) + '.mp4'
} }
} catch(e) { } } catch(e) { }
return url return url
} }
@ -59,7 +59,7 @@ module.exports = function(request, fs) {
this.kFormatter = (num) => { this.kFormatter = (num) => {
return Math.abs(num) > 999 ? Math.sign(num)*((Math.abs(num)/1000).toFixed(1)) + 'k' : Math.sign(num)*Math.abs(num) return Math.abs(num) > 999 ? Math.sign(num)*((Math.abs(num)/1000).toFixed(1)) + 'k' : Math.sign(num)*Math.abs(num)
} }
this.timeDifference = (time) => { this.timeDifference = (time) => {
time = parseInt(time) * 1000 time = parseInt(time) * 1000
let ms_per_minute = 60 * 1000 let ms_per_minute = 60 * 1000
@ -121,7 +121,7 @@ module.exports = function(request, fs) {
return r return r
} }
} }
this.toUTCString = (time) => { this.toUTCString = (time) => {
let d = new Date(); let d = new Date();
d.setTime(time*1000); d.setTime(time*1000);
@ -165,7 +165,7 @@ module.exports = function(request, fs) {
}) })
}) })
} }
this.isGif = (url) => { this.isGif = (url) => {
try { try {
url = new URL(url) url = new URL(url)
@ -197,4 +197,61 @@ module.exports = function(request, fs) {
return '' return ''
} }
} }
this.formatLinkFlair = async (post) => {
if (!config.flairs_enabled) {
return ''
}
const wrap = (inner) => `<span class="flair">${inner}</span>`
if (post.link_flair_text === null)
return ''
if (post.link_flair_type === 'text')
return wrap(post.link_flair_text)
if (post.link_flair_type === 'richtext') {
let flair = ''
for (let fragment of post.link_flair_richtext) {
if (fragment.e === 'text')
flair += fragment.t
else if (fragment.e === 'emoji')
flair += `<span class="emoji" style="background-image: url(${await downloadAndSave(fragment.u, 'flair_')})"></span>`
}
return wrap(flair)
}
return ''
}
this.formatUserFlair = async (post) => {
if (!config.flairs_enabled) {
return ''
}
// Generate the entire HTML here for consistency in both pug and HTML
const wrap = (inner) => `<span class="flair">${inner}</span>`
if (post.author_flair_text === null)
return ''
if (post.author_flair_type === 'text')
return wrap(post.author_flair_text)
if (post.author_flair_type === 'richtext') {
let flair = ''
for (let fragment of post.author_flair_richtext) {
// `e` seems to mean `type`
if (fragment.e === 'text')
flair += fragment.t // `t` is the text
else if (fragment.e === 'emoji')
flair += `<span class="emoji" style="background-image: url(${await downloadAndSave(fragment.u, 'flair_')})"></span>` // `u` is the emoji URL
}
return wrap(flair)
}
return ''
}
} }

View File

@ -18,7 +18,7 @@ module.exports = function() {
let moderator = false let moderator = false
let submitter = false let submitter = false
let edited_span = '' let edited_span = ''
if(post_author === comments.author) { if(post_author === comments.author) {
classlist.push('submitter') classlist.push('submitter')
submitter_link = `<a href="${post_url}" title="submitter">[S]</a>` submitter_link = `<a href="${post_url}" title="submitter">[S]</a>`
@ -48,6 +48,7 @@ module.exports = function() {
</summary> </summary>
<div class="meta"> <div class="meta">
<p class="author">${commentAuthor(comments, classlist, submitter && submitter_link, moderator && moderator_badge)}</p> <p class="author">${commentAuthor(comments, classlist, submitter && submitter_link, moderator && moderator_badge)}</p>
<p>${comments.user_flair}</p>
<p class="ups">${ups}</p> <p class="ups">${ups}</p>
<p class="created" title="${toUTCString(comments.created)}"> <p class="created" title="${toUTCString(comments.created)}">
<a href="${comments.permalink}">${timeDifference(comments.created)}${edited_span}</a> <a href="${comments.permalink}">${timeDifference(comments.created)}${edited_span}</a>
@ -104,7 +105,7 @@ module.exports = function() {
let submitter = false let submitter = false
let ups = '' let ups = ''
let edited_span = '' let edited_span = ''
if(post_author === comment.author) { if(post_author === comment.author) {
classlist.push('submitter') classlist.push('submitter')
submitter_link = `<a href="${post_url}" title="submitter">[S]</a>` submitter_link = `<a href="${post_url}" title="submitter">[S]</a>`
@ -134,6 +135,7 @@ module.exports = function() {
</summary> </summary>
<div class="meta"> <div class="meta">
<p class="author">${commentAuthor(comment, classlist, submitter && submitter_link, moderator && moderator_badge)}</p> <p class="author">${commentAuthor(comment, classlist, submitter && submitter_link, moderator && moderator_badge)}</p>
<p>${comment.user_flair}</p>
<p class="ups">${ups}</p> <p class="ups">${ups}</p>
<p class="created" title="${toUTCString(comment.created)}"> <p class="created" title="${toUTCString(comment.created)}">
<a href="${comment.permalink}">${timeDifference(comment.created)}${edited_span}</a> <a href="${comment.permalink}">${timeDifference(comment.created)}${edited_span}</a>
@ -185,7 +187,7 @@ module.exports = function() {
comments_html += `</details></div>` comments_html += `</details></div>`
} }
next_comment_parent_id = null next_comment_parent_id = null
resolve(comments_html) resolve(comments_html)
})() })()
}) })

View File

@ -1,12 +1,12 @@
module.exports = function(tools) { module.exports = function(tools) {
const config = require('../config') const config = require('../config')
const {spawn} = require('child_process') const {spawn} = require('child_process')
const fs = require('fs') const fs = require('fs')
this.downloadAndSave = (url, file_prefix = '', gifmp4, isYouTubeThumbnail) => { this.downloadAndSave = (url, file_prefix = '', gifmp4, isYouTubeThumbnail) => {
/** /**
* This function downloads media (video or image) to disk. * This function downloads media (video or image) to disk.
* Returns a localized URL * Returns a localized URL
* *
* For example for images: * For example for images:
* https://external-preview.redd.it/DiaeK_j5fqpBqbatvo7GZzbHNJY2oxEym93B_3.jpg * https://external-preview.redd.it/DiaeK_j5fqpBqbatvo7GZzbHNJY2oxEym93B_3.jpg
* => * =>
@ -32,21 +32,23 @@ module.exports = function(tools) {
if(gifmp4) { if(gifmp4) {
file_ext = 'mp4' file_ext = 'mp4'
} else { } else {
if(!pathname.includes('.')) { if (file_prefix === 'flair_') {
/** // Flair emojis end in the name without a file extension
file_ext = 'png'
} else if(!pathname.includes('.')) { /**
* Sometimes reddit API returns video without extension, like * Sometimes reddit API returns video without extension, like
* "DASH_480" and not "DASH_480.mp4". * "DASH_480" and not "DASH_480.mp4".
*/ */
file_ext = 'mp4' file_ext = 'mp4'
has_extension = false has_extension = false
} else { } else {
file_ext = pathname.substring(pathname.lastIndexOf('.') + 1) file_ext = pathname.substring(pathname.lastIndexOf('.') + 1)
} }
} }
if(file_prefix === 'thumb_') if(file_prefix === 'thumb_')
dir = 'thumbs/' dir = 'thumbs/'
if(file_prefix === 'flair') if(file_prefix === 'flair_')
dir = 'flairs/' dir = 'flairs/'
if(valid_video_extensions.includes(file_ext) || gifmp4) { if(valid_video_extensions.includes(file_ext) || gifmp4) {
@ -130,7 +132,14 @@ module.exports = function(tools) {
if(temp_url.searchParams.get('width')) { if(temp_url.searchParams.get('width')) {
width = temp_url.searchParams.get('width') width = temp_url.searchParams.get('width')
} }
filename = `${file_prefix}w:${temp_url.searchParams.get('width')}_${temp_url.pathname.split('/').slice(-1)}` if(file_prefix === 'flair_') {
// Flair emojis have a full path of `UUID/name`,
// so we need to incorporate the UUID to avoid duplicates
// since names alone are not unique across all of reddit
filename = `${pathname.slice(1).replace('/', '_')}.png` // Only first replacement is fine
} else {
filename = `${file_prefix}w:${temp_url.searchParams.get('width')}_${temp_url.pathname.split('/').slice(-1)}`
}
} }
path = `./dist/pics/${dir}${filename}` path = `./dist/pics/${dir}${filename}`
if(!fs.existsSync(path)) { if(!fs.existsSync(path)) {

View File

@ -7,7 +7,7 @@ module.exports = function(fetch) {
if(!parsed) { if(!parsed) {
json = JSON.parse(json) json = JSON.parse(json)
} }
let post = json[0].data.children[0].data let post = json[0].data.children[0].data
let post_id = post.name let post_id = post.name
let comments = json[1].data.children let comments = json[1].data.children
@ -32,14 +32,16 @@ module.exports = function(fetch) {
media: null, media: null,
images: null, images: null,
crosspost: false, crosspost: false,
selftext: unescape(post.selftext_html) selftext: unescape(post.selftext_html),
link_flair: await formatLinkFlair(post),
user_flair: await formatUserFlair(post)
} }
let validEmbedDomains = ['gfycat.com', 'youtube.com'] let validEmbedDomains = ['gfycat.com', 'youtube.com']
let has_gif = false let has_gif = false
let gif_to_mp4 = null let gif_to_mp4 = null
let reddit_video = null let reddit_video = null
if(post.preview) { if(post.preview) {
if(post.preview.reddit_video_preview) { if(post.preview.reddit_video_preview) {
if(post.preview.reddit_video_preview.is_gif) { if(post.preview.reddit_video_preview.is_gif) {
@ -66,7 +68,7 @@ module.exports = function(fetch) {
} }
obj = await processPostMedia(obj, post, post.media, has_gif, reddit_video, gif_to_mp4) obj = await processPostMedia(obj, post, post.media, has_gif, reddit_video, gif_to_mp4)
if(post.crosspost_parent_list) { if(post.crosspost_parent_list) {
post.crosspost = post.crosspost_parent_list[0] post.crosspost = post.crosspost_parent_list[0]
} }
@ -84,7 +86,8 @@ module.exports = function(fetch) {
ups: post.crosspost.ups, ups: post.crosspost.ups,
selftext: unescape(post.selftext_html), selftext: unescape(post.selftext_html),
selftext_crosspost: unescape(post.crosspost.selftext_html), selftext_crosspost: unescape(post.crosspost.selftext_html),
is_crosspost: true is_crosspost: true,
user_flair: await formatUserFlair(post)
} }
} }
@ -93,7 +96,7 @@ module.exports = function(fetch) {
source: await downloadAndSave(post.preview.images[0].source.url) source: await downloadAndSave(post.preview.images[0].source.url)
} }
} }
if(obj.media) { if(obj.media) {
if(obj.media.source === 'external') { if(obj.media.source === 'external') {
if(post.preview) { if(post.preview) {
@ -103,7 +106,7 @@ module.exports = function(fetch) {
} }
} }
} }
if(post.gallery_data) { if(post.gallery_data) {
obj.gallery = true obj.gallery = true
obj.gallery_items = [] obj.gallery_items = []
@ -120,13 +123,13 @@ module.exports = function(fetch) {
} }
} }
} }
let comms = [] let comms = []
for(var i = 0; i < comments.length; i++) { for(var i = 0; i < comments.length; i++) {
let comment = comments[i].data let comment = comments[i].data
let kind = comments[i].kind let kind = comments[i].kind
let obj = {} let obj = {}
if(kind !== 'more') { if(kind !== 'more') {
obj = { obj = {
author: comment.author, author: comment.author,
@ -143,7 +146,8 @@ module.exports = function(fetch) {
score_hidden: comment.score_hidden, score_hidden: comment.score_hidden,
edited: comment.edited, edited: comment.edited,
replies: [], replies: [],
depth: 0 depth: 0,
user_flair: await formatUserFlair(comment)
} }
} else { } else {
obj = { obj = {
@ -155,26 +159,26 @@ module.exports = function(fetch) {
children: [] children: []
} }
} }
if(comment.replies && kind !== 'more') { if(comment.replies && kind !== 'more') {
if(comment.replies.data) { if(comment.replies.data) {
if(comment.replies.data.children.length > 0) { if(comment.replies.data.children.length > 0) {
obj.replies = processReplies(comment.replies.data.children, post_id, 1) obj.replies = await processReplies(comment.replies.data.children, post_id, 1)
} }
} }
} }
if(comment.children) { if(comment.children) {
for(var j = 0; j < comment.children.length; j++) { for(var j = 0; j < comment.children.length; j++) {
obj.children.push(comment.children[j]) obj.children.push(comment.children[j])
} }
} }
comms.push(obj) comms.push(obj)
} }
obj.comments = comms obj.comments = comms
resolve(obj) resolve(obj)
})() })()
}) })
@ -198,7 +202,7 @@ module.exports = function(fetch) {
return { post_data: post_data, comments: comments_html } return { post_data: post_data, comments: comments_html }
} }
this.processReplies = (data, post_id, depth) => { this.processReplies = async (data, post_id, depth) => {
let return_replies = [] let return_replies = []
for(var i = 0; i < data.length; i++) { for(var i = 0; i < data.length; i++) {
let kind = data[i].kind let kind = data[i].kind
@ -220,7 +224,8 @@ module.exports = function(fetch) {
score_hidden: reply.score_hidden, score_hidden: reply.score_hidden,
edited: reply.edited, edited: reply.edited,
replies: [], replies: [],
depth: depth depth: depth,
user_flair: await formatUserFlair(reply)
} }
} else { } else {
obj = { obj = {
@ -233,13 +238,13 @@ module.exports = function(fetch) {
depth: depth depth: depth
} }
} }
if(reply.replies && kind !== 'more') { if(reply.replies && kind !== 'more') {
if(reply.replies.data.children.length) { if(reply.replies.data.children.length) {
for(var j = 0; j < reply.replies.data.children.length; j++) { for(var j = 0; j < reply.replies.data.children.length; j++) {
let comment = reply.replies.data.children[j].data let comment = reply.replies.data.children[j].data
let objct = {} let objct = {}
if(comment.author && comment.body_html) { if(comment.author && comment.body_html) {
objct = { objct = {
author: comment.author, author: comment.author,
@ -255,7 +260,8 @@ module.exports = function(fetch) {
distinguished: comment.distinguished, distinguished: comment.distinguished,
distinguished: comment.edited, distinguished: comment.edited,
replies: [], replies: [],
depth: depth + 1 depth: depth + 1,
user_flair: await formatUserFlair(comment)
} }
} else { } else {
objct = { objct = {
@ -273,11 +279,11 @@ module.exports = function(fetch) {
} }
} }
} }
if(comment.replies) { if(comment.replies) {
if(comment.replies.data) { if(comment.replies.data) {
if(comment.replies.data.children.length > 0) { if(comment.replies.data.children.length > 0) {
objct.replies = processReplies(comment.replies.data.children, post_id, depth ) objct.replies = await processReplies(comment.replies.data.children, post_id, depth )
} }
} }
} }
@ -286,13 +292,13 @@ module.exports = function(fetch) {
} }
} }
} }
if(reply.children) { if(reply.children) {
for(var j = 0; j < reply.children.length; j++) { for(var j = 0; j < reply.children.length; j++) {
obj.children.push(reply.children[j]) obj.children.push(reply.children[j])
} }
} }
return_replies.push(obj) return_replies.push(obj)
} }
return return_replies return return_replies

View File

@ -11,7 +11,7 @@ module.exports = function() {
} else { } else {
let before = json.data.before let before = json.data.before
let after = json.data.after let after = json.data.after
let ret = { let ret = {
info: { info: {
before: before, before: before,
@ -19,9 +19,9 @@ module.exports = function() {
}, },
links: [] links: []
} }
let children_len = json.data.children.length let children_len = json.data.children.length
for(var i = 0; i < children_len; i++) { for(var i = 0; i < children_len; i++) {
let data = json.data.children[i].data let data = json.data.children[i].data
let images = null let images = null
@ -39,7 +39,7 @@ module.exports = function() {
is_self_link = true is_self_link = true
} }
} }
if(data.preview && data.thumbnail !== 'self') { if(data.preview && data.thumbnail !== 'self') {
if(!data.url.startsWith('/r/') && isGif(data.url)) { if(!data.url.startsWith('/r/') && isGif(data.url)) {
images = { images = {
@ -73,7 +73,9 @@ module.exports = function() {
url: data.url, url: data.url,
stickied: data.stickied, stickied: data.stickied,
is_self_link: is_self_link, is_self_link: is_self_link,
subreddit_front: subreddit_front subreddit_front: subreddit_front,
link_flair: await formatLinkFlair(data),
user_flair: await formatUserFlair(data)
} }
ret.links.push(obj) ret.links.push(obj)
} }

View File

@ -21,7 +21,7 @@ module.exports = function() {
if(!after && !before) { if(!after && !before) {
user_front = true user_front = true
} }
if(json.overview.data.children) { if(json.overview.data.children) {
if(json.overview.data.children[posts_limit - 1]) { if(json.overview.data.children[posts_limit - 1]) {
after = json.overview.data.children[posts_limit - 1].data.name after = json.overview.data.children[posts_limit - 1].data.name
@ -30,16 +30,16 @@ module.exports = function() {
before = json.overview.data.children[0].data.name before = json.overview.data.children[0].data.name
} }
} }
for(var i = 0; i < posts_limit; i++) { for(var i = 0; i < posts_limit; i++) {
let post = json.overview.data.children[i].data let post = json.overview.data.children[i].data
let thumbnail = 'self' let thumbnail = 'self'
let type = json.overview.data.children[i].kind let type = json.overview.data.children[i].kind
let obj let obj
let post_id = post.permalink.split('/').slice(-2)[0] + '/' let post_id = post.permalink.split('/').slice(-2)[0] + '/'
let url = post.permalink.replace(post_id, '') let url = post.permalink.replace(post_id, '')
if(type === 't3') { if(type === 't3') {
let duration = null let duration = null
if(post.media) { if(post.media) {
@ -62,7 +62,8 @@ module.exports = function() {
edited: post.edited, edited: post.edited,
selftext_html: unescape(post.selftext_html), selftext_html: unescape(post.selftext_html),
num_comments: post.num_comments, num_comments: post.num_comments,
permalink: post.permalink permalink: post.permalink,
user_flair: await formatUserFlair(post)
} }
} }
if(type === 't1') { if(type === 't1') {
@ -79,7 +80,8 @@ module.exports = function() {
num_comments: post.num_comments, num_comments: post.num_comments,
permalink: post.permalink, permalink: post.permalink,
link_author: post.link_author, link_author: post.link_author,
link_title: post.link_title link_title: post.link_title,
user_flair: await formatUserFlair(post)
} }
} }
posts.push(obj) posts.push(obj)
@ -98,7 +100,7 @@ module.exports = function() {
after: after, after: after,
posts: posts posts: posts
} }
resolve(obj) resolve(obj)
})() })()
}) })

View File

@ -12,7 +12,7 @@ html
#post #post
header header
div div
p subreddit: p subreddit:
a(href="/r/" + subreddit + "") a(href="/r/" + subreddit + "")
p /r/#{subreddit} p /r/#{subreddit}
.info .info
@ -23,8 +23,7 @@ html
.title .title
a(href="" + post.url + "") a(href="" + post.url + "")
h2 #{cleanTitle(post.title)} h2 #{cleanTitle(post.title)}
if post.link_flair_text != post.link_flair
span(class="postflair") #{post.link_flair_text}
span(class="domain") (#{post.domain}) span(class="domain") (#{post.domain})
p.submitted p.submitted
span(title="" + toUTCString(post.created) + "") submitted #{timeDifference(post.created)} by span(title="" + toUTCString(post.created) + "") submitted #{timeDifference(post.created)} by
@ -33,6 +32,7 @@ html
else else
a(href="/u/" + post.author + "") a(href="/u/" + post.author + "")
| #{post.author} | #{post.author}
!= post.user_flair
if post.crosspost.is_crosspost === true if post.crosspost.is_crosspost === true
.crosspost .crosspost
.title .title
@ -52,6 +52,7 @@ html
else else
a(href="/u/" + post.crosspost.author + "") a(href="/u/" + post.crosspost.author + "")
| #{post.crosspost.author} | #{post.crosspost.author}
!= post.user_flair
p.to to p.to to
a(href="/r/" + post.crosspost.subreddit + "") a(href="/r/" + post.crosspost.subreddit + "")
| #{post.crosspost.subreddit} | #{post.crosspost.subreddit}
@ -128,8 +129,8 @@ html
source(src="" + post.media.source + "", type="video/mp4") source(src="" + post.media.source + "", type="video/mp4")
| Your browser does not support the video element. | Your browser does not support the video element.
a(href="" + post.media.source + "") [media] a(href="" + post.media.source + "") [media]
if post.selftext if post.selftext
div.usertext-body !{post.selftext} div.usertext-body !{post.selftext}
if viewing_comment if viewing_comment
.infobar .infobar
p you are viewing a single comment's thread. p you are viewing a single comment's thread.

View File

@ -84,14 +84,12 @@ html
if link.is_self_link if link.is_self_link
a(href="" + link.permalink + "") a(href="" + link.permalink + "")
h2(class="" + (link.stickied ? 'green' : '') + "") #{cleanTitle(link.title)} h2(class="" + (link.stickied ? 'green' : '') + "") #{cleanTitle(link.title)}
if link.link_flair_text != link.link_flair
span(class="postflair") #{link.link_flair_text}
span (#{link.domain}) span (#{link.domain})
else else
a(href="" + link.url + "") a(href="" + link.url + "")
h2(class="" + (link.stickied ? 'green' : '') + "") #{cleanTitle(link.title)} h2(class="" + (link.stickied ? 'green' : '') + "") #{cleanTitle(link.title)}
if link.link_flair_text != link.link_flair
span(class="postflair") #{link.link_flair_text}
span (#{link.domain}) span (#{link.domain})
.meta .meta
p.submitted submitted p.submitted submitted
@ -101,6 +99,7 @@ html
else else
a(href="/u/" + link.author + "") a(href="/u/" + link.author + "")
| #{link.author} | #{link.author}
!= link.user_flair
p.to to p.to to
a(href="/r/" + link.subreddit + "") a(href="/r/" + link.subreddit + "")
| #{link.subreddit} | #{link.subreddit}

View File

@ -80,9 +80,11 @@ html
.title .title
a(href="" + post.permalink + "") #{cleanTitle(post.title)} a(href="" + post.permalink + "") #{cleanTitle(post.title)}
.meta .meta
p.submitted(title="" + toUTCString(post.created) + "") submitted #{timeDifference(post.created)} by p.submitted(title="" + toUTCString(post.created) + "") submitted #{timeDifference(post.created)}
| by
a(href="/u/" + data.username + "") #{data.username} a(href="/u/" + data.username + "") #{data.username}
| to | to
!= post.user_flair
a(href="/r/" + post.subreddit + "", class="subreddit") #{post.subreddit} a(href="/r/" + post.subreddit + "", class="subreddit") #{post.subreddit}
a.comments(href="" + post.permalink + "") #{post.num_comments} comments a.comments(href="" + post.permalink + "") #{post.num_comments} comments
if post.type === 't1' if post.type === 't1'
@ -98,7 +100,7 @@ html
a(href="/u/" + post.link_author + "") #{post.link_author} a(href="/u/" + post.link_author + "") #{post.link_author}
.subreddit .subreddit
p in p in
a(href="/r/" + post.subreddit + "") #{post.subreddit} a(href="/r/" + post.subreddit + "") #{post.subreddit}
.comment .comment
details(open="") details(open="")
summary summary
@ -108,10 +110,12 @@ html
.meta .meta
p.author p.author
a(href="/u/" + data.username + "") #{data.username} a(href="/u/" + data.username + "") #{data.username}
p
!= post.user_flair
p.ups #{post.ups} points p.ups #{post.ups} points
p.created(title="" + toUTCString(post.created) + "") #{timeDifference(post.created)} p.created(title="" + toUTCString(post.created) + "") #{timeDifference(post.created)}
.body .body
div !{post.body_html} div !{post.body_html}
a.context(href="" + post.permalink + "?context=10") context a.context(href="" + post.permalink + "?context=10") context
a.comments.t1(href="" + post.url + "") full comments (#{post.num_comments}) a.comments.t1(href="" + post.url + "") full comments (#{post.num_comments})
if data.before || data.after if data.before || data.after
@ -127,28 +131,3 @@ html
br br
p(title="" + toUTCString(data.created) + "") account created: #{toDateString(data.created)} p(title="" + toUTCString(data.created) + "") account created: #{toDateString(data.created)}
p verified: #{(data.verified) ? "yes" : "no" } p verified: #{(data.verified) ? "yes" : "no" }