profile.nim 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120
  1. # SPDX-License-Identifier: AGPL-3.0-only
  2. import strutils, strformat
  3. import karax/[karaxdsl, vdom, vstyles]
  4. import renderutils, search
  5. import ".."/[types, utils, formatters]
  6. proc renderStat(num: int; class: string; text=""): VNode =
  7. let t = if text.len > 0: text else: class
  8. buildHtml(li(class=class)):
  9. span(class="profile-stat-header"): text capitalizeAscii(t)
  10. span(class="profile-stat-num"):
  11. text insertSep($num, ',')
  12. proc renderUserCard*(user: User; prefs: Prefs): VNode =
  13. buildHtml(tdiv(class="profile-card")):
  14. tdiv(class="profile-card-info"):
  15. let
  16. url = getPicUrl(user.getUserPic())
  17. size =
  18. if prefs.autoplayGifs and user.userPic.endsWith("gif"): ""
  19. else: "_400x400"
  20. a(class="profile-card-avatar", href=url, target="_blank"):
  21. genImg(user.getUserPic(size))
  22. tdiv(class="profile-card-tabs-name"):
  23. linkUser(user, class="profile-card-fullname")
  24. verifiedIcon(user)
  25. linkUser(user, class="profile-card-username")
  26. tdiv(class="profile-card-extra"):
  27. if user.bio.len > 0:
  28. tdiv(class="profile-bio"):
  29. p(dir="auto"):
  30. verbatim replaceUrls(user.bio, prefs)
  31. if user.location.len > 0:
  32. tdiv(class="profile-location"):
  33. span: icon "location"
  34. let (place, url) = getLocation(user)
  35. if url.len > 1:
  36. a(href=url): text place
  37. elif "://" in place:
  38. a(href=place): text place
  39. else:
  40. span: text place
  41. if user.website.len > 0:
  42. tdiv(class="profile-website"):
  43. span:
  44. let url = replaceUrls(user.website, prefs)
  45. icon "link"
  46. a(href=url): text url.shortLink
  47. tdiv(class="profile-joindate"):
  48. span(title=getJoinDateFull(user)):
  49. icon "calendar", getJoinDate(user)
  50. tdiv(class="profile-card-extra-links"):
  51. ul(class="profile-statlist"):
  52. renderStat(user.tweets, "posts", text="Tweets")
  53. renderStat(user.following, "following")
  54. renderStat(user.followers, "followers")
  55. renderStat(user.likes, "likes")
  56. proc renderPhotoRail(profile: Profile): VNode =
  57. let count = insertSep($profile.user.media, ',')
  58. buildHtml(tdiv(class="photo-rail-card")):
  59. tdiv(class="photo-rail-header"):
  60. a(href=(&"/{profile.user.username}/media")):
  61. icon "picture", count & " Photos and videos"
  62. input(id="photo-rail-grid-toggle", `type`="checkbox")
  63. label(`for`="photo-rail-grid-toggle", class="photo-rail-header-mobile"):
  64. icon "picture", count & " Photos and videos"
  65. icon "down"
  66. tdiv(class="photo-rail-grid"):
  67. for i, photo in profile.photoRail:
  68. if i == 16: break
  69. let photoSuffix =
  70. if "format" in photo.url or "placeholder" in photo.url: ""
  71. else: ":thumb"
  72. a(href=(&"/{profile.user.username}/status/{photo.tweetId}#m")):
  73. genImg(photo.url & photoSuffix)
  74. proc renderBanner(banner: string): VNode =
  75. buildHtml():
  76. if banner.len == 0:
  77. a()
  78. elif banner.startsWith('#'):
  79. a(style={backgroundColor: banner})
  80. else:
  81. a(href=getPicUrl(banner), target="_blank"): genImg(banner)
  82. proc renderProtected(username: string): VNode =
  83. buildHtml(tdiv(class="timeline-container")):
  84. tdiv(class="timeline-header timeline-protected"):
  85. h2: text "This account's tweets are protected."
  86. p: text &"Only confirmed followers have access to @{username}'s tweets."
  87. proc renderProfile*(profile: var Profile; prefs: Prefs; path: string): VNode =
  88. profile.tweets.query.fromUser = @[profile.user.username]
  89. buildHtml(tdiv(class="profile-tabs")):
  90. if not prefs.hideBanner:
  91. tdiv(class="profile-banner"):
  92. renderBanner(profile.user.banner)
  93. let sticky = if prefs.stickyProfile: " sticky" else: ""
  94. tdiv(class=("profile-tab" & sticky)):
  95. renderUserCard(profile.user, prefs)
  96. if profile.photoRail.len > 0:
  97. renderPhotoRail(profile)
  98. if profile.user.protected:
  99. renderProtected(profile.user.username)
  100. else:
  101. renderTweetSearch(profile.tweets, prefs, path, profile.pinned)