Add replying to and quoting text where applicable
This commit is contained in:
parent
396322772f
commit
1cf37e4e84
4 changed files with 53 additions and 24 deletions
|
@ -208,6 +208,7 @@ proc parseTweet(js: JsonNode; jsCard: JsonNode = newJNull()): Tweet =
|
|||
id: js{"id_str"}.getId,
|
||||
threadId: js{"conversation_id_str"}.getId,
|
||||
replyId: js{"in_reply_to_status_id_str"}.getId,
|
||||
replyHandle: js{"in_reply_to_screen_name"}.getStr,
|
||||
text: js{"full_text"}.getStr,
|
||||
time: js{"created_at"}.getTime,
|
||||
hasThread: js{"self_thread"}.notNull,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
# SPDX-License-Identifier: AGPL-3.0-only
|
||||
import asyncdispatch, strutils, sequtils, uri, options, sugar
|
||||
import asyncdispatch, strutils, sequtils, uri, options, sugar, strformat
|
||||
|
||||
import jester, karax/vdom
|
||||
|
||||
|
@ -64,30 +64,43 @@ proc createStatusRouter*(cfg: Config) =
|
|||
resp Http404, showError(error, cfg)
|
||||
|
||||
let
|
||||
title = pageTitle(conv.tweet)
|
||||
ogTitle = pageTitle(conv.tweet.user)
|
||||
desc = conv.tweet.text
|
||||
avatar = conv.tweet.user.userPic
|
||||
time = some(conv.tweet.time)
|
||||
tweet = conv.tweet
|
||||
title = pageTitle(tweet)
|
||||
ogTitle = pageTitle(tweet.user)
|
||||
desc = tweet.text
|
||||
avatar = tweet.user.userPic
|
||||
time = some(tweet.time)
|
||||
|
||||
var
|
||||
images = conv.tweet.photos
|
||||
images = tweet.photos
|
||||
video = ""
|
||||
context = ""
|
||||
contextUrl = ""
|
||||
|
||||
if conv.tweet.video.isSome():
|
||||
let videoObj = get(conv.tweet.video)
|
||||
if tweet.quote.isSome():
|
||||
let
|
||||
quote = tweet.quote.get()
|
||||
quoteUser = quote.user
|
||||
context = &"↘ Quoting: {quoteUser.fullname} (@{quoteUser.username})"
|
||||
contextUrl = &"{getUrlPrefix(cfg)}/i/status/{quote.id}"
|
||||
elif tweet.replyId != 0:
|
||||
context = &"↩ Replying to: @{tweet.replyHandle}"
|
||||
contextUrl = &"{getUrlPrefix(cfg)}/i/status/{tweet.replyId}"
|
||||
|
||||
if tweet.video.isSome():
|
||||
let videoObj = get(tweet.video)
|
||||
images = @[videoObj.thumb]
|
||||
|
||||
let vars = videoObj.variants.filterIt(it.contentType == mp4)
|
||||
# idk why this wont sort when it sorts everywhere else
|
||||
#video = vars.sortedByIt(it.bitrate)[^1].url
|
||||
video = vars[^1].url
|
||||
elif conv.tweet.gif.isSome():
|
||||
let gif = get(conv.tweet.gif)
|
||||
elif tweet.gif.isSome():
|
||||
let gif = get(tweet.gif)
|
||||
images = @[gif.thumb]
|
||||
video = getPicUrl(gif.url)
|
||||
#elif conv.tweet.card.isSome():
|
||||
# let card = conv.tweet.card.get()
|
||||
#elif tweet.card.isSome():
|
||||
# let card = tweet.card.get()
|
||||
# if card.image.len > 0:
|
||||
# images = @[card.image]
|
||||
# elif card.video.isSome():
|
||||
|
@ -95,7 +108,8 @@ proc createStatusRouter*(cfg: Config) =
|
|||
|
||||
let html = renderConversation(conv, prefs, getPath() & "#m")
|
||||
resp renderMain(html, request, cfg, prefs, title, desc, ogTitle,
|
||||
images=images, video=video, avatar=avatar, time=time)
|
||||
images=images, video=video, avatar=avatar, time=time,
|
||||
context=context, contextUrl=contextUrl)
|
||||
|
||||
get "/@name/@s/@id/@m/?@i?":
|
||||
cond @"s" in ["status", "statuses"]
|
||||
|
|
|
@ -211,6 +211,7 @@ type
|
|||
text*: string
|
||||
time*: DateTime
|
||||
reply*: seq[string]
|
||||
replyHandle*: string
|
||||
pinned*: bool
|
||||
hasThread*: bool
|
||||
available*: bool
|
||||
|
|
|
@ -38,7 +38,7 @@ proc renderNavbar(cfg: Config; req: Request; rss, canonical: string): VNode =
|
|||
|
||||
proc renderHead*(prefs: Prefs; cfg: Config; req: Request; titleText=""; desc="";
|
||||
video=""; images: seq[string] = @[]; banner=""; ogTitle="";
|
||||
rss=""; canonical=""; avatar="";
|
||||
rss=""; canonical=""; avatar=""; context=""; contextUrl="";
|
||||
time: Option[DateTime] = none(DateTime)): VNode =
|
||||
var theme = prefs.theme.toTheme
|
||||
if "theme" in req.params:
|
||||
|
@ -140,16 +140,28 @@ proc renderHead*(prefs: Prefs; cfg: Config; req: Request; titleText=""; desc="";
|
|||
meta(property="og:video:url", content=video)
|
||||
meta(property="og:video:secure_url", content=video)
|
||||
meta(property="og:video:type", content="video/mp4")
|
||||
var title = encodeUrl(finalizedDesc)
|
||||
var author = encodeUrl(finalizedTitleText)
|
||||
|
||||
var
|
||||
title = encodeUrl(finalizedDesc)
|
||||
author = encodeUrl(finalizedTitleText)
|
||||
url = req.path
|
||||
|
||||
if len(finalizedDesc) > 67:
|
||||
title = author
|
||||
author = encodeUrl(finalizedDesc)
|
||||
|
||||
verbatim &"<link rel=\"alternate\" href=\"{getUrlPrefix(cfg)}/oembed.json?type=video&provider={encodeUrl(siteName)}&title={title}&user={author}&url={encodeUrl(req.path)}\" type=\"application/json+oembed\" />"
|
||||
#link(rel="alternate",
|
||||
# href=&"{getUrlPrefix(cfg)}/oembed.json?type=video&title={encodeUrl(stripHtml(desc))}&user={encodeUrl(finalizedTitleText)}&url={encodeUrl(req.path)}",
|
||||
# `type`="application/json+oembed")
|
||||
if context != "":
|
||||
author = encodeUrl(context & "\n") & author
|
||||
|
||||
if contextUrl != "":
|
||||
url = contextUrl
|
||||
|
||||
verbatim &"<link rel=\"alternate\" href=\"{getUrlPrefix(cfg)}/oembed.json?type=video&provider={encodeUrl(siteName)}&title={title}&user={author}&url={encodeUrl(url)}\" type=\"application/json+oembed\" />"
|
||||
elif context != "" and contextUrl != "":
|
||||
var
|
||||
title = encodeUrl(finalizedTitleText)
|
||||
author = encodeUrl(context)
|
||||
verbatim &"<link rel=\"alternate\" href=\"{getUrlPrefix(cfg)}/oembed.json?type=video&provider={encodeUrl(siteName)}&title={title}&user={author}&url={encodeUrl(contextUrl)}\" type=\"application/json+oembed\" />"
|
||||
|
||||
# this is last so images are also preloaded
|
||||
# if this is done earlier, Chrome only preloads one image for some reason
|
||||
|
@ -158,14 +170,15 @@ proc renderHead*(prefs: Prefs; cfg: Config; req: Request; titleText=""; desc="";
|
|||
|
||||
proc renderMain*(body: VNode; req: Request; cfg: Config; prefs=defaultPrefs;
|
||||
titleText=""; desc=""; ogTitle=""; rss=""; video="";
|
||||
images: seq[string] = @[]; banner=""; avatar="";
|
||||
time: Option[DateTime] = none(DateTime)): string =
|
||||
images: seq[string] = @[]; banner=""; avatar=""; context="";
|
||||
contextUrl = ""; time: Option[DateTime] = none(DateTime)
|
||||
): string =
|
||||
|
||||
let canonical = getTwitterLink(req.path, req.params)
|
||||
|
||||
let node = buildHtml(html(lang="en")):
|
||||
renderHead(prefs, cfg, req, titleText, desc, video, images, banner, ogTitle,
|
||||
rss, canonical, avatar, time)
|
||||
rss, canonical, avatar, context, contextUrl, time)
|
||||
|
||||
body:
|
||||
renderNavbar(cfg, req, rss, canonical)
|
||||
|
|
Loading…
Reference in a new issue