renderutils.nim 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  1. # SPDX-License-Identifier: AGPL-3.0-only
  2. import strutils, strformat
  3. import karax/[karaxdsl, vdom, vstyles]
  4. import ".."/[types, utils]
  5. const smallWebp* = "?name=small&format=webp"
  6. proc getSmallPic*(url: string): string =
  7. result = url
  8. if "?" notin url and not url.endsWith("placeholder.png"):
  9. result &= smallWebp
  10. result = getPicUrl(result)
  11. proc icon*(icon: string; text=""; title=""; class=""; href=""): VNode =
  12. var c = "icon-" & icon
  13. if class.len > 0: c = &"{c} {class}"
  14. buildHtml(tdiv(class="icon-container")):
  15. if href.len > 0:
  16. a(class=c, title=title, href=href)
  17. else:
  18. span(class=c, title=title)
  19. if text.len > 0:
  20. text " " & text
  21. template verifiedIcon*(user: User): untyped {.dirty.} =
  22. if user.verifiedType != VerifiedType.none:
  23. let lower = ($user.verifiedType).toLowerAscii()
  24. icon "ok", class=(&"verified-icon {lower}"), title=(&"Verified {lower} account")
  25. else:
  26. text ""
  27. proc linkUser*(user: User, class=""): VNode =
  28. let
  29. isName = "username" notin class
  30. href = "/" & user.username
  31. nameText = if isName: user.fullname
  32. else: "@" & user.username
  33. buildHtml(a(href=href, class=class, title=nameText)):
  34. text nameText
  35. if isName:
  36. verifiedIcon(user)
  37. if user.protected:
  38. text " "
  39. icon "lock", title="Protected account"
  40. proc linkText*(text: string; class=""): VNode =
  41. let url = if "http" notin text: https & text else: text
  42. buildHtml():
  43. a(href=url, class=class): text text
  44. proc hiddenField*(name, value: string): VNode =
  45. buildHtml():
  46. input(name=name, style={display: "none"}, value=value)
  47. proc refererField*(path: string): VNode =
  48. hiddenField("referer", path)
  49. proc buttonReferer*(action, text, path: string; class=""; `method`="post"): VNode =
  50. buildHtml(form(`method`=`method`, action=action, class=class)):
  51. refererField path
  52. button(`type`="submit"):
  53. text text
  54. proc genCheckbox*(pref, label: string; state: bool): VNode =
  55. buildHtml(label(class="pref-group checkbox-container")):
  56. text label
  57. input(name=pref, `type`="checkbox", checked=state)
  58. span(class="checkbox")
  59. proc genInput*(pref, label, state, placeholder: string; class=""; autofocus=true): VNode =
  60. let p = placeholder
  61. buildHtml(tdiv(class=("pref-group pref-input " & class))):
  62. if label.len > 0:
  63. label(`for`=pref): text label
  64. input(name=pref, `type`="text", placeholder=p, value=state, autofocus=(autofocus and state.len == 0))
  65. proc genSelect*(pref, label, state: string; options: seq[string]): VNode =
  66. buildHtml(tdiv(class="pref-group pref-input")):
  67. label(`for`=pref): text label
  68. select(name=pref):
  69. for opt in options:
  70. option(value=opt, selected=(opt == state)):
  71. text opt
  72. proc genDate*(pref, state: string): VNode =
  73. buildHtml(span(class="date-input")):
  74. input(name=pref, `type`="date", value=state)
  75. icon "calendar"
  76. proc genImg*(url: string; class=""): VNode =
  77. buildHtml():
  78. img(src=getPicUrl(url), class=class, alt="", loading="lazy")
  79. proc getTabClass*(query: Query; tab: QueryKind): string =
  80. if query.kind == tab: "tab-item active"
  81. else: "tab-item"
  82. proc getAvatarClass*(prefs: Prefs): string =
  83. if prefs.squareAvatars: "avatar"
  84. else: "avatar round"