Modernize ContactModal
This commit is contained in:
parent
1d2fcde49f
commit
c05d23e628
21 changed files with 426 additions and 493 deletions
|
@ -58,6 +58,7 @@ import {
|
|||
import { AvatarDataType, getDefaultAvatars } from '../../types/Avatar';
|
||||
import { getAvatarData } from '../../util/getAvatarData';
|
||||
import { isSameAvatarData } from '../../util/isSameAvatarData';
|
||||
import { longRunningTaskWrapper } from '../../util/longRunningTaskWrapper';
|
||||
|
||||
import { NoopActionType } from './noop';
|
||||
|
||||
|
@ -780,6 +781,7 @@ export const actions = {
|
|||
openConversationInternal,
|
||||
removeAllConversations,
|
||||
removeCustomColorOnConversations,
|
||||
removeMemberFromGroup,
|
||||
repairNewestMessage,
|
||||
repairOldestMessage,
|
||||
replaceAvatar,
|
||||
|
@ -803,11 +805,14 @@ export const actions = {
|
|||
showArchivedConversations,
|
||||
showChooseGroupMembers,
|
||||
showInbox,
|
||||
showSafetyNumberInConversation,
|
||||
startComposing,
|
||||
startNewConversationFromPhoneNumber,
|
||||
startSettingGroupMetadata,
|
||||
toggleAdmin,
|
||||
toggleConversationInChooseMembers,
|
||||
toggleComposeEditingAvatar,
|
||||
updateConversationModelSharedGroups,
|
||||
verifyConversationsStoppingMessageSend,
|
||||
};
|
||||
|
||||
|
@ -1720,6 +1725,73 @@ function openConversationExternal(
|
|||
};
|
||||
}
|
||||
|
||||
function removeMemberFromGroup(
|
||||
conversationId: string,
|
||||
contactId: string
|
||||
): ThunkAction<void, RootStateType, unknown, NoopActionType> {
|
||||
return dispatch => {
|
||||
const conversationModel = window.ConversationController.get(conversationId);
|
||||
if (conversationModel) {
|
||||
const idForLogging = conversationModel.idForLogging();
|
||||
longRunningTaskWrapper({
|
||||
name: 'removeMemberFromGroup',
|
||||
idForLogging,
|
||||
task: () => conversationModel.removeFromGroupV2(contactId),
|
||||
});
|
||||
}
|
||||
dispatch({
|
||||
type: 'NOOP',
|
||||
payload: null,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function toggleAdmin(
|
||||
conversationId: string,
|
||||
contactId: string
|
||||
): ThunkAction<void, RootStateType, unknown, NoopActionType> {
|
||||
return dispatch => {
|
||||
const conversationModel = window.ConversationController.get(conversationId);
|
||||
if (conversationModel) {
|
||||
conversationModel.toggleAdmin(contactId);
|
||||
}
|
||||
dispatch({
|
||||
type: 'NOOP',
|
||||
payload: null,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function updateConversationModelSharedGroups(
|
||||
conversationId: string
|
||||
): ThunkAction<void, RootStateType, unknown, NoopActionType> {
|
||||
return dispatch => {
|
||||
const conversation = window.ConversationController.get(conversationId);
|
||||
if (conversation && conversation.throttledUpdateSharedGroups) {
|
||||
conversation.throttledUpdateSharedGroups();
|
||||
}
|
||||
dispatch({
|
||||
type: 'NOOP',
|
||||
payload: null,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function showSafetyNumberInConversation(
|
||||
conversationId: string
|
||||
): ThunkAction<void, RootStateType, unknown, NoopActionType> {
|
||||
return dispatch => {
|
||||
window.Whisper.events.trigger(
|
||||
'showSafetyNumberInConversation',
|
||||
conversationId
|
||||
);
|
||||
dispatch({
|
||||
type: 'NOOP',
|
||||
payload: null,
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
function showInbox(): ShowInboxActionType {
|
||||
return {
|
||||
type: 'SHOW_INBOX',
|
||||
|
|
|
@ -4,16 +4,33 @@
|
|||
// State
|
||||
|
||||
export type GlobalModalsStateType = {
|
||||
readonly contactModalState?: ContactModalStateType;
|
||||
readonly isProfileEditorVisible: boolean;
|
||||
readonly profileEditorHasError: boolean;
|
||||
};
|
||||
|
||||
// Actions
|
||||
|
||||
const HIDE_CONTACT_MODAL = 'globalModals/HIDE_CONTACT_MODAL';
|
||||
const SHOW_CONTACT_MODAL = 'globalModals/SHOW_CONTACT_MODAL';
|
||||
const TOGGLE_PROFILE_EDITOR = 'globalModals/TOGGLE_PROFILE_EDITOR';
|
||||
export const TOGGLE_PROFILE_EDITOR_ERROR =
|
||||
'globalModals/TOGGLE_PROFILE_EDITOR_ERROR';
|
||||
|
||||
export type ContactModalStateType = {
|
||||
contactId: string;
|
||||
conversationId?: string;
|
||||
};
|
||||
|
||||
type HideContactModalActionType = {
|
||||
type: typeof HIDE_CONTACT_MODAL;
|
||||
};
|
||||
|
||||
type ShowContactModalActionType = {
|
||||
type: typeof SHOW_CONTACT_MODAL;
|
||||
payload: ContactModalStateType;
|
||||
};
|
||||
|
||||
type ToggleProfileEditorActionType = {
|
||||
type: typeof TOGGLE_PROFILE_EDITOR;
|
||||
};
|
||||
|
@ -23,16 +40,39 @@ export type ToggleProfileEditorErrorActionType = {
|
|||
};
|
||||
|
||||
export type GlobalModalsActionType =
|
||||
| HideContactModalActionType
|
||||
| ShowContactModalActionType
|
||||
| ToggleProfileEditorActionType
|
||||
| ToggleProfileEditorErrorActionType;
|
||||
|
||||
// Action Creators
|
||||
|
||||
export const actions = {
|
||||
hideContactModal,
|
||||
showContactModal,
|
||||
toggleProfileEditor,
|
||||
toggleProfileEditorHasError,
|
||||
};
|
||||
|
||||
function hideContactModal(): HideContactModalActionType {
|
||||
return {
|
||||
type: HIDE_CONTACT_MODAL,
|
||||
};
|
||||
}
|
||||
|
||||
function showContactModal(
|
||||
contactId: string,
|
||||
conversationId?: string
|
||||
): ShowContactModalActionType {
|
||||
return {
|
||||
type: SHOW_CONTACT_MODAL,
|
||||
payload: {
|
||||
contactId,
|
||||
conversationId,
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
function toggleProfileEditor(): ToggleProfileEditorActionType {
|
||||
return { type: TOGGLE_PROFILE_EDITOR };
|
||||
}
|
||||
|
@ -68,5 +108,19 @@ export function reducer(
|
|||
};
|
||||
}
|
||||
|
||||
if (action.type === SHOW_CONTACT_MODAL) {
|
||||
return {
|
||||
...state,
|
||||
contactModalState: action.payload,
|
||||
};
|
||||
}
|
||||
|
||||
if (action.type === HIDE_CONTACT_MODAL) {
|
||||
return {
|
||||
...state,
|
||||
contactModalState: undefined,
|
||||
};
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
|
|
@ -1,21 +0,0 @@
|
|||
// Copyright 2020 Signal Messenger, LLC
|
||||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import React from 'react';
|
||||
import { Provider } from 'react-redux';
|
||||
|
||||
import { Store } from 'redux';
|
||||
|
||||
import {
|
||||
SmartContactModal,
|
||||
SmartContactModalProps,
|
||||
} from '../smart/ContactModal';
|
||||
|
||||
export const createContactModal = (
|
||||
store: Store,
|
||||
props: SmartContactModalProps
|
||||
): React.ReactElement => (
|
||||
<Provider store={store}>
|
||||
<SmartContactModal {...props} />
|
||||
</Provider>
|
||||
);
|
|
@ -5,33 +5,18 @@ import { connect } from 'react-redux';
|
|||
import { mapDispatchToProps } from '../actions';
|
||||
import {
|
||||
ContactModal,
|
||||
PropsType,
|
||||
PropsDataType,
|
||||
} from '../../components/conversation/ContactModal';
|
||||
import { StateType } from '../reducer';
|
||||
|
||||
import { getIntl } from '../selectors/user';
|
||||
import { getConversationSelector } from '../selectors/conversations';
|
||||
|
||||
export type SmartContactModalProps = {
|
||||
contactId: string;
|
||||
currentConversationId: string;
|
||||
readonly onClose: () => unknown;
|
||||
readonly openConversation: (conversationId: string) => void;
|
||||
readonly removeMember: (conversationId: string) => void;
|
||||
readonly showSafetyNumber: (conversationId: string) => void;
|
||||
readonly toggleAdmin: (conversationId: string) => void;
|
||||
readonly updateSharedGroups: () => void;
|
||||
};
|
||||
const mapStateToProps = (state: StateType): PropsDataType => {
|
||||
const { contactId, conversationId } =
|
||||
state.globalModals.contactModalState || {};
|
||||
|
||||
const mapStateToProps = (
|
||||
state: StateType,
|
||||
props: SmartContactModalProps
|
||||
): PropsType => {
|
||||
const { contactId, currentConversationId } = props;
|
||||
|
||||
const currentConversation = getConversationSelector(state)(
|
||||
currentConversationId
|
||||
);
|
||||
const currentConversation = getConversationSelector(state)(conversationId);
|
||||
const contact = getConversationSelector(state)(contactId);
|
||||
|
||||
const areWeAdmin =
|
||||
|
@ -51,9 +36,9 @@ const mapStateToProps = (
|
|||
}
|
||||
|
||||
return {
|
||||
...props,
|
||||
areWeAdmin,
|
||||
contact,
|
||||
conversationId,
|
||||
i18n: getIntl(state),
|
||||
isAdmin,
|
||||
isMember,
|
||||
|
|
|
@ -25,7 +25,6 @@ export type SmartConversationDetailsProps = {
|
|||
loadRecentMediaItems: (limit: number) => void;
|
||||
setDisappearingMessages: (seconds: number) => void;
|
||||
showAllMedia: () => void;
|
||||
showContactModal: (conversationId: string) => void;
|
||||
showGroupChatColorEditor: () => void;
|
||||
showGroupLinkManagement: () => void;
|
||||
showGroupV2Permissions: () => void;
|
||||
|
|
|
@ -7,6 +7,7 @@ import { mapDispatchToProps } from '../actions';
|
|||
import { GlobalModalContainer } from '../../components/GlobalModalContainer';
|
||||
import { StateType } from '../reducer';
|
||||
import { SmartProfileEditorModal } from './ProfileEditorModal';
|
||||
import { SmartContactModal } from './ContactModal';
|
||||
|
||||
const FilteredSmartProfileEditorModal = SmartProfileEditorModal;
|
||||
|
||||
|
@ -14,9 +15,14 @@ function renderProfileEditor(): JSX.Element {
|
|||
return <FilteredSmartProfileEditorModal />;
|
||||
}
|
||||
|
||||
function renderContactModal(): JSX.Element {
|
||||
return <SmartContactModal />;
|
||||
}
|
||||
|
||||
const mapStateToProps = (state: StateType) => {
|
||||
return {
|
||||
...state.globalModals,
|
||||
renderContactModal,
|
||||
renderProfileEditor,
|
||||
};
|
||||
};
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue