You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
session-desktop/ts/components/leftpane/overlay/OverlayClosedGroup.tsx

122 lines
3.8 KiB
TypeScript

import React, { useState } from 'react';
import { useDispatch, useSelector } from 'react-redux';
import { SessionButton, SessionButtonColor, SessionButtonType } from '../../basic/SessionButton';
import { SessionIdEditable } from '../../basic/SessionIdEditable';
import { SessionSpinner } from '../../basic/SessionSpinner';
import { MemberListItem } from '../../MemberListItem';
import { OverlayHeader } from './OverlayHeader';
// tslint:disable: no-submodule-imports use-simple-attributes
import { setOverlayMode } from '../../../state/ducks/section';
import { getPrivateContactsPubkeys } from '../../../state/selectors/conversations';
import { SpacerLG } from '../../basic/Text';
import { MainViewController } from '../../MainViewController';
import useKey from 'react-use/lib/useKey';
export const OverlayClosedGroup = () => {
const dispatch = useDispatch();
const privateContactsPubkeys = useSelector(getPrivateContactsPubkeys);
// FIXME autofocus inputref on mount
const [groupName, setGroupName] = useState('');
const [loading, setLoading] = useState(false);
const [selectedMemberIds, setSelectedMemberIds] = useState<Array<string>>([]);
function closeOverlay() {
dispatch(setOverlayMode(undefined));
}
function handleSelectMember(memberId: string) {
if (selectedMemberIds.includes(memberId)) {
return;
}
setSelectedMemberIds([...selectedMemberIds, memberId]);
}
function handleUnselectMember(unselectId: string) {
setSelectedMemberIds(
selectedMemberIds.filter(id => {
return id !== unselectId;
})
);
}
async function onEnterPressed() {
if (loading) {
window?.log?.warn('Closed group creation already in progress');
return;
}
setLoading(true);
const groupCreated = await MainViewController.createClosedGroup(groupName, selectedMemberIds);
if (groupCreated) {
closeOverlay();
return;
}
setLoading(false);
}
useKey('Escape', closeOverlay);
const title = window.i18n('newClosedGroup');
const buttonText = window.i18n('done');
const subtitle = window.i18n('createClosedGroupNamePrompt');
const placeholder = window.i18n('createClosedGroupPlaceholder');
const noContactsForClosedGroup = privateContactsPubkeys.length === 0;
return (
<div className="module-left-pane-overlay">
<OverlayHeader title={title} subtitle={subtitle} />
<div className="create-group-name-input">
<SessionIdEditable
editable={!noContactsForClosedGroup}
placeholder={placeholder}
value={groupName}
isGroup={true}
maxLength={100}
onChange={setGroupName}
onPressEnter={onEnterPressed}
/>
</div>
<SessionSpinner loading={loading} />
<SpacerLG />
<div className="group-member-list__container">
{noContactsForClosedGroup ? (
<div className="group-member-list__no-contacts">{window.i18n('noContactsForGroup')}</div>
) : (
<div className="group-member-list__selection">
{privateContactsPubkeys.map((memberPubkey: string) => (
<MemberListItem
pubkey={memberPubkey}
isSelected={selectedMemberIds.some(m => m === memberPubkey)}
key={memberPubkey}
onSelect={selectedMember => {
handleSelectMember(selectedMember);
}}
onUnselect={unselectedMember => {
handleUnselectMember(unselectedMember);
}}
/>
))}
</div>
)}
</div>
<SpacerLG />
<SessionButton
buttonColor={SessionButtonColor.Green}
buttonType={SessionButtonType.BrandOutline}
text={buttonText}
disabled={noContactsForClosedGroup}
onClick={onEnterPressed}
dataTestId="next-button"
/>
</div>
);
};