Jelajahi Sumber

Support tweet locations

Zed 6 tahun lalu
induk
melakukan
f8f4487c33
7 mengubah file dengan 34 tambahan dan 5 penghapusan
  1. 5 0
      src/formatters.nim
  2. 1 0
      src/parser.nim
  3. 6 0
      src/parserutils.nim
  4. 5 0
      src/sass/tweet/_base.scss
  5. 1 0
      src/types.nim
  6. 4 4
      src/views/profile.nim
  7. 12 1
      src/views/tweet.nim

+ 5 - 0
src/formatters.nim

@@ -103,3 +103,8 @@ proc getTwitterLink*(path: string; params: Table[string, string]): string =
   result = $(parseUri("https://twitter.com") / path ? p)
   if username.len > 0:
     result = result.replace("/" & username, "")
+
+proc getLocation*(u: Profile | Tweet): (string, string) =
+  let loc = u.location.split(":")
+  let url = if loc.len > 1: "/search?q=place:" & loc[1] else: ""
+  (loc[0], url)

+ 1 - 0
src/parser.nim

@@ -108,6 +108,7 @@ proc parseTweet*(node: XmlNode): Tweet =
     stats:     parseTweetStats(tweet),
     reply:     parseTweetReply(tweet),
     mediaTags: getMediaTags(tweet),
+    location:  getTweetLocation(tweet),
     hasThread: tweet.select(".content > .self-thread-context") != nil,
     pinned:    "pinned" in tweet.attr("class"),
     available: true

+ 6 - 0
src/parserutils.nim

@@ -285,3 +285,9 @@ proc getMediaTags*(node: XmlNode): seq[Profile] =
     let un = user["screen_name"].getStr
     if un notin usernames: continue
     result.add Profile(username: un, fullname: user["name"].getStr)
+
+proc getTweetLocation*(node: XmlNode): string =
+  let geo = node.select(".js-geo-pivot-link")
+  if geo == nil: return
+  result = geo.innerText().stripText()
+  result &= ":" & geo.attr("data-place-id")

+ 5 - 0
src/sass/tweet/_base.scss

@@ -128,6 +128,10 @@
     font-size: 13px;
 }
 
+.tweet-geo {
+    color: var(--fg_faded);
+}
+
 .replying-to {
     color: var(--fg_faded);
     margin: -2px 0 4px;
@@ -168,6 +172,7 @@
 .show-thread {
     display: block;
     pointer-events: all;
+    padding-top: 2px;
 }
 
 .unavailable-box {

+ 1 - 0
src/types.nim

@@ -147,6 +147,7 @@ type
     hasThread*: bool
     available*: bool
     tombstone*: string
+    location*: string
     stats*: TweetStats
     retweet*: Option[Retweet]
     attribution*: Option[Profile]

+ 4 - 4
src/views/profile.nim

@@ -31,11 +31,11 @@ proc renderProfileCard*(profile: Profile; prefs: Prefs): VNode =
       if profile.location.len > 0:
         tdiv(class="profile-location"):
           span: icon "location"
-          let loc = profile.location.split(":")
-          if loc.len > 1:
-            a(href=("/search?q=place:" & loc[1])): text loc[0]
+          let (place, url) = profile.getLocation()
+          if url.len > 1:
+            a(href=url): text place
           else:
-            span: text loc[0]
+            span: text place
 
       if profile.website.len > 0:
         tdiv(class="profile-website"):

+ 12 - 1
src/views/tweet.nim

@@ -245,6 +245,17 @@ proc renderQuote(quote: Quote; prefs: Prefs): VNode =
       a(class="show-thread", href=getLink(quote)):
         text "Show this thread"
 
+proc renderLocation*(tweet: Tweet): string =
+  let (place, url) = tweet.getLocation()
+  if place.len == 0: return
+  let node = buildHtml(span(class="tweet-geo")):
+    text " – at "
+    if url.len > 1:
+      a(href=url): text place
+    else:
+      text place
+  return $node
+
 proc renderTweet*(tweet: Tweet; prefs: Prefs; path: string; class="";
                   index=0; total=(-1); last=false; showThread=false;
                   mainTweet=false): VNode =
@@ -272,7 +283,7 @@ proc renderTweet*(tweet: Tweet; prefs: Prefs; path: string; class="";
         renderReply(tweet)
 
       tdiv(class="tweet-content media-body", dir="auto"):
-        verbatim replaceUrl(tweet.text, prefs)
+        verbatim replaceUrl(tweet.text, prefs) & renderLocation(tweet)
 
       if tweet.attribution.isSome:
         renderAttribution(tweet.attribution.get())