import React from 'react'; import { SessionIconButton, SessionIconSize, SessionIconType } from './icon'; import { SessionToggle } from './SessionToggle'; import { SessionIdEditable } from './SessionIdEditable'; import { UserSearchDropdown } from './UserSearchDropdown'; import { ContactType, SessionMemberListItem } from './SessionMemberListItem'; import { ConversationType } from '../../state/ducks/conversations'; import { SessionButton, SessionButtonColor, SessionButtonType, } from './SessionButton'; import { SessionSpinner } from './SessionSpinner'; import { PillDivider } from './PillDivider'; import classNames from 'classnames'; export enum SessionClosableOverlayType { Contact = 'contact', Message = 'message', OpenGroup = 'open-group', ClosedGroup = 'closed-group', } interface Props { overlayMode: SessionClosableOverlayType; onChangeSessionID: any; onCloseClick: any; onButtonClick: any; contacts?: Array; searchTerm?: string; searchResults?: any; updateSearch?: any; showSpinner?: boolean; } interface State { groupName: string; selectedMembers: Array; senderKeys: boolean; } export class SessionClosableOverlay extends React.Component { private readonly inputRef: React.RefObject; public constructor(props: Props) { super(props); this.state = { groupName: '', selectedMembers: [], senderKeys: false, }; this.inputRef = React.createRef(); this.onKeyUp = this.onKeyUp.bind(this); this.onGroupNameChanged = this.onGroupNameChanged.bind(this); window.addEventListener('keyup', this.onKeyUp); } public componentDidMount() { if (this.inputRef.current) { this.inputRef.current.focus(); } } public getContacts() { const conversations = window.getConversations() || []; const conversationList = conversations.filter((conversation: any) => { return ( !conversation.isMe() && conversation.isPrivate() && !conversation.isSecondaryDevice() && !conversation.isBlocked() ); }); return conversationList.map((d: any) => { const lokiProfile = d.getLokiProfile(); const name = lokiProfile ? lokiProfile.displayName : 'Anonymous'; // TODO: should take existing members into account const existingMember = false; return { id: d.id, authorPhoneNumber: d.id, authorProfileName: name, selected: false, authorName: name, authorColor: d.getColor(), checkmarked: false, existingMember, }; }); } // tslint:disable-next-line max-func-body-length */ public render(): JSX.Element { const { overlayMode, onCloseClick, onChangeSessionID, showSpinner, searchTerm, updateSearch, searchResults, onButtonClick, } = this.props; const isAddContactView = overlayMode === SessionClosableOverlayType.Contact; const isMessageView = overlayMode === SessionClosableOverlayType.Message; const isOpenGroupView = overlayMode === SessionClosableOverlayType.OpenGroup; const isClosedGroupView = overlayMode === SessionClosableOverlayType.ClosedGroup; let title; let buttonText; let descriptionLong; let subtitle; let placeholder; switch (overlayMode) { case 'message': title = window.i18n('newSession'); buttonText = window.i18n('next'); descriptionLong = window.i18n('usersCanShareTheir...'); subtitle = window.i18n('enterSessionID'); placeholder = window.i18n('pasteSessionIDRecipient'); break; case 'contact': title = window.i18n('addContact'); buttonText = window.i18n('next'); descriptionLong = window.i18n('usersCanShareTheir...'); subtitle = window.i18n('enterSessionID'); placeholder = window.i18n('pasteSessionIDRecipient'); break; case 'open-group': title = window.i18n('addChannel'); buttonText = window.i18n('joinChannel'); descriptionLong = window.i18n('addChannelDescription'); subtitle = window.i18n('enterChannelURL'); placeholder = window.i18n('channelUrlPlaceholder'); break; case 'closed-group': title = window.i18n('newClosedGroup'); buttonText = window.i18n('createClosedGroup'); descriptionLong = window.i18n('createClosedGroupDescription'); subtitle = window.i18n('createClosedGroupNamePrompt'); placeholder = window.i18n('createClosedGroupPlaceholder'); break; default: } const { groupName, selectedMembers, senderKeys } = this.state; const ourSessionID = window.textsecure.storage.user.getNumber(); const contacts = this.getContacts(); const noContactsForClosedGroup = overlayMode === SessionClosableOverlayType.ClosedGroup && contacts.length === 0; return (

{title}

{subtitle}


{isOpenGroupView || isClosedGroupView ? (
onButtonClick(groupName, selectedMembers)} />
) : ( )} {showSpinner && } {isClosedGroupView && ( <>
{noContactsForClosedGroup ? (
{window.i18n('noContactsForGroup')}
) : (
{this.renderMemberList(contacts)}
)}
)}
{descriptionLong}
{isMessageView &&

{window.i18n('or')}

} {isMessageView && ( )} {isAddContactView && ( )} {isAddContactView && ( )} {isClosedGroupView && window.lokiFeatureFlags.enableSenderKeys && (
{ const value = this.state.senderKeys; this.setState({ senderKeys: !value }); }} /> {window.i18n('useSenderKeys')}
)} onButtonClick(groupName, selectedMembers, senderKeys)} />
); } private renderMemberList(members: any) { return members.map((member: ContactType, index: number) => ( { this.handleSelectMember(selectedMember); }} onUnselect={(selectedMember: ContactType) => { this.handleUnselectMember(selectedMember); }} /> )); } private handleSelectMember(member: ContactType) { if (this.state.selectedMembers.includes(member)) { return; } this.setState({ selectedMembers: [...this.state.selectedMembers, member], }); } private handleUnselectMember(member: ContactType) { this.setState({ selectedMembers: this.state.selectedMembers.filter(selectedMember => { return selectedMember.id !== member.id; }), }); } private onGroupNameChanged(event: any) { this.setState({ groupName: event, }); } private onKeyUp(event: any) { if (event.key === 'Escape') { window.removeEventListener('keyup', this.onKeyUp); this.props.onCloseClick(); } } }