mirror of
https://github.com/simplex-chat/simplex-chat.git
synced 2026-07-20 07:01:40 +00:00
wip
This commit is contained in:
@@ -2769,9 +2769,8 @@ processChatCommand cxt nm = \case
|
||||
throwCmdError $ "the number of members, moderators and admins would exceed the limit of " <> show maxGroupRosterSize
|
||||
(errs1, changed1) <- changeRoleInvitedMems user gInfo invitedMems
|
||||
let doBumpRoster = useRelays' gInfo && memberRole' (membership gInfo) == GROwner && (isRosterRole newRole || anyPrivilegedTarget)
|
||||
rosterVer <- if doBumpRoster then Just <$> reserveRosterVersion gInfo else pure Nothing
|
||||
-- roster (with the change projected in) before the delta, so a relay stores the blob at this version before forwarding the delta
|
||||
forM_ rosterVer $ \v -> broadcastRoster user gInfo v (RDRoleChanged newRole currentMems) `catchAllErrors` eToView
|
||||
rosterVer <- if doBumpRoster then Just <$> broadcastRoster user gInfo (RDRoleChanged newRole currentMems) else pure Nothing
|
||||
(errs2, changed2, acis, msgSigned) <- changeRoleCurrentMems user g rosterVer currentMems
|
||||
unless (null acis) $ toView $ CEvtNewChatItems user acis
|
||||
let errs = errs1 <> errs2
|
||||
@@ -2898,9 +2897,8 @@ processChatCommand cxt nm = \case
|
||||
(errs1, deleted1) <- deleteInvitedMems user invitedMems
|
||||
let recipients = filter memberCurrent members
|
||||
let doBumpRoster = useRelays' gInfo && memberRole' (membership gInfo) == GROwner && anyPrivilegedRemoved
|
||||
rosterVer <- if doBumpRoster then Just <$> reserveRosterVersion gInfo else pure Nothing
|
||||
-- roster (excluding the removed members) before the delta, so a relay stores the blob at this version before forwarding the delta
|
||||
forM_ rosterVer $ \v -> broadcastRoster user gInfo v (RDRemoved currentMems) `catchAllErrors` eToView
|
||||
rosterVer <- if doBumpRoster then Just <$> broadcastRoster user gInfo (RDRemoved currentMems) else pure Nothing
|
||||
(errs2, deleted2, acis2, signed2) <- deleteMemsSend user gInfo Nothing rosterVer recipients currentMems
|
||||
(errs3, deleted3, acis3, signed3) <-
|
||||
foldM (\acc m -> deletePendingMember acc user gInfo [m] m) ([], [], [], False) pendingApprvMems
|
||||
|
||||
@@ -2270,17 +2270,6 @@ sendGroupMessage' user gInfo members chatMsgEvent =
|
||||
((Right msg) :| [], _) -> pure msg
|
||||
_ -> throwChatError $ CEInternalError "sendGroupMessage': expected 1 message"
|
||||
|
||||
-- TODO [relays] improvement: publish roster_version in link data so the owner can recover the latest version
|
||||
-- TODO after restoring from a stale backup (relays accept only strictly-greater versions)
|
||||
-- Persist the next roster version before sending the events that carry it (so a recipient never advances
|
||||
-- past a version the owner hasn't recorded). The matching blob is broadcast separately, by broadcastRoster,
|
||||
-- with the change projected onto the served roster - so it excludes demoted/removed members.
|
||||
reserveRosterVersion :: GroupInfo -> CM VersionRoster
|
||||
reserveRosterVersion gInfo = do
|
||||
let rosterVer = maybe (VersionRoster 0) (\(VersionRoster n) -> VersionRoster (n + 1)) (rosterVersion gInfo)
|
||||
withStore' $ \db -> setGroupRosterVersion db gInfo rosterVer
|
||||
pure rosterVer
|
||||
|
||||
-- The roster change being broadcast, projected onto the current roster members in broadcastRoster. This lets the
|
||||
-- roster blob be built (and sent) before the change is applied to the owner's own member records, so the owner
|
||||
-- never demotes/removes a member locally before the change has been propagated to relays.
|
||||
@@ -2295,13 +2284,25 @@ applyRosterDelta delta current = case delta of
|
||||
where
|
||||
without ms = let ids = S.fromList (map groupMemberId' ms) in filter ((`S.notMember` ids) . groupMemberId') current
|
||||
|
||||
broadcastRoster :: User -> GroupInfo -> VersionRoster -> RosterDelta -> CM ()
|
||||
broadcastRoster user gInfo rosterVer delta = do
|
||||
cxt <- chatStoreCxt
|
||||
(relays, rosterMems) <- withStore' $ \db ->
|
||||
(,) <$> getGroupRelayMembers db cxt user gInfo <*> getGroupRosterMembers db cxt user gInfo
|
||||
forM_ (L.nonEmpty relays) $ \relays' ->
|
||||
sendRoster user gInfo (L.toList relays') rosterVer (buildGroupRoster $ applyRosterDelta delta rosterMems)
|
||||
-- TODO [relays] improvement: publish roster_version in link data so the owner can recover the latest version
|
||||
-- TODO after restoring from a stale backup (relays accept only strictly-greater versions)
|
||||
-- Reserve and persist the next roster version (committed before the events that carry it, so a recipient never
|
||||
-- advances past a version the owner hasn't recorded), then broadcast the matching blob with the change projected
|
||||
-- onto the served roster (so it excludes demoted/removed members). Returns the reserved version for the delta
|
||||
-- that follows. The blob send is best-effort - a failed send heals on the next change or on resume.
|
||||
broadcastRoster :: User -> GroupInfo -> RosterDelta -> CM VersionRoster
|
||||
broadcastRoster user gInfo delta = do
|
||||
let rosterVer = maybe (VersionRoster 0) (\(VersionRoster n) -> VersionRoster (n + 1)) (rosterVersion gInfo)
|
||||
withStore' $ \db -> setGroupRosterVersion db gInfo rosterVer
|
||||
sendRosterBlob rosterVer `catchAllErrors` eToView
|
||||
pure rosterVer
|
||||
where
|
||||
sendRosterBlob rosterVer = do
|
||||
cxt <- chatStoreCxt
|
||||
(relays, rosterMems) <- withStore' $ \db ->
|
||||
(,) <$> getGroupRelayMembers db cxt user gInfo <*> getGroupRosterMembers db cxt user gInfo
|
||||
forM_ (L.nonEmpty relays) $ \relays' ->
|
||||
sendRoster user gInfo (L.toList relays') rosterVer (buildGroupRoster $ applyRosterDelta delta rosterMems)
|
||||
|
||||
-- Send the current roster (no version bump) to a newly added relay so it can serve joiners.
|
||||
sendGroupRosterToRelay :: User -> GroupInfo -> GroupMember -> CM ()
|
||||
|
||||
Reference in New Issue
Block a user