Browse Source

Implement link previews

Zed 7 years ago
parent
commit
ec5f67123a
5 changed files with 44 additions and 9 deletions
  1. 0 1
      README.md
  2. 1 1
      public/style.css
  3. 6 0
      src/formatters.nim
  4. 12 2
      src/nitter.nim
  5. 25 5
      src/views/general.nim

+ 0 - 1
README.md

@@ -27,7 +27,6 @@ is on implementing missing features.
 
 - Search (images/videos, hashtags, etc.)
 - Custom timeline filter
-- Nitter link previews
 - More caching (waiting for [moigagoo/norm#19](https://github.com/moigagoo/norm/pull/19))
 - Simple account system with customizable feed
 - Video support with hls.js

+ 1 - 1
public/style.css

@@ -140,7 +140,7 @@ a:hover {
 
 .replying-to {
     color: hsla(240,1%,73%,.9);
-    margin: -4px 0 4px 0;
+    margin: -2px 0 4px 0;
 }
 
 .status-el .status-content {

+ 6 - 0
src/formatters.nim

@@ -68,9 +68,15 @@ proc getUserpic*(userpic: string; style=""): string =
 proc getUserpic*(profile: Profile; style=""): string =
   getUserPic(profile.userpic, style)
 
+proc getVideoEmbed*(video: Video): string =
+  &"https://twitter.com/i/videos/{video.videoId}?embed_source=facebook"
+
 proc pageTitle*(profile: Profile): string =
   &"{profile.fullname} (@{profile.username})"
 
+proc pageDesc*(profile: Profile): string =
+  "The latest tweets from " & profile.fullname
+
 proc getTime*(tweet: Tweet): string =
   tweet.time.format("d/M/yyyy', ' HH:mm:ss")
 

+ 12 - 2
src/nitter.nim

@@ -24,7 +24,7 @@ proc showSingleTimeline(name, after, agent: string; query: Option[Query]): Futur
     return ""
 
   let profileHtml = renderProfile(profile, await timelineFut, await railFut)
-  return renderMain(profileHtml, title=cfg.title, titleText=pageTitle(profile))
+  return renderMain(profileHtml, title=cfg.title, titleText=pageTitle(profile), desc=pageDesc(profile))
 
 proc showMultiTimeline(names: seq[string]; after, agent: string; query: Option[Query]): Future[string] {.async.} =
   var q = query
@@ -91,7 +91,17 @@ routes:
       resp Http404, showError("Tweet not found", cfg.title)
 
     let title = pageTitle(conversation.tweet.profile)
-    resp renderMain(renderConversation(conversation), title=cfg.title, titleText=title)
+    let desc = conversation.tweet.text
+    let html = renderConversation(conversation)
+
+    if conversation.tweet.video.isSome():
+      let thumb = get(conversation.tweet.video).thumb
+      let vidUrl = getVideoEmbed(get(conversation.tweet.video))
+      resp renderMain(html, title=cfg.title, titleText=title, desc=desc,
+                      images = @[thumb], `type`="video", video=vidUrl)
+    else:
+      resp renderMain(html, title=cfg.title, titleText=title,
+                      desc=desc, images=conversation.tweet.photos)
 
   get "/pic/@sig/@url":
     cond "http" in @"url"

+ 25 - 5
src/views/general.nim

@@ -1,16 +1,36 @@
 import karax/[karaxdsl, vdom]
 
+import ../utils
+
 const doctype = "<!DOCTYPE html>\n"
 
-proc renderMain*(body: VNode; title="Nitter"; titleText=""): string =
+proc renderMain*(body: VNode; title="Nitter"; titleText=""; desc="";
+                 `type`="article"; video=""; images: seq[string] = @[]): string =
   let node = buildHtml(html(lang="en")):
     head:
-      if titleText.len > 0:
-        title: text titleText & " | " & title
-      else:
-        title: text title
       link(rel="stylesheet", `type`="text/css", href="/style.css")
 
+      title:
+        if titleText.len > 0:
+          text titleText & " | " & title
+        else:
+          text title
+
+      meta(name="og:type", content=`type`)
+      meta(name="og:title", content=titleText)
+      meta(name="og:description", content=desc)
+      meta(name="og:site_name", content="Twitter")
+
+      for url in images:
+        meta(name="og:image", content=getSigUrl(url, "pic"))
+
+      if video.len > 0:
+        meta(name="og:video:url", content=video)
+        meta(name="og:video:secure_url", content=video)
+        meta(name="og:video:type", content="text/html")
+        meta(name="og:video:width", content="1200")
+        meta(name="og:video:height", content="675")
+
     body:
       nav(id="nav", class="nav-bar container"):
         tdiv(class="inner-nav"):