tweet.nim 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115
  1. #? stdtmpl(subsChar = '$', metaChar = '#')
  2. #import xmltree, strutils, times, sequtils, uri
  3. #import ../types, ../formatters, ../utils
  4. #
  5. #proc renderHeading(tweet: Tweet): string =
  6. #if tweet.retweetBy.isSome:
  7. <div class="retweet">
  8. <span>🔄 ${tweet.retweetBy.get()} retweeted</span>
  9. </div>
  10. #end if
  11. #if tweet.pinned:
  12. <div class="pinned">
  13. <span>📌 Pinned Tweet</span>
  14. </div>
  15. #end if
  16. <div class="media-heading">
  17. <div class="heading-name-row">
  18. <img class="avatar" src=${tweet.profile.getUserpic("_bigger").getSigUrl("pic")}>
  19. <div class="name-and-account-name">
  20. ${linkUser(tweet.profile, "h4", class="username", username=false)}
  21. ${linkUser(tweet.profile, "", class="account-name")}
  22. </div>
  23. <span class="heading-right">
  24. <a href="${tweet.link}" class="timeago faint-link">
  25. <time title="${tweet.time.format("d/M/yyyy', ' HH:mm:ss")}">${tweet.shortTime}</time>
  26. </a>
  27. </span>
  28. </div>
  29. </div>
  30. #end proc
  31. #
  32. #proc renderMediaGroup(tweet: Tweet): string =
  33. #let groups = if tweet.photos.len > 2: tweet.photos.distribute(2) else: @[tweet.photos]
  34. #let display = if groups.len == 1 and groups[0].len == 1: "display: table-caption;" else: ""
  35. #var first = true
  36. <div class="attachments media-body" style="${display}">
  37. #for photos in groups:
  38. #let margin = if not first: "margin-top: .25em;" else: ""
  39. #let flex = if photos.len > 1 or groups.len > 1: "display: flex;" else: ""
  40. <div class="gallery-row cover-fit" style="${margin}">
  41. #for photo in photos:
  42. <div class="attachment image">
  43. ##TODO: why doesn't this work?
  44. <a href=${getSigUrl(photo & "?name=orig", "pic")} target="_blank" class="image-attachment">
  45. <div class="still-image" style="${flex}">
  46. <img src=${getSigUrl(photo, "pic")} referrerpolicy="">
  47. </div>
  48. </a>
  49. </div>
  50. #end for
  51. </div>
  52. #first = false
  53. #end for
  54. </div>
  55. #end proc
  56. #
  57. #proc renderVideo(video: Video): string =
  58. <div class="attachments media-body">
  59. <div class="gallery-row" style="max-height: unset;">
  60. <div class="attachment image">
  61. <video poster=${video.thumb.getSigUrl("pic")} autoplay muted loop></video>
  62. <div class="video-overlay">
  63. <p>Video playback not supported</p>
  64. </div>
  65. </div>
  66. </div>
  67. </div>
  68. #end proc
  69. #
  70. #proc renderGif(gif: Gif): string =
  71. <div class="attachments media-body" style="display: table-cell;">
  72. <div class="gallery-row" style="max-height: unset;">
  73. <div class="attachment image">
  74. <video class="gif" poster=${gif.thumb.getSigUrl("pic")} autoplay muted loop>
  75. <source src=${gif.url.getSigUrl("video")} type="video/mp4">
  76. </video>
  77. </div>
  78. </div>
  79. </div>
  80. #end proc
  81. #
  82. #proc renderStats(tweet: Tweet): string =
  83. <div class="tweet-stats">
  84. <span class="tweet-stat">💬 ${$tweet.replies}</span>
  85. <span class="tweet-stat">🔄 ${$tweet.retweets}</span>
  86. <span class="tweet-stat">👍 ${$tweet.likes}</span>
  87. </div>
  88. #end proc
  89. #
  90. #proc renderTweet*(tweet: Tweet; class=""): string =
  91. #if class.len > 0:
  92. <div class="${class}">
  93. #end if
  94. <div class="status-el">
  95. <div class="status-body">
  96. ${renderHeading(tweet)}
  97. <div class="status-content-wrapper">
  98. <div class="status-content media-body">
  99. ${linkifyText(xmltree.escape(tweet.text))}
  100. </div>
  101. </div>
  102. #if tweet.photos.len > 0:
  103. ${renderMediaGroup(tweet)}
  104. #elif tweet.video.isSome:
  105. ${renderVideo(tweet.video.get())}
  106. #elif tweet.gif.isSome:
  107. ${renderGif(tweet.gif.get())}
  108. #end if
  109. ${renderStats(tweet)}
  110. </div>
  111. </div>
  112. #if class.len > 0:
  113. </div>
  114. #end if
  115. #end proc