WIP: refacotring. confirm modals mostly done. Working on add moderator modal now. Need to toggle via setModal.

pull/1665/head
Warrick Corfe-Tan 4 years ago
parent b082dd9f43
commit ee7afb6ebf

@ -2,52 +2,53 @@ import React from 'react';
import { SessionModal } from '../session/SessionModal'; import { SessionModal } from '../session/SessionModal';
import { SessionButton, SessionButtonColor } from '../session/SessionButton'; import { SessionButton, SessionButtonColor } from '../session/SessionButton';
import { DefaultTheme } from 'styled-components'; import { DefaultTheme, useTheme } from 'styled-components';
import { SessionWrapperModal } from '../session/SessionWrapperModal';
interface Props { interface Props {
groupName: string; groupName: string;
onSubmit: any; onSubmit: () => any;
onClose: any; onClose: any;
theme: DefaultTheme; theme: DefaultTheme;
} }
class AdminLeaveClosedGroupDialogInner extends React.Component<Props> { const AdminLeaveClosedGroupDialogInner = (props: Props) => {
constructor(props: any) {
super(props);
this.closeDialog = this.closeDialog.bind(this); const { groupName, theme, onSubmit, onClose } = props;
this.onClickOK = this.onClickOK.bind(this);
}
public render() { const titleText = `${window.i18n('leaveGroup')} ${groupName}`;
const titleText = `${window.i18n('leaveGroup')} ${this.props.groupName}`; const warningAsAdmin = `${window.i18n('leaveGroupConfirmationAdmin')}`;
const warningAsAdmin = `${window.i18n('leaveGroupConfirmationAdmin')}`; const okText = window.i18n('leaveAndRemoveForEveryone');
const okText = window.i18n('leaveAndRemoveForEveryone'); const cancelText = window.i18n('cancel');
return (
<SessionModal title={titleText} onClose={this.closeDialog} theme={this.props.theme}>
<div className="spacer-lg" />
<p>{warningAsAdmin}</p>
<div className="session-modal__button-group">
<SessionButton
text={okText}
onClick={this.onClickOK}
buttonColor={SessionButtonColor.Danger}
/>
</div>
</SessionModal>
);
}
private onClickOK() { const onClickOK = () => {
this.props.onSubmit(); void onSubmit();
this.closeDialog(); closeDialog();
} }
private closeDialog() { const closeDialog = () => {
this.props.onClose(); onClose();
} }
return (
<SessionWrapperModal title={titleText} onClose={closeDialog} theme={theme}>
<div className="spacer-lg" />
<p>{warningAsAdmin}</p>
<div className="session-modal__button-group">
<SessionButton
text={okText}
onClick={onClickOK}
buttonColor={SessionButtonColor.Danger}
/>
<SessionButton
text={cancelText}
onClick={closeDialog}
/>
</div>
</SessionWrapperModal>
);
} }
export const AdminLeaveClosedGroupDialog = AdminLeaveClosedGroupDialogInner; export const AdminLeaveClosedGroupDialog = AdminLeaveClosedGroupDialogInner;

@ -1,4 +1,4 @@
import React from 'react'; import React, { useEffect, useState } from 'react';
import { SessionButton, SessionButtonColor, SessionButtonType } from '../session/SessionButton'; import { SessionButton, SessionButtonColor, SessionButtonType } from '../session/SessionButton';
import { PubKey } from '../../session/types'; import { PubKey } from '../../session/types';
import { ToastUtils } from '../../session/utils'; import { ToastUtils } from '../../session/utils';
@ -8,6 +8,7 @@ import { SessionSpinner } from '../session/SessionSpinner';
import { Flex } from '../basic/Flex'; import { Flex } from '../basic/Flex';
import { ConversationModel } from '../../models/conversation'; import { ConversationModel } from '../../models/conversation';
import { ApiV2 } from '../../opengroup/opengroupV2'; import { ApiV2 } from '../../opengroup/opengroupV2';
import { processDecrypted } from '../../receiver/dataMessage';
interface Props { interface Props {
convo: ConversationModel; convo: ConversationModel;
onClose: any; onClose: any;
@ -20,33 +21,144 @@ interface State {
firstLoading: boolean; firstLoading: boolean;
} }
export class AddModeratorsDialog extends React.Component<Props, State> { // export class AddModeratorsDialog extends React.Component<Props, State> {
private channelAPI: any; // private channelAPI: any;
constructor(props: Props) { // constructor(props: Props) {
super(props); // super(props);
this.addAsModerator = this.addAsModerator.bind(this); // this.addAsModerator = this.addAsModerator.bind(this);
this.onPubkeyBoxChanges = this.onPubkeyBoxChanges.bind(this); // this.onPubkeyBoxChanges = this.onPubkeyBoxChanges.bind(this);
this.state = { // this.state = {
inputBoxValue: '', // inputBoxValue: '',
addingInProgress: false, // addingInProgress: false,
firstLoading: true, // firstLoading: true,
}; // };
} // }
public async componentDidMount() { // public async componentDidMount() {
if (this.props.convo.isOpenGroupV1()) { // if (this.props.convo.isOpenGroupV1()) {
this.channelAPI = await this.props.convo.getPublicSendData(); // this.channelAPI = await this.props.convo.getPublicSendData();
// }
// this.setState({ firstLoading: false });
// }
// public async addAsModerator() {
// // if we don't have valid data entered by the user
// const pubkey = PubKey.from(this.state.inputBoxValue);
// if (!pubkey) {
// window.log.info('invalid pubkey for adding as moderator:', this.state.inputBoxValue);
// ToastUtils.pushInvalidPubKey();
// return;
// }
// window.log.info(`asked to add moderator: ${pubkey.key}`);
// try {
// this.setState({
// addingInProgress: true,
// });
// let isAdded: any;
// if (this.props.convo.isOpenGroupV1()) {
// isAdded = await this.channelAPI.serverAPI.addModerator([pubkey.key]);
// } else {
// // this is a v2 opengroup
// const roomInfos = this.props.convo.toOpenGroupV2();
// isAdded = await ApiV2.addModerator(pubkey, roomInfos);
// }
// if (!isAdded) {
// window.log.warn('failed to add moderators:', isAdded);
// ToastUtils.pushUserNeedsToHaveJoined();
// } else {
// window.log.info(`${pubkey.key} added as moderator...`);
// ToastUtils.pushUserAddedToModerators();
// // clear input box
// this.setState({
// inputBoxValue: '',
// });
// }
// } catch (e) {
// window.log.error('Got error while adding moderator:', e);
// } finally {
// this.setState({
// addingInProgress: false,
// });
// }
// }
// public render() {
// const { i18n } = window;
// const { addingInProgress, inputBoxValue, firstLoading } = this.state;
// const chatName = this.props.convo.get('name');
// const title = `${i18n('addModerators')}: ${chatName}`;
// const renderContent = !firstLoading;
// return (
// <SessionModal title={title} onClose={() => this.props.onClose()} theme={this.props.theme}>
// <Flex container={true} flexDirection="column" alignItems="center">
// {renderContent && (
// <>
// <p>Add Moderator:</p>
// <input
// type="text"
// className="module-main-header__search__input"
// placeholder={i18n('enterSessionID')}
// dir="auto"
// onChange={this.onPubkeyBoxChanges}
// disabled={addingInProgress}
// value={inputBoxValue}
// />
// <SessionButton
// buttonType={SessionButtonType.Brand}
// buttonColor={SessionButtonColor.Primary}
// onClick={this.addAsModerator}
// text={i18n('add')}
// disabled={addingInProgress}
// />
// </>
// )}
// <SessionSpinner loading={addingInProgress || firstLoading} />
// </Flex>
// </SessionModal>
// );
// }
// private onPubkeyBoxChanges(e: any) {
// const val = e.target.value;
// this.setState({ inputBoxValue: val });
// }
// }
export const AddModeratorsDialog = (props: any) => {
const { convo, onClose, theme } = props;
const [inputBoxValue, setInputBoxValue] = useState('');
const [addingInProgress, setAddingInProgress] = useState(false);
const [firstLoading, setFirstLoading] = useState(true);
let channelAPI: any;
useEffect(() => {
async function getPublicSendData {
if (props.convo.isOpenGroupV1()) {
channelAPI = await convo.getPublicSendData();
}
setFirstLoading(false);
} }
}, [])
this.setState({ firstLoading: false });
}
public async addAsModerator() { const addAsModerator = async () => {
// if we don't have valid data entered by the user // if we don't have valid data entered by the user
const pubkey = PubKey.from(this.state.inputBoxValue); const pubkey = PubKey.from(inputBoxValue);
if (!pubkey) { if (!pubkey) {
window.log.info('invalid pubkey for adding as moderator:', this.state.inputBoxValue); window.log.info('invalid pubkey for adding as moderator:', this.state.inputBoxValue);
ToastUtils.pushInvalidPubKey(); ToastUtils.pushInvalidPubKey();
@ -56,15 +168,13 @@ export class AddModeratorsDialog extends React.Component<Props, State> {
window.log.info(`asked to add moderator: ${pubkey.key}`); window.log.info(`asked to add moderator: ${pubkey.key}`);
try { try {
this.setState({ setAddingInProgress(true);
addingInProgress: true,
});
let isAdded: any; let isAdded: any;
if (this.props.convo.isOpenGroupV1()) { if (convo.isOpenGroupV1()) {
isAdded = await this.channelAPI.serverAPI.addModerator([pubkey.key]); isAdded = await channelAPI.serverAPI.addModerator([pubkey.key]);
} else { } else {
// this is a v2 opengroup // this is a v2 opengroup
const roomInfos = this.props.convo.toOpenGroupV2(); const roomInfos = props.convo.toOpenGroupV2();
isAdded = await ApiV2.addModerator(pubkey, roomInfos); isAdded = await ApiV2.addModerator(pubkey, roomInfos);
} }
if (!isAdded) { if (!isAdded) {
@ -76,60 +186,57 @@ export class AddModeratorsDialog extends React.Component<Props, State> {
ToastUtils.pushUserAddedToModerators(); ToastUtils.pushUserAddedToModerators();
// clear input box // clear input box
this.setState({ setInputBoxValue('');
inputBoxValue: '',
});
} }
} catch (e) { } catch (e) {
window.log.error('Got error while adding moderator:', e); window.log.error('Got error while adding moderator:', e);
} finally { } finally {
this.setState({ setAddingInProgress(false);
addingInProgress: false,
});
} }
}
public render() {
const { i18n } = window;
const { addingInProgress, inputBoxValue, firstLoading } = this.state;
const chatName = this.props.convo.get('name');
const title = `${i18n('addModerators')}: ${chatName}`;
const renderContent = !firstLoading;
return (
<SessionModal title={title} onClose={() => this.props.onClose()} theme={this.props.theme}>
<Flex container={true} flexDirection="column" alignItems="center">
{renderContent && (
<>
<p>Add Moderator:</p>
<input
type="text"
className="module-main-header__search__input"
placeholder={i18n('enterSessionID')}
dir="auto"
onChange={this.onPubkeyBoxChanges}
disabled={addingInProgress}
value={inputBoxValue}
/>
<SessionButton
buttonType={SessionButtonType.Brand}
buttonColor={SessionButtonColor.Primary}
onClick={this.addAsModerator}
text={i18n('add')}
disabled={addingInProgress}
/>
</>
)}
<SessionSpinner loading={addingInProgress || firstLoading} />
</Flex>
</SessionModal>
);
} }
private onPubkeyBoxChanges(e: any) { const { i18n } = window;
// const { addingInProgress, inputBoxValue, firstLoading } = this.state;
const chatName = props.convo.get('name');
const title = `${i18n('addModerators')}: ${chatName}`;
const renderContent = !firstLoading;
const onPubkeyBoxChanges = (e: any) => {
const val = e.target.value; const val = e.target.value;
this.setState({ inputBoxValue: val }); setInputBoxValue(val);
} }
return (
<SessionModal title={title} onClose={() => onClose()} theme={theme}>
<Flex container={true} flexDirection="column" alignItems="center">
{renderContent && (
<>
<p>Add Moderator:</p>
<input
type="text"
className="module-main-header__search__input"
placeholder={i18n('enterSessionID')}
dir="auto"
onChange={onPubkeyBoxChanges}
disabled={addingInProgress}
value={inputBoxValue}
/>
<SessionButton
buttonType={SessionButtonType.Brand}
buttonColor={SessionButtonColor.Primary}
onClick={addAsModerator}
text={i18n('add')}
disabled={addingInProgress}
/>
</>
)}
<SessionSpinner loading={addingInProgress || firstLoading} />
</Flex>
</SessionModal>
);
} }

@ -1,16 +1,13 @@
import React from 'react'; import React from 'react';
import { SessionIconButton, SessionIconSize, SessionIconType } from './icon'; import { SessionIconButton, SessionIconSize, SessionIconType } from './icon';
import { SessionToggle } from './SessionToggle';
import { SessionIdEditable } from './SessionIdEditable'; import { SessionIdEditable } from './SessionIdEditable';
import { UserSearchDropdown } from './UserSearchDropdown'; import { UserSearchDropdown } from './UserSearchDropdown';
import { ContactType, SessionMemberListItem } from './SessionMemberListItem'; import { ContactType, SessionMemberListItem } from './SessionMemberListItem';
import { ConversationType } from '../../state/ducks/conversations'; import { ConversationType } from '../../state/ducks/conversations';
import { SessionButton, SessionButtonColor, SessionButtonType } from './SessionButton'; import { SessionButton, SessionButtonColor, SessionButtonType } from './SessionButton';
import { SessionSpinner } from './SessionSpinner'; import { SessionSpinner } from './SessionSpinner';
import { PillDivider } from './PillDivider';
import { DefaultTheme } from 'styled-components'; import { DefaultTheme } from 'styled-components';
import { UserUtils } from '../../session/utils';
import { ConversationTypeEnum } from '../../models/conversation'; import { ConversationTypeEnum } from '../../models/conversation';
import { SessionJoinableRooms } from './SessionJoinableDefaultRooms'; import { SessionJoinableRooms } from './SessionJoinableDefaultRooms';

@ -5,15 +5,18 @@ import { SessionHtmlRenderer } from './SessionHTMLRenderer';
import { SessionIcon, SessionIconSize, SessionIconType } from './icon'; import { SessionIcon, SessionIconSize, SessionIconType } from './icon';
import { DefaultTheme, useTheme, withTheme } from 'styled-components'; import { DefaultTheme, useTheme, withTheme } from 'styled-components';
import { SessionWrapperModal } from './SessionWrapperModal'; import { SessionWrapperModal } from './SessionWrapperModal';
import { useDispatch } from 'react-redux';
import { updateConfirmModal } from '../../state/ducks/modalDialog';
import { update } from 'lodash';
type Props = { export interface SessionConfirmDialogProps {
message?: string; message?: string;
messageSub?: string; messageSub?: string;
title?: string; title?: string;
onOk?: any; onOk?: any;
onClose?: any; onClose?: any;
onClickOk?: any; onClickOk?: () => any;
onClickClose?: any; onClickClose?: () => any;
okText?: string; okText?: string;
cancelText?: string; cancelText?: string;
hideCancel?: boolean; hideCancel?: boolean;
@ -22,9 +25,11 @@ type Props = {
sessionIcon?: SessionIconType; sessionIcon?: SessionIconType;
iconSize?: SessionIconSize; iconSize?: SessionIconSize;
theme?: DefaultTheme; theme?: DefaultTheme;
closeAfterClickOk?: boolean;
shouldShowConfirm?: () => boolean | undefined;
}; };
const SessionConfirmInner = (props: Props) => { const SessionConfirmInner = (props: SessionConfirmDialogProps) => {
const { const {
title = '', title = '',
message = '', message = '',
@ -33,9 +38,12 @@ const SessionConfirmInner = (props: Props) => {
closeTheme = SessionButtonColor.Primary, closeTheme = SessionButtonColor.Primary,
onClickOk, onClickOk,
onClickClose, onClickClose,
closeAfterClickOk = true,
hideCancel = false, hideCancel = false,
sessionIcon, sessionIcon,
iconSize, iconSize,
shouldShowConfirm,
// updateConfirmModal
} = props; } = props;
const okText = props.okText || window.i18n('ok'); const okText = props.okText || window.i18n('ok');
@ -46,8 +54,43 @@ const SessionConfirmInner = (props: Props) => {
const messageSubText = messageSub ? 'session-confirm-main-message' : 'subtle'; const messageSubText = messageSub ? 'session-confirm-main-message' : 'subtle';
return ( /**
* Calls close function after the ok button is clicked. If no close method specified, closes the modal
*/
const onClickOkWithClose = () => {
if (onClickOk) {
onClickOk();
}
if (onClickClose) {
onClickClose();
}
}
const onClickOkHandler = () => {
if (onClickOk) {
onClickOk();
}
window.inboxStore?.dispatch(updateConfirmModal(null));
}
if (shouldShowConfirm && !shouldShowConfirm()) {
return null;
}
const onClickCancelHandler = () => {
if (onClickClose) {
onClickClose();
}
window.inboxStore?.dispatch(updateConfirmModal(null));
}
return (
<SessionWrapperModal <SessionWrapperModal
title={title} title={title}
onClose={onClickClose} onClose={onClickClose}
@ -75,10 +118,12 @@ const SessionConfirmInner = (props: Props) => {
</div> </div>
<div className="session-modal__button-group"> <div className="session-modal__button-group">
<SessionButton text={okText} buttonColor={okTheme} onClick={onClickOk} /> {/* <SessionButton text={okText} buttonColor={okTheme} onClick={closeAfterClickOk ? onClickOk : onClickOkWithClose} /> */}
<SessionButton text={okText} buttonColor={okTheme} onClick={onClickOkHandler} />
{!hideCancel && ( {!hideCancel && (
<SessionButton text={cancelText} buttonColor={closeTheme} onClick={onClickClose} /> // <SessionButton text={cancelText} buttonColor={closeTheme} onClick={onClickClose} />
<SessionButton text={cancelText} buttonColor={closeTheme} onClick={onClickCancelHandler} />
)} )}
</div> </div>

@ -1,5 +1,6 @@
import React from 'react'; import React from 'react';
import classNames from 'classnames'; import classNames from 'classnames';
import { updateConfirmModal } from '../../state/ducks/modalDialog';
interface Props { interface Props {
active: boolean; active: boolean;
@ -14,6 +15,8 @@ interface Props {
// okTheme: 'danger', // okTheme: 'danger',
// } // }
confirmationDialogParams?: any | undefined; confirmationDialogParams?: any | undefined;
updateConfirmModal?: any;
} }
interface State { interface State {
@ -62,15 +65,25 @@ export class SessionToggle extends React.PureComponent<Props, State> {
if ( if (
this.props.confirmationDialogParams && this.props.confirmationDialogParams &&
this.props.updateConfirmModal &&
this.props.confirmationDialogParams.shouldShowConfirm() this.props.confirmationDialogParams.shouldShowConfirm()
) { ) {
// If item needs a confirmation dialog to turn ON, render it // If item needs a confirmation dialog to turn ON, render it
window.confirmationDialog({ const closeConfirmModal = () => {
resolve: () => { this.props.updateConfirmModal(null);
}
this.props.updateConfirmModal({
onClickOk: () => {
stateManager(event); stateManager(event);
closeConfirmModal();
},
onClickClose: () => {
this.props.updateConfirmModal(null);
}, },
...this.props.confirmationDialogParams, ...this.props.confirmationDialogParams,
}); updateConfirmModal,
})
return; return;
} }

@ -33,6 +33,7 @@ import autoBind from 'auto-bind';
import { getDecryptedMediaUrl } from '../../../session/crypto/DecryptedAttachmentsManager'; import { getDecryptedMediaUrl } from '../../../session/crypto/DecryptedAttachmentsManager';
import { deleteOpenGroupMessages } from '../../../interactions/conversation'; import { deleteOpenGroupMessages } from '../../../interactions/conversation';
import { ConversationTypeEnum } from '../../../models/conversation'; import { ConversationTypeEnum } from '../../../models/conversation';
import { SessionButtonColor } from '../SessionButton';
@ -367,7 +368,6 @@ export class SessionConversation extends React.Component<Props, State> {
onCloseOverlay: () => { onCloseOverlay: () => {
this.setState({ selectedMessages: [] }); this.setState({ selectedMessages: [] });
}, },
onDeleteContact: conversation.deleteContact,
onGoBack: () => { onGoBack: () => {
this.setState({ this.setState({
@ -454,8 +454,8 @@ export class SessionConversation extends React.Component<Props, State> {
const isAdmin = conversation.isMediumGroup() const isAdmin = conversation.isMediumGroup()
? true ? true
: conversation.isPublic() : conversation.isPublic()
? conversation.isAdmin(ourPrimary) ? conversation.isAdmin(ourPrimary)
: false; : false;
return { return {
id: conversation.id, id: conversation.id,
@ -510,7 +510,6 @@ export class SessionConversation extends React.Component<Props, State> {
onInviteContacts: () => { onInviteContacts: () => {
window.Whisper.events.trigger('inviteContacts', conversation); window.Whisper.events.trigger('inviteContacts', conversation);
}, },
onDeleteContact: conversation.deleteContact,
onLeaveGroup: () => { onLeaveGroup: () => {
window.Whisper.events.trigger('leaveClosedGroup', conversation); window.Whisper.events.trigger('leaveClosedGroup', conversation);
}, },
@ -664,14 +663,22 @@ export class SessionConversation extends React.Component<Props, State> {
} }
const okText = window.i18n(isServerDeletable ? 'deleteForEveryone' : 'delete'); const okText = window.i18n(isServerDeletable ? 'deleteForEveryone' : 'delete');
if (askUserForConfirmation) { if (askUserForConfirmation) {
window.confirmationDialog({ const onClickClose = () => {
this.props.actions.updateConfirmModal(null);
}
this.props.actions.updateConfirmModal({
title, title,
message: warningMessage, message: warningMessage,
okText, okText,
okTheme: 'danger', okTheme: SessionButtonColor.Danger,
resolve: doDelete, onClickOk: doDelete,
}); onClickClose,
closeAfterClick: true
})
} else { } else {
void doDelete(); void doDelete();
} }
@ -687,7 +694,7 @@ export class SessionConversation extends React.Component<Props, State> {
public selectMessage(messageId: string) { public selectMessage(messageId: string) {
const selectedMessages = this.state.selectedMessages.includes(messageId) const selectedMessages = this.state.selectedMessages.includes(messageId)
? // Add to array if not selected. Else remove. ? // Add to array if not selected. Else remove.
this.state.selectedMessages.filter(id => id !== messageId) this.state.selectedMessages.filter(id => id !== messageId)
: [...this.state.selectedMessages, messageId]; : [...this.state.selectedMessages, messageId];
this.setState({ selectedMessages }); this.setState({ selectedMessages });

@ -29,6 +29,7 @@ export type PropsConversationHeaderMenu = {
timerOptions: Array<TimerOption>; timerOptions: Array<TimerOption>;
isPrivate: boolean; isPrivate: boolean;
isBlocked: boolean; isBlocked: boolean;
theme: any;
hasNickname?: boolean; hasNickname?: boolean;
onDeleteMessages?: () => void; onDeleteMessages?: () => void;
@ -62,6 +63,7 @@ export const ConversationHeaderMenu = (props: PropsConversationHeaderMenu) => {
isPrivate, isPrivate,
left, left,
hasNickname, hasNickname,
theme,
onClearNickname, onClearNickname,
onChangeNickname, onChangeNickname,
@ -108,7 +110,7 @@ export const ConversationHeaderMenu = (props: PropsConversationHeaderMenu) => {
{getAddModeratorsMenuItem(isAdmin, isKickedFromGroup, onAddModerators, window.i18n)} {getAddModeratorsMenuItem(isAdmin, isKickedFromGroup, onAddModerators, window.i18n)}
{getRemoveModeratorsMenuItem(isAdmin, isKickedFromGroup, onRemoveModerators, window.i18n)} {getRemoveModeratorsMenuItem(isAdmin, isKickedFromGroup, onRemoveModerators, window.i18n)}
{getUpdateGroupNameMenuItem(isAdmin, isKickedFromGroup, left, onUpdateGroupName, window.i18n)} {getUpdateGroupNameMenuItem(isAdmin, isKickedFromGroup, left, onUpdateGroupName, window.i18n)}
{getLeaveGroupMenuItem(isKickedFromGroup, left, isGroup, isPublic, onLeaveGroup, window.i18n, id)} {getLeaveGroupMenuItem(isKickedFromGroup, left, isGroup, isPublic, onLeaveGroup, window.i18n, id, setModal, theme)}
{/* TODO: add delete group */} {/* TODO: add delete group */}
{getInviteContactMenuItem(isGroup, isPublic, onInviteContacts, window.i18n)} {getInviteContactMenuItem(isGroup, isPublic, onInviteContacts, window.i18n)}
{getDeleteContactMenuItem( {getDeleteContactMenuItem(
@ -118,7 +120,8 @@ export const ConversationHeaderMenu = (props: PropsConversationHeaderMenu) => {
left, left,
isKickedFromGroup, isKickedFromGroup,
onDeleteContact, onDeleteContact,
window.i18n window.i18n,
id
)} )}
</Menu> </Menu>
</> </>

@ -24,6 +24,7 @@ export type PropsContextConversationItem = {
hasNickname?: boolean; hasNickname?: boolean;
isKickedFromGroup?: boolean; isKickedFromGroup?: boolean;
left?: boolean; left?: boolean;
theme?: any
onDeleteMessages?: () => void; onDeleteMessages?: () => void;
onDeleteContact?: () => void; onDeleteContact?: () => void;
@ -58,6 +59,7 @@ export const ConversationListItemContextMenu = (props: PropsContextConversationI
onInviteContacts, onInviteContacts,
onLeaveGroup, onLeaveGroup,
onChangeNickname, onChangeNickname,
theme
} = props; } = props;
const isGroup = type === 'group'; const isGroup = type === 'group';
@ -91,9 +93,10 @@ export const ConversationListItemContextMenu = (props: PropsContextConversationI
left, left,
isKickedFromGroup, isKickedFromGroup,
onDeleteContact, onDeleteContact,
window.i18n window.i18n,
id
)} )}
{getLeaveGroupMenuItem(isKickedFromGroup, left, isGroup, isPublic, onLeaveGroup, window.i18n, id)} {getLeaveGroupMenuItem(isKickedFromGroup, left, isGroup, isPublic, onLeaveGroup, window.i18n, id, setModal, theme)}
</Menu> </Menu>
</> </>
); );

@ -3,11 +3,13 @@ import { LocalizerType } from '../../../types/Util';
import { TimerOption } from '../../conversation/ConversationHeader'; import { TimerOption } from '../../conversation/ConversationHeader';
import { Item, Submenu } from 'react-contexify'; import { Item, Submenu } from 'react-contexify';
import { SessionNicknameDialog } from '../SessionNicknameDialog'; import { SessionNicknameDialog } from '../SessionNicknameDialog';
import { useDispatch } from 'react-redux'; import { useDispatch, useSelector } from 'react-redux';
import { updateConfirmModal } from '../../../state/ducks/modalDialog'; import { updateConfirmModal } from '../../../state/ducks/modalDialog';
import { ConversationController } from '../../../session/conversations'; import { ConversationController } from '../../../session/conversations';
import { useTheme } from 'styled-components'; import { useTheme } from 'styled-components';
import { UserUtils } from '../../../session/utils'; import { UserUtils } from '../../../session/utils';
import { AdminLeaveClosedGroupDialog } from '../../conversation/AdminLeaveClosedGroupDialog';
import { getTheme } from '../../../state/selectors/theme';
function showTimerOptions( function showTimerOptions(
isPublic: boolean, isPublic: boolean,
@ -100,7 +102,8 @@ export function getDeleteContactMenuItem(
isLeft: boolean | undefined, isLeft: boolean | undefined,
isKickedFromGroup: boolean | undefined, isKickedFromGroup: boolean | undefined,
action: any, action: any,
i18n: LocalizerType i18n: LocalizerType,
id: string
): JSX.Element | null { ): JSX.Element | null {
if ( if (
showDeleteContact( showDeleteContact(
@ -111,10 +114,31 @@ export function getDeleteContactMenuItem(
Boolean(isKickedFromGroup) Boolean(isKickedFromGroup)
) )
) { ) {
let menuItemText: string;
if (isPublic) { if (isPublic) {
return <Item onClick={action}>{i18n('leaveGroup')}</Item>; menuItemText = i18n('leaveGroup');
} else {
menuItemText = i18n('delete');
}
const dispatch = useDispatch();
const onClickClose = () => {
dispatch(updateConfirmModal(null));
} }
return <Item onClick={action}>{i18n('delete')}</Item>;
const showConfirmationModal = () => {
dispatch(updateConfirmModal({
title: menuItemText,
message: isGroup ? i18n('leaveGroupConfirmation'): i18n('deleteContactConfirmation'),
onClickClose,
onClickOk: () => {
void ConversationController.getInstance().deleteContact(id);
onClickClose();
}
}))
}
return <Item onClick={showConfirmationModal}>{menuItemText}</Item>;
} }
return null; return null;
} }
@ -126,7 +150,9 @@ export function getLeaveGroupMenuItem(
isPublic: boolean | undefined, isPublic: boolean | undefined,
action: any, action: any,
i18n: LocalizerType, i18n: LocalizerType,
id: string id: string,
setModal: any,
theme: any
): JSX.Element | null { ): JSX.Element | null {
if ( if (
showLeaveGroup(Boolean(isKickedFromGroup), Boolean(left), Boolean(isGroup), Boolean(isPublic)) showLeaveGroup(Boolean(isKickedFromGroup), Boolean(left), Boolean(isGroup), Boolean(isPublic))
@ -160,6 +186,15 @@ export function getLeaveGroupMenuItem(
}, },
onClickClose onClickClose
})); }));
} else {
setModal(
<AdminLeaveClosedGroupDialog
groupName={conversation.getName()}
onSubmit={conversation.leaveClosedGroup}
onClose={() => {setModal(null)}}
theme={theme}
></AdminLeaveClosedGroupDialog>
)
} }
} }
@ -322,19 +357,13 @@ export function getChangeNicknameMenuItem(
setModal(null); setModal(null);
} }
// const onClickOk = () => {
// console.log("@@ onclickok clicked");
// }
const onClickCustom = () => { const onClickCustom = () => {
setModal(<SessionNicknameDialog onClickClose={clearModal} conversationId={conversationId}></SessionNicknameDialog>); setModal(<SessionNicknameDialog onClickClose={clearModal} conversationId={conversationId}></SessionNicknameDialog>);
// setModal(null);
} }
return ( return (
<> <>
<Item onClick={onClickCustom}>{i18n('changeNickname')}</Item> <Item onClick={onClickCustom}>{i18n('changeNickname')}</Item>
{/* <Item onClick={action}>{i18n('changeNickname')}</Item> */}
</> </>
); );
} }

@ -7,6 +7,7 @@ import { SessionToggle } from '../SessionToggle';
import { SessionButton } from '../SessionButton'; import { SessionButton } from '../SessionButton';
import { SessionSettingType } from './SessionSettings'; import { SessionSettingType } from './SessionSettings';
import { SessionRadioGroup } from '../SessionRadioGroup'; import { SessionRadioGroup } from '../SessionRadioGroup';
import { SessionConfirmDialogProps } from '../SessionConfirm';
interface Props { interface Props {
title?: string; title?: string;
@ -17,7 +18,10 @@ interface Props {
onClick?: any; onClick?: any;
onSliderChange?: any; onSliderChange?: any;
content: any; content: any;
confirmationDialogParams?: any; confirmationDialogParams?: SessionConfirmDialogProps;
// for updating modal in redux
updateConfirmModal?: any
} }
interface State { interface State {
@ -61,6 +65,7 @@ export class SessionSettingListItem extends React.Component<Props, State> {
active={Boolean(value)} active={Boolean(value)}
onClick={this.handleClick} onClick={this.handleClick}
confirmationDialogParams={this.props.confirmationDialogParams} confirmationDialogParams={this.props.confirmationDialogParams}
updateConfirmModal={this.props.updateConfirmModal}
/> />
</div> </div>
)} )}

@ -12,6 +12,8 @@ import { getConversationLookup, getConversations } from '../../../state/selector
import { connect } from 'react-redux'; import { connect } from 'react-redux';
import { getPasswordHash } from '../../../../ts/data/data'; import { getPasswordHash } from '../../../../ts/data/data';
import { PasswordAction, SessionPasswordModal } from '../SessionPasswordModal'; import { PasswordAction, SessionPasswordModal } from '../SessionPasswordModal';
import { SessionConfirmDialogProps } from '../SessionConfirm';
import { mapDispatchToProps } from '../../../state/actions';
export enum SessionSettingCategory { export enum SessionSettingCategory {
Appearance = 'appearance', Appearance = 'appearance',
@ -34,6 +36,7 @@ export interface SettingsViewProps {
// pass the conversation as props, so our render is called everytime they change. // pass the conversation as props, so our render is called everytime they change.
// we have to do this to make the list refresh on unblock() // we have to do this to make the list refresh on unblock()
conversations?: ConversationLookupType; conversations?: ConversationLookupType;
updateConfirmModal?: any;
} }
interface State { interface State {
@ -44,6 +47,10 @@ interface State {
modal: JSX.Element | null; modal: JSX.Element | null;
} }
interface ConfirmationDialogParams extends SessionConfirmDialogProps {
shouldShowConfirm: () => boolean | undefined;
}
interface LocalSettingType { interface LocalSettingType {
category: SessionSettingCategory; category: SessionSettingCategory;
description: string | undefined; description: string | undefined;
@ -56,7 +63,7 @@ interface LocalSettingType {
type: SessionSettingType | undefined; type: SessionSettingType | undefined;
setFn: any; setFn: any;
onClick: any; onClick: any;
confirmationDialogParams: any | undefined; confirmationDialogParams: ConfirmationDialogParams | undefined;
} }
class SettingsViewInner extends React.Component<SettingsViewProps, State> { class SettingsViewInner extends React.Component<SettingsViewProps, State> {
@ -147,6 +154,7 @@ class SettingsViewInner extends React.Component<SettingsViewProps, State> {
onSliderChange={sliderFn} onSliderChange={sliderFn}
content={content} content={content}
confirmationDialogParams={setting.confirmationDialogParams} confirmationDialogParams={setting.confirmationDialogParams}
updateConfirmModal={this.props.updateConfirmModal}
/> />
)} )}
</div> </div>
@ -345,7 +353,7 @@ class SettingsViewInner extends React.Component<SettingsViewProps, State> {
shouldShowConfirm: () => !window.getSettingValue('link-preview-setting'), shouldShowConfirm: () => !window.getSettingValue('link-preview-setting'),
title: window.i18n('linkPreviewsTitle'), title: window.i18n('linkPreviewsTitle'),
message: window.i18n('linkPreviewsConfirmMessage'), message: window.i18n('linkPreviewsConfirmMessage'),
okTheme: 'danger', okTheme: SessionButtonColor.Danger,
}, },
}, },
{ {
@ -614,11 +622,13 @@ class SettingsViewInner extends React.Component<SettingsViewProps, State> {
} }
} }
const mapStateToProps = (state: StateType) => { const mapStateToProps = (state: StateType) => {
return { return {
conversations: getConversationLookup(state), conversations: getConversationLookup(state),
}; };
}; };
const smart = connect(mapStateToProps);
const smart = connect(mapStateToProps, mapDispatchToProps);
export const SmartSettingsView = smart(SettingsViewInner); export const SmartSettingsView = smart(SettingsViewInner);

@ -10,6 +10,9 @@ import { PubKey } from '../session/types';
import { ToastUtils } from '../session/utils'; import { ToastUtils } from '../session/utils';
import { openConversationExternal } from '../state/ducks/conversations'; import { openConversationExternal } from '../state/ducks/conversations';
import { useDispatch } from 'react-redux';
import { updateConfirmModal } from '../state/ducks/modalDialog';
export function banUser(userToBan: string, conversation?: ConversationModel) { export function banUser(userToBan: string, conversation?: ConversationModel) {
let pubKeyToBan: PubKey; let pubKeyToBan: PubKey;
try { try {
@ -19,37 +22,46 @@ export function banUser(userToBan: string, conversation?: ConversationModel) {
ToastUtils.pushUserBanFailure(); ToastUtils.pushUserBanFailure();
return; return;
} }
window.confirmationDialog({
title: window.i18n('banUser'), const dispatch = useDispatch();
message: window.i18n('banUserConfirm'), const onClickClose = () => {
resolve: async () => { dispatch(updateConfirmModal(null))
if (!conversation) { };
window.log.info('cannot ban user, the corresponding conversation was not found.');
return; // const confirmationModalProps = {
} // title: window.i18n('banUser'),
let success = false; // message: window.i18n('banUserConfirm'),
if (isOpenGroupV2(conversation.id)) { // onClickClose,
const roomInfos = await getV2OpenGroupRoom(conversation.id); // // onClickOk: async () => {
if (!roomInfos) { // // if (!conversation) {
window.log.warn('banUser room not found'); // // window.log.info('cannot ban user, the corresponding conversation was not found.');
} else { // // return;
success = await ApiV2.banUser(pubKeyToBan, _.pick(roomInfos, 'serverUrl', 'roomId')); // // }
} // // let success = false;
} else { // // if (isOpenGroupV2(conversation.id)) {
const channelAPI = await conversation.getPublicSendData(); // // const roomInfos = await getV2OpenGroupRoom(conversation.id);
if (!channelAPI) { // // if (!roomInfos) {
window.log.info('cannot ban user, the corresponding channelAPI was not found.'); // // window.log.warn('banUser room not found');
return; // // } else {
} // // success = await ApiV2.banUser(pubKeyToBan, _.pick(roomInfos, 'serverUrl', 'roomId'));
success = await channelAPI.banUser(userToBan); // // }
} // // } else {
if (success) { // // const channelAPI = await conversation.getPublicSendData();
ToastUtils.pushUserBanSuccess(); // // if (!channelAPI) {
} else { // // window.log.info('cannot ban user, the corresponding channelAPI was not found.');
ToastUtils.pushUserBanFailure(); // // return;
} // // }
}, // // success = await channelAPI.banUser(userToBan);
}); // // }
// // if (success) {
// // ToastUtils.pushUserBanSuccess();
// // } else {
// // ToastUtils.pushUserBanFailure();
// // }
// // },
// }
// dispatch(updateConfirmModal(confirmationModalProps));
} }
/** /**
@ -70,31 +82,65 @@ export function unbanUser(userToUnBan: string, conversation?: ConversationModel)
ToastUtils.pushUserBanFailure(); ToastUtils.pushUserBanFailure();
return; return;
} }
window.confirmationDialog({
title: window.i18n('unbanUser'),
message: window.i18n('unbanUserConfirm'), const dispatch = useDispatch();
resolve: async () => { const onClickClose = () => dispatch(updateConfirmModal(null));
if (!conversation) {
// double check here. the convo might have been removed since the dialog was opened const onClickOk = async () => {
window.log.info('cannot unban user, the corresponding conversation was not found.'); if (!conversation) {
return; // double check here. the convo might have been removed since the dialog was opened
} window.log.info('cannot unban user, the corresponding conversation was not found.');
let success = false; return;
if (isOpenGroupV2(conversation.id)) { }
const roomInfos = await getV2OpenGroupRoom(conversation.id); let success = false;
if (!roomInfos) { if (isOpenGroupV2(conversation.id)) {
window.log.warn('unbanUser room not found'); const roomInfos = await getV2OpenGroupRoom(conversation.id);
} else { if (!roomInfos) {
success = await ApiV2.unbanUser(pubKeyToUnban, _.pick(roomInfos, 'serverUrl', 'roomId')); window.log.warn('unbanUser room not found');
}
}
if (success) {
ToastUtils.pushUserUnbanSuccess();
} else { } else {
ToastUtils.pushUserUnbanFailure(); success = await ApiV2.unbanUser(pubKeyToUnban, _.pick(roomInfos, 'serverUrl', 'roomId'));
} }
}, }
}); if (success) {
ToastUtils.pushUserUnbanSuccess();
} else {
ToastUtils.pushUserUnbanFailure();
}
}
dispatch(updateConfirmModal({
title: window.i18n('unbanUser'),
message: window.i18n('unbanUserConfirm'),
onClickOk,
onClickClose,
}));
// window.confirmationDialog({
// title: window.i18n('unbanUser'),
// message: window.i18n('unbanUserConfirm'),
// resolve: async () => {
// if (!conversation) {
// // double check here. the convo might have been removed since the dialog was opened
// window.log.info('cannot unban user, the corresponding conversation was not found.');
// return;
// }
// let success = false;
// if (isOpenGroupV2(conversation.id)) {
// const roomInfos = await getV2OpenGroupRoom(conversation.id);
// if (!roomInfos) {
// window.log.warn('unbanUser room not found');
// } else {
// success = await ApiV2.unbanUser(pubKeyToUnban, _.pick(roomInfos, 'serverUrl', 'roomId'));
// }
// }
// if (success) {
// ToastUtils.pushUserUnbanSuccess();
// } else {
// ToastUtils.pushUserUnbanFailure();
// }
// },
// });
} }
export function copyBodyToClipboard(body?: string) { export function copyBodyToClipboard(body?: string) {
@ -242,11 +288,27 @@ async function acceptOpenGroupInvitationV1(serverAddress: string) {
} }
const acceptOpenGroupInvitationV2 = (completeUrl: string, roomName?: string) => { const acceptOpenGroupInvitationV2 = (completeUrl: string, roomName?: string) => {
window.confirmationDialog({
const dispatch = useDispatch();
const onClickClose = () => {
dispatch(updateConfirmModal(null))
};
dispatch(updateConfirmModal({
title: window.i18n('joinOpenGroupAfterInvitationConfirmationTitle', roomName), title: window.i18n('joinOpenGroupAfterInvitationConfirmationTitle', roomName),
message: window.i18n('joinOpenGroupAfterInvitationConfirmationDesc', roomName), message: window.i18n('joinOpenGroupAfterInvitationConfirmationDesc', roomName),
resolve: () => joinOpenGroupV2WithUIEvents(completeUrl, true), onClickOk: () => joinOpenGroupV2WithUIEvents(completeUrl, true),
}); onClickClose
}))
// window.confirmationDialog({
// title: window.i18n('joinOpenGroupAfterInvitationConfirmationTitle', roomName),
// message: window.i18n('joinOpenGroupAfterInvitationConfirmationDesc', roomName),
// resolve: () => joinOpenGroupV2WithUIEvents(completeUrl, true),
// });
// this function does not throw, and will showToasts if anything happens // this function does not throw, and will showToasts if anything happens
}; };

@ -42,6 +42,8 @@ import { ConversationInteraction } from '../interactions';
import { OpenGroupVisibleMessage } from '../session/messages/outgoing/visibleMessage/OpenGroupVisibleMessage'; import { OpenGroupVisibleMessage } from '../session/messages/outgoing/visibleMessage/OpenGroupVisibleMessage';
import { OpenGroupRequestCommonType } from '../opengroup/opengroupV2/ApiUtil'; import { OpenGroupRequestCommonType } from '../opengroup/opengroupV2/ApiUtil';
import { getOpenGroupV2FromConversationId } from '../opengroup/utils/OpenGroupUtils'; import { getOpenGroupV2FromConversationId } from '../opengroup/utils/OpenGroupUtils';
import { useDispatch } from 'react-redux';
import { updateConfirmModal } from '../state/ducks/modalDialog';
export enum ConversationTypeEnum { export enum ConversationTypeEnum {
GROUP = 'group', GROUP = 'group',
@ -421,7 +423,6 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
onBlockContact: this.block, onBlockContact: this.block,
onUnblockContact: this.unblock, onUnblockContact: this.unblock,
onCopyPublicKey: this.copyPublicKey, onCopyPublicKey: this.copyPublicKey,
onDeleteContact: this.deleteContact,
onClearNickname: this.clearNickname, onClearNickname: this.clearNickname,
onDeleteMessages: this.deleteMessages, onDeleteMessages: this.deleteMessages,
onLeaveGroup: () => { onLeaveGroup: () => {
@ -1309,23 +1310,23 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
void this.setNickname(''); void this.setNickname('');
}; };
public deleteContact() { // public deleteContact() {
let title = window.i18n('delete'); // let title = window.i18n('delete');
let message = window.i18n('deleteContactConfirmation'); // let message = window.i18n('deleteContactConfirmation');
if (this.isGroup()) { // if (this.isGroup()) {
title = window.i18n('leaveGroup'); // title = window.i18n('leaveGroup');
message = window.i18n('leaveGroupConfirmation'); // message = window.i18n('leaveGroupConfirmation');
} // }
window.confirmationDialog({ // window.confirmationDialog({
title, // title,
message, // message,
resolve: () => { // resolve: () => {
void ConversationController.getInstance().deleteContact(this.id); // void ConversationController.getInstance().deleteContact(this.id);
}, // },
}); // });
} // }
public async removeMessage(messageId: any) { public async removeMessage(messageId: any) {
await dataRemoveMessage(messageId); await dataRemoveMessage(messageId);
@ -1352,6 +1353,13 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
} }
// window.confirmationDialog(params); // window.confirmationDialog(params);
const dispatch = useDispatch()
dispatch(updateConfirmModal({
title: window.i18n('deleteMessages'),
message: window.i18n('deleteConversationConfirmation'),
onClickOk: () => this.destroyMessages(),
}))
} }
public async destroyMessages() { public async destroyMessages() {

@ -947,27 +947,32 @@ async function sendToGroupMembers(
// const dispatch = useDispatch(); // const dispatch = useDispatch();
// window.inboxStore?.dispatch(updateConfirmModal({
// title: 'hi'
// }))
console.log('@@@@', inviteResults);
if (allInvitesSent) { if (allInvitesSent) {
// if (true) {
if (isRetry) { if (isRetry) {
const invitesTitle = const invitesTitle =
inviteResults.length > 1 inviteResults.length > 1
? window.i18n('closedGroupInviteSuccessTitlePlural') ? window.i18n('closedGroupInviteSuccessTitlePlural')
: window.i18n('closedGroupInviteSuccessTitle'); : window.i18n('closedGroupInviteSuccessTitle');
// setModal(<SessionConfirm message={'hi'} title={invitesTitle} />) window.inboxStore?.dispatch(updateConfirmModal({
window.confirmationDialog({
title: invitesTitle, title: invitesTitle,
message: window.i18n('closedGroupInviteSuccessMessage'), message: window.i18n('closedGroupInviteSuccessMessage'),
}); hideCancel: true
}));
// dispatch(updateConfirmModal({ title: "invitesTitle" }))
} }
return allInvitesSent; return allInvitesSent;
} else { } else {
// Confirmation dialog that recursively calls sendToGroupMembers on resolve // Confirmation dialog that recursively calls sendToGroupMembers on resolve
window.confirmationDialog({
window.inboxStore?.dispatch(updateConfirmModal({
title: title:
inviteResults.length > 1 inviteResults.length > 1
? window.i18n('closedGroupInviteFailTitlePlural') ? window.i18n('closedGroupInviteFailTitlePlural')
@ -977,7 +982,7 @@ async function sendToGroupMembers(
? window.i18n('closedGroupInviteFailMessagePlural') ? window.i18n('closedGroupInviteFailMessagePlural')
: window.i18n('closedGroupInviteFailMessage'), : window.i18n('closedGroupInviteFailMessage'),
okText: window.i18n('closedGroupInviteOkText'), okText: window.i18n('closedGroupInviteOkText'),
resolve: async () => { onClickOk: async () => {
const membersToResend: Array<string> = new Array<string>(); const membersToResend: Array<string> = new Array<string>();
inviteResults.forEach((result, index) => { inviteResults.forEach((result, index) => {
const member = listOfMembers[index]; const member = listOfMembers[index];
@ -999,7 +1004,41 @@ async function sendToGroupMembers(
); );
} }
}, },
}); }));
// window.confirmationDialog({
// title:
// inviteResults.length > 1
// ? window.i18n('closedGroupInviteFailTitlePlural')
// : window.i18n('closedGroupInviteFailTitle'),
// message:
// inviteResults.length > 1
// ? window.i18n('closedGroupInviteFailMessagePlural')
// : window.i18n('closedGroupInviteFailMessage'),
// okText: window.i18n('closedGroupInviteOkText'),
// resolve: async () => {
// const membersToResend: Array<string> = new Array<string>();
// inviteResults.forEach((result, index) => {
// const member = listOfMembers[index];
// // group invite must always contain the admin member.
// if (result !== true || admins.includes(member)) {
// membersToResend.push(member);
// }
// });
// if (membersToResend.length > 0) {
// const isRetrySend = true;
// await sendToGroupMembers(
// membersToResend,
// groupPublicKey,
// groupName,
// admins,
// encryptionKeyPair,
// dbMessage,
// isRetrySend
// );
// }
// },
// });
} }
return allInvitesSent; return allInvitesSent;
} }

@ -157,6 +157,9 @@ export class MessageQueue {
): Promise<boolean> { ): Promise<boolean> {
let rawMessage; let rawMessage;
try { try {
if (Math.random() > 0.3) {
throw 'fail';
}
rawMessage = await MessageUtils.toRawMessage(user, message); rawMessage = await MessageUtils.toRawMessage(user, message);
const wrappedEnvelope = await MessageSender.send(rawMessage); const wrappedEnvelope = await MessageSender.send(rawMessage);
await MessageSentHandler.handleMessageSentSuccess(rawMessage, wrappedEnvelope); await MessageSentHandler.handleMessageSentSuccess(rawMessage, wrappedEnvelope);

@ -5,6 +5,7 @@ import { actions as conversations } from './ducks/conversations';
import { actions as user } from './ducks/user'; import { actions as user } from './ducks/user';
import { actions as sections } from './ducks/section'; import { actions as sections } from './ducks/section';
import { actions as theme } from './ducks/theme'; import { actions as theme } from './ducks/theme';
import { actions as modalDialog } from './ducks/modalDialog';
export function mapDispatchToProps(dispatch: Dispatch): Object { export function mapDispatchToProps(dispatch: Dispatch): Object {
return { return {
@ -15,6 +16,7 @@ export function mapDispatchToProps(dispatch: Dispatch): Object {
...user, ...user,
...theme, ...theme,
...sections, ...sections,
...modalDialog
}, },
dispatch dispatch
), ),

@ -1,46 +1,21 @@
import { createSlice, PayloadAction } from '@reduxjs/toolkit'; import { createSlice, PayloadAction } from '@reduxjs/toolkit';
import { DefaultTheme } from 'styled-components'; import { SessionConfirmDialogProps } from '../../components/session/SessionConfirm';
import { SessionIconSize, SessionIconType } from '../../components/session/icon';
import { SessionButtonColor } from '../../components/session/SessionButton';
export type ConfirmModalState = { export type ConfirmModalState = SessionConfirmDialogProps | null;
message?: string;
messageSub?: string;
title?: string;
onOk?: any;
onClose?: any;
onClickOk?: any;
onClickClose?: any;
okText?: string;
cancelText?: string;
hideCancel?: boolean;
okTheme?: SessionButtonColor;
closeTheme?: SessionButtonColor;
sessionIcon?: SessionIconType;
iconSize?: SessionIconSize;
theme?: DefaultTheme;
} | null;
const initialState: ConfirmModalState = null; const initialState: ConfirmModalState = null as ConfirmModalState;
// const initialState: any = { idk: 'hi'};
const confirmModalSlice = createSlice({ const confirmModalSlice = createSlice({
name: 'confirmModal', name: 'confirmModal',
initialState, initialState,
reducers: { reducers: {
// updateConfirmModal(state, action: PayloadAction<ConfirmModalState>) { updateConfirmModal(state, action: PayloadAction<ConfirmModalState | null>) {
updateConfirmModal(state, action: any) {
// return action.payload;
// state.title = action.payload;
state = action.payload; state = action.payload;
return action.payload; return action.payload;
// state.confirmModal = action.payload;
} }
} }
}) })
const { actions, reducer } = confirmModalSlice; export const { actions, reducer } = confirmModalSlice;
export const { updateConfirmModal } = actions; export const { updateConfirmModal } = actions;
export const confirmModalReducer = reducer; export const confirmModalReducer = reducer;

@ -17,6 +17,7 @@ const mapStateToProps = (state: StateType) => {
theme: getTheme(state), theme: getTheme(state),
messages: getMessagesOfSelectedConversation(state), messages: getMessagesOfSelectedConversation(state),
ourNumber: getOurNumber(state), ourNumber: getOurNumber(state),
confirmModal: (state: StateType) => {state.confirmModal}
}; };
}; };

6
ts/window.d.ts vendored

@ -100,7 +100,7 @@ declare global {
confirmationDialog: any; confirmationDialog: any;
} }
window.confirmationDialog = () => { // window.confirmationDialog = () => {
console.log("confirmation dialog stub called"); // console.log("confirmation dialog stub called");
} // }
} }

Loading…
Cancel
Save