ident
All repositories: gitoria
4.1 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 '../lib/accounts.hl'import { inboxRows, markRead, connectionRows } from '../lib/notify.hl'import { unreadCount } from '../lib/notify-helpers.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 = ''row = rowOf(id)if (row == null) { return null }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' } }r = markRead(me.id, id, read)if (r.error != null) { return r }return { items = inboxRows(me.id) }}
Branches
- mainmain branch
Latest commits
- 74235815ident mission 009 (4/4): docs (README files map + same-output test, STATUS, LOG), report, tests/letcount.py + realdata-baseline/comparemre
- fe183516ident mission 009 (3/4): let only where reassigned — 293 never-reassigned lets are plain declarations; kept: reassigned, loop bodies, names of a file member, a name declared twice in one function; same outputmre
- 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