Skip to content

Commit

Permalink
Merge branch 'FIGBERT/follows' (zedeus/nitter#363)
Browse files Browse the repository at this point in the history
  • Loading branch information
acarasimon96 committed Sep 9, 2021
2 parents ae185e7 + 1ebfa09 commit f9de565
Show file tree
Hide file tree
Showing 9 changed files with 157 additions and 13 deletions.
9 changes: 4 additions & 5 deletions src/nitter.nim
Expand Up @@ -8,8 +8,8 @@ import jester
import types, config, prefs, formatters, redis_cache, http_pool, tokens
import views/[general, about]
import routes/[
preferences, timeline, status, media, search, rss, list,
unsupported, embed, resolver, router_utils]
home, preferences, timeline, status, media, search, rss, list,
unsupported, embed, resolver, router_utils, follow]

const instancesUrl = "https://github.com/zedeus/nitter/wiki/Instances"

Expand Down Expand Up @@ -54,9 +54,6 @@ settings:
bindAddr = cfg.address

routes:
get "/":
resp renderMain(renderSearch(), request, cfg, themePrefs())

get "/about":
resp renderMain(renderAbout(), request, cfg, themePrefs())

Expand All @@ -80,6 +77,8 @@ routes:
a("another instance", href = instancesUrl) &
" or try again later.", cfg)

extend home, ""
extend follow, ""
extend unsupported, ""
extend preferences, ""
extend resolver, ""
Expand Down
5 changes: 5 additions & 0 deletions src/prefs_impl.nim
Expand Up @@ -49,6 +49,11 @@ macro genPrefs*(prefDsl: untyped) =
const `name`*: PrefList = toOrderedTable(`table`)

genPrefs:
Timeline:
following(input, ""):
"A comma-separated list of users to follow."
placeholder: "one,two,three"

Privacy:
replaceTwitter(input, "nitter.net"):
"Replace Twitter links with Nitter (blank to disable)"
Expand Down
42 changes: 42 additions & 0 deletions src/routes/follow.nim
@@ -0,0 +1,42 @@
import jester, asyncdispatch, strutils, sequtils
import router_utils
import ../types

export follow

proc addUserToFollowing*(following, toAdd: string): string =
var updated = following.split(",")
if updated == @[""]:
return toAdd
elif toAdd in updated:
return following
else:
updated = concat(updated, @[toAdd])
result = updated.join(",")

proc removeUserFromFollowing*(following, remove: string): string =
var updated = following.split(",")
if updated == @[""]:
return ""
else:
updated = filter(updated, proc(x: string): bool = x != remove)
result = updated.join(",")

proc createFollowRouter*(cfg: Config) =
router follow:
post "/follow/@name":
let
following = cookiePrefs().following
toAdd = @"name"
updated = addUserToFollowing(following, toAdd)
setCookie("following", updated, daysForward(360),
httpOnly=true, secure=cfg.useHttps, path="/")
redirect(refPath())
post "/unfollow/@name":
let
following = cookiePrefs().following
remove = @"name"
updated = removeUserFromFollowing(following, remove)
setCookie("following", updated, daysForward(360),
httpOnly=true, secure=cfg.useHttps, path="/")
redirect(refPath())
49 changes: 49 additions & 0 deletions src/routes/home.nim
@@ -0,0 +1,49 @@
import jester
import asyncdispatch, strutils, options, router_utils, timeline
import ".."/[prefs, types, utils, redis_cache]
import ../views/[general, home, search]

export home

proc showHome*(request: Request; query: Query; cfg: Config; prefs: Prefs;
after: string): Future[string] {.async.} =
let
timeline = await getSearch[Tweet](query, after)
html = renderHome(timeline, prefs, getPath())
return renderMain(html, request, cfg, prefs)

proc createHomeRouter*(cfg: Config) =
router home:
get "/":
let
prefs = cookiePrefs()
after = getCursor()
names = getNames(prefs.following)

var query = request.getQuery("", prefs.following)
query.fromUser = names

if @"scroll".len > 0:
var timeline = await getSearch[Tweet](query, after)
if timeline.content.len == 0: resp Http404
timeline.beginning = true
resp $renderHome(timeline, prefs, getPath())

if names.len == 0:
resp renderMain(renderSearch(), request, cfg, themePrefs())
resp (await showHome(request, query, cfg, prefs, after))
get "/following":
let
prefs = cookiePrefs()
names = getNames(prefs.following)
var
profs: seq[Profile]
query = request.getQuery("", prefs.following)
query.fromUser = names
query.kind = userList

for name in names:
let prof = await getCachedProfile(name)
profs &= @[prof]

resp renderMain(renderFollowing(query, profs, prefs), request, cfg, prefs)
11 changes: 9 additions & 2 deletions src/sass/profile/card.scss
Expand Up @@ -13,9 +13,12 @@
width: 100%;
}

.profile-card-tabs-name {
.profile-card-tabs-name-and-follow {
@include breakable;
max-width: 100%;
width: 100%;
display: flex;
flex-wrap: wrap;
justify-content: space-between;
}

.profile-card-username {
Expand All @@ -34,6 +37,10 @@
max-width: 100%;
}

.profile-card-follow-button {
float: none;
}

.profile-card-avatar {
display: block;
width: 100%;
Expand Down
32 changes: 32 additions & 0 deletions src/views/home.nim
@@ -0,0 +1,32 @@
import karax/[karaxdsl, vdom]
import search, timeline, renderutils
import ../types

proc renderFollowingUsers*(results: seq[Profile]; prefs: Prefs): VNode =
buildHtml(tdiv(class="timeline")):
for user in results:
renderUser(user, prefs)

proc renderHomeTabs*(query: Query): VNode =
buildHtml(ul(class="tab")):
li(class=query.getTabClass(posts)):
a(href="/"): text "Tweets"
li(class=query.getTabClass(userList)):
a(href=("/following")): text "Following"

proc renderHome*(results: Result[Tweet]; prefs: Prefs; path: string): VNode =
let query = results.query
buildHtml(tdiv(class="timeline-container")):
if query.fromUser.len > 0:
renderHomeTabs(query)

if query.fromUser.len == 0 or query.kind == tweets:
tdiv(class="timeline-header"):
renderSearchPanel(query)

renderTimelineTweets(results, prefs, path)

proc renderFollowing*(query: Query; following: seq[Profile]; prefs: Prefs): VNode =
buildHtml(tdiv(class="timeline-container")):
renderHomeTabs(query)
renderFollowingUsers(following, prefs)
16 changes: 11 additions & 5 deletions src/views/profile.nim
Expand Up @@ -11,7 +11,7 @@ proc renderStat(num, class: string; text=""): VNode =
span(class="profile-stat-num"):
text if num.len == 0: "?" else: insertSep(num, ',')

proc renderProfileCard*(profile: Profile; prefs: Prefs): VNode =
proc renderProfileCard*(profile: Profile; prefs: Prefs, path: string): VNode =
buildHtml(tdiv(class="profile-card")):
tdiv(class="profile-card-info"):
let url = getPicUrl(profile.getUserPic())
Expand All @@ -21,9 +21,15 @@ proc renderProfileCard*(profile: Profile; prefs: Prefs): VNode =
a(class="profile-card-avatar", href=url, target="_blank"):
genImg(profile.getUserpic(size))

tdiv(class="profile-card-tabs-name"):
linkUser(profile, class="profile-card-fullname")
linkUser(profile, class="profile-card-username")
tdiv(class="profile-card-tabs-name-and-follow"):
tdiv():
linkUser(profile, class="profile-card-fullname")
linkUser(profile, class="profile-card-username")
let following = isFollowing(profile.username, prefs.following)
if not following:
buttonReferer "/follow/" & profile.username, "Follow", path, "profile-card-follow-button"
else:
buttonReferer "/unfollow/" & profile.username, "Unfollow", path, "profile-card-follow-button"

tdiv(class="profile-card-extra"):
if profile.bio.len > 0:
Expand Down Expand Up @@ -104,7 +110,7 @@ proc renderProfile*(profile: Profile; timeline: var Timeline;

let sticky = if prefs.stickyProfile: "sticky" else: "unset"
tdiv(class="profile-tab", style={position: sticky}):
renderProfileCard(profile, prefs)
renderProfileCard(profile, prefs, path)
if photoRail.len > 0:
renderPhotoRail(profile, photoRail)

Expand Down
4 changes: 4 additions & 0 deletions src/views/renderutils.nim
Expand Up @@ -93,3 +93,7 @@ proc getTabClass*(query: Query; tab: QueryKind): string =
result = "tab-item"
if query.kind == tab:
result &= " active"

proc isFollowing*(name, following: string): bool =
let following = following.split(",")
return name in following
2 changes: 1 addition & 1 deletion src/views/timeline.nim
Expand Up @@ -56,7 +56,7 @@ proc threadFilter(tweets: openArray[Tweet]; threads: openArray[int64]; it: Tweet
elif t.replyId == result[0].id:
result.add t

proc renderUser(user: Profile; prefs: Prefs): VNode =
proc renderUser*(user: Profile; prefs: Prefs): VNode =
buildHtml(tdiv(class="timeline-item")):
a(class="tweet-link", href=("/" & user.username))
tdiv(class="tweet-body profile-result"):
Expand Down

0 comments on commit f9de565

Please sign in to comment.