Display "more replies"

This commit is contained in:
Zed 2019-07-01 03:13:12 +02:00
parent 160c28eda3
commit a901e50df5
6 changed files with 77 additions and 33 deletions

View file

@ -505,6 +505,18 @@ video {
margin-bottom: 10px; margin-bottom: 10px;
} }
.more-replies {
padding-top: 0.3em;
}
.more-replies-text {
display: block;
margin-left: 58px;
padding: 7px 0;
text-overflow: ellipsis;
white-space: nowrap;
}
.thread-line .status-el::before { .thread-line .status-el::before {
background: #8a3731; background: #8a3731;
content: ''; content: '';
@ -530,6 +542,20 @@ video {
margin: 0; margin: 0;
} }
.thread-line .more-replies::before {
content: '...';
background: unset;
color: #b94e46;
font-weight: bold;
font-size: 22px;
line-height: 0.25em;
left: 1.2em;
width: 5px;
top: 2px;
margin-bottom: 0px;
margin-left: -5px;
}
.panel { .panel {
margin: auto; margin: auto;
font-size: 130%; font-size: 130%;

View file

@ -110,14 +110,14 @@ proc getVideo*(tweet: Tweet; token: string) {.async.} =
tweet.video = some(parseVideo(json)) tweet.video = some(parseVideo(json))
tokenUses.inc tokenUses.inc
proc getVideos*(tweets: Tweets; token="") {.async.} = proc getVideos*(thread: Thread; token="") {.async.} =
var gToken = token var gToken = token
var videoFuts: seq[Future[void]] var videoFuts: seq[Future[void]]
if gToken.len == 0: if gToken.len == 0:
gToken = await getGuestToken() gToken = await getGuestToken()
for tweet in tweets.filterIt(it.video.isSome): for tweet in thread.tweets.filterIt(it.video.isSome):
videoFuts.add getVideo(tweet, token) videoFuts.add getVideo(tweet, token)
await all(videoFuts) await all(videoFuts)
@ -150,8 +150,8 @@ proc getPoll*(tweet: Tweet) {.async.} =
tweet.poll = some(parsePoll(html)) tweet.poll = some(parsePoll(html))
proc getPolls*(tweets: Tweets) {.async.} = proc getPolls*(thread: Thread) {.async.} =
var polls = tweets.filterIt(it.poll.isSome) var polls = thread.tweets.filterIt(it.poll.isSome)
await all(polls.map(getPoll)) await all(polls.map(getPoll))
proc getConversationPolls*(convo: Conversation) {.async.} = proc getConversationPolls*(convo: Conversation) {.async.} =
@ -222,13 +222,14 @@ proc getTimeline*(username: string; after=""): Future[Timeline] {.async.} =
if json["new_latent_count"].to(int) == 0: return if json["new_latent_count"].to(int) == 0: return
if not json.hasKey("items_html"): return if not json.hasKey("items_html"): return
let html = parseHtml(json["items_html"].to(string)) let
html = parseHtml(json["items_html"].to(string))
thread = parseThread(html)
vidsFut = getVideos(thread)
pollFut = getPolls(thread)
result.tweets = parseTweets(html)
let vidsFut = getVideos(result.tweets)
let pollFut = getPolls(result.tweets)
await all(vidsFut, pollFut) await all(vidsFut, pollFut)
result.tweets = thread.tweets
proc getTweet*(username: string; id: string): Future[Conversation] {.async.} = proc getTweet*(username: string; id: string): Future[Conversation] {.async.} =
let headers = newHttpHeaders({ let headers = newHttpHeaders({

View file

@ -82,19 +82,21 @@ proc parseTweet*(node: XmlNode): Tweet =
if quote != nil: if quote != nil:
result.quote = some(parseQuote(quote)) result.quote = some(parseQuote(quote))
proc parseTweets*(nodes: XmlNode): Tweets = proc parseThread*(nodes: XmlNode): Thread =
if nodes == nil: return if nodes == nil: return
for n in nodes.filterIt(it.kind != xnText): for n in nodes.filterIt(it.kind != xnText):
let class = n.attr("class").toLower() let class = n.attr("class").toLower()
if "tombstone" in class or "unavailable" in class: if "tombstone" in class or "unavailable" in class:
result.add Tweet() result.tweets.add Tweet()
elif "morereplies" notin class: elif "morereplies" in class:
result.add parseTweet(n) result.more = getMoreReplies(n)
else:
result.tweets.add parseTweet(n)
proc parseConversation*(node: XmlNode): Conversation = proc parseConversation*(node: XmlNode): Conversation =
result = Conversation( result = Conversation(
tweet: parseTweet(node.select(".permalink-tweet-container")), tweet: parseTweet(node.select(".permalink-tweet-container")),
before: parseTweets(node.select(".in-reply-to .stream-items")) before: parseThread(node.select(".in-reply-to .stream-items"))
) )
let replies = node.select(".replies-to .stream-items") let replies = node.select(".replies-to .stream-items")
@ -105,11 +107,11 @@ proc parseConversation*(node: XmlNode): Conversation =
let thread = reply.select(".stream-items") let thread = reply.select(".stream-items")
if "self" in class: if "self" in class:
result.after = parseTweets(thread) result.after = parseThread(thread)
elif "lone" in class: elif "lone" in class:
result.replies.add parseTweets(reply) result.replies.add parseThread(reply)
else: else:
result.replies.add parseTweets(thread) result.replies.add parseThread(thread)
proc parseVideo*(node: JsonNode): Video = proc parseVideo*(node: JsonNode): Video =
let let

View file

@ -162,3 +162,10 @@ proc getTweetCards*(tweet: Tweet; node: XmlNode) =
if node.attr("data-has-cards") == "false": return if node.attr("data-has-cards") == "false": return
if "poll" in node.attr("data-card2-type"): if "poll" in node.attr("data-card2-type"):
tweet.poll = some(Poll()) tweet.poll = some(Poll())
proc getMoreReplies*(node: XmlNode): int =
let text = node.innerText().strip()
try:
result = parseInt(text.split(" ")[0])
except:
result = -1

View file

@ -83,19 +83,21 @@ type
poll*: Option[Poll] poll*: Option[Poll]
available*: bool available*: bool
Tweets* = seq[Tweet] Thread* = object
tweets*: seq[Tweet]
more*: int
Conversation* = ref object Conversation* = ref object
tweet*: Tweet tweet*: Tweet
before*: Tweets before*: Thread
after*: Tweets after*: Thread
replies*: seq[Tweets] replies*: seq[Thread]
Timeline* = ref object Timeline* = ref object
tweets*: Tweets tweets*: seq[Tweet]
minId*: string minId*: string
maxId*: string maxId*: string
hasMore*: bool hasMore*: bool
proc contains*(thread: Tweets; tweet: Tweet): bool = proc contains*(thread: Thread; tweet: Tweet): bool =
thread.anyIt(it.id == tweet.id) thread.tweets.anyIt(it.id == tweet.id)

View file

@ -51,7 +51,7 @@
#end proc #end proc
# #
#proc renderTimeline*(timeline: Timeline; profile: Profile; beginning: bool): string = #proc renderTimeline*(timeline: Timeline; profile: Profile; beginning: bool): string =
#var retweets: Tweets #var retweets: seq[Tweet]
<div id="tweets"> <div id="tweets">
#if not beginning: #if not beginning:
<div class="show-more status-el"> <div class="show-more status-el">
@ -104,21 +104,21 @@
#proc renderConversation*(conversation: Conversation): string = #proc renderConversation*(conversation: Conversation): string =
<div class="conversation" id="tweets"> <div class="conversation" id="tweets">
<div class="main-thread"> <div class="main-thread">
#if conversation.before.len > 0: #if conversation.before.tweets.len > 0:
<div class="before-tweet thread-line"> <div class="before-tweet thread-line">
#for tweet in conversation.before: #for tweet in conversation.before.tweets:
${renderTweet(tweet)} ${renderTweet(tweet)}
#end for #end for
</div> </div>
#end if #end if
<div class="main-tweet"> <div class="main-tweet">
#let afterClass = if conversation.after.len > 0: "thread thread-line" else: "" #let afterClass = if conversation.after.tweets.len > 0: "thread thread-line" else: ""
${renderTweet(conversation.tweet, class=afterClass)} ${renderTweet(conversation.tweet, class=afterClass)}
</div> </div>
#if conversation.after.len > 0: #if conversation.after.tweets.len > 0:
<div class="after-tweet thread-line"> <div class="after-tweet thread-line">
#for i, tweet in conversation.after: #for i, tweet in conversation.after.tweets:
${renderTweet(tweet, last=(i == conversation.after.high))} ${renderTweet(tweet, last=(i == conversation.after.tweets.high))}
#end for #end for
</div> </div>
#end if #end if
@ -127,9 +127,15 @@
<div class="replies"> <div class="replies">
#for thread in conversation.replies: #for thread in conversation.replies:
<div class="reply thread thread-line"> <div class="reply thread thread-line">
#for i, tweet in thread: #for i, tweet in thread.tweets:
${renderTweet(tweet, last=(i == thread.high))} ${renderTweet(tweet, last=(i == thread.tweets.high and thread.more == 0))}
#end for #end for
#if thread.more != 0:
#let num = if thread.more != -1: $thread.more & " " else: ""
<div class="status-el more-replies">
<a class="more-replies-text" title="Not implemented yet">${num}more replies</a>
</div>
#end if
</div> </div>
#end for #end for
</div> </div>