fix: bunch of changes to match acceptance criteria

pull/3052/head
Audric Ackermann 6 months ago
parent 038e08ed3d
commit c30fcfd013
No known key found for this signature in database

@ -8,11 +8,14 @@ import { UserUtils } from '../session/utils';
import { GroupInvite } from '../session/utils/job_runners/jobs/GroupInviteJob';
import { hasClosedGroupV2QAButtons } from '../shared/env_vars';
import {
useMemberHasAcceptedInvite,
useMemberInviteFailed,
useMemberInviteSending,
useMemberInviteSent,
useMemberIsPromoted,
useMemberPromoteSending,
useMemberPromotionFailed,
useMemberPromotionNotSent,
useMemberPromotionSent,
} from '../state/selectors/groups';
import { Avatar, AvatarSize, CrownIcon } from './avatar/Avatar';
@ -118,6 +121,7 @@ type MemberListItemProps = {
displayGroupStatus?: boolean;
groupPk?: string;
disabled?: boolean;
hideRadioButton?: boolean;
};
const ResendContainer = ({
@ -139,8 +143,8 @@ const ResendContainer = ({
padding="0 var(--margins-lg)"
gap="var(--margins-sm)"
>
<ResendInviteButton groupPk={groupPk} pubkey={pubkey} />
<ResendPromoteButton groupPk={groupPk} pubkey={pubkey} />
<ResendButton groupPk={groupPk} pubkey={pubkey} />
<PromoteButton groupPk={groupPk} pubkey={pubkey} />
</Flex>
);
}
@ -215,15 +219,24 @@ const GroupStatusContainer = ({
return null;
};
const ResendInviteButton = ({
groupPk,
pubkey,
}: {
pubkey: PubkeyType;
groupPk: GroupPubkeyType;
}) => {
const inviteFailed = useMemberInviteFailed(pubkey, groupPk);
if (!inviteFailed) {
const ResendButton = ({ groupPk, pubkey }: { pubkey: PubkeyType; groupPk: GroupPubkeyType }) => {
const acceptedInvite = useMemberHasAcceptedInvite(pubkey, groupPk);
const promotionFailed = useMemberPromotionFailed(pubkey, groupPk);
const promotionSent = useMemberPromotionSent(pubkey, groupPk);
const promotionNotSent = useMemberPromotionNotSent(pubkey, groupPk);
const promoted = useMemberIsPromoted(pubkey, groupPk);
// as soon as the `admin` flag is set in the group for that member, we should be able to resend a promote as we cannot remove an admin.
const canResendPromotion =
hasClosedGroupV2QAButtons() &&
(promotionFailed || promotionSent || promotionNotSent || promoted);
// we can always remove/and readd a non-admin member. So we consider that a member who accepted the invite cannot be resent an invite.
const canResendInvite = !acceptedInvite;
const shouldShowResendButton = canResendInvite || canResendPromotion;
if (!shouldShowResendButton) {
return null;
}
return (
@ -239,9 +252,10 @@ const ResendInviteButton = ({
window.log.warn('tried to resend invite but we do not have correct details');
return;
}
const token = await MetaGroupWrapperActions.swarmSubAccountToken(groupPk, pubkey);
const unrevokeSubRequest = new SubaccountUnrevokeSubRequest({
groupPk,
revokeTokenHex: [pubkey],
revokeTokenHex: [token],
timestamp: NetworkTime.now(),
secretKey: group.secretKey,
});
@ -256,7 +270,10 @@ const ResendInviteButton = ({
// if we tried to invite that member as admin right away, let's retry it as such.
const inviteAsAdmin =
member.promotionNotSent || member.promotionFailed || member.promotionPending;
member.promotionNotSent ||
member.promotionFailed ||
member.promotionPending ||
member.promoted;
await GroupInvite.addJob({
groupPk,
member: pubkey,
@ -267,14 +284,13 @@ const ResendInviteButton = ({
);
};
const ResendPromoteButton = ({
groupPk,
pubkey,
}: {
pubkey: PubkeyType;
groupPk: GroupPubkeyType;
}) => {
if (!hasClosedGroupV2QAButtons()) {
const PromoteButton = ({ groupPk, pubkey }: { pubkey: PubkeyType; groupPk: GroupPubkeyType }) => {
const memberAcceptedInvite = useMemberHasAcceptedInvite(pubkey, groupPk);
const memberIsPromoted = useMemberIsPromoted(pubkey, groupPk);
// When invite-as-admin was used to invite that member, the resend button is available to resend the promote message.
// We want to show that button only to promote a normal member who accepted a normal invite but wasn't promoted yet.
// ^ this is only the case for testing. The UI will be different once we release the promotion process
if (!hasClosedGroupV2QAButtons() || !memberAcceptedInvite || memberIsPromoted) {
return null;
}
return (
@ -309,8 +325,11 @@ export const MemberListItem = ({
disabled,
withBorder,
maxNameWidth,
hideRadioButton,
}: MemberListItemProps) => {
const memberName = useNicknameOrProfileNameOrShortenedPubkey(pubkey);
const isUs = UserUtils.isUsFromCache(pubkey);
const ourName = isUs ? window.i18n('you') : null;
return (
<StyledSessionMemberItem
@ -335,7 +354,7 @@ export const MemberListItem = ({
alignItems="flex-start"
>
<StyledName data-testid={'group-member-name'} maxName={maxNameWidth}>
{memberName}
{ourName || memberName}
</StyledName>
<GroupStatusContainer
pubkey={pubkey}
@ -347,7 +366,7 @@ export const MemberListItem = ({
<ResendContainer pubkey={pubkey} displayGroupStatus={displayGroupStatus} groupPk={groupPk} />
{!inMentions && (
{!inMentions && !hideRadioButton && (
<StyledCheckContainer>
<SessionRadio active={isSelected} value={pubkey} inputName={pubkey} label="" />
</StyledCheckContainer>

@ -76,6 +76,7 @@ const ClassicMemberList = (props: {
onSelect={onSelect}
onUnselect={onUnselect}
isAdmin={isAdmin}
hideRadioButton={isAdmin} // we want to hide the toggle for admins are they are not selectable
disableBg={true}
displayGroupStatus={isV2Group && weAreAdmin}
groupPk={convoId}
@ -196,14 +197,9 @@ export const UpdateGroupMembersDialog = (props: Props) => {
}
if (groupAdmins?.includes(member)) {
if (PubKey.is03Pubkey(conversationId)) {
window?.log?.warn(`User ${member} cannot be selected as they are an admin.`);
return;
}
ToastUtils.pushCannotRemoveCreatorFromGroup();
window?.log?.warn(
`User ${member} cannot be selected as they are the creator of the closed group.`
);
ToastUtils.pushCannotRemoveGroupAdmin();
window?.log?.warn(`User ${member} cannot be selected as they are an admin.`);
return;
}

@ -547,8 +547,7 @@ export async function deleteMessagesById(messageIds: Array<string>, conversation
window.inboxStore?.dispatch(
updateConfirmModal({
title: window.i18n('clearMessagesForMe'),
i18nMessage: { token: 'deleteMessage', args: { count: selectedMessages.length } },
title: window.i18n('deleteMessage', { count: selectedMessages.length }),
radioOptions: !isMe
? [
{

@ -60,7 +60,6 @@ export function pushLoadAttachmentFailure(message?: string) {
// TODOLATER pushToast functions should take I18nArgs and then run strip in the function itself.
export function pushFileSizeErrorAsByte() {
pushToastError('fileSizeWarning', window.i18n.stripped('attachmentsErrorSize'));
}
@ -114,7 +113,6 @@ export function pushMessageDeleteForbidden() {
export function pushUnableToCall() {
pushToastError('unableToCall', window.i18n.stripped('callsCannotStart'));
}
export function pushedMissedCall(userName: string) {
@ -184,7 +182,7 @@ export function pushDeleted(count: number) {
pushToastSuccess('deleted', window.i18n.stripped('deleteMessageDeleted', { count }));
}
export function pushCannotRemoveCreatorFromGroup() {
export function pushCannotRemoveGroupAdmin() {
pushToastWarning('adminCannotBeRemoved', window.i18n.stripped('adminCannotBeRemoved'));
}

@ -64,9 +64,15 @@ async function addJob({ groupPk, member, inviteAsAdmin }: JobExtraArgs) {
await runners.groupInviteJobRunner.addJob(groupInviteJob);
window?.inboxStore?.dispatch(
groupInfoActions.setInvitePending({ groupPk, pubkey: member, sending: true })
);
if (inviteAsAdmin) {
window?.inboxStore?.dispatch(
groupInfoActions.setPromotionPending({ groupPk, pubkey: member, sending: true })
);
} else {
window?.inboxStore?.dispatch(
groupInfoActions.setInvitePending({ groupPk, pubkey: member, sending: true })
);
}
}
}
@ -219,9 +225,16 @@ class GroupInviteJob extends PersistedJob<GroupInvitePersistedData> {
}
updateFailedStateForMember(groupPk, member, failed);
window?.inboxStore?.dispatch(
groupInfoActions.setInvitePending({ groupPk, pubkey: member, sending: false })
);
if (inviteAsAdmin) {
window?.inboxStore?.dispatch(
groupInfoActions.setPromotionPending({ groupPk, pubkey: member, sending: false })
);
} else {
window?.inboxStore?.dispatch(
groupInfoActions.setInvitePending({ groupPk, pubkey: member, sending: true })
);
}
window?.inboxStore?.dispatch(
groupInfoActions.refreshGroupDetailsFromWrapper({ groupPk }) as any
);

@ -184,10 +184,9 @@ async function pushChangesToGroupSwarmIfNeeded({
const changes = LibSessionUtil.batchResultsToGroupSuccessfulChange(result, {
allOldHashes,
messages: pendingConfigData,
});
if (isEmpty(changes)) {
if ((allOldHashes.size || pendingConfigData.length) && isEmpty(changes)) {
return RunJobResult.RetryJobIfPossible;
}

@ -52,6 +52,11 @@ function getMemberInviteFailed(state: StateType, pubkey: PubkeyType, convo?: Gro
return findMemberInMembers(members, pubkey)?.inviteFailed || false;
}
function getMemberInviteNotSent(state: StateType, pubkey: PubkeyType, convo?: GroupPubkeyType) {
const members = getMembersOfGroup(state, convo);
return findMemberInMembers(members, pubkey)?.inviteNotSent || false;
}
function getMemberInviteSent(state: StateType, pubkey: PubkeyType, convo?: GroupPubkeyType) {
const members = getMembersOfGroup(state, convo);
@ -63,6 +68,11 @@ function getMemberIsPromoted(state: StateType, pubkey: PubkeyType, convo?: Group
return findMemberInMembers(members, pubkey)?.promoted || false;
}
function getMemberHasAcceptedInvite(state: StateType, pubkey: PubkeyType, convo?: GroupPubkeyType) {
const members = getMembersOfGroup(state, convo);
return findMemberInMembers(members, pubkey)?.inviteAccepted || false;
}
function getMemberPromotionFailed(state: StateType, pubkey: PubkeyType, convo?: GroupPubkeyType) {
const members = getMembersOfGroup(state, convo);
return findMemberInMembers(members, pubkey)?.promotionFailed || false;
@ -73,6 +83,11 @@ function getMemberPromotionSent(state: StateType, pubkey: PubkeyType, convo?: Gr
return findMemberInMembers(members, pubkey)?.promotionPending || false;
}
function getMemberPromotionNotSent(state: StateType, pubkey: PubkeyType, convo?: GroupPubkeyType) {
const members = getMembersOfGroup(state, convo);
return findMemberInMembers(members, pubkey)?.promotionNotSent || false;
}
export function getLibMembersCount(state: StateType, convo?: GroupPubkeyType): Array<string> {
return getLibMembersPubkeys(state, convo);
}
@ -136,9 +151,16 @@ export function useMemberInviteSent(member: PubkeyType, groupPk: GroupPubkeyType
return useSelector((state: StateType) => getMemberInviteSent(state, member, groupPk));
}
export function useMemberInviteNotSent(member: PubkeyType, groupPk: GroupPubkeyType) {
return useSelector((state: StateType) => getMemberInviteNotSent(state, member, groupPk));
}
export function useMemberIsPromoted(member: PubkeyType, groupPk: GroupPubkeyType) {
return useSelector((state: StateType) => getMemberIsPromoted(state, member, groupPk));
}
export function useMemberHasAcceptedInvite(member: PubkeyType, groupPk: GroupPubkeyType) {
return useSelector((state: StateType) => getMemberHasAcceptedInvite(state, member, groupPk));
}
export function useMemberPromotionFailed(member: PubkeyType, groupPk: GroupPubkeyType) {
return useSelector((state: StateType) => getMemberPromotionFailed(state, member, groupPk));
@ -148,6 +170,10 @@ export function useMemberPromotionSent(member: PubkeyType, groupPk: GroupPubkeyT
return useSelector((state: StateType) => getMemberPromotionSent(state, member, groupPk));
}
export function useMemberPromotionNotSent(member: PubkeyType, groupPk: GroupPubkeyType) {
return useSelector((state: StateType) => getMemberPromotionNotSent(state, member, groupPk));
}
export function useMemberGroupChangePending() {
return useSelector(getIsMemberGroupChangePendingFromUI);
}

Loading…
Cancel
Save