gitoriaLog in with ident

ident

All repositories: gitoria

ReadmeCodePull requestsReleasesTicketsSettings
Commit81b15b7b81b15b7bState of 2026-09-27, before the move to gitoriamre81b15b7b/components/inbox.hl

4.0 KB

  1. // components/inbox.hl — `/inbox`: THE NOTIFICATIONS INBOX (piece 4 of 6, ticket ident#6;
  2. // CONCEPT.md "Notifications": "The user reads them in ident's notifications inbox").
  3. // Every notification of every identity of the signed-in account, newest first: identity,
  4. // app, name, text, icon, action link, time; read / unread (a button per notification).
  5. // Below: the apps the account's identities are registered in — each links to its per-app
  6. // page (`/inbox/<connection id>`, components/appsettings.hl).
  7. //
  8. // Faces are named `inbox…` (a face is found by its EVENT NAME across all files).
  9. parent './main.hl'
  10. import { accountOfSession } from '../store.hl'
  11. import { inboxRows, unreadCount, markRead, connectionRows } from '../notify.hl'
  12. import { siteName } from '../project.hl'
  13. session = null
  14. me = accountOfSession(session)
  15. signedIn = me != null
  16. signedOut = me == null
  17. meEmail = me != null ? me.email : ''
  18. items = me != null ? inboxRows(me.id) : []
  19. hasItems = items.length > 0
  20. noItems = items.length == 0
  21. unread = unreadCount(items)
  22. unreadText = unread == 1 ? '1 unread' : unread + ' unread'
  23. conns = me != null ? connectionRows(me.id) : []
  24. hasConns = conns.length > 0
  25. noConns = conns.length == 0
  26. __title = siteName + ' | inbox'
  27. message = ''
  28. View {
  29. identCard { class = "wide"
  30. if (signedOut) {
  31. h1 { "Inbox" }
  32. p { id = "signinfirst" class = "lead" "Sign in to ident first: " a { href = "/" "sign in" } "." }
  33. }
  34. if (signedIn) {
  35. accountBar {
  36. userEmail { id = "meemail" meEmail }
  37. unreadTotal { id = "unreadcount" unreadText }
  38. }
  39. section { id = "inboxsection"
  40. h1 { "Inbox" }
  41. if (noItems) { p { id = "noitems" class = "lead" "No notifications yet. Apps you signed in to with ident can send you some; they show up here." } }
  42. ul { id = "inbox"
  43. for (n of items) {
  44. li { class = n.state
  45. if (n.hasIcon) { img { class = "icon" src = n.icon alt = "" width = "40" height = "40" loading = "lazy" referrerpolicy = "no-referrer" } }
  46. noteMain {
  47. noteHead {
  48. noteName { n.name }
  49. if (n.urgent) { urgentBadge { "urgent" } }
  50. if (n.unread) { unreadBadge { "new" } }
  51. }
  52. noteFrom { n.app " · " n.identity }
  53. noteText { n.text }
  54. noteFoot {
  55. time { n.time }
  56. if (n.hasLink) { a { class = "action" href = n.link target = "_blank" rel = "noopener noreferrer" "Open" } }
  57. button { type = "button" class = "quiet small toggle" value = n.id n.toggleText on click(e) { emit toggle(e.target.value) } }
  58. }
  59. }
  60. }
  61. }
  62. }
  63. }
  64. section { id = "connsection"
  65. h2 { "Notification settings per app" }
  66. if (noConns) { p { id = "noconns" class = "lead" "None of your identities is registered in an app yet." } }
  67. ul { id = "conns"
  68. for (c of conns) {
  69. li {
  70. a { class = "conn" href = c.href c.app }
  71. connDetails { c.identity " · since " c.since }
  72. }
  73. }
  74. }
  75. }
  76. }
  77. p { id = "message" class = "message" message }
  78. }
  79. }
  80. rowOf = (id) => {
  81. for (n of items) { if ('' + n.id == '' + id) { return n } }
  82. return null
  83. }
  84. setItems = (list) => {
  85. items = list
  86. hasItems = list.length > 0
  87. noItems = list.length == 0
  88. let u = 0
  89. for (n of list) { if (n.unread) { u = u + 1 } }
  90. unread = u
  91. unreadText = u == 1 ? '1 unread' : u + ' unread'
  92. return null
  93. }
  94. on toggle(id) {
  95. message = ''
  96. let row = rowOf(id)
  97. if (row == null) { return null }
  98. let r = emit server inboxMark('' + id, !row.read)
  99. if (r == null) {
  100. message = 'the server did not answer — try again'
  101. return null
  102. }
  103. if (r.error != null) {
  104. message = r.error
  105. return null
  106. }
  107. setItems(r.items)
  108. }
  109. // ---- the faces ------------------------------------------------------------------------
  110. // The LAST parameter is the session; accountOfSession only accepts the framework's own
  111. // Session (hl:web never takes it from the peer, hybriel#16/#31).
  112. on server inboxMark(id, read, session) {
  113. let me = accountOfSession(session)
  114. if (me == null) { return { error = 'you are not signed in' } }
  115. let r = markRead(me.id, id, read)
  116. if (r.error != null) { return r }
  117. return { items = inboxRows(me.id) }
  118. }

Branches

Latest commits

  • 81b15b7bState of 2026-09-27, before the move to gitoriamre