ident
All repositories: gitoria
4.0 KB
// components/inbox.hl — `/inbox`: THE NOTIFICATIONS INBOX (piece 4 of 6, ticket ident#6;// CONCEPT.md "Notifications": "The user reads them in ident's notifications inbox").// Every notification of every identity of the signed-in account, newest first: identity,// app, name, text, icon, action link, time; read / unread (a button per notification).// Below: the apps the account's identities are registered in — each links to its per-app// page (`/inbox/<connection id>`, components/appsettings.hl).//// Faces are named `inbox…` (a face is found by its EVENT NAME across all files).parent './main.hl'import { accountOfSession } from '../store.hl'import { inboxRows, unreadCount, markRead, connectionRows } from '../notify.hl'import { siteName } from '../project.hl'session = nullme = accountOfSession(session)signedIn = me != nullsignedOut = me == nullmeEmail = me != null ? me.email : ''items = me != null ? inboxRows(me.id) : []hasItems = items.length > 0noItems = items.length == 0unread = unreadCount(items)unreadText = unread == 1 ? '1 unread' : unread + ' unread'conns = me != null ? connectionRows(me.id) : []hasConns = conns.length > 0noConns = conns.length == 0__title = siteName + ' | inbox'message = ''View {identCard { class = "wide"if (signedOut) {h1 { "Inbox" }p { id = "signinfirst" class = "lead" "Sign in to ident first: " a { href = "/" "sign in" } "." }}if (signedIn) {accountBar {userEmail { id = "meemail" meEmail }unreadTotal { id = "unreadcount" unreadText }}section { id = "inboxsection"h1 { "Inbox" }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." } }ul { id = "inbox"for (n of items) {li { class = n.stateif (n.hasIcon) { img { class = "icon" src = n.icon alt = "" width = "40" height = "40" loading = "lazy" referrerpolicy = "no-referrer" } }noteMain {noteHead {noteName { n.name }if (n.urgent) { urgentBadge { "urgent" } }if (n.unread) { unreadBadge { "new" } }}noteFrom { n.app " · " n.identity }noteText { n.text }noteFoot {time { n.time }if (n.hasLink) { a { class = "action" href = n.link target = "_blank" rel = "noopener noreferrer" "Open" } }button { type = "button" class = "quiet small toggle" value = n.id n.toggleText on click(e) { emit toggle(e.target.value) } }}}}}}}section { id = "connsection"h2 { "Notification settings per app" }if (noConns) { p { id = "noconns" class = "lead" "None of your identities is registered in an app yet." } }ul { id = "conns"for (c of conns) {li {a { class = "conn" href = c.href c.app }connDetails { c.identity " · since " c.since }}}}}}p { id = "message" class = "message" message }}}rowOf = (id) => {for (n of items) { if ('' + n.id == '' + id) { return n } }return null}setItems = (list) => {items = listhasItems = list.length > 0noItems = list.length == 0let u = 0for (n of list) { if (n.unread) { u = u + 1 } }unread = uunreadText = u == 1 ? '1 unread' : u + ' unread'return null}on toggle(id) {message = ''let row = rowOf(id)if (row == null) { return null }let r = emit server inboxMark('' + id, !row.read)if (r == null) {message = 'the server did not answer — try again'return null}if (r.error != null) {message = r.errorreturn null}setItems(r.items)}// ---- the faces ------------------------------------------------------------------------// The LAST parameter is the session; accountOfSession only accepts the framework's own// Session (hl:web never takes it from the peer, hybriel#16/#31).on server inboxMark(id, read, session) {let me = accountOfSession(session)if (me == null) { return { error = 'you are not signed in' } }let r = markRead(me.id, id, read)if (r.error != null) { return r }return { items = inboxRows(me.id) }}
Branches
- mainmain branch
Latest commits
- 81b15b7bState of 2026-09-27, before the move to gitoriamre