gitoriaLog in with ident

ident

All repositories: gitoria

ReadmeCodePull requestsReleasesTicketsSettings
Commitd2e7f91bd2e7f91bident mission 009 (2/4): one lib file per topic (login, accounts, identities, apps, invites, selector, notify + helpers, util), function routes as thin wrappers in lib/api.hl, project.hl = the map; same outputmred2e7f91b/components/inbox.hl

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

Branches

Latest commits

  • d2e7f91bident mission 009 (2/4): one lib file per topic (login, accounts, identities, apps, invites, selector, notify + helpers, util), function routes as thin wrappers in lib/api.hl, project.hl = the map; same outputmre
  • 91017164ident mission 009 (1/4): file moves — the root .hl files into lib/ (api.hl → lib/api-helpers.hl), styles.hl → components/styles.hl; imports adjusted, no other changemre
  • f8bdcbc2ident: Hybriel master 06617221 (plugin allocators 3a781359 + 413f60e4, mpackdb 2cb7ae5e, http1 773de63e); all gates greenmre
  • ff78726cident: Hybriel master 190aa11d (fc838894 GC correctness, #127, #126 closure scopes); gates all greenmre
  • a3a7d21aident: Hybriel master 8efba065 (#126 GC by bytes, #48 lambda params copy); session-writing lambdas take &sessionmre
  • 98226b41antcolony#40: mission references point to the moved missionsmre
  • ff805b9aantcolony#40: history (LOG.md), worker briefs (missions/) and reports moved here from antcolony, numbered per project; old numbers in antcolony docs/mission-map.mdmre
  • 51a7bcdfident: Hybriel master 73267707 (#122); /code uses the new page() signature; pending address passed as parameter; once-checksmre
  • 836f644fident#24: installable app (manifest, service worker, data-free offline /start), own iconmre
  • 8bebbbf2deploy.sh: back up live storage/.sessions/.env before every deploy (newest 5 kept)mre
  • cc063ea2deploy.sh: never send .git or .gitignore to Byrodinmre
  • 81b15b7bState of 2026-09-27, before the move to gitoriamre