Sfoglia il codice sorgente

Show related tweets under replies

Fixes #1334
Zed 2 mesi fa
parent
commit
092397cd6f
6 ha cambiato i file con 46 aggiunte e 3 eliminazioni
  1. 18 1
      src/parser.nim
  2. 3 0
      src/prefs_impl.nim
  3. 9 0
      src/sass/tweet/thread.scss
  4. 1 0
      src/types.nim
  5. 1 1
      src/views/general.nim
  6. 14 1
      src/views/status.nim

+ 18 - 1
src/parser.nim

@@ -710,10 +710,26 @@ proc parseGraphTweet*(js: JsonNode): Tweet =
   with birdwatch, js{"birdwatch_pivot"}:
     result.note = parseCommunityNote(birdwatch)
 
+proc getConvSection(js: JsonNode): string =
+  let details = select(
+    js{"item", "client_event_info", "details"},
+    js{"item", "clientEventInfo", "details"}
+  )
+  select(
+    details{"conversation_details", "conversation_section"},
+    details{"conversationDetails", "conversationSection"}
+  ).getStr
+
 proc parseGraphThread(js: JsonNode): tuple[thread: Chain; self: bool] =
+  var checkedSection = false
   for t in ? js{"content", "items"}:
     let entryId = t.getEntryId
     if "tweet-" in entryId and "promoted" notin entryId:
+      if not checkedSection:
+        checkedSection = true
+        if getConvSection(t) == "RelatedTweet":
+          result.thread.related = true
+
       let tweet = t.getTweetResult("item")
       if tweet.notNull:
         result.thread.content.add parseGraphTweet(tweet)
@@ -774,7 +790,8 @@ proc parseGraphConversation*(js: JsonNode; tweetId: string): Conversation =
               result.before.content.add tweet
           elif not entryId.endsWith(tweetId):
             result.before.content.add Tweet(id: entryId.getId)
-        elif entryId.startsWith("conversationthread"):
+        elif entryId.startsWith("conversationthread") or
+             entryId.startsWith("tweetdetailrelatedtweets"):
           let (thread, self) = parseGraphThread(e)
           if self:
             result.after = thread

+ 3 - 0
src/prefs_impl.nim

@@ -78,6 +78,9 @@ genPrefs:
     hideReplies(checkbox, false):
       "Hide tweet replies"
 
+    hideRelated(checkbox, true):
+      "Hide related tweets under replies"
+
     hideCommunityNotes(checkbox, false):
       "Hide community notes"
 

+ 9 - 0
src/sass/tweet/thread.scss

@@ -185,3 +185,12 @@
     }
   }
 }
+
+.related-header {
+  padding: 8px 12px;
+  margin-top: 10px;
+  background-color: var(--bg_panel);
+  color: var(--fg_faded);
+  font-size: 14px;
+  border-bottom: 1px solid var(--border_grey);
+}

+ 1 - 0
src/types.nim

@@ -359,6 +359,7 @@ type
     content*: Tweets
     hasMore*: bool
     cursor*: string
+    related*: bool
 
   Conversation* = ref object
     tweet*: Tweet

+ 1 - 1
src/views/general.nim

@@ -50,7 +50,7 @@ proc renderHead*(prefs: Prefs; cfg: Config; req: Request; titleText=""; desc="";
   let opensearchUrl = getUrlPrefix(cfg) & "/opensearch"
 
   buildHtml(head):
-    link(rel="stylesheet", type="text/css", href="/css/style.css?v=50")
+    link(rel="stylesheet", type="text/css", href="/css/style.css?v=51")
     link(rel="stylesheet", type="text/css", href="/css/fontello.css?v=7")
 
     if theme.len > 0:

+ 14 - 1
src/views/status.nim

@@ -1,4 +1,5 @@
 # SPDX-License-Identifier: AGPL-3.0-only
+import sequtils
 import karax/[karaxdsl, vdom]
 
 import ".."/[types, formatters]
@@ -48,7 +49,7 @@ proc renderReplies*(replies: Result[Chain]; prefs: Prefs; path: string;
     var hasReplies = false
     var replyCount = 0
     for thread in replies.content:
-      if thread.content.len == 0: continue
+      if thread.content.len == 0 or thread.related: continue
       hasReplies = true
       replyCount += thread.content.len
       renderReplyThread(thread, prefs, path)
@@ -58,6 +59,14 @@ proc renderReplies*(replies: Result[Chain]; prefs: Prefs; path: string;
         let extra = if sort == Relevance: "" else: "sort=" & $sort & "&"
         renderMore(Query(), replies.bottom, focus="#r", extra=extra)
 
+proc renderRelated(replies: Result[Chain]; prefs: Prefs; path: string): VNode =
+  buildHtml(tdiv(class="related-tweets")):
+    tdiv(class="related-header"):
+      text "Related tweets"
+    for thread in replies.content:
+      if thread.content.len == 0 or not thread.related: continue
+      renderReplyThread(thread, prefs, path)
+
 proc renderConversation*(conv: Conversation; prefs: Prefs; path: string;
                          sort = Relevance): VNode =
   let hasAfter = conv.after.content.len > 0
@@ -95,6 +104,10 @@ proc renderConversation*(conv: Conversation; prefs: Prefs; path: string;
         renderReplySort(sort)
         renderReplies(conv.replies, prefs, path, conv.tweet, sort)
 
+    if not prefs.hideRelated:
+      if conv.replies.content.anyIt(it.related and it.content.len > 0):
+        renderRelated(conv.replies, prefs, path)
+
     renderToTop(focus="#m")
 
 proc renderEditHistory*(edits: EditHistory; prefs: Prefs; path: string): VNode =