From 99529847e09123c590835ff45a8594a47074220c Mon Sep 17 00:00:00 2001 From: Audric Ackermann Date: Thu, 6 Feb 2025 13:37:56 +1100 Subject: [PATCH] fix: invite contacts to groups is not blocking --- ts/components/dialog/InviteContactsDialog.tsx | 16 ++++++------ .../utils/job_runners/jobs/GroupInviteJob.ts | 5 ++-- ts/state/ducks/metaGroups.ts | 25 +++++++++++++++++-- 3 files changed, 33 insertions(+), 13 deletions(-) diff --git a/ts/components/dialog/InviteContactsDialog.tsx b/ts/components/dialog/InviteContactsDialog.tsx index e4250b745..87f142a03 100644 --- a/ts/components/dialog/InviteContactsDialog.tsx +++ b/ts/components/dialog/InviteContactsDialog.tsx @@ -7,7 +7,7 @@ import { useDispatch } from 'react-redux'; import { VALIDATION } from '../../session/constants'; import { ConvoHub } from '../../session/conversations'; import { ToastUtils, UserUtils } from '../../session/utils'; -import { updateInviteContactModal } from '../../state/ducks/modalDialog'; +import { updateGroupMembersModal, updateInviteContactModal } from '../../state/ducks/modalDialog'; import { SpacerLG } from '../basic/Text'; import { @@ -22,12 +22,10 @@ import { PubKey } from '../../session/types'; import { SessionUtilUserGroups } from '../../session/utils/libsession/libsession_utils_user_groups'; import { groupInfoActions } from '../../state/ducks/metaGroups'; import { useContactsToInviteToGroup } from '../../state/selectors/conversations'; -import { useMemberGroupChangePending } from '../../state/selectors/groups'; import { useSelectedIsGroupV2 } from '../../state/selectors/selectedConversation'; import { MemberListItem } from '../MemberListItem'; import { SessionWrapperModal } from '../SessionWrapperModal'; import { SessionButton, SessionButtonColor, SessionButtonType } from '../basic/SessionButton'; -import { SessionSpinner } from '../loading'; import { SessionToggle } from '../basic/SessionToggle'; import { GroupInviteRequiredVersionBanner } from '../NoticeBanner'; import { hasClosedGroupV2QAButtons } from '../../shared/env_vars'; @@ -117,9 +115,6 @@ const InviteContactsDialogInner = (props: Props) => { const dispatch = useDispatch(); const privateContactPubkeys = useContactsToInviteToGroup() as Array; - - const isProcessingUIChange = useMemberGroupChangePending(); - const isPrivate = useIsPrivate(conversationId); const isPublic = useIsPublic(conversationId); const membersFromRedux = useSortedGroupMembers(conversationId) || []; @@ -163,6 +158,11 @@ const InviteContactsDialogInner = (props: Props) => { }); dispatch(action as any); empty(); + // We want to show the dialog where "invite sending" is visible (i.e. the current group members) instead of this one + // once we hit "invite" + closeDialog(); + dispatch(updateGroupMembersModal({ conversationId })); + return; } void submitForClosedGroup(conversationId, selectedContacts); @@ -221,13 +221,12 @@ const InviteContactsDialogInner = (props: Props) => { )} -
@@ -236,7 +235,6 @@ const InviteContactsDialogInner = (props: Props) => { buttonColor={SessionButtonColor.Danger} buttonType={SessionButtonType.Simple} onClick={closeDialog} - disabled={isProcessingUIChange} dataTestId="session-confirm-cancel-button" />
diff --git a/ts/session/utils/job_runners/jobs/GroupInviteJob.ts b/ts/session/utils/job_runners/jobs/GroupInviteJob.ts index 0eff4695c..4a7029592 100644 --- a/ts/session/utils/job_runners/jobs/GroupInviteJob.ts +++ b/ts/session/utils/job_runners/jobs/GroupInviteJob.ts @@ -285,7 +285,7 @@ class GroupInviteJob extends PersistedJob { ); } - updateFailedStateForMember(groupPk, member, failed); + debounceFailedStateForMember(groupPk, member, failed); window?.inboxStore?.dispatch( groupInfoActions.refreshGroupDetailsFromWrapper({ groupPk }) as any @@ -325,9 +325,10 @@ class GroupInviteJob extends PersistedJob { export const GroupInvite = { GroupInviteJob, addJob, + debounceFailedStateForMember, }; -function updateFailedStateForMember(groupPk: GroupPubkeyType, member: PubkeyType, failed: boolean) { +function debounceFailedStateForMember(groupPk: GroupPubkeyType, member: PubkeyType, failed: boolean) { let thisGroupFailure = invitesFailed.get(groupPk); if (!failed) { diff --git a/ts/state/ducks/metaGroups.ts b/ts/state/ducks/metaGroups.ts index 95151b9ee..6257a2c62 100644 --- a/ts/state/ducks/metaGroups.ts +++ b/ts/state/ducks/metaGroups.ts @@ -546,6 +546,8 @@ async function handleWithHistoryMembers({ }); // a group invite job will be added to the queue await MetaGroupWrapperActions.memberSetInviteNotSent(groupPk, member); + // update the in-memory failed state, so that if we fail again to send that invite, the toast is shown again + GroupInvite.debounceFailedStateForMember(groupPk, member, false); } const encryptedSupplementKeys = withHistory.length ? await MetaGroupWrapperActions.generateSupplementKeys(groupPk, withHistory) @@ -695,9 +697,12 @@ async function handleMemberAddedFromUI({ }); if (sequenceResult !== RunJobResult.Success) { await LibSessionUtil.saveDumpsToDb(groupPk); - + window.log.warn( + `handleMemberAddedFromUI: pushChangesToGroupSwarmIfNeeded for ${ed25519Str(groupPk)} did not return success` + ); + // throwing so we handle the reset state in the catch below throw new Error( - 'handleMemberAddedFromUI: pushChangesToGroupSwarmIfNeeded did not return success' + `handleMemberAddedFromUI: pushChangesToGroupSwarmIfNeeded for ${ed25519Str(groupPk)} did not return success` ); } } catch (e) { @@ -705,6 +710,21 @@ async function handleMemberAddedFromUI({ 'handleMemberAddedFromUI: pushChangesToGroupSwarmIfNeeded failed with:', e.message ); + + try { + const merged = withHistory.concat(withoutHistory); + for (let index = 0; index < merged.length; index++) { + await MetaGroupWrapperActions.memberSetInviteFailed(groupPk, merged[index]); + // this gets reset once we do send an invite to that user + GroupInvite.debounceFailedStateForMember(groupPk, merged[index], true); + } + } catch (e2) { + window.log.warn( + 'handleMemberAddedFromUI: marking members invite failed, failed with:', + e2.message + ); + } + return false; } // schedule send invite details, auth signature, etc. to the new users @@ -716,6 +736,7 @@ async function handleMemberAddedFromUI({ }); await convo.commit(); + return true; } /**