diff --git a/public/style.css b/public/style.css index 45d89b1..4e6ed68 100644 --- a/public/style.css +++ b/public/style.css @@ -138,6 +138,11 @@ a:hover { margin-left: 4px; } +.replying-to { + color: hsla(240,1%,73%,.7); + margin: 4px 0; +} + .status-el .status-content { font-family: sans-serif; line-height: 1.4em; diff --git a/src/parser.nim b/src/parser.nim index b6decbc..0f6d06b 100644 --- a/src/parser.nim +++ b/src/parser.nim @@ -41,8 +41,10 @@ proc parseTweetProfile*(profile: XmlNode): Profile = proc parseQuote*(quote: XmlNode): Quote = result = Quote( - id: quote.attr("data-item-id"), - text: getQuoteText(quote) + id: quote.attr("data-item-id"), + text: getQuoteText(quote), + reply: parseTweetReply(quote), + hasThread: quote.select(".self-thread-context") != nil, ) result.profile = Profile( @@ -64,6 +66,8 @@ proc parseTweet*(node: XmlNode): Tweet = shortTime: getShortTime(tweet), profile: parseTweetProfile(tweet), stats: parseTweetStats(tweet), + reply: parseTweetReply(tweet), + hasThread: tweet.select(".self-thread-context") != nil, pinned: "pinned" in tweet.attr("class"), available: true ) diff --git a/src/parserutils.nim b/src/parserutils.nim index f7ba651..a1f8c0a 100644 --- a/src/parserutils.nim +++ b/src/parserutils.nim @@ -120,11 +120,17 @@ proc parseTweetStats*(node: XmlNode): TweetStats = of "rep": result.replies = text[0] of "lik": result.likes = text[0] +proc parseTweetReply*(node: XmlNode): seq[string] = + let reply = node.select(".ReplyingToContextBelowAuthor") + if reply == nil: return + for username in reply.selectAll("a"): + result.add username.selectText("b") + proc getGif(player: XmlNode): Gif = let thumb = player.attr("style").replace(thumbRegex, "$1") id = thumb.replace(gifRegex, "$1") - url = fmt"https://video.twimg.com/tweet_video/{id}.mp4" + url = &"https://video.twimg.com/tweet_video/{id}.mp4" Gif(url: url, thumb: thumb) proc getTweetMedia*(tweet: Tweet; node: XmlNode) = @@ -146,15 +152,15 @@ proc getQuoteMedia*(quote: var Quote; node: XmlNode) = let media = node.select(".QuoteMedia") if media != nil: - quote.thumb = some(media.selectAttr("img", "src")) + quote.thumb = media.selectAttr("img", "src") let badge = node.select(".AdaptiveMedia-badgeText") let gifBadge = node.select(".Icon--gifBadge") if badge != nil: - quote.badge = some(badge.innerText()) + quote.badge = badge.innerText() elif gifBadge != nil: - quote.badge = some("GIF") + quote.badge = "GIF" proc getTweetCards*(tweet: Tweet; node: XmlNode) = if node.attr("data-has-cards") == "false": return diff --git a/src/types.nim b/src/types.nim index 4758f80..639aee2 100644 --- a/src/types.nim +++ b/src/types.nim @@ -58,9 +58,11 @@ type id*: string profile*: Profile text*: string + reply*: seq[string] + hasThread*: bool sensitive*: bool - thumb*: Option[string] - badge*: Option[string] + thumb*: string + badge*: string Retweet* = object by*: string @@ -77,8 +79,10 @@ type text*: string time*: Time shortTime*: string - available*: bool + reply*: seq[string] pinned*: bool + available*: bool + hasThread*: bool stats*: TweetStats retweet*: Option[Retweet] quote*: Option[Quote] diff --git a/src/views/tweet.nimf b/src/views/tweet.nimf index 9f9e7a7..e2fc056 100644 --- a/src/views/tweet.nimf +++ b/src/views/tweet.nimf @@ -1,5 +1,5 @@ #? stdtmpl(subsChar = '$', metaChar = '#') -#import xmltree, strutils, times, sequtils, uri +#import xmltree, strutils, strformat, sequtils, times, uri #import ../types, ../formatters, ../utils # #proc renderHeading(tweet: Tweet): string = @@ -29,38 +29,6 @@ #end proc # -#proc renderQuote(quote: Quote): string = -#let hasMedia = quote.thumb.isSome() or quote.sensitive -