reduxify remaining dialogs

pull/1703/head
Audric Ackermann 4 years ago
parent 93e43fe929
commit 651921590c
No known key found for this signature in database
GPG Key ID: 999F434D76324AD4

@ -12,12 +12,10 @@ const LinkPreviews = require('./link_previews');
const { Message } = require('../../ts/components/conversation/Message');
// Components
const { SessionSeedModal } = require('../../ts/components/session/SessionSeedModal');
const { SessionIDResetDialog } = require('../../ts/components/session/SessionIDResetDialog');
const { SessionRegistrationView } = require('../../ts/components/session/SessionRegistrationView');
const { SessionInboxView } = require('../../ts/components/session/SessionInboxView');
const { SessionPasswordModal } = require('../../ts/components/session/SessionPasswordModal');
// Types
const AttachmentType = require('./types/attachment');
@ -123,9 +121,7 @@ exports.setup = (options = {}) => {
const Components = {
SessionInboxView,
SessionSeedModal,
SessionIDResetDialog,
SessionPasswordModal,
SessionRegistrationView,
Message,
};

@ -9,24 +9,16 @@ import { SessionButton, SessionButtonColor, SessionButtonType } from './session/
import { SessionIconButton, SessionIconSize, SessionIconType } from './session/icon';
import { PillDivider } from './session/PillDivider';
import { SyncUtils, ToastUtils, UserUtils } from '../session/utils';
import { DefaultTheme } from 'styled-components';
import { MAX_USERNAME_LENGTH } from './session/registration/RegistrationTabs';
import { SessionSpinner } from './session/SessionSpinner';
import { ConversationTypeEnum } from '../models/conversation';
import { ConversationModel, ConversationTypeEnum } from '../models/conversation';
import { SessionWrapperModal } from './session/SessionWrapperModal';
import { AttachmentUtil } from '../util';
import { ConversationController } from '../session/conversations';
import { SpacerLG, SpacerMD } from './basic/Text';
interface Props {
profileName?: string;
avatarPath?: string;
pubkey?: string;
onClose?: any;
onOk?: any;
theme: DefaultTheme;
}
import autoBind from 'auto-bind';
import { editProfileModal } from '../state/ducks/modalDialog';
interface State {
profileName: string;
@ -36,23 +28,21 @@ interface State {
loading: boolean;
}
export class EditProfileDialog extends React.Component<Props, State> {
export class EditProfileDialog extends React.Component<{}, State> {
private readonly inputEl: any;
private readonly convo: ConversationModel;
constructor(props: any) {
super(props);
this.onNameEdited = this.onNameEdited.bind(this);
this.closeDialog = this.closeDialog.bind(this);
this.onClickOK = this.onClickOK.bind(this);
this.onKeyUp = this.onKeyUp.bind(this);
this.onFileSelected = this.onFileSelected.bind(this);
this.fireInputEvent = this.fireInputEvent.bind(this);
autoBind(this);
this.convo = ConversationController.getInstance().get(UserUtils.getOurPubKeyStrFromCache());
this.state = {
profileName: this.props.profileName || '',
setProfileName: this.props.profileName || '',
avatar: this.props.avatarPath || '',
profileName: this.convo.getProfileName() || '',
setProfileName: this.convo.getProfileName() || '',
avatar: this.convo.getAvatarPath() || '',
mode: 'default',
loading: false,
};
@ -98,7 +88,6 @@ export class EditProfileDialog extends React.Component<Props, State> {
}
public render() {
// const i18n = this.props.i18n;
const i18n = window.i18n;
const viewDefault = this.state.mode === 'default';
@ -194,7 +183,6 @@ export class EditProfileDialog extends React.Component<Props, State> {
onClick={() => {
this.setState({ mode: 'qr' });
}}
theme={this.props.theme}
/>
</div>
</div>
@ -226,7 +214,6 @@ export class EditProfileDialog extends React.Component<Props, State> {
onClick={() => {
this.setState({ mode: 'edit' });
}}
theme={this.props.theme}
/>
</div>
</>
@ -278,10 +265,11 @@ export class EditProfileDialog extends React.Component<Props, State> {
private renderAvatar() {
const { avatar, profileName } = this.state;
const { pubkey } = this.props;
const userName = profileName || pubkey;
const userName = profileName || this.convo.id;
return <Avatar avatarPath={avatar} name={userName} size={AvatarSize.XL} pubkey={pubkey} />;
return (
<Avatar avatarPath={avatar} name={userName} size={AvatarSize.XL} pubkey={this.convo.id} />
);
}
private onNameEdited(event: any) {
@ -299,7 +287,6 @@ export class EditProfileDialog extends React.Component<Props, State> {
switch (event.key) {
case 'Enter':
if (this.state.mode === 'edit') {
// this.onClickOK();
this.onClickOK();
}
break;
@ -353,7 +340,7 @@ export class EditProfileDialog extends React.Component<Props, State> {
private closeDialog() {
window.removeEventListener('keyup', this.onKeyUp);
this.props.onClose();
window.inboxStore?.dispatch(editProfileModal(null));
}
private async commitProfileEdits(newName: string, avatar: any) {

@ -86,9 +86,8 @@ const InnerLeftPaneContactSection = () => {
);
};
const LeftPaneSection = (props: { isExpired: boolean; setModal: any }) => {
const LeftPaneSection = (props: { isExpired: boolean }) => {
const focusedSection = useSelector(getFocusedSection);
const { setModal } = props;
if (focusedSection === SectionType.Message) {
return <InnerLeftPaneMessageSection isExpired={props.isExpired} />;
@ -98,7 +97,7 @@ const LeftPaneSection = (props: { isExpired: boolean; setModal: any }) => {
return <InnerLeftPaneContactSection />;
}
if (focusedSection === SectionType.Settings) {
return <LeftPaneSettingSection setModal={setModal} />;
return <LeftPaneSettingSection />;
}
return <></>;
};
@ -106,17 +105,14 @@ const LeftPaneSection = (props: { isExpired: boolean; setModal: any }) => {
export const LeftPane = (props: Props) => {
const theme = useSelector(getTheme);
const [modal, setModal] = useState<any>(null);
return (
<>
{modal ? modal : null}
<SessionTheme theme={theme}>
<div className="module-left-pane-session">
<ActionsPanel />
<div className="module-left-pane">
<LeftPaneSection setModal={setModal} isExpired={props.isExpired} />
<LeftPaneSection isExpired={props.isExpired} />
</div>
</div>
</SessionTheme>

@ -9,6 +9,7 @@ import { SessionWrapperModal } from './session/SessionWrapperModal';
import { SpacerMD } from './basic/Text';
import autoBind from 'auto-bind';
import { updateUserDetailsModal } from '../state/ducks/modalDialog';
import { openConversationExternal } from '../state/ducks/conversations';
type Props = {
conversationId: string;
@ -99,7 +100,7 @@ export class UserDetailsDialog extends React.Component<Props, State> {
ConversationTypeEnum.PRIVATE
);
window.inboxStore?.dispatch(window.actionsCreators.openConversationExternal(conversation.id));
window.inboxStore?.dispatch(openConversationExternal(conversation.id));
this.closeDialog();
}

@ -1,32 +1,31 @@
import React from 'react';
import { SessionButton, SessionButtonColor } from '../session/SessionButton';
import { DefaultTheme } from 'styled-components';
import { SessionWrapperModal } from '../session/SessionWrapperModal';
import { SpacerLG } from '../basic/Text';
import { ConversationController } from '../../session/conversations';
import { adminLeaveClosedGroup } from '../../state/ducks/modalDialog';
type Props = {
groupName: string;
onSubmit: () => any;
onClose: any;
theme: DefaultTheme;
conversationId: string;
};
const AdminLeaveClosedGroupDialogInner = (props: Props) => {
const { groupName, theme, onSubmit, onClose } = props;
const titleText = `${window.i18n('leaveGroup')} ${groupName}`;
export const AdminLeaveClosedGroupDialog = (props: Props) => {
const convo = ConversationController.getInstance().get(props.conversationId);
const titleText = `${window.i18n('leaveGroup')} ${convo.getName()}`;
const warningAsAdmin = `${window.i18n('leaveGroupConfirmationAdmin')}`;
const okText = window.i18n('leaveAndRemoveForEveryone');
const cancelText = window.i18n('cancel');
const onClickOK = () => {
void onSubmit();
const onClickOK = async () => {
await ConversationController.getInstance()
.get(props.conversationId)
.leaveClosedGroup();
closeDialog();
};
const closeDialog = () => {
onClose();
window.inboxStore?.dispatch(adminLeaveClosedGroup(null));
};
return (
@ -41,5 +40,3 @@ const AdminLeaveClosedGroupDialogInner = (props: Props) => {
</SessionWrapperModal>
);
};
export const AdminLeaveClosedGroupDialog = AdminLeaveClosedGroupDialogInner;

@ -50,8 +50,13 @@ import { EditProfileDialog } from '../EditProfileDialog';
import { SessionConfirm } from './SessionConfirm';
import {
getAddModeratorsModal,
getAdminLeaveClosedGroupDialog,
getChangeNickNameDialog,
getConfirmModal,
getEditProfileDialog,
getInviteContactModal,
getOnionPathDialog,
getRecoveryPhraseDialog,
getRemoveModeratorsModal,
getUpdateGroupMembersModal,
getUpdateGroupNameModal,
@ -63,6 +68,10 @@ import { RemoveModeratorsDialog } from '../conversation/ModeratorsRemoveDialog';
import { UpdateGroupNameDialog } from '../conversation/UpdateGroupNameDialog';
import { UpdateGroupMembersDialog } from '../conversation/UpdateGroupMembersDialog';
import { UserDetailsDialog } from '../UserDetailsDialog';
import { SessionNicknameDialog } from './SessionNicknameDialog';
import { editProfileModal, onionPathModal } from '../../state/ducks/modalDialog';
import { SessionSeedModal } from './SessionSeedModal';
import { AdminLeaveClosedGroupDialog } from '../conversation/AdminLeaveClosedGroupDialog';
// tslint:disable-next-line: no-import-side-effect no-submodule-imports
@ -76,24 +85,20 @@ export enum SectionType {
PathIndicator,
}
const Section = (props: { setModal?: any; type: SectionType; avatarPath?: string }) => {
const Section = (props: { type: SectionType; avatarPath?: string }) => {
const ourNumber = useSelector(getOurNumber);
const unreadMessageCount = useSelector(getUnreadMessageCount);
const theme = useSelector(getTheme);
const dispatch = useDispatch();
const { setModal, type, avatarPath } = props;
const { type, avatarPath } = props;
const focusedSection = useSelector(getFocusedSection);
const isSelected = focusedSection === props.type;
const handleModalClose = () => {
setModal(null);
};
const handleClick = () => {
/* tslint:disable:no-void-expression */
if (type === SectionType.Profile) {
setModal(<EditProfileDialog onClose={handleModalClose} theme={theme} />);
dispatch(editProfileModal({}));
} else if (type === SectionType.Moon) {
const themeFromSettings = window.Events.getThemeSetting();
const updatedTheme = themeFromSettings === 'dark' ? 'light' : 'dark';
@ -103,7 +108,7 @@ const Section = (props: { setModal?: any; type: SectionType; avatarPath?: string
dispatch(applyTheme(newThemeObject));
} else if (type === SectionType.PathIndicator) {
// Show Path Indicator Modal
setModal(<OnionPathModal onClose={handleModalClose} />);
dispatch(onionPathModal({}));
} else {
dispatch(clearSearch());
dispatch(showLeftPaneSection(type));
@ -346,9 +351,14 @@ const ModalContainer = () => {
const updateGroupMembersModalState = useSelector(getUpdateGroupMembersModal);
const updateGroupNameModalState = useSelector(getUpdateGroupNameModal);
const userDetailsModalState = useSelector(getUserDetailsModal);
const changeNicknameModal = useSelector(getChangeNickNameDialog);
const editProfileModalState = useSelector(getEditProfileDialog);
const onionPathModalState = useSelector(getOnionPathDialog);
const recoveryPhraseModalState = useSelector(getRecoveryPhraseDialog);
const adminLeaveClosedGroupModalState = useSelector(getAdminLeaveClosedGroupDialog);
return (
<React.Fragment>
<>
{confirmModalState && <SessionConfirm {...confirmModalState} />}
{inviteModalState && <InviteContactsDialog {...inviteModalState} />}
{addModeratorsModalState && <AddModeratorsDialog {...addModeratorsModalState} />}
@ -358,7 +368,14 @@ const ModalContainer = () => {
)}
{updateGroupNameModalState && <UpdateGroupNameDialog {...updateGroupNameModalState} />}
{userDetailsModalState && <UserDetailsDialog {...userDetailsModalState} />}
</React.Fragment>
{changeNicknameModal && <SessionNicknameDialog {...changeNicknameModal} />}
{editProfileModalState && <EditProfileDialog {...editProfileModalState} />}
{onionPathModalState && <OnionPathModal {...onionPathModalState} />}
{recoveryPhraseModalState && <SessionSeedModal {...recoveryPhraseModalState} />}
{adminLeaveClosedGroupModalState && (
<AdminLeaveClosedGroupDialog {...adminLeaveClosedGroupModalState} />
)}
</>
);
};
@ -369,7 +386,6 @@ const ModalContainer = () => {
export const ActionsPanel = () => {
const [startCleanUpMedia, setStartCleanUpMedia] = useState(false);
const ourPrimaryConversation = useSelector(getOurPrimaryConversation);
const [modal, setModal] = useState<any>(null);
// this maxi useEffect is called only once: when the component is mounted.
// For the action panel, it means this is called only one per app start/with a user loggedin
@ -412,21 +428,16 @@ export const ActionsPanel = () => {
return (
<>
{modal && modal}
<ModalContainer />
<div className="module-left-pane__sections-container">
<Section
setModal={setModal}
type={SectionType.Profile}
avatarPath={ourPrimaryConversation.avatarPath}
/>
<Section type={SectionType.Profile} avatarPath={ourPrimaryConversation.avatarPath} />
<Section type={SectionType.Message} />
<Section type={SectionType.Contact} />
<Section type={SectionType.Settings} />
<SessionToastContainer />
<Section setModal={setModal} type={SectionType.PathIndicator} />
<Section type={SectionType.PathIndicator} />
<Section type={SectionType.Moon} />
</div>
</>

@ -62,7 +62,6 @@ interface State {
loading: boolean;
overlay: false | SessionComposeToType;
valuePasted: string;
modal: null | JSX.Element;
}
export class LeftPaneMessageSection extends React.Component<Props, State> {
@ -75,7 +74,6 @@ export class LeftPaneMessageSection extends React.Component<Props, State> {
loading: false,
overlay: false,
valuePasted: '',
modal: null,
};
autoBind(this);
@ -169,18 +167,11 @@ export class LeftPaneMessageSection extends React.Component<Props, State> {
return (
<div className="session-left-pane-section-content">
{this.renderHeader()}
{this.state.modal ? this.state.modal : null}
{overlay ? this.renderClosableOverlay(overlay) : this.renderConversations()}
</div>
);
}
public setModal(modal: null | JSX.Element) {
this.setState({
modal,
});
}
public renderConversations() {
return (
<div className="module-conversations-list-content">

@ -14,6 +14,7 @@ import { getFocusedSettingsSection } from '../../state/selectors/section';
import { getTheme } from '../../state/selectors/theme';
import { SessionConfirm } from './SessionConfirm';
import { SessionSeedModal } from './SessionSeedModal';
import { recoveryPhraseModal, updateConfirmModal } from '../../state/ducks/modalDialog';
type Props = {
settingsCategory: SessionSettingCategory;
@ -104,37 +105,33 @@ const LeftPaneSettingsCategories = () => {
);
};
const onDeleteAccount = (setModal: any) => {
const onDeleteAccount = () => {
const title = window.i18n('clearAllData');
const message = window.i18n('deleteAccountWarning');
const clearModal = () => {
setModal(null);
const onClickClose = () => {
window.inboxStore?.dispatch(updateConfirmModal(null));
};
setModal(
<SessionConfirm
title={title}
message={message}
onClickOk={deleteAccount}
okTheme={SessionButtonColor.Danger}
onClickClose={clearModal}
/>
window.inboxStore?.dispatch(
updateConfirmModal({
title,
message,
okTheme: SessionButtonColor.Danger,
onClickOk: deleteAccount,
onClickClose,
closeAfterClickOk: true,
})
);
};
const onShowRecoverPhrase = (setModal: any) => {
const clearModal = () => {
setModal(null);
};
setModal(<SessionSeedModal onClose={clearModal} />);
const onShowRecoveryPhrase = () => {
window.inboxStore?.dispatch(recoveryPhraseModal({}));
};
const LeftPaneBottomButtons = (props: { setModal: any }) => {
const LeftPaneBottomButtons = () => {
const dangerButtonText = window.i18n('clearAllData');
const showRecoveryPhrase = window.i18n('showRecoveryPhrase');
const { setModal } = props;
return (
<div className="left-pane-setting-bottom-buttons">
@ -143,7 +140,7 @@ const LeftPaneBottomButtons = (props: { setModal: any }) => {
buttonType={SessionButtonType.SquareOutline}
buttonColor={SessionButtonColor.Danger}
onClick={() => {
onDeleteAccount(setModal);
onDeleteAccount();
}}
/>
@ -152,23 +149,21 @@ const LeftPaneBottomButtons = (props: { setModal: any }) => {
buttonType={SessionButtonType.SquareOutline}
buttonColor={SessionButtonColor.White}
onClick={() => {
onShowRecoverPhrase(setModal);
onShowRecoveryPhrase();
}}
/>
</div>
);
};
export const LeftPaneSettingSection = (props: { setModal: any }) => {
export const LeftPaneSettingSection = () => {
const theme = useSelector(getTheme);
const { setModal } = props;
return (
<div className="left-pane-setting-section">
<LeftPaneSectionHeader label={window.i18n('settingsHeader')} theme={theme} />
<div className="left-pane-setting-content">
<LeftPaneSettingsCategories />
<LeftPaneBottomButtons setModal={setModal} />
<LeftPaneBottomButtons />
</div>
</div>
);

@ -1,25 +1,22 @@
import React, { useState } from 'react';
import { ConversationController } from '../../session/conversations/ConversationController';
import { SessionButton } from './SessionButton';
import { DefaultTheme, useTheme, withTheme } from 'styled-components';
import _ from 'lodash';
import { SessionWrapperModal } from './SessionWrapperModal';
import { SpacerLG } from '../basic/Text';
import { useDispatch } from 'react-redux';
import { changeNickNameModal } from '../../state/ducks/modalDialog';
type Props = {
onClickOk?: any;
onClickClose?: any;
theme?: DefaultTheme;
conversationId?: string;
conversationId: string;
};
const SessionNicknameInner = (props: Props) => {
const { onClickOk, onClickClose, conversationId } = props;
let { theme } = props;
export const SessionNicknameDialog = (props: Props) => {
const { conversationId } = props;
const [nickname, setNickname] = useState('');
theme = theme ? theme : useTheme();
const dispatch = useDispatch();
/**
* Changes the state of nickname variable. If enter is pressed, saves the current
@ -34,6 +31,10 @@ const SessionNicknameInner = (props: Props) => {
}
};
const onClickClose = () => {
dispatch(changeNickNameModal(null));
};
/**
* Saves the currently entered nickname.
*/
@ -42,23 +43,11 @@ const SessionNicknameInner = (props: Props) => {
throw new Error('Cant save without conversation id');
}
const conversation = ConversationController.getInstance().get(conversationId);
if (onClickOk) {
onClickOk(nickname);
}
await conversation.setNickname(nickname);
onClickClose();
};
return (
// <SessionModal
// title={window.i18n('changeNickname')}
// onClose={onClickClose}
// showExitIcon={false}
// showHeader={true}
// theme={theme}
// >
// TODO: Implement showHeader option for modal
<SessionWrapperModal
title={window.i18n('changeNickname')}
onClose={onClickClose}
@ -87,5 +76,3 @@ const SessionNicknameInner = (props: Props) => {
</SessionWrapperModal>
);
};
export const SessionNicknameDialog = withTheme(SessionNicknameInner);

@ -10,11 +10,8 @@ import { QRCode } from 'react-qr-svg';
import { mn_decode } from '../../session/crypto/mnemonic';
import { SessionWrapperModal } from './SessionWrapperModal';
import { SpacerLG, SpacerSM, SpacerXS } from '../basic/Text';
interface Props {
onClose: any;
theme: DefaultTheme;
}
import autoBind from 'auto-bind';
import { recoveryPhraseModal } from '../../state/ducks/modalDialog';
interface State {
error: string;
@ -26,7 +23,7 @@ interface State {
passwordValid: boolean;
}
class SessionSeedModalInner extends React.Component<Props, State> {
class SessionSeedModalInner extends React.Component<{}, State> {
constructor(props: any) {
super(props);
@ -40,11 +37,7 @@ class SessionSeedModalInner extends React.Component<Props, State> {
passwordValid: false,
};
this.copyRecoveryPhrase = this.copyRecoveryPhrase.bind(this);
this.getRecoveryPhrase = this.getRecoveryPhrase.bind(this);
this.confirmPassword = this.confirmPassword.bind(this);
this.checkHasPassword = this.checkHasPassword.bind(this);
this.onEnter = this.onEnter.bind(this);
autoBind(this);
}
public componentDidMount() {
@ -57,9 +50,9 @@ class SessionSeedModalInner extends React.Component<Props, State> {
void this.checkHasPassword();
void this.getRecoveryPhrase();
const { onClose } = this.props;
const { hasPassword, passwordValid } = this.state;
const loading = this.state.loadingPassword || this.state.loadingSeed;
const onClose = () => window.inboxStore?.dispatch(recoveryPhraseModal(null));
return (
<>
@ -81,7 +74,8 @@ class SessionSeedModalInner extends React.Component<Props, State> {
private renderPasswordView() {
const error = this.state.error;
const i18n = window.i18n;
const { onClose } = this.props;
const onClose = () => window.inboxStore?.dispatch(recoveryPhraseModal(null));
return (
<>
@ -206,7 +200,7 @@ class SessionSeedModalInner extends React.Component<Props, State> {
window.clipboard.writeText(recoveryPhrase);
ToastUtils.pushCopiedToClipBoard();
this.props.onClose();
window.inboxStore?.dispatch(recoveryPhraseModal(null));
}
private onEnter(event: any) {

@ -1,6 +1,6 @@
import React from 'react';
import { icons, SessionIconSize, SessionIconType } from '../icon';
import styled, { css, DefaultTheme, keyframes } from 'styled-components';
import styled, { css, DefaultTheme, keyframes, useTheme } from 'styled-components';
import _ from 'lodash';
export type SessionIconProps = {
@ -12,7 +12,7 @@ export type SessionIconProps = {
glowDuration?: number;
borderRadius?: number;
glowStartDelay?: number;
theme: DefaultTheme;
theme?: DefaultTheme;
};
const getIconDimensionFromIconSize = (iconSize: SessionIconSize | number) => {
@ -163,6 +163,8 @@ export const SessionIcon = (props: SessionIconProps) => {
iconSize = iconSize || SessionIconSize.Medium;
iconRotation = iconRotation || 0;
const themeToUse = theme || useTheme();
const iconDimensions = getIconDimensionFromIconSize(iconSize);
const iconDef = icons[iconType];
const ratio = iconDef?.ratio || 1;
@ -182,7 +184,7 @@ export const SessionIcon = (props: SessionIconProps) => {
borderRadius={borderRadius}
iconRotation={iconRotation}
iconColor={iconColor}
theme={theme}
theme={themeToUse}
/>
);
};

@ -2,13 +2,13 @@ import React from 'react';
import classNames from 'classnames';
import { SessionIcon, SessionIconProps } from '../icon';
import { SessionNotificationCount } from '../SessionNotificationCount';
import { DefaultTheme } from 'styled-components';
import { DefaultTheme, useTheme } from 'styled-components';
interface SProps extends SessionIconProps {
onClick?: any;
notificationCount?: number;
isSelected?: boolean;
theme: DefaultTheme;
theme?: DefaultTheme;
}
export const SessionIconButton = (props: SProps) => {
@ -28,6 +28,8 @@ export const SessionIconButton = (props: SProps) => {
}
};
const themeToUSe = theme || useTheme();
return (
<div
className={classNames('session-icon-button', iconSize, isSelected ? 'no-opacity' : '')}
@ -39,7 +41,7 @@ export const SessionIconButton = (props: SProps) => {
iconSize={iconSize}
iconColor={iconColor}
iconRotation={iconRotation}
theme={theme}
theme={themeToUSe}
/>
{Boolean(notificationCount) && <SessionNotificationCount count={notificationCount} />}
</div>

@ -55,12 +55,8 @@ export const ConversationHeaderMenu = (props: PropsConversationHeaderMenu) => {
currentNotificationSetting,
} = props;
const [modal, setModal] = useState<any>(null);
return (
<>
{modal ? modal : null}
<Menu id={triggerId} animation={animation.fade}>
{getDisappearingMenuItem(
isPublic,
@ -82,20 +78,13 @@ export const ConversationHeaderMenu = (props: PropsConversationHeaderMenu) => {
{getCopyMenuItem(isPublic, isGroup, conversationId)}
{getMarkAllReadMenuItem(conversationId)}
{getChangeNicknameMenuItem(isMe, isGroup, conversationId, setModal)}
{getChangeNicknameMenuItem(isMe, isGroup, conversationId)}
{getClearNicknameMenuItem(isMe, hasNickname, isGroup, conversationId)}
{getDeleteMessagesMenuItem(isPublic, conversationId)}
{getAddModeratorsMenuItem(isAdmin, isKickedFromGroup, conversationId)}
{getRemoveModeratorsMenuItem(isAdmin, isKickedFromGroup, conversationId)}
{getUpdateGroupNameMenuItem(isAdmin, isKickedFromGroup, left, conversationId)}
{getLeaveGroupMenuItem(
isKickedFromGroup,
left,
isGroup,
isPublic,
conversationId,
setModal
)}
{getLeaveGroupMenuItem(isKickedFromGroup, left, isGroup, isPublic, conversationId)}
{/* TODO: add delete group */}
{getInviteContactMenuItem(isGroup, isPublic, conversationId)}
{getDeleteContactMenuItem(isMe, isGroup, isPublic, left, isKickedFromGroup, conversationId)}

@ -43,30 +43,19 @@ export const ConversationListItemContextMenu = (props: PropsContextConversationI
const isGroup = type === 'group';
const [modal, setModal] = useState<any>(null);
return (
<>
{modal ? modal : null}
<Menu id={triggerId} animation={animation.fade}>
{getBlockMenuItem(isMe, type === ConversationTypeEnum.PRIVATE, isBlocked, conversationId)}
{getCopyMenuItem(isPublic, isGroup, conversationId)}
{getMarkAllReadMenuItem(conversationId)}
{getChangeNicknameMenuItem(isMe, isGroup, conversationId, setModal)}
{getChangeNicknameMenuItem(isMe, isGroup, conversationId)}
{getClearNicknameMenuItem(isMe, hasNickname, isGroup, conversationId)}
{getDeleteMessagesMenuItem(isPublic, conversationId)}
{getInviteContactMenuItem(isGroup, isPublic, conversationId)}
{getDeleteContactMenuItem(isMe, isGroup, isPublic, left, isKickedFromGroup, conversationId)}
{getLeaveGroupMenuItem(
isKickedFromGroup,
left,
isGroup,
isPublic,
conversationId,
setModal
)}
{getLeaveGroupMenuItem(isKickedFromGroup, left, isGroup, isPublic, conversationId)}
</Menu>
</>
);

@ -3,9 +3,12 @@ import React from 'react';
import { NotificationForConvoOption, TimerOption } from '../../conversation/ConversationHeader';
import { Item, Submenu } from 'react-contexify';
import { ConversationNotificationSettingType } from '../../../models/conversation';
import { SessionNicknameDialog } from '../SessionNicknameDialog';
import { useDispatch } from 'react-redux';
import { updateConfirmModal } from '../../../state/ducks/modalDialog';
import {
adminLeaveClosedGroup,
changeNickNameModal,
updateConfirmModal,
} from '../../../state/ducks/modalDialog';
import { ConversationController } from '../../../session/conversations';
import { UserUtils } from '../../../session/utils';
import { AdminLeaveClosedGroupDialog } from '../../conversation/AdminLeaveClosedGroupDialog';
@ -179,8 +182,7 @@ export function getLeaveGroupMenuItem(
left: boolean | undefined,
isGroup: boolean | undefined,
isPublic: boolean | undefined,
conversationId: string,
setModal: any
conversationId: string
): JSX.Element | null {
if (
showLeaveGroup(Boolean(isKickedFromGroup), Boolean(left), Boolean(isGroup), Boolean(isPublic))
@ -218,15 +220,10 @@ export function getLeaveGroupMenuItem(
})
);
} else {
setModal(
<AdminLeaveClosedGroupDialog
groupName={conversation.getName()}
onSubmit={conversation.leaveClosedGroup}
onClose={() => {
setModal(null);
}}
theme={theme}
/>
dispatch(
adminLeaveClosedGroup({
conversationId,
})
);
}
};
@ -429,22 +426,18 @@ export function getClearNicknameMenuItem(
export function getChangeNicknameMenuItem(
isMe: boolean | undefined,
isGroup: boolean | undefined,
conversationId?: string,
setModal?: any
conversationId: string
): JSX.Element | null {
const dispatch = useDispatch();
if (showChangeNickname(Boolean(isMe), Boolean(isGroup))) {
const clearModal = () => {
setModal(null);
};
const onClickCustom = () => {
setModal(<SessionNicknameDialog onClickClose={clearModal} conversationId={conversationId} />);
};
return (
<>
<Item onClick={onClickCustom}>{window.i18n('changeNickname')}</Item>
</>
<Item
onClick={() => {
dispatch(changeNickNameModal({ conversationId }));
}}
>
{window.i18n('changeNickname')}
</Item>
);
}
return null;

@ -17,6 +17,7 @@ import _ from 'lodash';
import { ConversationController } from '../session/conversations';
import { BlockedNumberController } from '../util/blockedNumberController';
import {
changeNickNameModal,
updateAddModeratorsModal,
updateConfirmModal,
updateGroupMembersModal,
@ -235,6 +236,10 @@ export async function clearNickNameByConvoId(conversationId: string) {
await conversation.setNickname('');
}
export function showChangeNickNameByConvoId(conversationId: string) {
window.inboxStore?.dispatch(changeNickNameModal({ conversationId }));
}
export async function deleteMessagesByConvoIdNoConfirmation(conversationId: string) {
const conversation = ConversationController.getInstance().get(conversationId);
await removeAllMessagesInConversation(conversationId);

@ -3,10 +3,16 @@ import { SessionConfirmDialogProps } from '../../components/session/SessionConfi
export type ConfirmModalState = SessionConfirmDialogProps | null;
export type InviteContactModalState = { conversationId: string } | null;
export type AddModeratorsModalState = { conversationId: string } | null;
export type RemoveModeratorsModalState = { conversationId: string } | null;
export type UpdateGroupMembersModalState = { conversationId: string } | null;
export type UpdateGroupNameModalState = { conversationId: string } | null;
export type AddModeratorsModalState = InviteContactModalState;
export type RemoveModeratorsModalState = InviteContactModalState;
export type UpdateGroupMembersModalState = InviteContactModalState;
export type UpdateGroupNameModalState = InviteContactModalState;
export type ChangeNickNameModalState = InviteContactModalState;
export type AdminLeaveClosedGroupModalState = InviteContactModalState;
export type EditProfileModalState = {} | null;
export type OnionPathModalState = EditProfileModalState;
export type RecoveryPhraseModalState = EditProfileModalState;
export type UserDetailsModalState = {
conversationId: string;
authorAvatarPath?: string;
@ -21,6 +27,11 @@ export type ModalState = {
groupNameModal: UpdateGroupNameModalState;
groupMembersModal: UpdateGroupMembersModalState;
userDetailsModal: UserDetailsModalState;
nickNameModal: ChangeNickNameModalState;
editProfileModal: EditProfileModalState;
onionPathModal: OnionPathModalState;
recoveryPhraseModal: RecoveryPhraseModalState;
adminLeaveClosedGroup: AdminLeaveClosedGroupModalState;
};
export const initialModalState: ModalState = {
@ -31,6 +42,11 @@ export const initialModalState: ModalState = {
groupNameModal: null,
groupMembersModal: null,
userDetailsModal: null,
nickNameModal: null,
editProfileModal: null,
onionPathModal: null,
recoveryPhraseModal: null,
adminLeaveClosedGroup: null,
};
const ModalSlice = createSlice({
@ -58,6 +74,21 @@ const ModalSlice = createSlice({
updateUserDetailsModal(state, action: PayloadAction<UserDetailsModalState | null>) {
return { ...state, userDetailsModal: action.payload };
},
changeNickNameModal(state, action: PayloadAction<ChangeNickNameModalState | null>) {
return { ...state, nickNameModal: action.payload };
},
editProfileModal(state, action: PayloadAction<EditProfileModalState | null>) {
return { ...state, editProfileModal: action.payload };
},
onionPathModal(state, action: PayloadAction<OnionPathModalState | null>) {
return { ...state, onionPathModal: action.payload };
},
recoveryPhraseModal(state, action: PayloadAction<RecoveryPhraseModalState | null>) {
return { ...state, onionPathModal: action.payload };
},
adminLeaveClosedGroup(state, action: PayloadAction<AdminLeaveClosedGroupModalState | null>) {
return { ...state, adminLeaveClosedGroup: action.payload };
},
},
});
@ -70,5 +101,10 @@ export const {
updateGroupNameModal,
updateGroupMembersModal,
updateUserDetailsModal,
changeNickNameModal,
editProfileModal,
onionPathModal,
recoveryPhraseModal,
adminLeaveClosedGroup,
} = actions;
export const modalReducer = reducer;

@ -3,9 +3,14 @@ import { createSelector } from 'reselect';
import { StateType } from '../reducer';
import {
AddModeratorsModalState,
AdminLeaveClosedGroupModalState,
ChangeNickNameModalState,
ConfirmModalState,
EditProfileModalState,
InviteContactModalState,
ModalState,
OnionPathModalState,
RecoveryPhraseModalState,
RemoveModeratorsModalState,
UpdateGroupMembersModalState,
UpdateGroupNameModalState,
@ -50,3 +55,28 @@ export const getUserDetailsModal = createSelector(
getModal,
(state: ModalState): UserDetailsModalState => state.userDetailsModal
);
export const getChangeNickNameDialog = createSelector(
getModal,
(state: ModalState): ChangeNickNameModalState => state.nickNameModal
);
export const getEditProfileDialog = createSelector(
getModal,
(state: ModalState): EditProfileModalState => state.editProfileModal
);
export const getOnionPathDialog = createSelector(
getModal,
(state: ModalState): OnionPathModalState => state.onionPathModal
);
export const getRecoveryPhraseDialog = createSelector(
getModal,
(state: ModalState): RecoveryPhraseModalState => state.recoveryPhraseModal
);
export const getAdminLeaveClosedGroupDialog = createSelector(
getModal,
(state: ModalState): AdminLeaveClosedGroupModalState => state.adminLeaveClosedGroup
);

Loading…
Cancel
Save