Sfoglia il codice sorgente

Display "more replies"

Zed 7 anni fa
parent
commit
a901e50df5
6 ha cambiato i file con 77 aggiunte e 33 eliminazioni
  1. 26 0
      public/style.css
  2. 10 9
      src/api.nim
  3. 10 8
      src/parser.nim
  4. 7 0
      src/parserutils.nim
  5. 9 7
      src/types.nim
  6. 15 9
      src/views/user.nimf

+ 26 - 0
public/style.css

@@ -505,6 +505,18 @@ video {
     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 {
     background: #8a3731;
     content: '';
@@ -530,6 +542,20 @@ video {
     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 {
     margin: auto;
     font-size: 130%;

+ 10 - 9
src/api.nim

@@ -110,14 +110,14 @@ proc getVideo*(tweet: Tweet; token: string) {.async.} =
   tweet.video = some(parseVideo(json))
   tokenUses.inc
 
-proc getVideos*(tweets: Tweets; token="") {.async.} =
+proc getVideos*(thread: Thread; token="") {.async.} =
   var gToken = token
   var videoFuts: seq[Future[void]]
 
   if gToken.len == 0:
     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)
 
   await all(videoFuts)
@@ -150,8 +150,8 @@ proc getPoll*(tweet: Tweet) {.async.} =
 
   tweet.poll = some(parsePoll(html))
 
-proc getPolls*(tweets: Tweets) {.async.} =
-  var polls = tweets.filterIt(it.poll.isSome)
+proc getPolls*(thread: Thread) {.async.} =
+  var polls = thread.tweets.filterIt(it.poll.isSome)
   await all(polls.map(getPoll))
 
 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 not json.hasKey("items_html"): return
 
-  let html = parseHtml(json["items_html"].to(string))
-
-  result.tweets = parseTweets(html)
+  let
+    html = parseHtml(json["items_html"].to(string))
+    thread = parseThread(html)
+    vidsFut = getVideos(thread)
+    pollFut = getPolls(thread)
 
-  let vidsFut = getVideos(result.tweets)
-  let pollFut = getPolls(result.tweets)
   await all(vidsFut, pollFut)
+  result.tweets = thread.tweets
 
 proc getTweet*(username: string; id: string): Future[Conversation] {.async.} =
   let headers = newHttpHeaders({

+ 10 - 8
src/parser.nim

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

+ 7 - 0
src/parserutils.nim

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

+ 9 - 7
src/types.nim

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

+ 15 - 9
src/views/user.nimf

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