mirror of
https://codeberg.org/tacerus/teddit.git
synced 2024-11-22 14:59:26 +01:00
fix load more comments (morechildren-endpoint), fixes #122
This commit is contained in:
parent
006ac93de5
commit
567e6f7797
@ -1,5 +1,5 @@
|
||||
module.exports = function() {
|
||||
this.compilePostCommentsHtml = (comments, next_comment, post_id, post_url, morechildren_ids, post_author, viewing_comment, user_preferences) => {
|
||||
this.compilePostCommentsHtml = (comments, next_comment, post_id, post_url, morechildren_ids, post_author, viewing_comment, user_preferences, last_known_depth) => {
|
||||
return new Promise((resolve, reject) => {
|
||||
(async () => {
|
||||
let comments_html
|
||||
@ -13,7 +13,7 @@ module.exports = function() {
|
||||
|
||||
if(!user_preferences)
|
||||
user_preferences = {}
|
||||
|
||||
|
||||
if(comments.author !== undefined && comments.body_html !== undefined) {
|
||||
let classlist = []
|
||||
let submitter_link = ''
|
||||
@ -68,31 +68,49 @@ module.exports = function() {
|
||||
if(comments.children.length > 0) {
|
||||
let parent_id = comments.parent_id.split('_')[1]
|
||||
if(post_id === parent_id && !morechildren_ids) {
|
||||
let more_comments = []
|
||||
if(comments.children.length > 100) {
|
||||
more_comments = comments.children.slice(0, 100)
|
||||
} else {
|
||||
more_comments = comments.children
|
||||
}
|
||||
|
||||
comments_html = `
|
||||
<form method="POST">
|
||||
<button type="submit">load more comments (${comments.count})</button>
|
||||
<input type="hidden" name="url" id="url" value="${post_url}">
|
||||
<input type="hidden" name="all_ids" id="all_ids" value="${comments.children.join()}">
|
||||
<input type="hidden" name="comment_ids" id="comment_ids" value="${more_comments.join()}">
|
||||
</form>
|
||||
`
|
||||
} else {
|
||||
let load_comms_href = parent_id
|
||||
if(!morechildren_ids) {
|
||||
let load_comms_href = parent_id
|
||||
|
||||
comments_html = `
|
||||
<div class="load-more-comments">
|
||||
<a href="${load_comms_href}#c">load more comments (${comments.count})</a>
|
||||
</div>
|
||||
`
|
||||
} else {
|
||||
morechildren_ids = JSON.parse(morechildren_ids)
|
||||
comments_html = `
|
||||
<form method="POST">
|
||||
<button type="submit">load more comments (${morechildren_ids.length})</button>
|
||||
<input type="hidden" name="url" id="url" value="${post_url}">
|
||||
<input type="hidden" name="all_ids" id="all_ids" value='${morechildren_ids.join()}'>
|
||||
</form>
|
||||
`
|
||||
if(next_comment === false) {
|
||||
let more_comments = morechildren_ids[morechildren_ids.length - 1].data.children
|
||||
if(more_comments.length > 100) {
|
||||
more_comments = more_comments.slice(0, 100)
|
||||
} else {
|
||||
more_comments = more_comments
|
||||
}
|
||||
comments_html = `
|
||||
<form method="POST">
|
||||
<button type="submit">load more comments (${more_comments.length})</button>
|
||||
<input type="hidden" name="comment_ids" id="comment_ids" value="${more_comments.join()}">
|
||||
</form>
|
||||
`
|
||||
} else {
|
||||
comments_html = `
|
||||
<div class="load-more-comments">
|
||||
<a href="${load_comms_href}#c">load more comments (${comments.count})</a>
|
||||
</div>
|
||||
`
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -105,7 +123,21 @@ module.exports = function() {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if(morechildren_ids) {
|
||||
if(next_comment.depth != undefined) {
|
||||
if(next_comment.depth < last_known_depth) {
|
||||
let times = last_known_depth - next_comment.depth
|
||||
if(next_comment.depth == 0) {
|
||||
times = last_known_depth
|
||||
}
|
||||
for(var i = 0; i < times; i++) {
|
||||
comments_html += `</details></div>`
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(comments.replies) {
|
||||
for(var i = 0; i < comments.replies.length; i++) {
|
||||
let comment = comments.replies[i]
|
||||
@ -163,7 +195,7 @@ module.exports = function() {
|
||||
if(comment.replies) {
|
||||
if(comment.replies.length) {
|
||||
for(var j = 0; j < comment.replies.length; j++) {
|
||||
let next_reply
|
||||
let next_reply = false
|
||||
if(comment.replies[j+1]) {
|
||||
next_reply = comment.replies[j+1]
|
||||
}
|
||||
@ -200,7 +232,7 @@ module.exports = function() {
|
||||
next_comment_parent_id = next_comment.parent_id.split('_')[1]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if((comments.replies || comments.author !== undefined) && next_comment_parent_id !== comments.id) {
|
||||
comments_html += `</details></div>`
|
||||
}
|
||||
|
@ -76,13 +76,13 @@ module.exports = function(fetch) {
|
||||
}
|
||||
}
|
||||
|
||||
obj = await processPostMedia(obj, post, post.media, has_gif, reddit_video, gif_to_mp4, user_preferences)
|
||||
obj = await processPostMedia(obj, post, post.media, has_gif, reddit_video, gif_to_mp4)
|
||||
|
||||
if(post.crosspost_parent_list) {
|
||||
post.crosspost = post.crosspost_parent_list[0]
|
||||
}
|
||||
if(post.crosspost) {
|
||||
obj = await processPostMedia(obj, post.crosspost, post.crosspost.media, has_gif, reddit_video, gif_to_mp4, user_preferences)
|
||||
obj = await processPostMedia(obj, post.crosspost, post.crosspost.media, has_gif, reddit_video, gif_to_mp4)
|
||||
obj.crosspost = {
|
||||
author: post.crosspost.author,
|
||||
created: post.crosspost.created_utc,
|
||||
@ -164,7 +164,7 @@ module.exports = function(fetch) {
|
||||
score_hidden: comment.score_hidden,
|
||||
edited: comment.edited,
|
||||
replies: [],
|
||||
depth: 0,
|
||||
depth: comment.depth,
|
||||
user_flair: (user_preferences.flairs != 'false' ? await formatUserFlair(comment) : ''),
|
||||
controversiality: (user_preferences.highlight_controversial != 'false' ? comment.controversiality : '')
|
||||
}
|
||||
@ -206,12 +206,17 @@ module.exports = function(fetch) {
|
||||
this.finalizeJsonPost = async (processed_json, post_id, post_url, morechildren_ids, viewing_comment, user_preferences) => {
|
||||
let comments_html = `<div class="comments">`
|
||||
let comments = processed_json.comments
|
||||
let last_known_depth = undefined
|
||||
for(var i = 0; i < comments.length; i++) {
|
||||
let next_comment
|
||||
let next_comment = false
|
||||
if(comments[i+1]) {
|
||||
next_comment = comments[i+1]
|
||||
}
|
||||
comments_html += await compilePostCommentsHtml(comments[i], next_comment, post_id, post_url, morechildren_ids, processed_json.author, viewing_comment, user_preferences)
|
||||
if(comments[i].depth != undefined) {
|
||||
last_known_depth = comments[i].depth
|
||||
}
|
||||
|
||||
comments_html += await compilePostCommentsHtml(comments[i], next_comment, post_id, post_url, morechildren_ids, processed_json.author, viewing_comment, user_preferences, last_known_depth)
|
||||
}
|
||||
|
||||
comments_html += `</div>`
|
||||
|
54
inc/processMoreComments.js
Normal file
54
inc/processMoreComments.js
Normal file
@ -0,0 +1,54 @@
|
||||
module.exports = function() {
|
||||
const config = require('../config')
|
||||
this.moreComments = (fetch, redis, post_url, comment_ids, id) => {
|
||||
return new Promise(resolve => {
|
||||
(async () => {
|
||||
let key = `${post_url}:morechildren:comment_ids:${comment_ids}`
|
||||
redis.get(key, (error, json) => {
|
||||
if(error) {
|
||||
console.error(`Error getting the ${key} key from redis (moreComments()).`, error)
|
||||
resolve(false)
|
||||
}
|
||||
if(json) {
|
||||
json = JSON.parse(json)
|
||||
resolve(json)
|
||||
} else {
|
||||
let url = `https://oauth.reddit.com/api/morechildren?api_type=json&children=${comment_ids}&limit_children=false&link_id=t3_${id}`
|
||||
fetch(encodeURI(url), redditApiGETHeaders())
|
||||
.then(result => {
|
||||
if(result.status === 200) {
|
||||
result.json()
|
||||
.then(json => {
|
||||
if(json.json.data) {
|
||||
if(json.json.data.things) {
|
||||
let comments = json.json.data.things
|
||||
redis.setex(key, config.setexs.posts, JSON.stringify(comments), (error) => {
|
||||
if(error) {
|
||||
console.error(`Error setting the ${key} key to redis (moreComments()).`, error)
|
||||
resolve(false)
|
||||
} else {
|
||||
console.log(`Fetched the JSON from Reddit (endpoint "morechildren") for URL: ${post_url}. (moreComments())`)
|
||||
resolve(comments)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
resolve(false)
|
||||
}
|
||||
} else {
|
||||
resolve(false)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
console.error(`Something went wrong while fetching data from Reddit. ${result.status} – ${result.statusText} (moreComments())`)
|
||||
resolve(false)
|
||||
}
|
||||
}).catch(error => {
|
||||
console.log(`Error fetching the JSON from Reddit (endpoint "morechildren") with url: ${url}. (moreComments())`, error)
|
||||
resolve(false)
|
||||
})
|
||||
}
|
||||
})
|
||||
})()
|
||||
})
|
||||
}
|
||||
}1
|
2
package-lock.json
generated
2
package-lock.json
generated
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "teddit",
|
||||
"version": "0.1.1",
|
||||
"version": "0.3.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
|
191
routes.js
191
routes.js
@ -11,6 +11,7 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
let tedditApiSubreddit = require('./inc/teddit_api/handleSubreddit.js')();
|
||||
let tedditApiUser = require('./inc/teddit_api/handleUser.js')();
|
||||
let processSubredditsExplore = require('./inc/processSubredditsExplore.js')();
|
||||
let processMoreComments = require('./inc/processMoreComments.js')();
|
||||
|
||||
app.all('*', (req, res, next) => {
|
||||
let themeOverride = req.query.theme
|
||||
@ -1208,7 +1209,7 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
let sortby = req.query.sort
|
||||
let comment_id = ''
|
||||
let viewing_comment = false
|
||||
let more_comments_cursor = req.query.cursor
|
||||
let comment_ids = req.query.comment_ids
|
||||
let context = parseInt(req.query.context)
|
||||
|
||||
if(req.params.comment_id) {
|
||||
@ -1237,64 +1238,35 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
if(json) {
|
||||
console.log(`Got ${comments_url} key from redis.`);
|
||||
(async () => {
|
||||
if(!more_comments_cursor) {
|
||||
let processed_json = await processJsonPost(json, false, req.cookies)
|
||||
let finalized_json = await finalizeJsonPost(processed_json, id, post_url, null, viewing_comment, req.cookies)
|
||||
return res.render('post', {
|
||||
post: finalized_json.post_data,
|
||||
comments: finalized_json.comments,
|
||||
viewing_comment: viewing_comment,
|
||||
post_url: post_url,
|
||||
subreddit: subreddit,
|
||||
sortby: sortby,
|
||||
user_preferences: req.cookies,
|
||||
instance_nsfw_enabled: config.nsfw_enabled,
|
||||
post_media_max_heights: config.post_media_max_heights,
|
||||
redis_key: comments_key
|
||||
})
|
||||
} else {
|
||||
let key = `morechildren:${post_url};1`
|
||||
redis.get(key, (error, json) => {
|
||||
if(error) {
|
||||
console.error(`Error getting the ${key} key from redis.`, error)
|
||||
return res.render('index', { json: null, user_preferences: req.cookies })
|
||||
}
|
||||
if(json) {
|
||||
console.log(`Got ${key} key from redis.`);
|
||||
redis.get(post_url, (error, post_json) => {
|
||||
if(error) {
|
||||
console.error(`Error getting the ${post_url} key from redis.`, error)
|
||||
return res.render('index', { json: null, user_preferences: req.cookies })
|
||||
}
|
||||
if(post_json) {
|
||||
redis.get(`morechildren_ids:${post_url}`, (error, morechildren_ids) => {
|
||||
(async () => {
|
||||
post_json = JSON.parse(post_json)
|
||||
json = JSON.parse(json)
|
||||
post_json[1].data.children = json
|
||||
let processed_json = await processJsonPost(post_json, true, req.cookies)
|
||||
let finalized_json = await finalizeJsonPost(processed_json, id, post_url, morechildren_ids)
|
||||
|
||||
return res.render('post', {
|
||||
post: finalized_json.post_data,
|
||||
comments: finalized_json.comments,
|
||||
viewing_comment: false,
|
||||
post_url: post_url,
|
||||
subreddit: req.params.subreddit,
|
||||
sortby: sortby,
|
||||
more_comments_page: 1,
|
||||
user_preferences: req.cookies,
|
||||
instance_nsfw_enabled: config.nsfw_enabled,
|
||||
post_media_max_heights: config.post_media_max_heights,
|
||||
redis_key: comments_key
|
||||
})
|
||||
})()
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
})
|
||||
let parsed = false
|
||||
let more_comments = null
|
||||
if(comment_ids) {
|
||||
let key = `${post_url}:morechildren:comment_ids:${comment_ids}`
|
||||
more_comments = await moreComments(fetch, redis, post_url, comment_ids, id)
|
||||
|
||||
if(more_comments === false) {
|
||||
return res.redirect(post_url)
|
||||
} else {
|
||||
json = JSON.parse(json)
|
||||
json[1].data.children = more_comments
|
||||
parsed = true
|
||||
}
|
||||
}
|
||||
|
||||
let processed_json = await processJsonPost(json, parsed, req.cookies)
|
||||
let finalized_json = await finalizeJsonPost(processed_json, id, post_url, more_comments, viewing_comment, req.cookies)
|
||||
return res.render('post', {
|
||||
post: finalized_json.post_data,
|
||||
comments: finalized_json.comments,
|
||||
viewing_comment: viewing_comment,
|
||||
post_url: post_url,
|
||||
subreddit: subreddit,
|
||||
sortby: sortby,
|
||||
user_preferences: req.cookies,
|
||||
instance_nsfw_enabled: config.nsfw_enabled,
|
||||
post_media_max_heights: config.post_media_max_heights,
|
||||
redis_key: comments_key
|
||||
})
|
||||
})()
|
||||
} else {
|
||||
let url = ''
|
||||
@ -1315,8 +1287,20 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
} else {
|
||||
console.log(`Fetched the JSON from reddit.com${comments_url}.`);
|
||||
(async () => {
|
||||
let more_comments = null
|
||||
if(comment_ids) {
|
||||
let key = `${post_url}:morechildren:comment_ids:${comment_ids}`
|
||||
more_comments = await moreComments(fetch, redis, post_url, comment_ids, id)
|
||||
|
||||
if(more_comments === false) {
|
||||
return res.redirect(post_url)
|
||||
} else {
|
||||
json[1].data.children = more_comments
|
||||
}
|
||||
}
|
||||
|
||||
let processed_json = await processJsonPost(json, true, req.cookies)
|
||||
let finalized_json = await finalizeJsonPost(processed_json, id, post_url, null, viewing_comment)
|
||||
let finalized_json = await finalizeJsonPost(processed_json, id, post_url, more_comments, viewing_comment)
|
||||
return res.render('post', {
|
||||
post: finalized_json.post_data,
|
||||
comments: finalized_json.comments,
|
||||
@ -1801,82 +1785,21 @@ module.exports = (app, redis, fetch, RedditAPI) => {
|
||||
})
|
||||
|
||||
app.post('/r/:subreddit/comments/:id/:snippet', (req, res, next) => {
|
||||
/* morechildren route */
|
||||
let all_ids = req.body.all_ids
|
||||
let post_url = req.body.url
|
||||
/**
|
||||
* This is the "morechildren" route. This route is called when the
|
||||
* "load more comments" button at the bottom of some post is clicked.
|
||||
*/
|
||||
if(!config.use_reddit_oauth)
|
||||
return res.send(`This instance is using Reddit's public API (non-OAuth), and therefore this endpoint is not supported. In other words, this feature is only available if the instance is using Reddit OAuth API.`)
|
||||
|
||||
if(!all_ids || !post_url || !post_url.startsWith('/r/')) {
|
||||
return res.render('index', { json: null, user_preferences: req.cookies })
|
||||
} else {
|
||||
let post_id = post_url.split('/')[4]
|
||||
let ids_to_show = ''
|
||||
all_ids = all_ids.split(',')
|
||||
// TODO: paging
|
||||
let page = 1
|
||||
if(all_ids.length > 100) {
|
||||
ids_to_show = all_ids.slice(0,100)
|
||||
ids_to_show = ids_to_show.join()
|
||||
}
|
||||
|
||||
let key = `morechildren:${post_url};1`
|
||||
redis.get(key, (error, json) => {
|
||||
if(error) {
|
||||
console.error(`Error getting the ${key} key from redis.`, error)
|
||||
return res.render('index', { json: null, user_preferences: req.cookies })
|
||||
}
|
||||
if(json) {
|
||||
console.log(`Redirecting to ${post_url} with cursor...`);
|
||||
return res.redirect(`${post_url}?cursor=${page}&page=${page}`)
|
||||
} else {
|
||||
if(!config.use_reddit_oauth)
|
||||
return res.send(`This instance is using Reddit's public API (non-OAuth), and therefore this endpoint is not supported.`)
|
||||
let url = `https://oauth.reddit.com/api/morechildren?api_type=json&children=${ids_to_show}&limit_children=false&link_id=t3_${post_id}`
|
||||
fetch(encodeURI(url), redditApiGETHeaders())
|
||||
.then(result => {
|
||||
if(result.status === 200) {
|
||||
result.json()
|
||||
.then(json => {
|
||||
if(json.json.data) {
|
||||
if(json.json.data.things) {
|
||||
let comments = json.json.data.things
|
||||
redis.setex(key, config.setexs.posts, JSON.stringify(comments), (error) => {
|
||||
if(error) {
|
||||
console.error(`Error setting the ${key} key to redis.`, error)
|
||||
return res.render('post', { post: null, user_preferences: req.cookies })
|
||||
} else {
|
||||
redis.setex(`morechildren_ids:${post_url}`, config.setexs.posts, JSON.stringify(all_ids))
|
||||
console.log(`Fetched the JSON from Reddit (endpoint "morechildren") with url: ${url}.`)
|
||||
console.log(`Redirecting to ${post_url} with cursor...`)
|
||||
return res.redirect(`${post_url}?cursor=${page}&page=${page}`)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
return res.redirect(post_url)
|
||||
}
|
||||
} else {
|
||||
return res.redirect(post_url)
|
||||
}
|
||||
})
|
||||
} else {
|
||||
console.error(`Something went wrong while fetching data from Reddit. ${result.status} – ${result.statusText}`)
|
||||
console.error(config.reddit_api_error_text)
|
||||
return res.render('index', {
|
||||
json: null,
|
||||
http_status_code: result.status,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
}
|
||||
}).catch(error => {
|
||||
console.log(`Error fetching the JSON from Reddit (endpoint "morechildren") with url: ${url}.`, error)
|
||||
return res.render('index', {
|
||||
json: null,
|
||||
http_status_code: result.status,
|
||||
user_preferences: req.cookies
|
||||
})
|
||||
})
|
||||
}
|
||||
})
|
||||
}
|
||||
let subreddit = req.params.subreddit
|
||||
let id = req.params.id
|
||||
let snippet = encodeURIComponent(req.params.snippet)
|
||||
let post_url = `/r/${subreddit}/comments/${id}/${snippet}/`
|
||||
let page = req.query.page
|
||||
let comment_ids = req.body.comment_ids
|
||||
|
||||
return res.redirect(`${post_url}?comment_ids=${comment_ids}&page=1`)
|
||||
})
|
||||
|
||||
function resetPreferences(res) {
|
||||
|
Loading…
Reference in New Issue
Block a user