Skip to content

Commit

Permalink
Merge pull request #3797 from tloncorp/hm/fix-init-unreads
Browse files Browse the repository at this point in the history
activity: fix init unreads
  • Loading branch information
arthyn authored Jul 26, 2024
2 parents 67b7a48 + f46edd0 commit d2e3992
Show file tree
Hide file tree
Showing 4 changed files with 809 additions and 490 deletions.
207 changes: 99 additions & 108 deletions desk/app/activity.hoon
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
+$ card card:agent:gall
::
+$ current-state
$: %5
$: %6
allowed=notifications-allowed:a
=indices:a
=activity:a
Expand Down Expand Up @@ -135,11 +135,31 @@
=? old ?=(%2 -.old) (state-2-to-3 old)
=? old ?=(%3 -.old) (state-3-to-4 old)
=? old ?=(%4 -.old) (state-4-to-5 old)
?> ?=(%5 -.old)
=? old ?=(%5 -.old) (state-5-to-6 old)
?> ?=(%6 -.old)
=. state old
sync-reads
+$ versioned-state $%(state-5 state-4 state-3 state-2 state-1)
+$ state-5 current-state
(emit %pass /fix-init-unreads %agent [our.bowl dap.bowl] %poke noun+!>(%fix-init-unreads))
+$ versioned-state
$% state-6
state-5
state-4
state-3
state-2
state-1
==
+$ state-6 current-state
+$ state-5 _%*(. *state-6 - %5)
++ state-5-to-6
|= old=state-5
^- state-6
=/ [=indices:a =activity:a]
(sync-reads indices.old activity.old volume-settings.old)
:* %6
allowed.old
indices
activity
volume-settings.old
==
+$ state-4
$: %4
allowed=notifications-allowed:a
Expand Down Expand Up @@ -180,22 +200,22 @@
:* %4
allowed.old
new-indices
(activity-3-to-4 new-indices)
(activity-3-to-4 new-indices volume-settings.old)
volume-settings.old
==
++ indices-3-to-4
|= =indices:v3:old:a
^- indices:a
(~(run by indices) |=([=stream:a =reads:a] [stream reads *@da]))
++ activity-3-to-4
|= =indices:a
|= [=indices:a vs=volume-settings:a]
^- activity:a
=/ sources (sort-sources:src ~(tap in ~(key by indices)))
%+ roll sources
|= [=source:a =activity:a]
=/ index (~(got by indices) source)
%+ ~(put by activity) source
(summarize-unreads source index)
(~(summarize-unreads urd indices activity vs log) source index)
+$ state-2
$: %2
allowed=notifications-allowed:a
Expand Down Expand Up @@ -231,16 +251,19 @@
?+ mark ~|(bad-poke+mark !!)
%noun
?+ q.vase ~|(bad-poke+mark !!)
%refresh-activity refresh-all-summaries
%clean-keys correct-dm-keys
%fix-init-unreads fix-init-unreads
::
%sync-reads
=^ indices activity
(sync-reads indices activity volume-settings)
cor(indices indices)
::
%migrate
=. state *current-state
=. allowed %all
migrate
%refresh-activity
refresh-all-summaries
%clean-keys
correct-dm-keys
%sync-reads
sync-reads
==
::
%activity-action
Expand Down Expand Up @@ -797,102 +820,63 @@
=. allowed na
(give-update [%allow-notifications na] [%hose ~])
++ summarize-unreads
|= [=source:a =index:a]
^- activity-summary:a
%- (log |.("summarizing unreads for: {<source>}"))
=/ top=time -:(fall (ram:on-event:a stream.index) [*@da ~])
=/ unread-stream=stream:a
:: all base's events are from children so we can ignore
?: ?=(%base -.source) ~
:: we don't need to take child events into account when summarizing
:: the activity, so we filter them out
:: TODO: measure performance vs gas+murn+tap+lot
=- ->
%^ (dip:on-event:a @)
(lot:on-event:a stream.index `floor.reads.index ~)
~
|= [st=@ =time-id:a =event:a]
:_ [%.n st]
?. !child.event ~
`event
=/ children (get-children:src indices source)
%- (log |.("children: {<?:(?=(%base -.source) 'all' children)>}"))
(stream-to-unreads source index(stream unread-stream) children top)
++ stream-to-unreads
|= [=source:a =index:a children=(list source:a) top=time]
^- activity-summary:a
=/ cs=activity-summary:a
%+ roll
children
|= [=source:a sum=activity-summary:a]
=/ =index:a (~(gut by indices) source *index:a)
=/ as=activity-summary:a
?~ summary=(~(get by activity) source)
=> (summarize-unreads source index)
.(children ~)
u.summary(children ~)
%= sum
count (add count.sum count.as)
notify |(notify.sum notify.as)
newest (max newest.as newest.sum)
notify-count (add notify-count.sum notify-count.as)
==
%- (log |.("children summary: {<cs>}"))
=/ newest=time :(max newest.cs floor.reads.index bump.index top)
=/ total
:: if we're a channel, we only want thread notify counts, not totals
::
?: ?=(%channel -.source)
notify-count.cs
count.cs
=/ notify-count notify-count.cs
=/ main 0
=/ notified=? notify.cs
=/ main-notified=? |
=* stream stream.index
=| last=(unit message-key:a)
:: for each event
:: update count and newest
:: if reply, update thread state
|-
?~ stream
:* newest
total
notify-count
notified
?~(last ~ `[u.last main main-notified])
?:(?=(%base -.source) ~ (sy children))
~
==
=/ [[=time =event:a] rest=stream:a] (pop:on-event:a stream)
=/ volume (get-volume:evt volume-settings -.event)
::TODO support other event types
=* is-msg ?=(?(%dm-post %dm-reply %post %reply) -<.event)
=* is-init ?=(?(%dm-invite %chan-init) -<.event)
=* is-flag ?=(?(%flag-post %flag-reply) -<.event)
=* supported |(is-msg is-init is-flag)
?. supported $(stream rest)
=? notified &(notify.volume notified.event) &
=? notify-count &(notify.volume notified.event) +(notify-count)
=. newest (max newest time)
?. &(unreads.volume ?=(?(%dm-post %dm-reply %post %reply) -<.event))
$(stream rest)
=. total +(total)
=. main +(main)
=? main-notified &(notify:volume notified.event) &
=. last
?~ last `key.event
last
$(stream rest)
~(summarize-unreads urd indices activity volume-settings log)
::
:: when we migrated from chat and channels, we always added an init event
:: so that we can mark what's been joined and have something affect the
:: recency so that it ends up in the correct place on the sidebar.
:: however, we forgot to mark these as read, so we need to do that now.
:: otherwise we end up with a bunch of dms/channels that are
:: incorrectly unread.
++ fix-init-unreads
=+ .^(=channels:c %gx (scry-path %channels /v2/channels/full/noun))
=. indices (fix-channel-init-unreads indices channels)
=+ .^ [dms=(map ship dm:ch) clubs=(map id:club:ch club:ch)]
%gx (scry-path %chat /full/noun)
==
=. indices (fix-dm-init-unreads indices dms clubs)
refresh-all-summaries
++ fix-channel-init-unreads
|= [=indices:a =channels:c]
%- ~(urn by indices)
|= [=source:a =index:a]
:: if we're a channel with only the %chan-init event, we need to set
:: the floor to the last-read time
?. ?& ?=(%channel -.source)
?=([[* [[%chan-init *] *]] ~ ~] stream.index)
==
index
?~ channel=(~(get by channels) nest.source) index
index(floor.reads last-read.remark.u.channel)
++ fix-dm-init-unreads
|= [=indices:a dms=(map ship dm:ch) clubs=(map id:club:ch club:ch)]
^- indices:a
%- ~(urn by indices)
|= [=source:a =index:a]
:: if we're a DM with only the %dm-invite event, we need to set
:: the floor to the last-read time
?. ?& ?=(%dm -.source)
?=([[* [[%dm-invite *] *]] ~ ~] stream.index)
==
index
?- -.whom.source
%ship
?~ dm=(~(get by dms) p.whom.source) index
index(floor.reads last-read.remark.u.dm)
::
%club
?~ club=(~(get by clubs) p.whom.source) index
index(floor.reads last-read.remark.u.club)
==
:: previously we used items as a way to track individual reads because
:: floors were not local, but we have reverted to local floors and not
:: tracking individual reads
::
++ sync-reads
|= [=indices:a =activity:a vs=volume-settings:a]
=/ sources (sort-sources:src ~(tap in ~(key by indices)))
|-
?~ sources cor
?~ sources [indices activity]
=/ =source:a i.sources
=/ =index:a (~(got by indices) source)
=/ old-floor floor.reads.index
Expand All @@ -908,13 +892,18 @@
[~ %.n ?:((gth time-id st) time-id st)]
=. reads.index [new-floor ~]
:: with new reads, update our index and summary
=. cor (refresh-index source index)
=/ new=(unit activity-summary:a) (~(get by activity) source)
?: !=(?~(old ~ u.old(reads ~)) ?~(new ~ u.new(reads ~)))
=. indices (~(put by indices) source index)
=/ new-summary
%+ ~(summarize-unreads urd indices activity vs log)
source
index
=. activity
(~(put by activity) source new-summary)
?: !=(?~(old ~ u.old(reads ~)) new-summary(reads ~))
~& "%sync-reads: WARNING old and new summaries differ {<source>}"
~& "old floor: {<old-floor>} new floor: {<new-floor>}"
~& "old: {<old>}"
~& "new: {<new>}"
~& "new: {<`new-summary>}"
$(sources t.sources)
$(sources t.sources)
::
Expand Down Expand Up @@ -1062,7 +1051,8 @@
=/ entries ~(tap by unreads)
=; events=(list [time incoming-event:a])
|-
?~ events cor
?~ events
cor(indices (fix-channel-init-unreads indices channels))
=. cor (%*(. add-event start-time -.i.events) +.i.events)
$(events t.events)
|- ^- (list [time incoming-event:a])
Expand Down Expand Up @@ -1123,7 +1113,8 @@
=/ entries ~(tap by unreads)
=; events=(list [time incoming-event:a])
|-
?~ events cor
?~ events
cor(indices (fix-dm-init-unreads indices dms clubs))
=. cor (%*(. add-event start-time -.i.events) +.i.events)
$(events t.events)
|- ^- (list [time incoming-event:a])
Expand Down
95 changes: 95 additions & 0 deletions desk/lib/activity.hoon
Original file line number Diff line number Diff line change
Expand Up @@ -172,6 +172,101 @@
::
--
::
++ urd
|_ [=indices:a =activity:a =volume-settings:a log=$-((trap tape) _same)]
++ summarize-unreads
|= [=source:a =index:a]
^- activity-summary:a
%- (log |.("summarizing unreads for: {<source>}"))
=/ top=time -:(fall (ram:on-event:a stream.index) [*@da ~])
=/ unread-stream=stream:a
:: all base's events are from children so we can ignore
?: ?=(%base -.source) ~
:: we don't need to take child events into account when summarizing
:: the activity, so we filter them out
:: TODO: measure performance vs gas+murn+tap+lot
=- ->
%^ (dip:on-event:a @)
(lot:on-event:a stream.index `floor.reads.index ~)
~
|= [st=@ =time-id:a =event:a]
:_ [%.n st]
?: child.event ~
`event
=/ children (get-children:src indices source)
%- (log |.("children: {<?:(?=(%base -.source) 'all' children)>}"))
(stream-to-unreads source index(stream unread-stream) children top)
++ sum-children
|= children=(list source:a)
^- activity-summary:a
%+ roll
children
|= [=source:a sum=activity-summary:a]
=/ =index:a (~(gut by indices) source *index:a)
=/ as=activity-summary:a
?~ summary=(~(get by activity) source)
=> (summarize-unreads source index)
.(children ~)
u.summary(children ~)
%= sum
count (add count.sum count.as)
notify |(notify.sum notify.as)
newest (max newest.as newest.sum)
notify-count (add notify-count.sum notify-count.as)
==
++ stream-to-unreads
|= [=source:a =index:a children=(list source:a) top=time]
^- activity-summary:a
=/ cs=activity-summary:a
(sum-children children)
%- (log |.("children summary: {<cs>}"))
=/ newest=time :(max newest.cs floor.reads.index bump.index top)
=/ total
:: if we're a channel, we only want thread notify counts, not totals
::
?: ?=(%channel -.source)
notify-count.cs
count.cs
=/ notify-count notify-count.cs
=/ main 0
=/ notified=? notify.cs
=/ main-notified=? |
=* stream stream.index
=| last=(unit message-key:a)
:: for each event
:: update count and newest
:: if reply, update thread state
|-
?~ stream
:* newest
total
notify-count
notified
?~(last ~ `[u.last main main-notified])
?:(?=(%base -.source) ~ (sy children))
~
==
=/ [[=time =event:a] rest=stream:a] (pop:on-event:a stream)
=/ volume (get-volume:evt volume-settings -.event)
::TODO support other event types
=* is-msg ?=(?(%dm-post %dm-reply %post %reply) -<.event)
=* is-init ?=(?(%dm-invite %chan-init) -<.event)
=* is-flag ?=(?(%flag-post %flag-reply) -<.event)
=* supported |(is-msg is-init is-flag)
?. supported $(stream rest)
=? notified &(notify.volume notified.event) &
=? notify-count &(notify.volume notified.event) +(notify-count)
=. newest (max newest time)
?. &(unreads.volume ?=(?(%dm-post %dm-reply %post %reply) -<.event))
$(stream rest)
=. total +(total)
=. main +(main)
=? main-notified &(notify:volume notified.event) &
=. last
?~ last `key.event
last
$(stream rest)
--
++ convert-to
|%
++ v4
Expand Down
Loading

0 comments on commit d2e3992

Please sign in to comment.