فهرست منبع

Improve timeline support, "no more tweets" message

Zed 7 سال پیش
والد
کامیت
ac8d0e2052
4فایلهای تغییر یافته به همراه38 افزوده شده و 13 حذف شده
  1. 8 1
      public/style.css
  2. 13 4
      src/api.nim
  3. 6 0
      src/types.nim
  4. 11 8
      src/views/user.nimf

+ 8 - 1
public/style.css

@@ -575,7 +575,14 @@ nav {
 .timeline-protected-header {
     color: #d0564c;
     font-size: 21px;
-    font-weight: bold;
+    font-weight: 600;
+}
+
+.timeline-end {
+    text-align: center;
+    font-size: 16px;
+    color: #ff6c60;
+    font-weight: 600;
 }
 
 .media-gif {

+ 13 - 4
src/api.nim

@@ -150,7 +150,7 @@ proc getProfile*(username: string): Future[Profile] {.async.} =
 
   result = parsePopupProfile(html)
 
-proc getTimeline*(username: string; after=""): Future[Tweets] {.async.} =
+proc getTimeline*(username: string; after=""): Future[Timeline] {.async.} =
   let headers = newHttpHeaders({
     "Accept": "application/json, text/javascript, */*; q=0.01",
     "Referer": $(base / username),
@@ -164,10 +164,19 @@ proc getTimeline*(username: string; after=""): Future[Tweets] {.async.} =
   if after.len > 0:
     url &= "&max_position=" & after
 
-  let html = await fetchHtml(base / url, headers, jsonKey="items_html")
+  let json = await fetchJson(base / url, headers)
+  let html = parseHtml(json["items_html"].to(string))
 
-  result = parseTweets(html)
-  await getVideos(result)
+  result = Timeline(
+    tweets: parseTweets(html),
+    minId: json["min_position"].to(string),
+    hasMore: json["has_more_items"].to(bool),
+  )
+
+  if json.hasKey("max_position"):
+    result.maxId = json["max_position"].to(string)
+
+  await getVideos(result.tweets)
 
 proc getTweet*(id: string): Future[Conversation] {.async.} =
   let headers = newHttpHeaders({

+ 6 - 0
src/types.nim

@@ -78,5 +78,11 @@ type
     after*: Tweets
     replies*: seq[Tweets]
 
+  Timeline* = ref object
+    tweets*: Tweets
+    minId*: string
+    maxId*: string
+    hasMore*: bool
+
 proc contains*(thread: Tweets; tweet: Tweet): bool =
   thread.anyIt(it.id == tweet.id)

+ 11 - 8
src/views/user.nimf

@@ -52,7 +52,7 @@
 #end if
 #end proc
 #
-#proc renderTimeline*(tweets: Tweets; profile: Profile; beginning: bool): string =
+#proc renderTimeline*(timeline: Timeline; profile: Profile; beginning: bool): string =
 <div id="tweets">
   #if profile.protected:
   <div class="timeline-protected">
@@ -66,19 +66,22 @@
   </div>
   #end if
   #var retweets: Tweets
-  #for tweet in tweets:
+  #for tweet in timeline.tweets:
     #if tweet in retweets: continue
     #elif tweet.retweetBy.isSome: retweets.add tweet
     #end if
     ${renderTweet(tweet, "timeline-tweet")}
   #end for
-  #if tweets.len > 0:
+  #if timeline.hasMore:
   <div class="show-more">
-    #let retweet = tweets[^1].retweetId.get("")
-    #let id = if retweet.len > 0: retweet else: tweets[^1].id
-    <a href="/${profile.username}?after=${$id}">Load older tweets</a>
+    <a href="/${profile.username}?after=${timeline.minId}">Load older tweets</a>
   </div>
   #else:
+  <div class="timeline-protected">
+    <h2 class="timeline-end" style="text-align: center;">No more tweets.</h2>
+  </div>
+  #end if
+  #if timeline.tweets.len == 0:
   <div class="timeline-protected">
     <h2 class="timeline-protected-header" style="text-align: center;">No tweets found.</h2>
   </div>
@@ -86,7 +89,7 @@
 </div>
 #end proc
 #
-#proc renderProfile*(profile: Profile; tweets: Tweets; beginning: bool): string =
+#proc renderProfile*(profile: Profile; timeline: Timeline; beginning: bool): string =
 <div class="profile-tabs">
   <div class="profile-banner">
     ${renderBanner(profile)}
@@ -95,7 +98,7 @@
     ${renderProfileCard(profile)}
   </div>
   <div class="timeline-tab">
-    ${renderTimeline(tweets, profile, beginning)}
+    ${renderTimeline(timeline, profile, beginning)}
   </div>
 </div>
 #end proc