landscape: upgrade for new hark-store

This commit is contained in:
Liam Fitzgerald 2021-09-06 13:31:11 +10:00
parent 613980c511
commit 76e033c649
16 changed files with 543 additions and 123 deletions

View File

@ -1,7 +1,7 @@
:: hark-graph-hook: notifications for graph-store [landscape]
::
/- post, group-store, metadata=metadata-store, hook=hark-graph-hook, store=hark-store
/+ resource, mdl=metadata, default-agent, dbug, graph-store, graph, grouplib=group, store=hark-store
/+ resource, mdl=metadata, default-agent, dbug, graph-store, graph, grouplib=group
::
::
~% %hark-graph-hook-top ..part ~
@ -18,23 +18,34 @@
+$ state-1
[%1 base-state-0]
::
+$ state-2
[%2 base-state-1]
::
+$ base-state-0
$: watching=(set [resource index:post])
mentions=_&
watch-on-self=_&
==
::
+$ base-state-1
$: watching=(set [resource index:post])
mentions=_&
watch-on-self=_&
places=(map resource place:store)
==
::
++ scry
|* [[our=@p now=@da] =mold p=path]
?> ?=(^ p)
~! p
?> ?=(^ t.p)
.^(mold i.p (scot %p our) i.t.p (scot %da now) t.t.p)
::
++ scry-notif-conversion
|= [[our=@p now=@da] desk=term =mark]
^- $-(indexed-post:graph-store (unit notif-kind:hook))
^- $-(indexed-post:graph-store $-(cord (unit notif-kind:hook)))
%^ scry [our now]
$-(indexed-post:graph-store (unit notif-kind:hook))
$-(indexed-post:graph-store $-(cord (unit notif-kind:hook)))
/cf/[desk]/[mark]/notification-kind
--
::
@ -63,6 +74,7 @@
^- (quip card _this)
=+ !<(old=versioned-state vase)
=| cards=(list card)
=. cards [watch-graph:ha cards]
|-
?: ?=(%0 -.old)
%_ $
@ -202,7 +214,7 @@
%- ~(gas by *(set [resource index:graph-store]))
(turn ~(tap in indices) (lead rid))
:_ state(watching (~(dif in watching) to-remove))
=/ convert (get-conversion:ha rid)
=/ convert (get-conversion:ha rid '')
%+ roll
~(tap in indices)
|= [=index:graph-store out=(list card)]
@ -211,11 +223,11 @@
=/ notif-kind=(unit notif-kind:hook)
(convert indexed-post)
?~ notif-kind out
=/ =stats-index:store
[%graph rid (scag parent.index-len.u.notif-kind index)]
=/ =place:store
(get-place rid index)
?. ?=(%each mode.u.notif-kind) out
:_ out
(poke-hark %read-each stats-index index)
(poke-hark %read-each place index)
::
++ poke-hark
|= =action:store
@ -231,11 +243,8 @@
=(r rid)
:_ state(watching (~(dif in watching) unwatched))
^- (list card)
:- (poke-hark:ha %remove-graph rid)
%- zing
%+ turn ~(tap in unwatched)
|= [r=resource =index:graph-store]
(give:ha ~[/updates] %ignore r index)
~
:: XX: fix
::
++ add-graph
|= rid=resource
@ -280,15 +289,46 @@
grp ~(. grouplib bowl)
gra ~(. graph bowl)
::
++ graph-index-to-path
|= =index:graph-store
^- path
(turn index (cork (cury scot %ui) (cury rsh 4)))
::
++ summarize
|= contents=(list content:post)
%+ rap 3
%+ join ' '
%+ turn contents
|= =content:post
?- -.content
%text text.content
%url url.content
%code '<Code fragment>'
%reference '<A reference>'
%mention (scot %p ship.content)
==
::
++ get-place
|= [rid=resource =index:graph-store]
:- q.byk.bowl
(welp /graph/(scot %p entity.rid)/[name.rid] (graph-index-to-path index))
::
++ get-bin
|= [rid=resource parent=index:graph-store is-mention=?]
[?:(is-mention /mention /) (get-place rid parent)]
::
++ get-conversion
|= rid=resource
|= [rid=resource title=cord]
^- $-(indexed-post:graph-store (unit notif-kind:hook))
=+ %^ scry [our now]:bowl
,mark=(unit mark)
/gx/graph-store/graph/(scot %p entity.rid)/[name.rid]/mark/noun
?~ mark
|=(=indexed-post:graph-store ~)
(scry-notif-conversion [our now]:bowl q.byk.bowl u.mark)
=/ f=$-(indexed-post:graph-store $-(cord (unit notif-kind:hook)))
(scry-notif-conversion [our now]:bowl q.byk.bowl u.mark)
|= =indexed-post:graph-store
((f indexed-post) title)
::
++ give
|= [paths=(list path) =update:hook]
@ -338,8 +378,11 @@
(get-mark:gra r)
update-core(rid r, updates upds, mark m)
::
++ title
~+ title:(fall (peek-metadatum:met %graph rid) *metadatum:metadata)
::
++ get-conversion
~+ (^get-conversion rid)
~+ (^get-conversion rid title)
::
++ abet
^- (quip card _state)
@ -391,63 +434,61 @@
=. update-core (check-node-children node)
?: ?=(%| -.post.node)
update-core
::?~ mark update-core
=* pos p.post.node
=/ notif-kind=(unit notif-kind:hook)
(get-conversion [0 pos])
(get-conversion [0 pos])
?~ notif-kind
update-core
=/ desc=@t
?: (is-mention contents.pos)
%mention
name.u.notif-kind
=* not-kind u.notif-kind
=/ parent=index:post
(scag parent.index-len.not-kind index.pos)
=/ notif-index=index:store
[%graph rid mark desc parent]
=/ is-mention (is-mention contents.pos)
=/ =bin:store
(get-bin rid parent is-mention)
?: =(our.bowl author.pos)
(self-post node notif-index not-kind)
(self-post node bin u.notif-kind)
=. update-core
(update-unread-count not-kind notif-index [time-sent index]:pos)
%^ update-unread-count u.notif-kind bin
(scag self.index-len.not-kind index.pos)
=? update-core
?| =(desc %mention)
?| is-mention
(~(has in watching) [rid parent])
=(mark `%graph-validator-dm)
==
=/ =contents:store
[%graph (limo pos ~)]
(add-unread notif-index [time-sent.pos %.n contents])
=/ link=path
(welp /(fall mark '')/(scot %p entity.rid)/[name.rid] (graph-index-to-path index.pos))
=/ =body:store
[title.not-kind body.not-kind now.bowl path.bin link]
(add-unread bin body)
update-core
::
::
++ update-unread-count
|= [=notif-kind:hook =index:store time=@da ref=index:graph-store]
=/ =stats-index:store
(to-stats-index:store index)
|= [=notif-kind:hook =bin:store =index:graph-store]
?- mode.notif-kind
%count (hark %unread-count stats-index time)
%each (hark %unread-each stats-index ref time)
%count (hark %unread-count place.bin %.y 1)
%each (hark %unread-each place.bin /(rsh 4 (scot %ui (rear index))))
%none update-core
==
::
++ self-post
|= $: =node:graph-store
=index:store
=bin:store
=notif-kind:hook
==
^+ update-core
?> ?=(%& -.post.node)
=/ =stats-index:store
(to-stats-index:store index)
=. update-core
(hark %seen-index time-sent.p.post.node stats-index)
(hark %seen-index place.bin)
=? update-core ?=(%count mode.notif-kind)
(hark %read-count stats-index)
(hark %read-count place.bin)
=? update-core watch-on-self
(new-watch index.p.post.node [watch-for index-len]:notif-kind)
update-core
::
++ add-unread
|= [=index:store =notification:store]
(hark %add-note index notification)
|= [=bin:store =body:store]
(hark %add-note bin body)
--
--

View File

@ -14,6 +14,8 @@
$: %0
watching=(set resource)
==
+$ update
$>(?(%add-members %remove-members) update:group-store)
::
--
::
@ -127,13 +129,13 @@
[~ state]
?. (~(has in watching) resource.update)
[~ state]
=/ =contents:store
[%group ~[update]]
=/ =notification:store [now.bowl %.n contents]
=/ =index:store
[%group resource.update -.update]
=/ body=(unit body:store)
(get-content:ha update)
?~ body `state
=/ =bin:store
(get-bin:ha resource.update -.update)
:_ state
~[(add-unread index notification)]
~[(add-unread bin u.body)]
:: +metadata-update is stubbed for now, for the following reasons
:: - There's no semantic difference in metadata-store between
:: adding and editing a channel
@ -145,12 +147,12 @@
[~ state]
::
++ add-unread
|= [=index:store =notification:store]
|= [=bin:store =body:store]
^- card
=- [%pass / %agent [our.bowl %hark-store] %poke -]
:- %hark-action
!> ^- action:store
[%add-note index notification]
[%add-note bin body]
--
::
++ on-peek on-peek:def
@ -159,7 +161,48 @@
++ on-fail on-fail:def
--
|_ =bowl:gall
+* met ~(. metadata bowl)
+* met ~(. mdl bowl)
++ get-content
|= =update:group-store
^- (unit body:store)
?. ?=(?(%add-members %remove-members) -.update) ~
?~ meta=(peek-metadatum:met %groups resource.update)
~
=/ ships=(list content:store)
%+ turn ~(tap in ships.update)
|= =ship
^- content:store
ship+ship
=/ sep=content:store text+', '
=. ships
(join sep ships)
?- -.update
%add-members
:- ~
:* (snoc ships text+(rap 3 ' joined ' title.u.meta ~))
~
now.bowl
/
/
==
::
%remove-members
:- ~
:* (snoc ships text+(rap 3 ' joined ' title.u.meta ~))
~
now.bowl
/
/
==
==
++ get-bin
|= [rid=resource reason=@t]
^- bin:store
[/[reason] (get-place rid)]
++ get-place
|= rid=resource
^- place:store
[q.byk.bowl /(scot %p entity.rid)/[name.rid]]
::
++ watch-groups
^- card

View File

@ -0,0 +1,105 @@
/- hark=hark-store, invite=invite-store
/+ verb, dbug, default-agent, agentio
|%
+$ card card:agent:gall
--
=<
%+ verb &
%- agent:dbug
^- agent:gall
|_ =bowl:gall
+* this .
def ~(. (default-agent this %|) bowl)
io ~(. agentio bowl)
pass pass:io
cc ~(. +> bowl)
++ on-init on-init:def
::
++ on-load
|= =vase
:_ this
(drop safe-watch:sub:cc)
++ on-save !>(~)
::
++ on-poke on-poke:def
++ on-peek on-peek:def
++ on-watch on-watch:def
++ on-agent
|= [=wire =sign:agent:gall]
|^
?+ wire (on-agent:def wire sign)
[%invites ~] take-invites
==
++ take-invites
?- -.sign
?(%poke-ack %watch-ack) (on-agent:def wire sign)
%kick :_(this (drop safe-watch:sub:cc))
::
%fact
?. ?=(%invite-update p.cage.sign) `this
=+ !<(=update:invite q.cage.sign)
?+ -.update `this
::
%invite
:_ this
(~(created inv:cc [term uid]:update) invite.update)^~
::
%accepted
:_ this
~(accepted inv:cc [term uid]:update)^~
==
==
--
::
++ on-arvo on-arvo:def
++ on-fail on-fail:def
++ on-leave on-leave:def
--
|_ =bowl:gall
+* io ~(. agentio bowl)
pass pass:io
++ ha
|%
++ pass ~(. ^pass /hark)
++ poke
|=(=action:hark (poke-our:pass %hark-store hark-action+!>(action)))
--
++ sub
|%
++ path /updates
++ wire /invites
++ pass ~(. ^pass wire)
++ watch (watch-our:pass %invite-store path)
++ watching (~(has by wex.bowl) [wire our.bowl %invite-store])
++ safe-watch `(unit card)`?:(watching ~ `watch)
--
::
++ inv
|_ [=term uid=serial:invite]
++ bin [/ place]
++ path /[term]/(scot %uv uid)
++ place `place:hark`[q.byk.bowl path]
++ accepted
(poke:ha %del-place place)
++ created
|= =invite:invite
=; =body:hark
(poke:ha %add-note bin body)
=, invite
=/ title=@t
%: rap 3
'You have been invited to '
(scot %p entity.resource)
'/'
name.resource
' by '
~
==
:* ~[text+title ship+ship]
~[text+text]
now.bowl
/
path
==
--
--

View File

@ -1,6 +1,6 @@
::
/- *notify, resource, hark-store, post
/+ default-agent, verb, dbug, group, agentio
/+ default-agent, verb, dbug, group, agentio, graphlib=graph
::
|%
+$ card card:agent:gall
@ -18,19 +18,25 @@
$: providers=(jug @p term)
==
::
+$ state-0
$: %0
=provider-state
+$ base-state-0
$: =provider-state
=client-state
==
::
+$ state-0
[%0 base-state-0]
::
+$ state-1
[%1 base-state-0]
::
+$ versioned-state
$% state-0
state-1
==
::
--
::
=| state-0
=| state-1
=* state -
::
%- agent:dbug
@ -47,19 +53,27 @@
::
++ on-init
:_ this
[(~(watch-our pass:io /hark) %hark-store /updates)]~
[(~(watch-our pass:io /hark) %hark-store /notes)]~
::
++ on-save !>(state)
++ on-load
|= =old=vase
^- (quip card _this)
=/ old !<(versioned-state old-vase)
=| cards=(list card)
|-
?- -.old
%1 [(flop cards) this]
::
%0
:_ this(state old)
?. (~(has by wex.bowl) [/hark our.bowl %hark-store])
~
[(~(watch-our pass:io /hark) %hark-store /updates)]~
%_ $
::
cards
%+ welp cards
:~ (~(leave-our pass:io /hark) %hark-store)
(~(watch-our pass:io /hark) %hark-store /notes)
==
==
==
::
++ on-poke
@ -199,12 +213,10 @@
?. ?=(%hark-update p.cage.sign)
~
=+ !<(hark-update=update:hark-store q.cage.sign)
=/ notes=(list notification) (filter-notifications:do hark-update)
?~ notes
~
?~ not=(filter-notifications:do hark-update) ~
:: only send the last one, since hark accumulates notifcations
=/ =update [%notification `notification`(snag 0 (flop notes))]
=/ card (fact-all:io %notify-update !>(update))
=/ =update [%notification u.not]
=/ card=(unit card) ~ ::(fact-all:io %notify-update !>(update))
(drop card)
::
%kick
@ -281,39 +293,23 @@
++ on-fail on-fail:def
--
|_ bowl=bowl:gall
+* gra ~(. graphlib bowl)
::
++ filter-notifications
|= =update:hark-store
^- (list notification)
?+ -.update ~
%more
(zing (turn more.update filter-notifications))
::
%added
?- -.index.update
%graph
?: =(`%graph-validator-dm mark.index.update)
?. ?=(%graph -.contents.notification.update)
~
%+ turn list.contents.notification.update
|= =post:post
^- notification
[graph.index.update index.post]
?: =(`%graph-validator-chat mark.index.update)
=/ hid (group-is-hidden graph.index.update)
?~ hid ~
?. u.hid ~
?. ?=(%graph -.contents.notification.update)
~
%+ turn list.contents.notification.update
|= =post:post
^- notification
[graph.index.update index.post]
~
::
%group ~
==
==
^- (unit notification)
?. ?=(%add-note -.update) ~
=* place place.bin.update
?. ?=(%landscape desk.place) ~
?. ?=([%graph *] path.place) ~
=/ link=path link.body.update
?. ?=([@ @ @ *] link) ~
?~ ship=(slaw %p i.t.link) ~
=* name i.t.t.link
=/ =resource:resource [u.ship name]
=/ =index:graph-store
(turn t.t.t.link (curr rash dim:ag))
`[resource index]
::
++ group-is-hidden
|= =resource:resource

View File

@ -1,41 +1,40 @@
:~ :- %apes
:~ %chat-cli
%chat-hook
:~ %metadata-store :: start stores first
%contact-store
%chat-store
%graph-store
%group-store
%hark-store
%invite-store
%s3-store
%settings-store
%chat-cli
%chat-hook
%chat-view
%clock
%contact-hook
%contact-pull-hook
%contact-push-hook
%contact-store
%contact-view
%demo-pull-hook
%demo-push-hook
%demo-store
%dm-hook
%graph-pull-hook
%graph-push-hook
%graph-store
%group-pull-hook
%group-push-hook
%group-store
%group-view
%hark-chat-hook
%hark-graph-hook
%hark-group-hook
%hark-store
%hark-invite-hook
%invite-hook
%invite-store
%invite-view
%launch
%metadata-hook
%metadata-pull-hook
%metadata-push-hook
%metadata-store
%notify
%observe-hook
%s3-store
%sane
%settings-store
%weather
==
:- %fish

View File

@ -3,7 +3,7 @@
color+0xee.5432
glob+'https://bootstrap.urbit.org/glob-0v4.0k6hb.4s38v.su79d.10vd5.7c8lu.glob'
base+'landscape'
version+[0 0 1]
version+[1 3 5]
website+'https://tlon.io'
license+'MIT'
==

View File

@ -84,6 +84,10 @@
=/ =rave:clay
?:(?=(%sing genre) [genre mood] [genre mood])
(warp-our q.byk.bowl `rave)
::
++ connect
|= [=binding:eyre app=term]
(arvo %e %connect binding app)
--
::
++ fact-curry
@ -115,6 +119,16 @@
^- card
[%give %fact paths cage]
::
++ fact-all
|= =cage
^- (unit card)
=/ paths=(set path)
%- ~(gas in *(set path))
%+ turn ~(tap by sup.bowl)
|=([duct ship =path] path)
?: =(~ paths) ~
`(fact cage ~(tap in paths))
::
++ kick
|= paths=(list path)
[%give %kick paths ~]

View File

@ -1,10 +1,24 @@
/- sur=graph-store, pos=post, pull-hook
/- sur=graph-store, pos=post, pull-hook, hark=hark-store
/+ res=resource, migrate
=< [sur .]
=< [pos .]
=, sur
=, pos
|%
++ hark-content
|= =content
^- content:hark
?- -.content
%text content
%mention ship+ship.content
%url text+url.content
%code text+'A code excerpt'
%reference text+'A reference'
==
::
++ hark-contents
|= cs=(list content)
(turn cs hark-content)
:: NOTE: move these functions to zuse
++ nu :: parse number as hex
|= jon=json

View File

@ -1,4 +1,5 @@
/- *post, met=metadata-store, graph=graph-store, hark=hark-graph-hook
/- *post, met=metadata-store, hark=hark-graph-hook
/+ graph=graph-store
|_ i=indexed-post
++ grow
|%
@ -24,9 +25,15 @@
==
::
++ notification-kind
|= title=cord
^- (unit notif-kind:hark)
?+ index.p.i ~
[@ ~] `[%message [0 1] %count %none]
[@ ~]
:- ~
:* ~[text+(rap 3 'New messages in ' title ~)]
[ship+author.p.i text+': ' (hark-contents:graph contents.p.i)]
[0 1] %count %none
==
==
::
++ transform-add-nodes

View File

@ -1,6 +1,8 @@
/- *post, met=metadata-store, graph=graph-store, hark=hark-graph-hook
/- *post, met=metadata-store, hark=hark-graph-hook
/+ graph=graph-store
|_ i=indexed-post
++ grow
::
++ grow
|%
++ noun i
::
@ -11,9 +13,15 @@
i
::
++ notification-kind
|= title=cord
^- (unit notif-kind:hark)
?+ index.p.i ~
[@ @ ~] `[%message [1 2] %count %none]
[@ @ ~]
:- ~
:* ~[text+'New messages from ' ship+author.p.i]
(hark-contents:graph contents.p.i)
[1 2] %count %none
==
==
::
--

View File

@ -1,4 +1,5 @@
/- *post, met=metadata-store, graph=graph-store, hark=hark-graph-hook
/- *post, met=metadata-store, hark=hark-graph-hook
/+ graph=graph-store
|_ i=indexed-post
++ grow
|%
@ -49,10 +50,24 @@
==
::
++ notification-kind
|= title=cord
^- (unit notif-kind:hark)
?+ index.p.i ~
[@ ~] `[%link [0 1] %each %children]
[@ @ %1 ~] `[%comment [1 2] %count %siblings]
[@ ~]
:- ~
:* [text+(rap 3 'New links in ' title ~)]~
[ship+author.p.i text+': ' (hark-contents:graph contents.p.i)]
[0 1] %each %children
==
[@ @ %1 ~]
:- ~
:* [text+(rap 3 'New comments on a post in ' title ~)]~
[ship+author.p.i text+': ' (hark-contents:graph contents.p.i)]
[1 2] %count %siblings
==
==
::
++ transform-add-nodes

View File

@ -1,4 +1,5 @@
/- *post, met=metadata-store, graph=graph-store, hark=hark-graph-hook
/- *post, met=metadata-store, hark=hark-graph-hook
/+ graph=graph-store
|_ i=indexed-post
++ grow
|%
@ -26,11 +27,16 @@
:: +notification-kind: don't track unreads, notify on replies
::
++ notification-kind
|= title=cord
^- (unit notif-kind:hark)
=/ len (lent index.p.i)
=/ =mode:hark
?:(=(1 len) %count %none)
`[%post [(dec len) len] mode %children]
:- ~
:* ~[text+(rap 3 'Your post in ' title ' received replies ' ~)]
[ship+author.p.i text+': ' (hark-contents:graph contents.p.i)]
[(dec len) len] mode %children
==
::
++ transform-add-nodes
|= [=index =post =atom was-parent-modified=?]

View File

@ -1,4 +1,5 @@
/- *post, met=metadata-store, graph=graph-store, hark=hark-graph-hook
/+ graph=graph-store
|_ i=indexed-post
++ grow
|%
@ -64,10 +65,22 @@
:: ignore all containers, only notify on content
::
++ notification-kind
|= title=cord
^- (unit notif-kind:hark)
?+ index.p.i ~
[@ %1 %1 ~] `[%note [0 1] %each %children]
[@ %2 @ %1 ~] `[%comment [1 3] %count %siblings]
[@ %1 %1 ~]
:- ~
:* [%text (rap 3 'New notes in ' title ~)]~
~[(hark-content:graph (snag 0 contents.p.i)) text+' by ' ship+author.p.i]
[0 1] %each %children
==
::
[@ %2 @ %1 ~]
:- ~
:* [%text (rap 3 'New comments in ' title ~)]~
[ship+author.p.i text+': ' (hark-contents:graph contents.p.i)]
[1 3] %count %siblings
==
==
::
++ transform-add-nodes

View File

@ -1,4 +1,4 @@
/- *resource, graph-store, post
/- *resource, graph-store, post, store=hark-store
^?
|%
::
@ -10,7 +10,12 @@
[parent=@ud self=@ud]
::
+$ notif-kind
[name=@t =index-len =mode =watch-for]
$: title=(list content:store)
body=(list content:store)
=index-len
=mode
=watch-for
==
::
+$ action
$%

View File

@ -0,0 +1,154 @@
^?
::
:: %hark-store: Notification, unreads store
::
:: Timeboxing & binning:
::
:: Unread notifications accumulate in $unreads. They are grouped by
:: their $bin. A notification may become read by either:
:: a) being read by a %read-count or %read-each or %read-note
:: b) being read by a %seen
::
:: If a) then we insert the corresponding bin into $reads at the
:: current timestamp
:: If b) then we empty $unreads and move all bins to $reads at the
:: current timestamp
::
:: Unread tracking:
:: Unread tracking has two 'modes' which may be used concurrently,
:: if necessary.
::
:: count:
:: This stores the unreads as a simple atom, describing the number
:: of unread items. May be increased with %unread-count and
:: set to zero with %read-count. Ideal for high-frequency linear
:: datastructures, e.g. chat
:: each:
:: This stores the unreads as a set of paths, describing the set of
:: unread items. Unreads may be added to the set with %unread-each
:: and removed with %read-each. Ideal for non-linear, low-frequency
:: datastructures, e.g. blogs
::
|%
:: $place: A location, under which landscape stores stats
::
:: .desk must match q.byk.bowl
:: Examples:
:: A chat:
:: [%landscape /~dopzod/urbit-help]
:: A note in a notebook:
:: [%landscape /~darrux-landes/feature-requests/12374893234232]
:: A group:
:: [%hark-group-hook /~bitbet-bolbel/urbit-community]
:: Comments on a link
:: [%landscape /~dabben-larbet/urbit-in-the-news/17014118450499614194868/2]
::
+$ place [=desk =path]
::
:: $bin: Identifier for grouping notifications
::
:: Examples
:: A mention in a chat:
:: [/mention %landscape /~dopzod/urbit-help]
:: New messages in a chat
:: [/message %landscape /~dopzod/urbit-help]
:: A new comment in a notebook:
:: [/comment %landscape /~darrux-landes/feature-requests/12374893234232/2]
::
+$ bin [=path =place]
:: $content: Notification content
+$ content
$% [%ship =ship]
[%text =cord]
==
::
:: $body: A notification body
::
+$ body
$: title=(list content)
content=(list content)
=time
binned=path
link=path
==
::
+$ notification
[date=@da =bin body=(list body)]
:: $timebox: Read notifications from a particular time
+$ timebox
(map bin notification)
:: $reads: Read notifications, ordered by time
+$ reads
((mop @da timebox) gth)
:: +unreads: Unread notifications
+$ unreads
(map bin notification)
::
+$ action
$% :: hook actions
::
:: %add-note: add a notification
[%add-note =bin =body]
:: %del-place: Underlying resource disappeared, remove all
:: associated notifications
[%del-place =place]
:: %unread-count: Change unread count by .count
[%unread-count =place inc=? count=@ud]
:: %unread-each: Add .path to list of unreads for .place
[%unread-each =place =path]
:: %seen-index: Update last-updated for .place to now.bowl
[%seen-index =place]
:: store actions
::
:: %archive: archive single notification
:: if .time is ~, then archiving unread notification
:: else, archiving read notification
[%archive time=(unit @da) =bin]
:: %read-count: set unread count to zero
[%read-count =place]
:: %read-each: remove path from unreads for .place
[%read-each =place =path]
:: %read-note: Read note at .bin
[%read-note =bin]
:: %archive-all: Archive all notifications
[%archive-all ~]
:: %read-all: Read all all notifications
[%read-all ~]
:: %seen: User opened notifications, reset timeboxing logic.
[%seen ~]
::
:: XX: previously in hark-store, now deprecated
:: the hooks responsible for creating notifications may offer pokes
:: similar to this
:: [%read-graph =resource]
:: [%read-group =resource]
:: [%remove-graph =resource]
::
==
:: .stats: Statistics for a .place
::
+$ stats
$: count=@ud
each=(set path)
last=@da
timebox=(unit @da)
==
::
+$ update
$% action
:: %more: more updates
[%more more=(list update)]
:: %note-read: note has been read with timestamp
[%note-read =time =bin]
[%added =notification]
:: %timebox: description of timebox.
::
:: If time is ~, this is the unread timebox
[%timebox time=(unit @da) =(list [bin notification])]
:: %place-stats: description of .stats for a .place
[%place-stats =place =stats]
:: %place-stats: stats for all .places
[%all-stats places=(map place stats)]
==
--