fix: refresh new Overlay of group with changes from unstable

pull/3281/head
Audric Ackermann 5 months ago
parent ddd03899a0
commit 9507cded10
No known key found for this signature in database

@ -116,49 +116,55 @@ export const OverlayClosedGroupV2 = () => {
const privateContactsPubkeys = useContactsToInviteToGroup(); const privateContactsPubkeys = useContactsToInviteToGroup();
const isCreatingGroup = useIsCreatingGroupFromUIPending(); const isCreatingGroup = useIsCreatingGroupFromUIPending();
const [groupName, setGroupName] = useState(''); const [groupName, setGroupName] = useState('');
const [groupNameError, setGroupNameError] = useState<string | undefined>();
const forceUpdate = useUpdate(); const forceUpdate = useUpdate();
const { const {
uniqueValues: members, uniqueValues: selectedMemberIds,
addTo: addToSelected, addTo: addToSelected,
removeFrom: removeFromSelected, removeFrom: removeFromSelected,
} = useSet<string>([]); } = useSet<string>([]);
const isSearch = useIsSearching(); const isSearch = useIsSearching();
const searchTerm = useSelector(getSearchTerm);
const searchResultContactsOnly = useSelector(getSearchResultsContactOnly); const searchResultContactsOnly = useSelector(getSearchResultsContactOnly);
function closeOverlay() { function closeOverlay() {
dispatch(clearSearch());
dispatch(resetLeftOverlayMode()); dispatch(resetLeftOverlayMode());
} }
async function onEnterPressed() { async function onEnterPressed() {
setGroupNameError(undefined);
setGroupName('');
if (isCreatingGroup) { if (isCreatingGroup) {
window?.log?.warn('Closed group creation already in progress'); window?.log?.warn('Closed group creation already in progress');
return; return;
} }
// Validate groupName and groupMembers length // Validate groupName and groupMembers length
if (groupName.length === 0) { if (groupName.length === 0) {
ToastUtils.pushToastError('invalidGroupName', window.i18n('groupNameEnterPlease')); ToastUtils.pushToastError('invalidGroupName', window.i18n('groupNameEnterPlease'));
return; return;
} }
if (groupName.length > LIBSESSION_CONSTANTS.BASE_GROUP_MAX_NAME_LENGTH) { if (groupName.length > LIBSESSION_CONSTANTS.BASE_GROUP_MAX_NAME_LENGTH) {
ToastUtils.pushToastError('invalidGroupName', window.i18n('groupNameEnterShorter')); setGroupNameError(window.i18n('groupNameEnterShorter'));
return; return;
} }
// >= because we add ourself as a member AFTER this. so a 10 member group is already invalid as it will be 11 with us // >= because we add ourself as a member AFTER this. so a 10 member group is already invalid as it will be 11 with us
// the same is valid with groups count < 1 // the same is valid with groups count < 1
if (members.length < 1) { if (selectedMemberIds.length < 1) {
ToastUtils.pushToastError('pickClosedGroupMember', window.i18n('groupCreateErrorNoMembers')); ToastUtils.pushToastError('pickClosedGroupMember', window.i18n('groupCreateErrorNoMembers'));
return; return;
} }
if (members.length >= VALIDATION.CLOSED_GROUP_SIZE_LIMIT) { if (selectedMemberIds.length >= VALIDATION.CLOSED_GROUP_SIZE_LIMIT) {
ToastUtils.pushToastError('closedGroupMaxSize', window.i18n('groupAddMemberMaximum')); ToastUtils.pushToastError('closedGroupMaxSize', window.i18n('groupAddMemberMaximum'));
return; return;
} }
// trigger the add through redux. // trigger the add through redux.
dispatch( dispatch(
groupInfoActions.initNewGroupInWrapper({ groupInfoActions.initNewGroupInWrapper({
members: concat(members, [us]), members: concat(selectedMemberIds, [us]),
groupName, groupName,
us, us,
}) as any }) as any
@ -166,16 +172,26 @@ export const OverlayClosedGroupV2 = () => {
} }
useKey('Escape', closeOverlay); useKey('Escape', closeOverlay);
const noContactsForClosedGroup = privateContactsPubkeys.length === 0;
const contactsToRender = isSearch ? searchResultContactsOnly : privateContactsPubkeys; const contactsToRender = isSearch ? searchResultContactsOnly : privateContactsPubkeys;
const disableCreateButton = !members.length && !groupName.length; const noContactsForClosedGroup = isEmpty(searchTerm) && contactsToRender.length === 0;
const disableCreateButton = isCreatingGroup || (!selectedMemberIds.length && !groupName.length);
return ( return (
<div className="module-left-pane-overlay"> <StyledLeftPaneOverlay
<div className="create-group-name-input"> container={true}
flexDirection={'column'}
flexGrow={1}
alignItems={'center'}
>
<Flex
container={true}
width={'100%'}
flexDirection="column"
alignItems="center"
padding={'var(--margins-md)'}
>
<SessionInput <SessionInput
autoFocus={true} autoFocus={true}
type="text" type="text"
@ -183,65 +199,74 @@ export const OverlayClosedGroupV2 = () => {
value={groupName} value={groupName}
onValueChanged={setGroupName} onValueChanged={setGroupName}
onEnterPressed={onEnterPressed} onEnterPressed={onEnterPressed}
// error={groupNameError} // TODO fix error handling with new groups (we are deprecating that UI soon) error={groupNameError}
maxLength={LIBSESSION_CONSTANTS.BASE_GROUP_MAX_NAME_LENGTH} maxLength={LIBSESSION_CONSTANTS.BASE_GROUP_MAX_NAME_LENGTH}
textSize="md" textSize="md"
centerText={true} centerText={true}
monospaced={true} monospaced={true}
isTextArea={true} isTextArea={true}
inputDataTestId="new-closed-group-name" inputDataTestId="new-closed-group-name"
editable={!noContactsForClosedGroup} editable={!noContactsForClosedGroup && !isCreatingGroup}
/> />
</div> <SpacerMD />
<SessionSpinner loading={isCreatingGroup} /> {/* TODO: localize those strings once out releasing those buttons for real Remove after QA */}
{/* TODO: localize those strings once out releasing those buttons for real Remove after QA */} {hasClosedGroupV2QAButtons() && (
{hasClosedGroupV2QAButtons() && ( <>
<> <span style={{ display: 'flex', alignItems: 'center' }}>
<span style={{ display: 'flex', alignItems: 'center' }}> Invite as admin?{' '}
Invite as admin?{' '} <SessionToggle
<SessionToggle active={window.sessionFeatureFlags.useGroupV2InviteAsAdmin}
active={window.sessionFeatureFlags.useGroupV2InviteAsAdmin} onClick={() => {
onClick={() => { window.sessionFeatureFlags.useGroupV2InviteAsAdmin =
window.sessionFeatureFlags.useGroupV2InviteAsAdmin = !window.sessionFeatureFlags.useGroupV2InviteAsAdmin;
!window.sessionFeatureFlags.useGroupV2InviteAsAdmin; forceUpdate();
forceUpdate(); }}
}} />
/> </span>
</span> </>
</> )}
)} <SessionSpinner loading={isCreatingGroup} />
<SpacerLG /> <SpacerLG />
</Flex>
<SessionSearchInput /> <SessionSearchInput />
{!noContactsForClosedGroup && window.sessionFeatureFlags.useClosedGroupV2 && ( {!noContactsForClosedGroup && <GroupInviteRequiredVersionBanner />}
<GroupInviteRequiredVersionBanner />
)}
<StyledGroupMemberListContainer> <StyledGroupMemberListContainer>
{noContactsForClosedGroup ? ( {noContactsForClosedGroup ? (
<NoContacts /> <NoContacts />
) : searchTerm && !contactsToRender.length ? (
<StyledNoResults>
<Localizer token="searchMatchesNoneSpecific" args={{ query: searchTerm }} />
</StyledNoResults>
) : ( ) : (
contactsToRender.map((memberPubkey: string) => ( contactsToRender.map((memberPubkey: string) => (
<MemberListItem <MemberListItem
key={`member-list-${memberPubkey}`}
pubkey={memberPubkey} pubkey={memberPubkey}
isSelected={members.some(m => m === memberPubkey)} isSelected={selectedMemberIds.includes(memberPubkey)}
key={memberPubkey}
onSelect={addToSelected} onSelect={addToSelected}
onUnselect={removeFromSelected} onUnselect={removeFromSelected}
disableBg={true} withBorder={false}
disabled={isCreatingGroup}
maxNameWidth="100%" maxNameWidth="100%"
/> />
)) ))
)} )}
</StyledGroupMemberListContainer> </StyledGroupMemberListContainer>
<SpacerLG style={{ flexShrink: 0 }} /> <SpacerLG style={{ flexShrink: 0 }} />
<SessionButton <Flex container={true} width={'100%'} flexDirection="column" padding={'var(--margins-md)'}>
text={window.i18n('create')} <SessionButton
disabled={disableCreateButton} text={window.i18n('create')}
onClick={onEnterPressed} disabled={disableCreateButton}
dataTestId="create-group-button" onClick={onEnterPressed}
margin="auto 0 var(--margins-lg) 0 " // just to keep that button at the bottom of the overlay (even with an empty list) dataTestId="create-group-button"
/> margin="auto 0 0" // just to keep that button at the bottom of the overlay (even with an empty list)
</div> />
</Flex>
<SpacerLG />
</StyledLeftPaneOverlay>
); );
}; };

Loading…
Cancel
Save