From 85108dca7cc7554701d3dfc735dcd9313d35d2a5 Mon Sep 17 00:00:00 2001 From: ~midsum-salrux Date: Wed, 31 Jan 2024 14:01:32 -0500 Subject: [PATCH 01/27] Activity agent skeleton --- desk/app/activity.hoon | 57 ++++++++++++++++++++++++++++++++++++ desk/sur/activity.hoon | 65 ++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 122 insertions(+) create mode 100644 desk/app/activity.hoon create mode 100644 desk/sur/activity.hoon diff --git a/desk/app/activity.hoon b/desk/app/activity.hoon new file mode 100644 index 0000000000..cbf347454c --- /dev/null +++ b/desk/app/activity.hoon @@ -0,0 +1,57 @@ +:: +/- *activity +/+ default-agent, verb, dbug +:: +|% ++$ card card:agent:gall +:: ++$ versioned-state + $% state-0 + == +:: ++$ state-0 + [%0 =stream =indices] +:: +=| state-0 +=* state - +:: +%- agent:dbug +%+ verb | +^- agent:gall +:: +=< + |_ =bowl:gall + +* this . + def ~(. (default-agent this %|) bowl) + :: + ++ on-init `this + :: + ++ on-save !>(state) + :: + ++ on-load + |= =vase + ^- (quip card _this) + =/ old !<(versioned-state old-state) + `this(state old) + :: + ++ on-poke + |= [=mark =vase] + ^- (quip card _this) + `this + :: + ++ on-arvo + |= [=wire =sign-arvo] + ^- (quip card _this) + `this + :: + ++ on-fail on-fail:def + :: + ++ on-leave + |= =path + `this + :: + ++ on-peek + |= =path + ^- (unit (unit cage)) + ~ + -- diff --git a/desk/sur/activity.hoon b/desk/sur/activity.hoon new file mode 100644 index 0000000000..86ff136826 --- /dev/null +++ b/desk/sur/activity.hoon @@ -0,0 +1,65 @@ +|% ++$ state + $: stream=(mop time event) + indices=(map concern stream) + == ++$ concern + $% [%group group-concern] + [%channel channel-concern] + [%dm dm-concern] + [%post post-concern] + [%writ writ-concern] + == ++$ group-concern group=flag ++$ channel-concern [channel=nest group=flag] ++$ dm-concern =whom ++$ post-concern [=post-key channel=nest group=flag] ++$ writ-concern [=writ-key =whom] +:: $event: an instance of activity +:: +:: $flavor: what activity generated the event and where did it happen +:: $content: text of the message that generated the event or a description +:: $level: what "level" of importance this is deemed by originator +:: $read: has this event been seen or interacted with +:: ++$ event [=flavor =level =content read=?] ++$ level ?(%notify %default %trivial) ++$ content + $@ @t + $% [%ship p=ship] + [%emph p=cord] + == ++$ flavor + :: specific occasions TBD + $% [%group group-concern occasion=?(%join %kick)] + [%channel channel-concern occasion=?(%message %mention %reply %notice)] + [%dm dm-concern occasion=?(%message %mention %reply %notice)] + [%post post-concern occasion=?(%message %mention %reply %notice)] + [%writ writ-concern occasion=?(%message %mention %reply %notice)] + == +:: +:: this is similar to the way unreads are handled for DMs. in the case of +:: chats, recency will just happen to be the same as the key time. +:: +++ unreads + =< unreads + |% + +$ unreads + (map whom unread) + +$ unread + $: count=@ud + unread=(unit [message-key count=@ud]) + threads=(map message-key [message-key count=@ud]) + == + +$ update + (pair whom unread) + -- ++$ message-key + $% [%time =id =time] + [%recency =id =time recency=time] + == ++$ whom + $% [%ship p=ship] + [%club p=id:club] + == +-- From 98c3a2daaf0161a9779efe3f22a465c3c6a2a6a2 Mon Sep 17 00:00:00 2001 From: ~midsum-salrux Date: Thu, 8 Feb 2024 10:28:01 -0500 Subject: [PATCH 02/27] Initial activity agent --- desk/app/activity.hoon | 113 +++++++++++++++++++++++++++++++++++------ desk/sur/activity.hoon | 45 +++++++++++----- 2 files changed, 129 insertions(+), 29 deletions(-) diff --git a/desk/app/activity.hoon b/desk/app/activity.hoon index cbf347454c..99b151039a 100644 --- a/desk/app/activity.hoon +++ b/desk/app/activity.hoon @@ -1,5 +1,5 @@ :: -/- *activity +/- a=activity /+ default-agent, verb, dbug :: |% @@ -10,7 +10,7 @@ == :: +$ state-0 - [%0 =stream =indices] + [%0 =stream:a =indices:a =volume:a] :: =| state-0 =* state - @@ -23,35 +23,116 @@ |_ =bowl:gall +* this . def ~(. (default-agent this %|) bowl) + cor ~(. +> [bowl ~]) :: - ++ on-init `this + ++ on-init + =^ cards state + abet:init:cor + [cards this] :: ++ on-save !>(state) :: ++ on-load |= =vase ^- (quip card _this) - =/ old !<(versioned-state old-state) - `this(state old) + =^ cards state + abet:(load:cor vase) + [cards this] :: ++ on-poke |= [=mark =vase] ^- (quip card _this) - `this + =^ cards state + abet:(poke:cor mark vase) + [cards this] + :: + ++ on-watch + |= =path + ^- (qup card _this) + =^ cards state + abet:(watch:cor path) + [cards this] :: ++ on-arvo |= [=wire =sign-arvo] ^- (quip card _this) `this :: - ++ on-fail on-fail:def - :: - ++ on-leave - |= =path - `this - :: - ++ on-peek - |= =path - ^- (unit (unit cage)) - ~ + ++ on-peek peek:cor + ++ on-leave on-leave:def + ++ on-fail on-fail:def -- +|_ [=bowl:gall cards=(list card)] +++ abet [(flop cards) state] +++ cor . +++ emit |=(=card cor(cards [card cards])) +++ emil |=(caz=(list card) cor(cards (welp (flop caz) cards))) +++ give |=(=gift:agent:gall (emit %give gift)) +++ from-self =(our src):bowl +++ init + ^+ cor + =. volume + %- malt + :~ [%dm-invite %notify] + [%dm-post %notify] + [%dm-post-mention %notify] + [%kick %default] + [%join %trivial] + [%post %trivial] + [%post-mention %notify] + [%reply %notify] + [%reply-mention %notify] + [%flag %default] + == + cor +++ load + |= =vase + |^ ^+ cor + =+ !<(old=versioned-state vase) + ?> ?=(%0 -.old) + =. state old + cor +++ poke + |= [=mark =vase] + ^+ cor + ?+ mark ~|(bad-poke+mark !!) + %activity-action + =+ !<(=action:a vase) + ?- -.action + %add + :: TODO + cor + %read + :: TODO + cor + %adjust + cor + == + == +++ watch + |= =(pole knot) + ^+ cor + ?+ pole ~|(bat-watch-path+pole !!) + ~ ?>(from-self cor) + %notifications ?>(from-self cor) + %reads ?>(from-self cor) + == +++ peek + |= =(pole knot) + ^- (unit (unit cage)) + ?+ pole [~ ~] + [%x ~] + ``activity-full+!>([stream indices]) + [%x %all ~] + ``activity-stream+!>((tap:eon:a stream)) + [%x %all start=@ count=@ ~] + ``activity-stream+!>((scag count (top:emp:a stream start))) + [%u %event id=@] + ``loob+!>((has:eon:a (slav %da id.pole))) + [%x %event id=@] + ``activity-event+!>((got:eon:a (slav %da id.pole))) + [%x %unreads ~] + :: TODO get unread summary from each bucket + ``activity-unreads+!>((summarize-unreads indices)) + == +-- diff --git a/desk/sur/activity.hoon b/desk/sur/activity.hoon index 7a5335f519..7a9b90a053 100644 --- a/desk/sur/activity.hoon +++ b/desk/sur/activity.hoon @@ -1,24 +1,28 @@ +/+ mp=mop-extensions |% -+$ stream (mop time event) ++$ stream ((mop time event) lte) ++$ eon ((on time event) lte) +++ emp ((mp time event) lte) +$ indices (map index [=stream =reads]) +$ reads [floor=time (set event-id=time)] -+$ derived-unreads [time count=@ud threads=(list [time count=@ud])] +$ index $% [%channel channel-concern] [%dm dm-concern] == -+$ group-concern group=flag -+$ channel-concern [channel=nest group=flag] -+$ dm-concern =whom -+$ post-concern [=message-key channel=nest group=flag] -+$ reply-concern [=message-key target=message-key channel=nest group=flag] -+$ dm-post-concern [=writ-key =whom] -+$ event [=flavor =level] -+$ level ?(%notify %default %trivial) -+$ content - :: same as content of actual message - ~ +:: could do this per-channel/concern ++$ volume (map flavor level) +$ flavor + $? %dm-invite + %dm-post + %kick + %join + %post + %post-mention + %reply + %flag + == ++$ level ?(%notify %default %trivial) ++$ event $% [%dm-invite dm-concern] [%dm-post dm-post-concern =content mention=?] [%kick group-concern =ship] @@ -27,9 +31,24 @@ [%reply reply-concern =content mention=?] [%flag post-concern] == ++$ group-concern group=flag ++$ channel-concern [channel=nest group=flag] ++$ dm-concern =whom ++$ post-concern [=message-key channel=nest group=flag] ++$ reply-concern [=message-key target=message-key channel=nest group=flag] ++$ dm-post-concern [=writ-key =whom] +$ whom $% [%ship p=ship] [%club p=id:club] == +$ message-key [=id =time] ++$ content + :: same as content of actual message + ~ ++$ action + $% [%add ...] + [%read ...] + [%adjust ...] + == ++$ unread-summary [time count=@ud threads=(list [time count=@ud])] -- From ea5ea6705169b15d4178fdddbe945a0bfb8d2efe Mon Sep 17 00:00:00 2001 From: ~midsum-salrux Date: Thu, 15 Feb 2024 12:09:32 -0500 Subject: [PATCH 03/27] Actions --- desk/sur/activity.hoon | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/desk/sur/activity.hoon b/desk/sur/activity.hoon index 7a9b90a053..55ebe7ac93 100644 --- a/desk/sur/activity.hoon +++ b/desk/sur/activity.hoon @@ -9,7 +9,6 @@ $% [%channel channel-concern] [%dm dm-concern] == -:: could do this per-channel/concern +$ volume (map flavor level) +$ flavor $? %dm-invite @@ -34,9 +33,9 @@ +$ group-concern group=flag +$ channel-concern [channel=nest group=flag] +$ dm-concern =whom ++$ dm-post-concern [=message-key =whom] +$ post-concern [=message-key channel=nest group=flag] +$ reply-concern [=message-key target=message-key channel=nest group=flag] -+$ dm-post-concern [=writ-key =whom] +$ whom $% [%ship p=ship] [%club p=id:club] @@ -46,9 +45,14 @@ :: same as content of actual message ~ +$ action - $% [%add ...] - [%read ...] - [%adjust ...] + $% [%add =event] + [%read =read-action] + [%adjust =flavor =level] == +$ unread-summary [time count=@ud threads=(list [time count=@ud])] ++$ read-action + $% [%last-seen =time] + [%thread =time] + [%post =time] + == -- From b2a48e1735ce104c591cb625d2d5bfe7404f5ac8 Mon Sep 17 00:00:00 2001 From: ~midsum-salrux Date: Thu, 15 Feb 2024 17:40:42 -0500 Subject: [PATCH 04/27] Change unread representation to better handle threads and sketch out actions --- desk/app/activity.hoon | 55 ++++++++++++++++++++++++++++++++++++------ desk/sur/activity.hoon | 13 ++++++---- 2 files changed, 56 insertions(+), 12 deletions(-) diff --git a/desk/app/activity.hoon b/desk/app/activity.hoon index 99b151039a..191ee07cee 100644 --- a/desk/app/activity.hoon +++ b/desk/app/activity.hoon @@ -69,6 +69,7 @@ ++ emil |=(caz=(list card) cor(cards (welp (flop caz) cards))) ++ give |=(=gift:agent:gall (emit %give gift)) ++ from-self =(our src):bowl +:: ++ init ^+ cor =. volume @@ -85,6 +86,7 @@ [%flag %default] == cor +:: ++ load |= =vase |^ ^+ cor @@ -92,6 +94,7 @@ ?> ?=(%0 -.old) =. state old cor +:: ++ poke |= [=mark =vase] ^+ cor @@ -100,15 +103,14 @@ =+ !<(=action:a vase) ?- -.action %add - :: TODO - cor + (add action) %read - :: TODO - cor + (read action) %adjust - cor + (adjust action) == == +:: ++ watch |= =(pole knot) ^+ cor @@ -117,6 +119,7 @@ %notifications ?>(from-self cor) %reads ?>(from-self cor) == +:: ++ peek |= =(pole knot) ^- (unit (unit cage)) @@ -132,7 +135,45 @@ [%x %event id=@] ``activity-event+!>((got:eon:a (slav %da id.pole))) [%x %unreads ~] - :: TODO get unread summary from each bucket - ``activity-unreads+!>((summarize-unreads indices)) + ``activity-unreads+!>(summarize-unreads) + == +:: +++ add + :: TODO add to stream & indices, update unreads, and send facts + |= =action:a + =. +:: +++ read + :: TODO update state and send facts + |= =action:a + ?- -.read-action.action + %last-seen + =/ indy (~(get by indices) index) + ?~ indy cor + =. indices + (~(put by indices) index [stream.indy [time.action events.indy]]) + cor + :: + %thread + =/ indy (~(get by indices) index) + ?~ indy cor + + :: + %post + =/ indy (~(get by indices) index) + ?~ indy cor + == +:: +++ adjust + |= =flavor:a =level:a + =. volume + (~(put by volume) flavor level + cor +:: +++ summarize-unreads + %- ~(run by indices) + |= [=stream:a =reads:a] + :: TODO slice by floor, remove seen messages, handle threads + ~ -- diff --git a/desk/sur/activity.hoon b/desk/sur/activity.hoon index 55ebe7ac93..1bb52bec91 100644 --- a/desk/sur/activity.hoon +++ b/desk/sur/activity.hoon @@ -1,10 +1,13 @@ /+ mp=mop-extensions |% -+$ stream ((mop time event) lte) -+$ eon ((on time event) lte) +++ eon ((on time event) lte) ++ emp ((mp time event) lte) +++ mep ((on time event-parent) lte) ++$ stream ((mop time event) lte) +$ indices (map index [=stream =reads]) -+$ reads [floor=time (set event-id=time)] ++$ reads [floor=time =event-parents)] ++$ event-parent [seen=? reply-floor=time] ++$ event-parents ((mop time event-parent) lte) +$ index $% [%channel channel-concern] [%dm dm-concern] @@ -40,13 +43,13 @@ $% [%ship p=ship] [%club p=id:club] == -+$ message-key [=id =time] ++$ message-key [id=(pair ship time) =time] +$ content :: same as content of actual message ~ +$ action $% [%add =event] - [%read =read-action] + [%read =index =read-action] [%adjust =flavor =level] == +$ unread-summary [time count=@ud threads=(list [time count=@ud])] From 0a81abd3017ed16fca17315b62fc82e4b384ed64 Mon Sep 17 00:00:00 2001 From: ~midsum-salrux Date: Fri, 16 Feb 2024 16:28:09 -0500 Subject: [PATCH 05/27] Unread summaries --- desk/app/activity.hoon | 100 ++++++++++++++++++++++++++++++++++++----- desk/sur/activity.hoon | 3 +- 2 files changed, 91 insertions(+), 12 deletions(-) diff --git a/desk/app/activity.hoon b/desk/app/activity.hoon index 191ee07cee..59e1831c4e 100644 --- a/desk/app/activity.hoon +++ b/desk/app/activity.hoon @@ -117,7 +117,7 @@ ?+ pole ~|(bat-watch-path+pole !!) ~ ?>(from-self cor) %notifications ?>(from-self cor) - %reads ?>(from-self cor) + %unreads ?>(from-self cor) == :: ++ peek @@ -135,7 +135,7 @@ [%x %event id=@] ``activity-event+!>((got:eon:a (slav %da id.pole))) [%x %unreads ~] - ``activity-unreads+!>(summarize-unreads) + ``activity-unreads+!>((~(run by indices) summarize-unreads)) == :: ++ add @@ -144,27 +144,60 @@ =. :: ++ read - :: TODO update state and send facts |= =action:a ?- -.read-action.action %last-seen =/ indy (~(get by indices) index) ?~ indy cor + =/ new + [stream.indy [time.action events.indy]] =. indices - (~(put by indices) index [stream.indy [time.action events.indy]]) + (~(put by indices) index new) + =. cor + (give-unreads new) cor - :: + :: %thread =/ indy (~(get by indices) index) ?~ indy cor - - :: + =/ new + (put:mep reads.u.indy time.read-action.action [& time.read-action.action]) + =. indices + (~(put by indices) index new) + =. cor + (give-unreads new) + cor + :: %post =/ indy (~(get by indices) index) ?~ indy cor - + =/ old-event-parent (~(get by indy) time.read-action.action) + ?~ old-event-parent cor + =/ new + :- stream.u.indy + (put:mep reads.u.indy time.read-action.action [& reply-floor.old-event.parent]) + =. indices + (~(put by indices) index new) + =. cor + (give-unreads new) + cor + :: + %all + =/ indy (~(get by indices) index) + ?~ indy cor + =/ new + [stream.u.indy [now.bowl ~]] + =. indices + (~(put by indices) index new) + =. cor + (give-unreads new) + cor == :: +++ give-unreads + |= [=stream:a =reads:a] + (give %fact ~[/unreads] activity-index-unreads+!>((summarize-unreads [stream reads]))) +:: ++ adjust |= =flavor:a =level:a =. volume @@ -172,8 +205,53 @@ cor :: ++ summarize-unreads - %- ~(run by indices) |= [=stream:a =reads:a] - :: TODO slice by floor, remove seen messages, handle threads - ~ + ^- unread-summary:a + =. stream (lot:eon stream `floor.reads ~) + =/ event-parents event-parents.reads + :: for each item in reads + :: remove the post from the event stream + :: remove replies older than reply-floor from the event stream + :: then call stream-to-unreads + |- + ?~ event-parents (stream-to-unreads stream) + =/ [[=time =event-parent:a] rest=event-parents:a] (pop:mep reads) + %= $ + event-parents + rest + :: + stream + %^ (dip:eon @) stream + ~ + |= [* =event:a] + ^- [(unit event:a) ? @] + ?> ?=(?(%post %reply %dm-post) -.event) + ?: &(seen.event-parent =(time time.message-key.event)) + [~ ~ ~] + ?. =(-.event %reply) + [`event ~ ~] + ?: (lth time.message-key.event reply-floor) + [~ ~ ~] + [`event ~ ~] + == +++ stream-to-unreads + |= stream:a + ^- unread-summary:a + =/ newest *time + =/ count 0 + =/ threads=(map time [oldest-unread=time count=@ud]) ~ + :: for each event + :: update count and newest + :: if reply, update thread state + |- + ?~ stream + :+ newest count + %+ turn ~(val by threads) + |=([parent=time oldest-unread=time count=@ud] [oldest-unread count])) + =/ [[@ =event:a] rest=stream:a] (pop:eon stream) + ?= threads =(-.event %reply) + :: TODO confirm that using time.message-key here is right + =/ old (~(gut by threads) target.event [time.message-key.event 0]) + (~(put by threads) target.event [oldest-unread.old +(count.old)]) + $(newest time.message-key.event, count +(count), stream rest) -- diff --git a/desk/sur/activity.hoon b/desk/sur/activity.hoon index 1bb52bec91..f3465aacdb 100644 --- a/desk/sur/activity.hoon +++ b/desk/sur/activity.hoon @@ -52,10 +52,11 @@ [%read =index =read-action] [%adjust =flavor =level] == -+$ unread-summary [time count=@ud threads=(list [time count=@ud])] ++$ unread-summary [newest=time count=@ud threads=(list [oldest-unread=time count=@ud])] +$ read-action $% [%last-seen =time] [%thread =time] [%post =time] + [%all ~] == -- From 4581aba46921d2fef91548e2015190aa3e667d99 Mon Sep 17 00:00:00 2001 From: ~midsum-salrux Date: Tue, 20 Feb 2024 13:43:34 -0500 Subject: [PATCH 06/27] Fix syntax errors --- desk/app/activity.hoon | 46 ++++++++++++++++++++++++------------------ desk/desk.bill | 1 + desk/sur/activity.hoon | 22 +++++++++----------- 3 files changed, 37 insertions(+), 32 deletions(-) diff --git a/desk/app/activity.hoon b/desk/app/activity.hoon index 59e1831c4e..3e25d3136b 100644 --- a/desk/app/activity.hoon +++ b/desk/app/activity.hoon @@ -2,24 +2,26 @@ /- a=activity /+ default-agent, verb, dbug :: -|% -+$ card card:agent:gall -:: -+$ versioned-state - $% state-0 - == -:: -+$ state-0 - [%0 =stream:a =indices:a =volume:a] +=> + |% + +$ card card:agent:gall + :: + +$ versioned-state + $% state-0 + == + :: + +$ state-0 + [%0 =stream:a =indices:a =volume:a] + -- :: =| state-0 =* state - :: -%- agent:dbug -%+ verb | ^- agent:gall :: =< + %+ verb | + %- agent:dbug |_ =bowl:gall +* this . def ~(. (default-agent this %|) bowl) @@ -89,7 +91,7 @@ :: ++ load |= =vase - |^ ^+ cor + ^+ cor =+ !<(old=versioned-state vase) ?> ?=(%0 -.old) =. state old @@ -141,10 +143,12 @@ ++ add :: TODO add to stream & indices, update unreads, and send facts |= =action:a - =. + ^+ cor + cor :: ++ read |= =action:a + ^+ cor ?- -.read-action.action %last-seen =/ indy (~(get by indices) index) @@ -188,7 +192,7 @@ =/ new [stream.u.indy [now.bowl ~]] =. indices - (~(put by indices) index new) + (~(put by indices) index new) =. cor (give-unreads new) cor @@ -196,19 +200,21 @@ :: ++ give-unreads |= [=stream:a =reads:a] + ^+ cor (give %fact ~[/unreads] activity-index-unreads+!>((summarize-unreads [stream reads]))) :: ++ adjust - |= =flavor:a =level:a + |= [=flavor:a =level:a] + ^+ cor =. volume - (~(put by volume) flavor level + (~(put by volume) flavor level) cor :: ++ summarize-unreads |= [=stream:a =reads:a] ^- unread-summary:a =. stream (lot:eon stream `floor.reads ~) - =/ event-parents event-parents.reads + =/ event-parents event-parents.reads :: for each item in reads :: remove the post from the event stream :: remove replies older than reply-floor from the event stream @@ -245,11 +251,11 @@ :: if reply, update thread state |- ?~ stream - :+ newest count + :+ newest count %+ turn ~(val by threads) - |=([parent=time oldest-unread=time count=@ud] [oldest-unread count])) + |=([parent=time oldest-unread=time count=@ud] [oldest-unread count]) =/ [[@ =event:a] rest=stream:a] (pop:eon stream) - ?= threads =(-.event %reply) + =? threads =(-.event %reply) :: TODO confirm that using time.message-key here is right =/ old (~(gut by threads) target.event [time.message-key.event 0]) (~(put by threads) target.event [oldest-unread.old +(count.old)]) diff --git a/desk/desk.bill b/desk/desk.bill index 9d6e30fff0..0d1dc0e3ca 100644 --- a/desk/desk.bill +++ b/desk/desk.bill @@ -7,4 +7,5 @@ %groups-ui %channels %channels-server + %activity == diff --git a/desk/sur/activity.hoon b/desk/sur/activity.hoon index f3465aacdb..64379b978b 100644 --- a/desk/sur/activity.hoon +++ b/desk/sur/activity.hoon @@ -1,3 +1,4 @@ +/- c=channels /+ mp=mop-extensions |% ++ eon ((on time event) lte) @@ -5,7 +6,7 @@ ++ mep ((on time event-parent) lte) +$ stream ((mop time event) lte) +$ indices (map index [=stream =reads]) -+$ reads [floor=time =event-parents)] ++$ reads [floor=time =event-parents] +$ event-parent [seen=? reply-floor=time] +$ event-parents ((mop time event-parent) lte) +$ index @@ -26,27 +27,24 @@ +$ level ?(%notify %default %trivial) +$ event $% [%dm-invite dm-concern] - [%dm-post dm-post-concern =content mention=?] + [%dm-post dm-post-concern content=story:c mention=?] [%kick group-concern =ship] [%join group-concern =ship] - [%post post-concern =content mention=?] - [%reply reply-concern =content mention=?] + [%post post-concern content=story:c mention=?] + [%reply reply-concern content=story:c mention=?] [%flag post-concern] == -+$ group-concern group=flag -+$ channel-concern [channel=nest group=flag] ++$ group-concern group=flag:c ++$ channel-concern [channel=nest:c group=flag:c] +$ dm-concern =whom +$ dm-post-concern [=message-key =whom] -+$ post-concern [=message-key channel=nest group=flag] -+$ reply-concern [=message-key target=message-key channel=nest group=flag] ++$ post-concern [=message-key channel=nest:c group=flag:c] ++$ reply-concern [=message-key target=message-key channel=nest:c group=flag:c] +$ whom $% [%ship p=ship] - [%club p=id:club] + [%club p=@uvH] == +$ message-key [id=(pair ship time) =time] -+$ content - :: same as content of actual message - ~ +$ action $% [%add =event] [%read =index =read-action] From b41dbd6eefbcefa5b717c5c59e534d0b8be50d16 Mon Sep 17 00:00:00 2001 From: ~midsum-salrux Date: Tue, 20 Feb 2024 15:26:33 -0500 Subject: [PATCH 07/27] Fix some compiler errors --- desk/app/activity.hoon | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/desk/app/activity.hoon b/desk/app/activity.hoon index 3e25d3136b..3479f7fcd6 100644 --- a/desk/app/activity.hoon +++ b/desk/app/activity.hoon @@ -253,11 +253,14 @@ ?~ stream :+ newest count %+ turn ~(val by threads) - |=([parent=time oldest-unread=time count=@ud] [oldest-unread count]) - =/ [[@ =event:a] rest=stream:a] (pop:eon stream) + |= [oldest-unread=time count=@ud] + [oldest-unread count] + =/ [[@ =event:a] rest=stream:a] (pop:eon:a stream) =? threads =(-.event %reply) :: TODO confirm that using time.message-key here is right - =/ old (~(gut by threads) target.event [time.message-key.event 0]) - (~(put by threads) target.event [oldest-unread.old +(count.old)]) + ?> ?=([%reply *] event) + =/ old (~(gut by threads) time.target.event [oldest-unread=time.message-key.event count=0]) + (~(put by threads) time.target.event [oldest-unread.old +(count.old)]) + ?> %.y :: assert that it's one with a message key (post or dm-post) $(newest time.message-key.event, count +(count), stream rest) -- From 53b90623ad3c2054733489f9bb8392aec58004ae Mon Sep 17 00:00:00 2001 From: fang Date: Tue, 20 Feb 2024 23:27:15 +0100 Subject: [PATCH 08/27] wip: get activity closer to compiling We also implement logic for finding the "floor", timestamp of oldest unread activity, for a certain category (everything, or a specific thread). (The reader should also note that the struggle with "time id" types continues...) --- desk/app/activity.hoon | 148 +++++++++++++++++++++++++++++------------ desk/sur/activity.hoon | 24 ++++--- 2 files changed, 123 insertions(+), 49 deletions(-) diff --git a/desk/app/activity.hoon b/desk/app/activity.hoon index 3479f7fcd6..d894a540d1 100644 --- a/desk/app/activity.hoon +++ b/desk/app/activity.hoon @@ -105,11 +105,11 @@ =+ !<(=action:a vase) ?- -.action %add - (add action) + (add +.action) %read - (read action) + (read +.action) %adjust - (adjust action) + (adjust +.action) == == :: @@ -142,60 +142,117 @@ :: ++ add :: TODO add to stream & indices, update unreads, and send facts - |= =action:a + |= =event:a ^+ cor + ::TODO make sure to set the reply-floor to be the parent time, for new threads, + :: +find-floor assumes on this + cor +:: +++ find-floor + |= [=index:a mode=$%([%all ~] [%reply parent=one-id:a])] + ^- new-floor=(unit time) + ?. (~(has by indices) index) ~ + :: starting at the last-known first-unread location (floor), walk towards + :: the present, to find the new first-unread location (new floor) + :: + =/ [=orig=stream =reads] + (~(got by indices) index) + ?> |(?=(%all -.mode) (has:eon:a event-parents.reads parent.mode)) + :: slice off the earlier part of the stream, for efficiency + :: + =/ =stream + =; beginning=time + (lot:eon orig-stream `beginning ~) + ?- -.mode + %all floor.reads + %reply reply-floor:(got:eon:a event-parents.reads parent.mode) + == + =| new-floor=(unit time) + |- + ?~ stream new-floor + :: + =^ [=time =event] stream (pop:eon:a stream) + ?: ?& ?=(%reply -.mode) + ?| !?=(%reply -.event) + =(message-key.event parent.mode) + == == + :: we're in reply mode, and it's not a reply event, or a reply to + :: something else, so, skip + :: + $ + =; is-read=? + :: if we found something that's unread, we need look no further + :: + ?. is-read $(stream ~) + :: otherwise, continue our walk towards the present + :: + $(new-floor `time) + ?+ -.event !! + ?(%dm-post %post) + =* id=one-id message-key.event + =/ par=(unit event-parent:a) (get:mep:a event-parents.reads id) + ?~(par | seen.u.par) + :: + %reply + =* id=one-id message-key.event + =/ par=(unit event-parent:a) (get:mep:a event-parents.reads id) + ?~(par | (gte time reply-floor.u.par)) + == +:: +++ update-floor + |= =index:a + ^+ cor + =/ new-floor (find-floor index %all ~) + =? indices ?=(^ new-floor) + %+ ~(jab by indices) index + |= [=stream =reads] + [stream reads(floor u.new-floor)] cor :: ++ read - |= =action:a + |= [=index:a action=read-action:a] ^+ cor - ?- -.read-action.action - %last-seen - =/ indy (~(get by indices) index) - ?~ indy cor - =/ new - [stream.indy [time.action events.indy]] - =. indices - (~(put by indices) index new) - =. cor - (give-unreads new) - cor - :: + ?- -.action %thread =/ indy (~(get by indices) index) ?~ indy cor =/ new - (put:mep reads.u.indy time.read-action.action [& time.read-action.action]) + =- u.indy(event-parents.reads -) + %+ put:mep:a event-parents.reads.u.indy + =; new-reply-floor=(unit time) + [id.action [& (fall new-reply-floor id.action)]] + (find-floor index %reply id.action) =. indices (~(put by indices) index new) - =. cor - (give-unreads new) - cor + =. cor (update-floor index) + (give-unreads new) :: %post =/ indy (~(get by indices) index) ?~ indy cor - =/ old-event-parent (~(get by indy) time.read-action.action) + =/ old-event-parent (get:mep:a event-parents.reads.u.indy id.action) ?~ old-event-parent cor =/ new - :- stream.u.indy - (put:mep reads.u.indy time.read-action.action [& reply-floor.old-event.parent]) + =- u.indy(event-parents.reads -) + %+ put:mep:a event-parents.reads.u.indy + [id.action u.old-event-parent(seen &)] =. indices (~(put by indices) index new) - =. cor - (give-unreads new) - cor + =. cor (update-floor index) + (give-unreads new) :: %all =/ indy (~(get by indices) index) ?~ indy cor =/ new - [stream.u.indy [now.bowl ~]] + =/ latest=(unit [=time event:a]) + ::REVIEW is this taking the item from the correct end? lol + (ram:eon:a stream.u.indy) + ?~ latest u.indy + u.indy(reads [time.u.latest ~]) =. indices (~(put by indices) index new) - =. cor - (give-unreads new) - cor + (give-unreads new) == :: ++ give-unreads @@ -213,7 +270,7 @@ ++ summarize-unreads |= [=stream:a =reads:a] ^- unread-summary:a - =. stream (lot:eon stream `floor.reads ~) + =. stream (lot:eon:a stream `floor.reads ~) =/ event-parents event-parents.reads :: for each item in reads :: remove the post from the event stream @@ -221,7 +278,7 @@ :: then call stream-to-unreads |- ?~ event-parents (stream-to-unreads stream) - =/ [[=time =event-parent:a] rest=event-parents:a] (pop:mep reads) + =/ [[=time =event-parent:a] rest=event-parents:a] (pop:mep:a reads) %= $ event-parents rest @@ -245,7 +302,7 @@ ^- unread-summary:a =/ newest *time =/ count 0 - =/ threads=(map time [oldest-unread=time count=@ud]) ~ + =/ threads=(map message-id:a [oldest-unread=time count=@ud]) ~ :: for each event :: update count and newest :: if reply, update thread state @@ -256,11 +313,20 @@ |= [oldest-unread=time count=@ud] [oldest-unread count] =/ [[@ =event:a] rest=stream:a] (pop:eon:a stream) - =? threads =(-.event %reply) - :: TODO confirm that using time.message-key here is right - ?> ?=([%reply *] event) - =/ old (~(gut by threads) time.target.event [oldest-unread=time.message-key.event count=0]) - (~(put by threads) time.target.event [oldest-unread.old +(count.old)]) - ?> %.y :: assert that it's one with a message key (post or dm-post) - $(newest time.message-key.event, count +(count), stream rest) + =. count +(count) + =. newest + ?> ?=(?(%dm-post %post %reply) -.event) + ::REVIEW should we take timestamp of parent post if reply?? + :: (in which case we would need to do (max newest time.mk.e)) + time.message-key.event + =? threads ?=(%reply -.event) + =/ old + %+ ~(gut by threads) id.target.event + [oldest-unread=time.message-key.event count=0] + %+ ~(put by threads) id.target.event + :: we don't need to update the timestamp, because we always process the + :: oldest message first + :: + [oldest-unread.old +(count.old)] + $(stream rest) -- diff --git a/desk/sur/activity.hoon b/desk/sur/activity.hoon index 64379b978b..d48f26bebc 100644 --- a/desk/sur/activity.hoon +++ b/desk/sur/activity.hoon @@ -6,9 +6,12 @@ ++ mep ((on time event-parent) lte) +$ stream ((mop time event) lte) +$ indices (map index [=stream =reads]) -+$ reads [floor=time =event-parents] ++$ reads + $: floor=time :: latest time above which everything is read + =event-parents :: + == +$ event-parent [seen=? reply-floor=time] -+$ event-parents ((mop time event-parent) lte) ++$ event-parents ((mop one-id event-parent) lte) +$ index $% [%channel channel-concern] [%dm dm-concern] @@ -44,17 +47,22 @@ $% [%ship p=ship] [%club p=@uvH] == -+$ message-key [id=(pair ship time) =time] ++$ one-id time ::TODO better name or the Lord so help me ++$ message-id (pair ship one-id) ++$ message-key [id=message-id =time] +$ action $% [%add =event] [%read =index =read-action] [%adjust =flavor =level] == -+$ unread-summary [newest=time count=@ud threads=(list [oldest-unread=time count=@ud])] ++$ unread-summary + $: newest=time + count=@ud + threads=(list [oldest-unread=time count=@ud]) + == +$ read-action - $% [%last-seen =time] - [%thread =time] - [%post =time] - [%all ~] + $% [%thread id=one-id] :: mark a whole thread as read + [%post id=one-id] :: mark an individual post as read + [%all ~] :: mark _everything_ as read == -- From 75fd71b0cf60b508df3e3272edeff43ad456cee5 Mon Sep 17 00:00:00 2001 From: ~midsum-salrux Date: Wed, 21 Feb 2024 14:18:17 -0500 Subject: [PATCH 09/27] Compiler errors --- desk/app/activity.hoon | 71 +++++++++++++++++++++--------------------- desk/sur/activity.hoon | 14 +++++---- 2 files changed, 43 insertions(+), 42 deletions(-) diff --git a/desk/app/activity.hoon b/desk/app/activity.hoon index d894a540d1..f0d3d1d7e4 100644 --- a/desk/app/activity.hoon +++ b/desk/app/activity.hoon @@ -17,11 +17,11 @@ =| state-0 =* state - :: +%- agent:dbug +%+ verb | ^- agent:gall :: =< - %+ verb | - %- agent:dbug |_ =bowl:gall +* this . def ~(. (default-agent this %|) bowl) @@ -50,16 +50,13 @@ :: ++ on-watch |= =path - ^- (qup card _this) + ^- (quip card _this) =^ cards state abet:(watch:cor path) [cards this] :: - ++ on-arvo - |= [=wire =sign-arvo] - ^- (quip card _this) - `this - :: + ++ on-arvo on-arvo:def + ++ on-agent on-agent:def ++ on-peek peek:cor ++ on-leave on-leave:def ++ on-fail on-fail:def @@ -76,6 +73,7 @@ ^+ cor =. volume %- malt + ^- (list [flavor:a level:a]) :~ [%dm-invite %notify] [%dm-post %notify] [%dm-post-mention %notify] @@ -118,8 +116,8 @@ ^+ cor ?+ pole ~|(bat-watch-path+pole !!) ~ ?>(from-self cor) - %notifications ?>(from-self cor) - %unreads ?>(from-self cor) + [%notifications ~] ?>(from-self cor) + [%unreads ~] ?>(from-self cor) == :: ++ peek @@ -131,11 +129,11 @@ [%x %all ~] ``activity-stream+!>((tap:eon:a stream)) [%x %all start=@ count=@ ~] - ``activity-stream+!>((scag count (top:emp:a stream start))) + ``activity-stream+!>((scag count.pole (top:emp:a stream start.pole))) [%u %event id=@] - ``loob+!>((has:eon:a (slav %da id.pole))) + ``loob+!>((has:eon:a stream (slav %da id.pole))) [%x %event id=@] - ``activity-event+!>((got:eon:a (slav %da id.pole))) + ``activity-event+!>((got:eon:a stream (slav %da id.pole))) [%x %unreads ~] ``activity-unreads+!>((~(run by indices) summarize-unreads)) == @@ -149,52 +147,52 @@ cor :: ++ find-floor - |= [=index:a mode=$%([%all ~] [%reply parent=one-id:a])] - ^- new-floor=(unit time) + |= [=index:a mode=$%([%all ~] [%reply parent=timid:a])] + ^- (unit time) ?. (~(has by indices) index) ~ :: starting at the last-known first-unread location (floor), walk towards :: the present, to find the new first-unread location (new floor) :: - =/ [=orig=stream =reads] + =/ [orig=stream:a =reads:a] (~(got by indices) index) - ?> |(?=(%all -.mode) (has:eon:a event-parents.reads parent.mode)) + ?> |(?=(%all -.mode) (has:mep:a event-parents.reads parent.mode)) :: slice off the earlier part of the stream, for efficiency :: - =/ =stream + =/ =stream:a =; beginning=time - (lot:eon orig-stream `beginning ~) + (lot:eon:a orig `beginning ~) ?- -.mode %all floor.reads - %reply reply-floor:(got:eon:a event-parents.reads parent.mode) + %reply reply-floor:(got:mep:a event-parents.reads parent.mode) == =| new-floor=(unit time) |- ?~ stream new-floor :: - =^ [=time =event] stream (pop:eon:a stream) + =/ [[=time =event:a] rest=stream:a] (pop:eon:a stream) ?: ?& ?=(%reply -.mode) ?| !?=(%reply -.event) - =(message-key.event parent.mode) + ?&(?=(?(%dm-post %post) -.event) =(message-key.event parent.mode)) == == :: we're in reply mode, and it's not a reply event, or a reply to :: something else, so, skip :: - $ + $(stream rest) =; is-read=? :: if we found something that's unread, we need look no further :: ?. is-read $(stream ~) :: otherwise, continue our walk towards the present :: - $(new-floor `time) + $(new-floor `time, stream rest) ?+ -.event !! ?(%dm-post %post) - =* id=one-id message-key.event + =* id=timid:a q.id.message-key.event =/ par=(unit event-parent:a) (get:mep:a event-parents.reads id) ?~(par | seen.u.par) :: %reply - =* id=one-id message-key.event + =* id=timid:a q.id.message-key.event =/ par=(unit event-parent:a) (get:mep:a event-parents.reads id) ?~(par | (gte time reply-floor.u.par)) == @@ -202,10 +200,10 @@ ++ update-floor |= =index:a ^+ cor - =/ new-floor (find-floor index %all ~) + =/ new-floor=(unit time) (find-floor index %all ~) =? indices ?=(^ new-floor) %+ ~(jab by indices) index - |= [=stream =reads] + |= [=stream:a =reads:a] [stream reads(floor u.new-floor)] cor :: @@ -278,24 +276,25 @@ :: then call stream-to-unreads |- ?~ event-parents (stream-to-unreads stream) - =/ [[=time =event-parent:a] rest=event-parents:a] (pop:mep:a reads) + =/ [[=time =event-parent:a] rest=event-parents:a] (pop:mep:a event-parents) %= $ event-parents rest :: stream - %^ (dip:eon @) stream + =- +.- + %^ (dip:eon:a @) stream ~ - |= [* =event:a] + |= [@ key=@da =event:a] ^- [(unit event:a) ? @] ?> ?=(?(%post %reply %dm-post) -.event) ?: &(seen.event-parent =(time time.message-key.event)) - [~ ~ ~] + [~ | ~] ?. =(-.event %reply) - [`event ~ ~] - ?: (lth time.message-key.event reply-floor) - [~ ~ ~] - [`event ~ ~] + [`event | ~] + ?: (lth time.message-key.event reply-floor.event-parent) + [~ | ~] + [`event | ~] == ++ stream-to-unreads |= stream:a diff --git a/desk/sur/activity.hoon b/desk/sur/activity.hoon index d48f26bebc..4ad572e8f9 100644 --- a/desk/sur/activity.hoon +++ b/desk/sur/activity.hoon @@ -11,7 +11,7 @@ =event-parents :: == +$ event-parent [seen=? reply-floor=time] -+$ event-parents ((mop one-id event-parent) lte) ++$ event-parents ((mop timid event-parent) lte) +$ index $% [%channel channel-concern] [%dm dm-concern] @@ -20,11 +20,13 @@ +$ flavor $? %dm-invite %dm-post + %dm-post-mention %kick %join %post %post-mention %reply + %reply-mention %flag == +$ level ?(%notify %default %trivial) @@ -47,8 +49,8 @@ $% [%ship p=ship] [%club p=@uvH] == -+$ one-id time ::TODO better name or the Lord so help me -+$ message-id (pair ship one-id) ++$ timid time ++$ message-id (pair ship timid) +$ message-key [id=message-id =time] +$ action $% [%add =event] @@ -61,8 +63,8 @@ threads=(list [oldest-unread=time count=@ud]) == +$ read-action - $% [%thread id=one-id] :: mark a whole thread as read - [%post id=one-id] :: mark an individual post as read - [%all ~] :: mark _everything_ as read + $% [%thread id=timid] :: mark a whole thread as read + [%post id=timid] :: mark an individual post as read + [%all ~] :: mark _everything_ as read == -- From 2a4ebf636373424e67d9f058b0f30e728c943dc1 Mon Sep 17 00:00:00 2001 From: ~midsum-salrux Date: Thu, 22 Feb 2024 16:28:23 -0500 Subject: [PATCH 10/27] %add action --- desk/app/activity.hoon | 83 ++++++++++++++++++++++++++++++++++++++++-- desk/sur/activity.hoon | 16 +++++--- 2 files changed, 89 insertions(+), 10 deletions(-) diff --git a/desk/app/activity.hoon b/desk/app/activity.hoon index f0d3d1d7e4..fb1d9648c6 100644 --- a/desk/app/activity.hoon +++ b/desk/app/activity.hoon @@ -77,6 +77,8 @@ :~ [%dm-invite %notify] [%dm-post %notify] [%dm-post-mention %notify] + [%dm-reply %notify] + [%dm-reply-mention %notify] [%kick %default] [%join %trivial] [%post %trivial] @@ -139,12 +141,85 @@ == :: ++ add - :: TODO add to stream & indices, update unreads, and send facts |= =event:a ^+ cor - ::TODO make sure to set the reply-floor to be the parent time, for new threads, - :: +find-floor assumes on this - cor + =. cor + (give %fact ~[/] activity-event+!>(event)) + =? cor (notifiable event) + (give %fact ~[/notifications] activity-event+!>(event)) + =. stream + (put:eon:a stream now.bowl event) + ?+ -.event cor + %dm-post + =/ index [%dm whom.event] + =/ indy (~(get by indices) index) + ?~ indy cor + =/ new + :* (put:eon:a stream.u.indy now.bowl event) + floor.reads.u.indy + %^ put:mep:a event-parents.reads.u.indy + now.bowl + [| now.bowl] + == + =. indices + (~(put by indices) index new) + cor + %dm-reply + =/ index [%dm whom.event] + =/ indy (~(get by indices) index) + ?~ indy cor + =/ new + :- (put:eon:a stream.u.indy now.bowl event) + reads.u.indy + =. indices + (~(put by indices) index new) + cor + %post + =/ index [%channel channel.event group.event] + =/ indy (~(get by indices) index) + ?~ indy cor + =/ new + :* (put:eon:a stream.u.indy now.bowl event) + floor.reads.u.indy + %^ put:mep:a event-parents.reads.u.indy + now.bowl + [| now.bowl] + == + =. indices + (~(put by indices) index new) + cor + %reply + =/ index [%channel channel.event group.event] + =/ indy (~(get by indices) index) + ?~ indy cor + =/ new + :- (put:eon:a stream.u.indy now.bowl event) + reads.u.indy + =. indices + (~(put by indices) index new) + cor + == +++ notifiable + |= =event:a + .= %notify + (~(gut by volume) (determine-flavor event) %default) +++ determine-flavor + |= =event:a + ^- flavor:a + ?- -.event + %dm-invite %dm-invite + %kick %kick + %join %join + %flag %flag + %post + ?. mention.event %post %post-mention + %reply + ?. mention.event %reply %reply-mention + %dm-post + ?. mention.event %dm-post %dm-post-mention + %dm-reply + ?. mention.event %dm-reply %dm-reply-mention + == :: ++ find-floor |= [=index:a mode=$%([%all ~] [%reply parent=timid:a])] diff --git a/desk/sur/activity.hoon b/desk/sur/activity.hoon index 4ad572e8f9..f6b1306532 100644 --- a/desk/sur/activity.hoon +++ b/desk/sur/activity.hoon @@ -21,6 +21,8 @@ $? %dm-invite %dm-post %dm-post-mention + %dm-reply + %dm-reply-mention %kick %join %post @@ -33,18 +35,20 @@ +$ event $% [%dm-invite dm-concern] [%dm-post dm-post-concern content=story:c mention=?] + [%dm-reply dm-reply-concern content=story:c mention=?] [%kick group-concern =ship] [%join group-concern =ship] [%post post-concern content=story:c mention=?] [%reply reply-concern content=story:c mention=?] [%flag post-concern] == -+$ group-concern group=flag:c -+$ channel-concern [channel=nest:c group=flag:c] -+$ dm-concern =whom -+$ dm-post-concern [=message-key =whom] -+$ post-concern [=message-key channel=nest:c group=flag:c] -+$ reply-concern [=message-key target=message-key channel=nest:c group=flag:c] ++$ group-concern group=flag:c ++$ channel-concern [channel=nest:c group=flag:c] ++$ dm-concern =whom ++$ dm-post-concern [=message-key =whom] ++$ dm-reply-concern [=message-key target=message-key =whom] ++$ post-concern [=message-key channel=nest:c group=flag:c] ++$ reply-concern [=message-key target=message-key channel=nest:c group=flag:c] +$ whom $% [%ship p=ship] [%club p=@uvH] From 7f17b6fa6e06d1d15b1bd3827a774a3fdaffc488 Mon Sep 17 00:00:00 2001 From: ~midsum-salrux Date: Thu, 22 Feb 2024 16:44:47 -0500 Subject: [PATCH 11/27] Handle first event insertion in index --- desk/app/activity.hoon | 56 ++++++++++++++++++++++-------------------- 1 file changed, 30 insertions(+), 26 deletions(-) diff --git a/desk/app/activity.hoon b/desk/app/activity.hoon index fb1d9648c6..951a2388e3 100644 --- a/desk/app/activity.hoon +++ b/desk/app/activity.hoon @@ -152,12 +152,13 @@ ?+ -.event cor %dm-post =/ index [%dm whom.event] - =/ indy (~(get by indices) index) - ?~ indy cor + =? indices !(~(has by indices) index) + (~(put by indices) index [*stream:a *reads:a]) + =/ indy (~(got by indices) index) =/ new - :* (put:eon:a stream.u.indy now.bowl event) - floor.reads.u.indy - %^ put:mep:a event-parents.reads.u.indy + :* (put:eon:a stream.indy now.bowl event) + floor.reads.indy + %^ put:mep:a event-parents.reads.indy now.bowl [| now.bowl] == @@ -166,22 +167,24 @@ cor %dm-reply =/ index [%dm whom.event] - =/ indy (~(get by indices) index) - ?~ indy cor + =? indices !(~(has by indices) index) + (~(put by indices) index *[stream:a reads:a]) + =/ indy (~(got by indices) index) =/ new - :- (put:eon:a stream.u.indy now.bowl event) - reads.u.indy + :- (put:eon:a stream.indy now.bowl event) + reads.indy =. indices (~(put by indices) index new) cor %post =/ index [%channel channel.event group.event] - =/ indy (~(get by indices) index) - ?~ indy cor + =? indices !(~(has by indices) index) + (~(put by indices) index *[stream:a reads:a]) + =/ indy (~(got by indices) index) =/ new - :* (put:eon:a stream.u.indy now.bowl event) - floor.reads.u.indy - %^ put:mep:a event-parents.reads.u.indy + :* (put:eon:a stream.indy now.bowl event) + floor.reads.indy + %^ put:mep:a event-parents.reads.indy now.bowl [| now.bowl] == @@ -190,11 +193,12 @@ cor %reply =/ index [%channel channel.event group.event] - =/ indy (~(get by indices) index) - ?~ indy cor + =? indices !(~(has by indices) index) + (~(put by indices) index *[stream:a reads:a]) + =/ indy (~(got by indices) index) =/ new - :- (put:eon:a stream.u.indy now.bowl event) - reads.u.indy + :- (put:eon:a stream.indy now.bowl event) + reads.indy =. indices (~(put by indices) index new) cor @@ -207,18 +211,18 @@ |= =event:a ^- flavor:a ?- -.event - %dm-invite %dm-invite - %kick %kick - %join %join - %flag %flag + %dm-invite %dm-invite + %kick %kick + %join %join + %flag %flag %post - ?. mention.event %post %post-mention + ?: mention.event %post-mention %post %reply - ?. mention.event %reply %reply-mention + ?: mention.event %reply-mention %reply %dm-post - ?. mention.event %dm-post %dm-post-mention + ?: mention.event %dm-post-mention %dm-post %dm-reply - ?. mention.event %dm-reply %dm-reply-mention + ?: mention.event %dm-reply-mention %dm-reply == :: ++ find-floor From 72bf769be21c0afad88339be850be03ef39f6a9b Mon Sep 17 00:00:00 2001 From: ~midsum-salrux Date: Tue, 27 Feb 2024 10:19:59 -0500 Subject: [PATCH 12/27] Switch to per-channel volume --- desk/app/activity.hoon | 60 ++++++++++++++++++++++++++++-------------- desk/sur/activity.hoon | 12 ++++++--- 2 files changed, 49 insertions(+), 23 deletions(-) diff --git a/desk/app/activity.hoon b/desk/app/activity.hoon index 951a2388e3..fd3c057311 100644 --- a/desk/app/activity.hoon +++ b/desk/app/activity.hoon @@ -71,22 +71,6 @@ :: ++ init ^+ cor - =. volume - %- malt - ^- (list [flavor:a level:a]) - :~ [%dm-invite %notify] - [%dm-post %notify] - [%dm-post-mention %notify] - [%dm-reply %notify] - [%dm-reply-mention %notify] - [%kick %default] - [%join %trivial] - [%post %trivial] - [%post-mention %notify] - [%reply %notify] - [%reply-mention %notify] - [%flag %default] - == cor :: ++ load @@ -203,10 +187,46 @@ (~(put by indices) index new) cor == +++ loudness + ^- (map flavor:a flavor-level:a) + %- malt + ^- (list [flavor:a flavor-level:a]) + :~ [%dm-invite %notify] + [%dm-post %notify] + [%dm-post-mention %notify] + [%dm-reply %notify] + [%dm-reply-mention %notify] + [%kick %default] + [%join %default] + [%post %default] + [%post-mention %notify] + [%reply %notify] + [%reply-mention %notify] + [%flag %default] + == ++ notifiable |= =event:a - .= %notify - (~(gut by volume) (determine-flavor event) %default) + ^- ? + =/ index (determine-index event) + =/ =index-level:a + ?~ index %soft + (~(gut by volume) u.index %soft) + ?- index-level + %loud & + %hush | + %soft + .= %notify + (~(gut by loudness) (determine-flavor event) %default) + == +++ determine-index + |= =event:a + ^- (unit index:a) + ?+ -.event ~ + %post `[%channel channel.event group.event] + %reply `[%channel channel.event group.event] + %dm-post `[%dm whom.event] + %dm-reply `[%dm whom.event] + == ++ determine-flavor |= =event:a ^- flavor:a @@ -338,10 +358,10 @@ (give %fact ~[/unreads] activity-index-unreads+!>((summarize-unreads [stream reads]))) :: ++ adjust - |= [=flavor:a =level:a] + |= [=index:a =index-level:a] ^+ cor =. volume - (~(put by volume) flavor level) + (~(put by volume) index index-level) cor :: ++ summarize-unreads diff --git a/desk/sur/activity.hoon b/desk/sur/activity.hoon index f6b1306532..0a26cbcfaf 100644 --- a/desk/sur/activity.hoon +++ b/desk/sur/activity.hoon @@ -16,7 +16,6 @@ $% [%channel channel-concern] [%dm dm-concern] == -+$ volume (map flavor level) +$ flavor $? %dm-invite %dm-post @@ -31,7 +30,14 @@ %reply-mention %flag == -+$ level ?(%notify %default %trivial) ++$ flavor-level ?(%notify %default) ++$ volume (map index index-level) ++$ index-level + $~ %soft + $? %loud :: always notify + %soft :: sometimes notify + %hush :: never notify + == +$ event $% [%dm-invite dm-concern] [%dm-post dm-post-concern content=story:c mention=?] @@ -59,7 +65,7 @@ +$ action $% [%add =event] [%read =index =read-action] - [%adjust =flavor =level] + [%adjust =index =index-level] == +$ unread-summary $: newest=time From 7a9811313f791742bc241a7f56c8bbf85a22dff1 Mon Sep 17 00:00:00 2001 From: ~midsum-salrux Date: Wed, 28 Feb 2024 10:55:18 -0500 Subject: [PATCH 13/27] First %activity tests --- desk/app/activity.hoon | 8 +++---- desk/mar/activity/action.hoon | 12 +++++++++++ desk/mar/activity/event.hoon | 12 +++++++++++ desk/sur/activity.hoon | 11 +++++----- desk/ted/test-activity.hoon | 39 +++++++++++++++++++++++++++++++++++ 5 files changed, 73 insertions(+), 9 deletions(-) create mode 100644 desk/mar/activity/action.hoon create mode 100644 desk/mar/activity/event.hoon create mode 100644 desk/ted/test-activity.hoon diff --git a/desk/app/activity.hoon b/desk/app/activity.hoon index fd3c057311..4e7d7b0c16 100644 --- a/desk/app/activity.hoon +++ b/desk/app/activity.hoon @@ -116,10 +116,10 @@ ``activity-stream+!>((tap:eon:a stream)) [%x %all start=@ count=@ ~] ``activity-stream+!>((scag count.pole (top:emp:a stream start.pole))) - [%u %event id=@] + [%u %event id=@ ~] ``loob+!>((has:eon:a stream (slav %da id.pole))) - [%x %event id=@] - ``activity-event+!>((got:eon:a stream (slav %da id.pole))) + [%x %event id=@ ~] + ``activity-event+!>([id.pole (got:eon:a stream (slav %da id.pole))]) [%x %unreads ~] ``activity-unreads+!>((~(run by indices) summarize-unreads)) == @@ -128,7 +128,7 @@ |= =event:a ^+ cor =. cor - (give %fact ~[/] activity-event+!>(event)) + (give %fact ~[/] activity-event+!>([now.bowl event])) =? cor (notifiable event) (give %fact ~[/notifications] activity-event+!>(event)) =. stream diff --git a/desk/mar/activity/action.hoon b/desk/mar/activity/action.hoon new file mode 100644 index 0000000000..9b63fe85f1 --- /dev/null +++ b/desk/mar/activity/action.hoon @@ -0,0 +1,12 @@ +/- a=activity +|_ =action:a +++ grad %noun +++ grow + |% + ++ noun action + -- +++ grab + |% + ++ noun action:a + -- +-- diff --git a/desk/mar/activity/event.hoon b/desk/mar/activity/event.hoon new file mode 100644 index 0000000000..37c865fa88 --- /dev/null +++ b/desk/mar/activity/event.hoon @@ -0,0 +1,12 @@ +/- a=activity +|_ =time-event:a +++ grad %noun +++ grow + |% + ++ noun time-event + -- +++ grab + |% + ++ noun time-event:a + -- +-- diff --git a/desk/sur/activity.hoon b/desk/sur/activity.hoon index 0a26cbcfaf..1bf461ae7e 100644 --- a/desk/sur/activity.hoon +++ b/desk/sur/activity.hoon @@ -1,4 +1,4 @@ -/- c=channels +/- c=channels, g=groups /+ mp=mop-extensions |% ++ eon ((on time event) lte) @@ -48,13 +48,14 @@ [%reply reply-concern content=story:c mention=?] [%flag post-concern] == -+$ group-concern group=flag:c -+$ channel-concern [channel=nest:c group=flag:c] ++$ time-event [=time =event] ++$ group-concern group=flag:g ++$ channel-concern [channel=nest:c group=flag:g] +$ dm-concern =whom +$ dm-post-concern [=message-key =whom] +$ dm-reply-concern [=message-key target=message-key =whom] -+$ post-concern [=message-key channel=nest:c group=flag:c] -+$ reply-concern [=message-key target=message-key channel=nest:c group=flag:c] ++$ post-concern [=message-key channel=nest:c group=flag:g] ++$ reply-concern [=message-key target=message-key channel=nest:c group=flag:g] +$ whom $% [%ship p=ship] [%club p=@uvH] diff --git a/desk/ted/test-activity.hoon b/desk/ted/test-activity.hoon new file mode 100644 index 0000000000..fb4012baa0 --- /dev/null +++ b/desk/ted/test-activity.hoon @@ -0,0 +1,39 @@ +/- spider, a=activity +/+ s=strandio +=, strand=strand:spider +^- thread:spider +|= arg=vase +=/ m (strand ,vase) +^- form:m +=/ verb (fall !<((unit ?) arg) |) +;< our=ship bind:m get-our:s +;< ~ bind:m (poke-our:s %hood %kiln-nuke !>([%activity &])) +;< ~ bind:m (poke-our:s %hood %kiln-revive !>(%activity)) +:: +:: add an event and get a fact +:: +=/ add-post=action:a + :- %add + ^- event:a + :* %post + :* [[~sampel-poster *time] *time] + [%chat ~sampel-palnet %mychat] + [~sampel-hoster %mygroup] + == + ~[[%inline ~['hello']]] + | + == +;< ~ bind:m (watch:s /root [our %activity] /) +;< ~ bind:m (poke-our:s %activity %activity-action !>(add-post)) +;< [=mark =vase] bind:m (take-fact:s /root) +=/ [fact-time=time fact-event=event:a] !<(time-event:a vase) +?> .= +.add-post fact-event +:: +:: scry the event we added +:: +;< exists=? bind:m (scry:s ? %gu %activity /event/(scot %da fact-time)) +?> exists +;< scried-event=time-event:a bind:m (scry:s time-event:a %gx %activity /event/(scot %da fact-time)/noun) +?> =(event.scried-event +:add-post) +:: +(pure:m !>(~)) From 3b9c6acf160758bbeb0f413055053ad8baedc305 Mon Sep 17 00:00:00 2001 From: ~midsum-salrux Date: Wed, 28 Feb 2024 13:27:10 -0500 Subject: [PATCH 14/27] PR feedback --- desk/app/activity.hoon | 58 +++++++++++++++++++++--------------------- desk/desk.bill | 1 - desk/sur/activity.hoon | 16 ++++++------ 3 files changed, 37 insertions(+), 38 deletions(-) diff --git a/desk/app/activity.hoon b/desk/app/activity.hoon index 4e7d7b0c16..859bcdf1d7 100644 --- a/desk/app/activity.hoon +++ b/desk/app/activity.hoon @@ -111,15 +111,15 @@ ^- (unit (unit cage)) ?+ pole [~ ~] [%x ~] - ``activity-full+!>([stream indices]) + ``activity-full+!>([stream indices (~(run by indices) summarize-unreads)]) [%x %all ~] - ``activity-stream+!>((tap:eon:a stream)) + ``activity-stream+!>((tap:on-event:a stream)) [%x %all start=@ count=@ ~] - ``activity-stream+!>((scag count.pole (top:emp:a stream start.pole))) + ``activity-stream+!>((scag count.pole (top:ex-event:a stream start.pole))) [%u %event id=@ ~] - ``loob+!>((has:eon:a stream (slav %da id.pole))) + ``loob+!>((has:on-event:a stream (slav %da id.pole))) [%x %event id=@ ~] - ``activity-event+!>([id.pole (got:eon:a stream (slav %da id.pole))]) + ``activity-event+!>([id.pole (got:on-event:a stream (slav %da id.pole))]) [%x %unreads ~] ``activity-unreads+!>((~(run by indices) summarize-unreads)) == @@ -132,7 +132,7 @@ =? cor (notifiable event) (give %fact ~[/notifications] activity-event+!>(event)) =. stream - (put:eon:a stream now.bowl event) + (put:on-event:a stream now.bowl event) ?+ -.event cor %dm-post =/ index [%dm whom.event] @@ -140,9 +140,9 @@ (~(put by indices) index [*stream:a *reads:a]) =/ indy (~(got by indices) index) =/ new - :* (put:eon:a stream.indy now.bowl event) + :* (put:on-event:a stream.indy now.bowl event) floor.reads.indy - %^ put:mep:a event-parents.reads.indy + %^ put:on-parent:a event-parents.reads.indy now.bowl [| now.bowl] == @@ -155,7 +155,7 @@ (~(put by indices) index *[stream:a reads:a]) =/ indy (~(got by indices) index) =/ new - :- (put:eon:a stream.indy now.bowl event) + :- (put:on-event:a stream.indy now.bowl event) reads.indy =. indices (~(put by indices) index new) @@ -166,9 +166,9 @@ (~(put by indices) index *[stream:a reads:a]) =/ indy (~(got by indices) index) =/ new - :* (put:eon:a stream.indy now.bowl event) + :* (put:on-event:a stream.indy now.bowl event) floor.reads.indy - %^ put:mep:a event-parents.reads.indy + %^ put:on-parent:a event-parents.reads.indy now.bowl [| now.bowl] == @@ -181,7 +181,7 @@ (~(put by indices) index *[stream:a reads:a]) =/ indy (~(got by indices) index) =/ new - :- (put:eon:a stream.indy now.bowl event) + :- (put:on-event:a stream.indy now.bowl event) reads.indy =. indices (~(put by indices) index new) @@ -246,7 +246,7 @@ == :: ++ find-floor - |= [=index:a mode=$%([%all ~] [%reply parent=timid:a])] + |= [=index:a mode=$%([%all ~] [%reply parent=time-id:a])] ^- (unit time) ?. (~(has by indices) index) ~ :: starting at the last-known first-unread location (floor), walk towards @@ -254,21 +254,21 @@ :: =/ [orig=stream:a =reads:a] (~(got by indices) index) - ?> |(?=(%all -.mode) (has:mep:a event-parents.reads parent.mode)) + ?> |(?=(%all -.mode) (has:on-parent:a event-parents.reads parent.mode)) :: slice off the earlier part of the stream, for efficiency :: =/ =stream:a =; beginning=time - (lot:eon:a orig `beginning ~) + (lot:on-event:a orig `beginning ~) ?- -.mode %all floor.reads - %reply reply-floor:(got:mep:a event-parents.reads parent.mode) + %reply reply-floor:(got:on-parent:a event-parents.reads parent.mode) == =| new-floor=(unit time) |- ?~ stream new-floor :: - =/ [[=time =event:a] rest=stream:a] (pop:eon:a stream) + =/ [[=time =event:a] rest=stream:a] (pop:on-event:a stream) ?: ?& ?=(%reply -.mode) ?| !?=(%reply -.event) ?&(?=(?(%dm-post %post) -.event) =(message-key.event parent.mode)) @@ -286,13 +286,13 @@ $(new-floor `time, stream rest) ?+ -.event !! ?(%dm-post %post) - =* id=timid:a q.id.message-key.event - =/ par=(unit event-parent:a) (get:mep:a event-parents.reads id) + =* id=time-id:a q.id.message-key.event + =/ par=(unit event-parent:a) (get:on-parent:a event-parents.reads id) ?~(par | seen.u.par) :: %reply - =* id=timid:a q.id.message-key.event - =/ par=(unit event-parent:a) (get:mep:a event-parents.reads id) + =* id=time-id:a q.id.message-key.event + =/ par=(unit event-parent:a) (get:on-parent:a event-parents.reads id) ?~(par | (gte time reply-floor.u.par)) == :: @@ -315,7 +315,7 @@ ?~ indy cor =/ new =- u.indy(event-parents.reads -) - %+ put:mep:a event-parents.reads.u.indy + %+ put:on-parent:a event-parents.reads.u.indy =; new-reply-floor=(unit time) [id.action [& (fall new-reply-floor id.action)]] (find-floor index %reply id.action) @@ -327,11 +327,11 @@ %post =/ indy (~(get by indices) index) ?~ indy cor - =/ old-event-parent (get:mep:a event-parents.reads.u.indy id.action) + =/ old-event-parent (get:on-parent:a event-parents.reads.u.indy id.action) ?~ old-event-parent cor =/ new =- u.indy(event-parents.reads -) - %+ put:mep:a event-parents.reads.u.indy + %+ put:on-parent:a event-parents.reads.u.indy [id.action u.old-event-parent(seen &)] =. indices (~(put by indices) index new) @@ -344,7 +344,7 @@ =/ new =/ latest=(unit [=time event:a]) ::REVIEW is this taking the item from the correct end? lol - (ram:eon:a stream.u.indy) + (ram:on-event:a stream.u.indy) ?~ latest u.indy u.indy(reads [time.u.latest ~]) =. indices @@ -367,7 +367,7 @@ ++ summarize-unreads |= [=stream:a =reads:a] ^- unread-summary:a - =. stream (lot:eon:a stream `floor.reads ~) + =. stream (lot:on-event:a stream `floor.reads ~) =/ event-parents event-parents.reads :: for each item in reads :: remove the post from the event stream @@ -375,14 +375,14 @@ :: then call stream-to-unreads |- ?~ event-parents (stream-to-unreads stream) - =/ [[=time =event-parent:a] rest=event-parents:a] (pop:mep:a event-parents) + =/ [[=time =event-parent:a] rest=event-parents:a] (pop:on-parent:a event-parents) %= $ event-parents rest :: stream =- +.- - %^ (dip:eon:a @) stream + %^ (dip:on-event:a @) stream ~ |= [@ key=@da =event:a] ^- [(unit event:a) ? @] @@ -410,7 +410,7 @@ %+ turn ~(val by threads) |= [oldest-unread=time count=@ud] [oldest-unread count] - =/ [[@ =event:a] rest=stream:a] (pop:eon:a stream) + =/ [[@ =event:a] rest=stream:a] (pop:on-event:a stream) =. count +(count) =. newest ?> ?=(?(%dm-post %post %reply) -.event) diff --git a/desk/desk.bill b/desk/desk.bill index ccb75a788f..0b7f1f2fe5 100644 --- a/desk/desk.bill +++ b/desk/desk.bill @@ -7,6 +7,5 @@ %groups-ui %channels %channels-server - %activity %profile == diff --git a/desk/sur/activity.hoon b/desk/sur/activity.hoon index 1bf461ae7e..0d1afb8236 100644 --- a/desk/sur/activity.hoon +++ b/desk/sur/activity.hoon @@ -1,9 +1,9 @@ /- c=channels, g=groups /+ mp=mop-extensions |% -++ eon ((on time event) lte) -++ emp ((mp time event) lte) -++ mep ((on time event-parent) lte) +++ on-event ((on time event) lte) +++ ex-event ((mp time event) lte) +++ on-parent ((on time event-parent) lte) +$ stream ((mop time event) lte) +$ indices (map index [=stream =reads]) +$ reads @@ -11,7 +11,7 @@ =event-parents :: == +$ event-parent [seen=? reply-floor=time] -+$ event-parents ((mop timid event-parent) lte) ++$ event-parents ((mop time-id event-parent) lte) +$ index $% [%channel channel-concern] [%dm dm-concern] @@ -60,8 +60,8 @@ $% [%ship p=ship] [%club p=@uvH] == -+$ timid time -+$ message-id (pair ship timid) ++$ time-id time ++$ message-id (pair ship time-id) +$ message-key [id=message-id =time] +$ action $% [%add =event] @@ -74,8 +74,8 @@ threads=(list [oldest-unread=time count=@ud]) == +$ read-action - $% [%thread id=timid] :: mark a whole thread as read - [%post id=timid] :: mark an individual post as read + $% [%thread id=time-id] :: mark a whole thread as read + [%post id=time-id] :: mark an individual post as read [%all ~] :: mark _everything_ as read == -- From 162d69aab8815b770fefd1d3232aca494b1de8d1 Mon Sep 17 00:00:00 2001 From: ~midsum-salrux Date: Wed, 28 Feb 2024 15:17:16 -0500 Subject: [PATCH 15/27] More tests --- desk/app/activity.hoon | 23 ++++++++++++----------- desk/mar/activity/full.hoon | 12 ++++++++++++ desk/mar/activity/index-unreads.hoon | 12 ++++++++++++ desk/sur/activity.hoon | 1 + desk/ted/test-activity.hoon | 28 ++++++++++++++++++++++++---- 5 files changed, 61 insertions(+), 15 deletions(-) create mode 100644 desk/mar/activity/full.hoon create mode 100644 desk/mar/activity/index-unreads.hoon diff --git a/desk/app/activity.hoon b/desk/app/activity.hoon index 859bcdf1d7..80ca78baaa 100644 --- a/desk/app/activity.hoon +++ b/desk/app/activity.hoon @@ -322,7 +322,7 @@ =. indices (~(put by indices) index new) =. cor (update-floor index) - (give-unreads new) + (give-unreads index new) :: %post =/ indy (~(get by indices) index) @@ -336,7 +336,7 @@ =. indices (~(put by indices) index new) =. cor (update-floor index) - (give-unreads new) + (give-unreads index new) :: %all =/ indy (~(get by indices) index) @@ -349,13 +349,13 @@ u.indy(reads [time.u.latest ~]) =. indices (~(put by indices) index new) - (give-unreads new) + (give-unreads index new) == :: ++ give-unreads - |= [=stream:a =reads:a] + |= [=index:a =stream:a =reads:a] ^+ cor - (give %fact ~[/unreads] activity-index-unreads+!>((summarize-unreads [stream reads]))) + (give %fact ~[/unreads] activity-index-unreads+!>([index (summarize-unreads [stream reads])])) :: ++ adjust |= [=index:a =index-level:a] @@ -374,7 +374,8 @@ :: remove replies older than reply-floor from the event stream :: then call stream-to-unreads |- - ?~ event-parents (stream-to-unreads stream) + ?~ event-parents + (stream-to-unreads stream) =/ [[=time =event-parent:a] rest=event-parents:a] (pop:on-parent:a event-parents) %= $ event-parents @@ -387,7 +388,7 @@ |= [@ key=@da =event:a] ^- [(unit event:a) ? @] ?> ?=(?(%post %reply %dm-post) -.event) - ?: &(seen.event-parent =(time time.message-key.event)) + ?: &(seen.event-parent =(time key)) [~ | ~] ?. =(-.event %reply) [`event | ~] @@ -396,9 +397,9 @@ [`event | ~] == ++ stream-to-unreads - |= stream:a + |= =stream:a ^- unread-summary:a - =/ newest *time + =/ newest=(unit time) ~ =/ count 0 =/ threads=(map message-id:a [oldest-unread=time count=@ud]) ~ :: for each event @@ -406,7 +407,7 @@ :: if reply, update thread state |- ?~ stream - :+ newest count + :+ (fall newest now.bowl) count %+ turn ~(val by threads) |= [oldest-unread=time count=@ud] [oldest-unread count] @@ -416,7 +417,7 @@ ?> ?=(?(%dm-post %post %reply) -.event) ::REVIEW should we take timestamp of parent post if reply?? :: (in which case we would need to do (max newest time.mk.e)) - time.message-key.event + `time.message-key.event =? threads ?=(%reply -.event) =/ old %+ ~(gut by threads) id.target.event diff --git a/desk/mar/activity/full.hoon b/desk/mar/activity/full.hoon new file mode 100644 index 0000000000..04524bd14f --- /dev/null +++ b/desk/mar/activity/full.hoon @@ -0,0 +1,12 @@ +/- a=activity +|_ =full-info:a +++ grad %noun +++ grow + |% + ++ noun full-info + -- +++ grab + |% + ++ noun full-info:a + -- +-- diff --git a/desk/mar/activity/index-unreads.hoon b/desk/mar/activity/index-unreads.hoon new file mode 100644 index 0000000000..6e4884a09b --- /dev/null +++ b/desk/mar/activity/index-unreads.hoon @@ -0,0 +1,12 @@ +/- a=activity +|_ [=index:a =unread-summary:a] +++ grad %noun +++ grow + |% + ++ noun [index unread-summary] + -- +++ grab + |% + ++ noun (pair index:a unread-summary:a) + -- +-- diff --git a/desk/sur/activity.hoon b/desk/sur/activity.hoon index 0d1afb8236..5aa3fdeef4 100644 --- a/desk/sur/activity.hoon +++ b/desk/sur/activity.hoon @@ -78,4 +78,5 @@ [%post id=time-id] :: mark an individual post as read [%all ~] :: mark _everything_ as read == ++$ full-info [=stream =indices unreads=(map index unread-summary)] -- diff --git a/desk/ted/test-activity.hoon b/desk/ted/test-activity.hoon index fb4012baa0..0bf743b586 100644 --- a/desk/ted/test-activity.hoon +++ b/desk/ted/test-activity.hoon @@ -7,16 +7,17 @@ ^- form:m =/ verb (fall !<((unit ?) arg) |) ;< our=ship bind:m get-our:s -;< ~ bind:m (poke-our:s %hood %kiln-nuke !>([%activity &])) +;< ~ bind:m (poke-our:s %hood %kiln-nuke !>([%activity |])) ;< ~ bind:m (poke-our:s %hood %kiln-revive !>(%activity)) :: :: add an event and get a fact :: +=/ post-time ~2010.1.1 =/ add-post=action:a :- %add ^- event:a :* %post - :* [[~sampel-poster *time] *time] + :* [[~sampel-poster post-time] post-time] [%chat ~sampel-palnet %mychat] [~sampel-hoster %mygroup] == @@ -25,8 +26,8 @@ == ;< ~ bind:m (watch:s /root [our %activity] /) ;< ~ bind:m (poke-our:s %activity %activity-action !>(add-post)) -;< [=mark =vase] bind:m (take-fact:s /root) -=/ [fact-time=time fact-event=event:a] !<(time-event:a vase) +;< [* add-vase=vase] bind:m (take-fact:s /root) +=/ [fact-time=time fact-event=event:a] !<(time-event:a add-vase) ?> .= +.add-post fact-event :: :: scry the event we added @@ -36,4 +37,23 @@ ;< scried-event=time-event:a bind:m (scry:s time-event:a %gx %activity /event/(scot %da fact-time)/noun) ?> =(event.scried-event +:add-post) :: +:: scry the full state +:: +;< =full-info:a bind:m (scry:s full-info:a %gx %activity /noun) +=/ expected-index [%channel [%chat ~sampel-palnet %mychat] [~sampel-hoster %mygroup]] +?> =(1 ~(wyt by stream.full-info)) +?> .= (silt ~[expected-index]) + ~(key by indices.full-info) +?> .= (~(got by unreads.full-info) expected-index) + [newest=post-time count=1 threads=~] +:: +:: read the post and get a fact +:: +;< ~ bind:m (watch:s /unreads [our %activity] /unreads) +;< ~ bind:m (poke-our:s %activity %activity-action !>([%read expected-index %post fact-time])) +;< [* read-vase=vase] bind:m (take-fact:s /unreads) +=/ [=index:a =unread-summary:a] !<([index:a unread-summary:a] read-vase) +?> =(index expected-index) +?> (gth newest.unread-summary post-time) +?> =(0 count.unread-summary) (pure:m !>(~)) From 5acc64e762bb5220033c0d7ff0b137d606c4dab4 Mon Sep 17 00:00:00 2001 From: ~latter-bolden Date: Sun, 3 Mar 2024 15:40:54 -0500 Subject: [PATCH 16/27] emoji picker: fix z-index --- apps/tlon-web/src/components/EmojiPicker.tsx | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/tlon-web/src/components/EmojiPicker.tsx b/apps/tlon-web/src/components/EmojiPicker.tsx index 5e6db393f7..0052a64429 100644 --- a/apps/tlon-web/src/components/EmojiPicker.tsx +++ b/apps/tlon-web/src/components/EmojiPicker.tsx @@ -147,8 +147,9 @@ export default function EmojiPicker({ collisionPadding={15} onInteractOutside={isMobile ? () => dismss() : undefined} data-testid="emoji-picker" + className="z-50" > -
+
{data ? ( Date: Sun, 3 Mar 2024 17:49:13 -0500 Subject: [PATCH 17/27] tests: add test for adding a reaction on mobile --- .../e2e/005-mobile-chat-options.spec.ts | 43 +++++++++++++++++++ .../chat/ChatMessage/ChatMessageOptions.tsx | 7 ++- apps/tlon-web/src/components/ActionMenu.tsx | 8 +++- 3 files changed, 56 insertions(+), 2 deletions(-) create mode 100644 apps/tlon-web/e2e/005-mobile-chat-options.spec.ts diff --git a/apps/tlon-web/e2e/005-mobile-chat-options.spec.ts b/apps/tlon-web/e2e/005-mobile-chat-options.spec.ts new file mode 100644 index 0000000000..e54f32da58 --- /dev/null +++ b/apps/tlon-web/e2e/005-mobile-chat-options.spec.ts @@ -0,0 +1,43 @@ +import { expect, test } from '@playwright/test'; + +import shipManifest from './shipManifest.json'; + +const groupHostUrl = `${shipManifest['~naldeg-mardev'].webUrl}/apps/groups/`; +const groupHost = 'mardev'; +const testGroupName = 'mardev Club'; +const testChannelName = 'mardev chat'; +const testMessageText = `hi, it's me, ~naldeg-mardev`; +const defaultVisibleEmoji = '😇'; + +test('Add reaction', async ({ browser }) => { + // authenticate as test group host + const hostContext = await browser.newContext({ + storageState: shipManifest['~naldeg-mardev'].authFile, + }); + const page = await hostContext.newPage(); + await page.setViewportSize({ width: 390, height: 844 }); + await page.goto(groupHostUrl); + + // navigate to test channel + await page.getByRole('link', { name: testGroupName }).waitFor(); + await page.getByRole('link', { name: testGroupName }).click(); + await page.getByRole('link', { name: testChannelName }).waitFor(); + await page.getByRole('link', { name: testChannelName }).click(); + + // open longpress menu + await page.getByText(testMessageText).click({ delay: 300 }); + await page.getByTestId('chat-message-options').waitFor(); + await expect(page.getByTestId('chat-message-options')).toBeVisible(); + + // open picker and add reaction + await page.getByTestId('react').click(); + await page.getByTestId('emoji-picker').waitFor(); + await expect(page.getByTestId('emoji-picker')).toBeVisible(); + await page.getByText(defaultVisibleEmoji).waitFor(); + await page.getByText(defaultVisibleEmoji).click(); + + // verify reaction + await page.getByTestId('emoji-picker').waitFor({ state: 'detached' }); + await page.getByText(defaultVisibleEmoji).waitFor(); + await expect(page.getByText(defaultVisibleEmoji)).toBeVisible(); +}); diff --git a/apps/tlon-web/src/chat/ChatMessage/ChatMessageOptions.tsx b/apps/tlon-web/src/chat/ChatMessage/ChatMessageOptions.tsx index bd58f7e41e..2c9aadeeaf 100644 --- a/apps/tlon-web/src/chat/ChatMessage/ChatMessageOptions.tsx +++ b/apps/tlon-web/src/chat/ChatMessage/ChatMessageOptions.tsx @@ -405,7 +405,12 @@ function ChatMessageOptions(props: { return ( <> {isMobile ? ( - + ) : (
; function classNameForType(type?: ActionType) { @@ -58,6 +59,7 @@ const ActionMenu = React.memo( disabled, align, ariaLabel, + testId, className, triggerClassName, contentClassName, @@ -81,9 +83,13 @@ const ActionMenu = React.memo( )} - + {actions.map((action) => (