renderutils.nim 3.9 KB

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