From f368b40dda8b9fdf00a6ea7e5aa441d17e8cf4a0 Mon Sep 17 00:00:00 2001 From: teddit Date: Fri, 8 Jan 2021 21:39:46 +0100 Subject: [PATCH] add subscribe to subreddit feature --- README.md | 1 + routes.js | 107 +++++++++++++++++++++++++++++++++++--- static/css/styles.css | 35 +++++++++++-- views/includes/topbar.pug | 100 ++++++++++++++++++----------------- views/preferences.pug | 13 +++++ views/subreddit.pug | 30 ++++++++++- 6 files changed, 227 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 1c42cf0..592c47a 100644 --- a/README.md +++ b/README.md @@ -29,6 +29,7 @@ Community instances: ## TODO +* Import/export preferences * User trophies * "other discussions" feature * "Open on reddit" links diff --git a/routes.js b/routes.js index 88fadbb..983ba0d 100644 --- a/routes.js +++ b/routes.js @@ -23,13 +23,92 @@ module.exports = (app, redis, fetch, RedditAPI) => { res.clearCookie('theme') res.clearCookie('flairs') res.clearCookie('nsfw_enabled') - res.clearCookie("highlight_controversial") + res.clearCookie('highlight_controversial') + res.clearCookie('subbed_subreddits') return res.redirect('/preferences') }) app.get('/privacy', (req, res, next) => { return res.render('privacypolicy', { user_preferences: req.cookies }) }) + + app.get('/subscribe/:subreddit', (req, res, next) => { + let subreddit = req.params.subreddit + let subbed = req.cookies.subbed_subreddits + let back = req.query.b + + if(!subreddit) + return res.redirect('/') + + if(!subbed || !Array.isArray(subbed)) + subbed = [] + + if(!subbed.includes(subreddit)) + subbed.push(subreddit) + + res.cookie('subbed_subreddits', subbed, { maxAge: 365 * 24 * 60 * 60 * 1000, httpOnly: true }) + + if(!back) + return res.redirect('/r/' + subreddit) + else { + back = back.replace(/,/g, '+') + return res.redirect(back) + } + }) + + app.get('/import_subscriptions/:subreddits', (req, res, next) => { + let subreddits = req.params.subreddits + let subbed = req.cookies.subbed_subreddits + let back = req.query.b + + if(!subreddits) + return res.redirect('/') + + if(!subbed || !Array.isArray(subbed)) + subbed = [] + + subreddits = subreddits.split('+') + for(var i = 0; i < subreddits.length; i++) { + if(!subbed.includes(subreddits[i])) + subbed.push(subreddits[i]) + } + + res.cookie('subbed_subreddits', subbed, { maxAge: 365 * 24 * 60 * 60 * 1000, httpOnly: true }) + + if(!back) + return res.redirect('/r/' + subreddits) + else { + back = back.replace(/,/g, '+').replace(/ /g, '+') + return res.redirect(back) + } + }) + + app.get('/unsubscribe/:subreddit', (req, res, next) => { + let subreddit = req.params.subreddit + let subbed = req.cookies.subbed_subreddits + let back = req.query.b + + if(!subreddit || !subbed || !Array.isArray(subbed)) { + res.clearCookie('subbed_subreddits') + return res.redirect('/') + } + + var index = subbed.indexOf(subreddit) + if(index !== -1) + subbed.splice(index, 1) + + if(subbed.length <= 0) + res.clearCookie('subbed_subreddits') + else + res.cookie('subbed_subreddits', subbed, { maxAge: 365 * 24 * 60 * 60 * 1000, httpOnly: true }) + + if(!back) + return res.redirect('/r/' + subreddit) + else { + back = back.replace(/,/g, '+') + return res.redirect(back) + } + }) app.get('/search', (req, res, next) => { let q = req.query.q @@ -116,8 +195,17 @@ module.exports = (app, redis, fetch, RedditAPI) => { api_req = true else api_req = false - + let key = `/after:${after}:before:${before}:sort:${sortby}:past:${past}` + + let subbed_subreddits = req.cookies.subbed_subreddits + let get_subbed_subreddits = false + if(subbed_subreddits && Array.isArray(subbed_subreddits)) { + get_subbed_subreddits = true + subbed_subreddits = subbed_subreddits.join('+') + key = `${subbed_subreddits.toLowerCase()}:${after}:${before}:sort:${sortby}:past:${past}` + } + redis.get(key, (error, json) => { if(error) { console.error('Error getting the frontpage key from redis.', error) @@ -140,10 +228,17 @@ module.exports = (app, redis, fetch, RedditAPI) => { })() } else { let url = '' - if(config.use_reddit_oauth) - url = `https://oauth.reddit.com/${sortby}?api_type=json&g=GLOBAL&t=${past}${d}` - else - url = `https://reddit.com/${sortby}.json?g=GLOBAL&t=${past}${d}` + if(config.use_reddit_oauth) { + if(get_subbed_subreddits) + url = `https://oauth.reddit.com/r/${subbed_subreddits}/${sortby}?api_type=json&count=25&g=GLOBAL&t=${past}${d}` + else + url = `https://oauth.reddit.com/${sortby}?api_type=json&g=GLOBAL&t=${past}${d}` + } else { + if(get_subbed_subreddits) + url = `https://reddit.com/r/${subbed_subreddits}/${sortby}.json?api_type=json&count=25&g=GLOBAL&t=${past}${d}` + else + url = `https://reddit.com/${sortby}.json?g=GLOBAL&t=${past}${d}` + } fetch(encodeURI(url), redditApiGETHeaders()) .then(result => { if(result.status === 200) { diff --git a/static/css/styles.css b/static/css/styles.css index a4f67da..01bf346 100644 --- a/static/css/styles.css +++ b/static/css/styles.css @@ -311,6 +311,11 @@ form legend { border-bottom: 1px solid #e3e3e3; margin-bottom: 10px; padding-bottom: 10px; + margin-top: 40px; + font-weight: bold; +} +form legend:first-child { + margin-top: 0px; } form .setting { margin: 10px 0px; @@ -398,10 +403,6 @@ header .tabmenu li.active a { border-radius: 3px; font-weight: bold; } -.subreddit-listing { - margin-left: 15px; - margin-top: 8px; -} .green { color: green !important; } @@ -1157,9 +1158,35 @@ body.dark .flair { font-size: smaller; padding-right: 15px; } +.subreddit-listing { + margin: 8px 0px; + list-style: none; +} +.subreddit-listing li { + margin: 15px 0px; +} #sidebar .content .description { margin-top: 38px; } +a.sub-to-subreddit { + color: #f9f9f9; + background: #007900; + font-size: var(--sm-font); + padding: 6px 8px 6px 8px; + margin: 0px 5px 0px 0px; +} +a.sub-to-subreddit:hover, +a.sub-to-subreddit:focus { + color: white !important; +} +a.sub-to-subreddit.gray { + background: gray; +} +.subscribe { + margin: 0px 0px 30px 0px; + width: 100%; + float: left; +} /* SEARCH */ #search { margin-bottom: 50px; diff --git a/views/includes/topbar.pug b/views/includes/topbar.pug index 3acb0a1..d0d878f 100644 --- a/views/includes/topbar.pug +++ b/views/includes/topbar.pug @@ -8,51 +8,55 @@ div#topbar .icon-container a(href="/preferences") [preferences] .top-links - a(href="/r/all") All - a(href="/r/AskReddit") AskReddit - a(href="/r/pics") pics - a(href="/r/news") news - a(href="/r/worldnews") worldnews - a(href="/r/funny") funny - a(href="/r/tifu") tifu - a(href="/r/videos") videos - a(href="/r/gaming") gaming - a(href="/r/aww") aww - a(href="/r/todayilearned") todayilearned - a(href="/r/gifs") gifs - a(href="/r/Art") Art - a(href="/r/explainlikeimfive") explainlikeimfive - a(href="/r/movies") movies - a(href="/r/Jokes") Jokes - a(href="/r/TwoXChromosomes") TwoXChromosomes - a(href="/r/mildlyinteresting") mildlyinteresting - a(href="/r/LifeProTips") LifeProTips - a(href="/r/askscience") askscience - a(href="/r/IAmA") IAmA - a(href="/r/dataisbeautiful") dataisbeautiful - a(href="/r/books") books - a(href="/r/science") science - a(href="/r/Showerthoughts") Showerthoughts - a(href="/r/gadgets") gadgets - a(href="/r/Futurology") Futurology - a(href="/r/nottheonion") nottheonion - a(href="/r/history") history - a(href="/r/sports") sports - a(href="/r/OldSchoolCool") OldSchoolCool - a(href="/r/GetMotivated") GetMotivated - a(href="/r/DIY") DIY - a(href="/r/photoshopbattles") photoshopbattles - a(href="/r/nosleep") nosleep - a(href="/r/Music") Music - a(href="/r/space") space - a(href="/r/food") food - a(href="/r/UpliftingNews") UpliftingNews - a(href="/r/EarthPorn") EarthPorn - a(href="/r/Documentaries") Documentaries - a(href="/r/InternetIsBeautiful") InternetIsBeautiful - a(href="/r/WritingPrompts") WritingPrompts - a(href="/r/creepy") creepy - a(href="/r/philosophy") philosophy - a(href="/r/announcements") announcements - a(href="/r/listentothis") listentothis - a(href="/r/blog") blog + if user_preferences.subbed_subreddits && Array.isArray(user_preferences.subbed_subreddits) + each subreddit in user_preferences.subbed_subreddits + a(href="/r/" + subreddit) #{subreddit} + else + a(href="/r/all") All + a(href="/r/AskReddit") AskReddit + a(href="/r/pics") pics + a(href="/r/news") news + a(href="/r/worldnews") worldnews + a(href="/r/funny") funny + a(href="/r/tifu") tifu + a(href="/r/videos") videos + a(href="/r/gaming") gaming + a(href="/r/aww") aww + a(href="/r/todayilearned") todayilearned + a(href="/r/gifs") gifs + a(href="/r/Art") Art + a(href="/r/explainlikeimfive") explainlikeimfive + a(href="/r/movies") movies + a(href="/r/Jokes") Jokes + a(href="/r/TwoXChromosomes") TwoXChromosomes + a(href="/r/mildlyinteresting") mildlyinteresting + a(href="/r/LifeProTips") LifeProTips + a(href="/r/askscience") askscience + a(href="/r/IAmA") IAmA + a(href="/r/dataisbeautiful") dataisbeautiful + a(href="/r/books") books + a(href="/r/science") science + a(href="/r/Showerthoughts") Showerthoughts + a(href="/r/gadgets") gadgets + a(href="/r/Futurology") Futurology + a(href="/r/nottheonion") nottheonion + a(href="/r/history") history + a(href="/r/sports") sports + a(href="/r/OldSchoolCool") OldSchoolCool + a(href="/r/GetMotivated") GetMotivated + a(href="/r/DIY") DIY + a(href="/r/photoshopbattles") photoshopbattles + a(href="/r/nosleep") nosleep + a(href="/r/Music") Music + a(href="/r/space") space + a(href="/r/food") food + a(href="/r/UpliftingNews") UpliftingNews + a(href="/r/EarthPorn") EarthPorn + a(href="/r/Documentaries") Documentaries + a(href="/r/InternetIsBeautiful") InternetIsBeautiful + a(href="/r/WritingPrompts") WritingPrompts + a(href="/r/creepy") creepy + a(href="/r/philosophy") philosophy + a(href="/r/announcements") announcements + a(href="/r/listentothis") listentothis + a(href="/r/blog") blog diff --git a/views/preferences.pug b/views/preferences.pug index 9ab1d57..7266eeb 100644 --- a/views/preferences.pug +++ b/views/preferences.pug @@ -37,6 +37,19 @@ html input(type="checkbox", name="nsfw_enabled", id="nsfw_enabled") else input(type="checkbox", name="nsfw_enabled", id="nsfw_enabled", checked="checked") + legend Subscribed subreddits + .setting + details + summary + span Show subscribed subreddits + if user_preferences.subbed_subreddits && Array.isArray(user_preferences.subbed_subreddits) + ul.subreddit-listing + each subreddit in user_preferences.subbed_subreddits + li + a(href="/unsubscribe/" + subreddit + "/?b=/preferences", class="sub-to-subreddit gray", title="subscriptions are saved in your browser's cookies") unsubscribe + a(href="/r/" + subreddit) #{subreddit} + else + small no subscribed subreddits small(class="notice") Preferences are stored client-side using cookies without any personal information. input(type="submit", value="Save preferences") a(href="/resetprefs", class="btn") Reset preferences diff --git a/views/subreddit.pug b/views/subreddit.pug index 681b6c6..95c2232 100644 --- a/views/subreddit.pug +++ b/views/subreddit.pug @@ -150,6 +150,20 @@ html input(type="checkbox", name="nsfw", id="nsfw", checked="checked") input(type="submit", value="search") if subreddit_about + .subscribe + - + let subbed_to_this_subreddit = false + let subbed = [] + if(user_preferences.subbed_subreddits && Array.isArray(user_preferences.subbed_subreddits)) + subbed = user_preferences.subbed_subreddits + for(let i = 0; i < subbed.length; i++) { + if(subbed[i] === subreddit) + subbed_to_this_subreddit = true + } + if subbed_to_this_subreddit + a(href="/unsubscribe/" + subreddit + "", class="sub-to-subreddit gray", title="subscriptions are saved in your browser's cookies") unsubscribe + else + a(href="/subscribe/" + subreddit + "", class="sub-to-subreddit", title="subscriptions are saved in your browser's cookies") subscribe if subreddit_about.subscribers .content p subscribers: #{subreddit_about.subscribers.toLocaleString()} @@ -169,6 +183,20 @@ html let subreddits = subreddit.split('+') ul(class="subreddit-listing") each subreddit in subreddits + - + let subbed_to_this_subreddit = false + let subbed = user_preferences.subbed_subreddits + for(let i = 0; i < subbed.length; i++) { + if(subbed[i] === subreddit) + subbed_to_this_subreddit = true + } li - a(href="/r/" + subreddit + "") #{subreddit} + if subbed_to_this_subreddit + a(href="/unsubscribe/" + subreddit + "?b=/r/" + subreddits + "", class="sub-to-subreddit gray", title="subscriptions are saved in your browser's cookies") unsubscribe + a(href="/r/" + subreddit + "") #{subreddit} + else + a(href="/subscribe/" + subreddit + "?b=/r/" + subreddits + "", class="sub-to-subreddit", title="subscriptions are saved in your browser's cookies") subscribe + a(href="/r/" + subreddit + "") #{subreddit} + - joined_subreddits = subreddits.join("+") + a(href="/import_subscriptions/" + joined_subreddits + "?b=/r/" + joined_subreddits) subscribe to all of these subreddits include includes/footer.pug