Moves ConversationDetails to react panels
This commit is contained in:
parent
ff3ef0179b
commit
d4124abb01
16 changed files with 220 additions and 199 deletions
|
@ -3,7 +3,6 @@
|
|||
|
||||
import React from 'react';
|
||||
import type { Meta, Story } from '@storybook/react';
|
||||
import { action } from '@storybook/addon-actions';
|
||||
|
||||
import type { Props } from './AddUserToAnotherGroupModal';
|
||||
import enMessages from '../../_locales/en/messages.json';
|
||||
|
@ -30,12 +29,8 @@ export default {
|
|||
i18n: {
|
||||
defaultValue: i18n,
|
||||
},
|
||||
addMemberToGroup: {
|
||||
defaultValue: action('addMemberToGroup'),
|
||||
},
|
||||
toggleAddUserToAnotherGroupModal: {
|
||||
defaultValue: action('toggleAddUserToAnotherGroupModal'),
|
||||
},
|
||||
addMembersToGroup: { action: true },
|
||||
toggleAddUserToAnotherGroupModal: { action: true },
|
||||
},
|
||||
} as Meta;
|
||||
|
||||
|
|
|
@ -32,10 +32,13 @@ type OwnProps = {
|
|||
|
||||
type DispatchProps = {
|
||||
toggleAddUserToAnotherGroupModal: (contactId?: string) => void;
|
||||
addMemberToGroup: (
|
||||
addMembersToGroup: (
|
||||
conversationId: string,
|
||||
contactId: string,
|
||||
onComplete: () => void
|
||||
contactIds: Array<string>,
|
||||
opts: {
|
||||
onSuccess?: () => unknown;
|
||||
onFailure?: () => unknown;
|
||||
}
|
||||
) => void;
|
||||
showToast: (toastType: ToastType, parameters?: ReplacementValuesType) => void;
|
||||
};
|
||||
|
@ -47,7 +50,7 @@ export function AddUserToAnotherGroupModal({
|
|||
theme,
|
||||
contact,
|
||||
toggleAddUserToAnotherGroupModal,
|
||||
addMemberToGroup,
|
||||
addMembersToGroup,
|
||||
showToast,
|
||||
candidateConversations,
|
||||
regionCode,
|
||||
|
@ -203,12 +206,13 @@ export function AddUserToAnotherGroupModal({
|
|||
showToast(ToastType.AddingUserToGroup, {
|
||||
contact: contact.title,
|
||||
});
|
||||
addMemberToGroup(selectedGroupId, contact.id, () =>
|
||||
showToast(ToastType.UserAddedToGroup, {
|
||||
contact: contact.title,
|
||||
group: selectedGroup.title,
|
||||
})
|
||||
);
|
||||
addMembersToGroup(selectedGroupId, [contact.id], {
|
||||
onSuccess: () =>
|
||||
showToast(ToastType.UserAddedToGroup, {
|
||||
contact: contact.title,
|
||||
group: selectedGroup.title,
|
||||
}),
|
||||
});
|
||||
toggleAddUserToAnotherGroupModal(undefined);
|
||||
},
|
||||
},
|
||||
|
|
|
@ -37,7 +37,6 @@ const commonProps = {
|
|||
|
||||
i18n,
|
||||
|
||||
onShowConversationDetails: action('onShowConversationDetails'),
|
||||
setDisappearingMessages: action('setDisappearingMessages'),
|
||||
destroyMessages: action('destroyMessages'),
|
||||
onSearchInConversation: action('onSearchInConversation'),
|
||||
|
|
|
@ -93,7 +93,6 @@ export type PropsActionsType = {
|
|||
onOutgoingVideoCallInConversation: (conversationId: string) => void;
|
||||
onSearchInConversation: () => void;
|
||||
onShowAllMedia: () => void;
|
||||
onShowConversationDetails: () => void;
|
||||
pushPanelForConversation: PushPanelForConversationActionType;
|
||||
setDisappearingMessages: (
|
||||
conversationId: string,
|
||||
|
@ -352,7 +351,6 @@ export class ConversationHeader extends React.Component<PropsType, StateType> {
|
|||
onMarkUnread,
|
||||
onMoveToInbox,
|
||||
onShowAllMedia,
|
||||
onShowConversationDetails,
|
||||
pushPanelForConversation,
|
||||
setDisappearingMessages,
|
||||
setMuteExpiration,
|
||||
|
@ -475,7 +473,13 @@ export class ConversationHeader extends React.Component<PropsType, StateType> {
|
|||
))}
|
||||
</SubMenu>
|
||||
{!isGroup || hasGV2AdminEnabled ? (
|
||||
<MenuItem onClick={onShowConversationDetails}>
|
||||
<MenuItem
|
||||
onClick={() =>
|
||||
pushPanelForConversation(id, {
|
||||
type: PanelType.ConversationDetails,
|
||||
})
|
||||
}
|
||||
>
|
||||
{isGroup
|
||||
? i18n('showConversationDetails')
|
||||
: i18n('showConversationDetails--direct')}
|
||||
|
@ -552,8 +556,13 @@ export class ConversationHeader extends React.Component<PropsType, StateType> {
|
|||
}
|
||||
|
||||
private renderHeader(): ReactNode {
|
||||
const { conversationTitle, groupVersion, onShowConversationDetails, type } =
|
||||
this.props;
|
||||
const {
|
||||
conversationTitle,
|
||||
id,
|
||||
groupVersion,
|
||||
pushPanelForConversation,
|
||||
type,
|
||||
} = this.props;
|
||||
|
||||
if (conversationTitle !== undefined) {
|
||||
return (
|
||||
|
@ -571,14 +580,16 @@ export class ConversationHeader extends React.Component<PropsType, StateType> {
|
|||
switch (type) {
|
||||
case 'direct':
|
||||
onClick = () => {
|
||||
onShowConversationDetails();
|
||||
pushPanelForConversation(id, { type: PanelType.ConversationDetails });
|
||||
};
|
||||
break;
|
||||
case 'group': {
|
||||
const hasGV2AdminEnabled = groupVersion === 2;
|
||||
onClick = hasGV2AdminEnabled
|
||||
? () => {
|
||||
onShowConversationDetails();
|
||||
pushPanelForConversation(id, {
|
||||
type: PanelType.ConversationDetails,
|
||||
});
|
||||
}
|
||||
: undefined;
|
||||
break;
|
||||
|
|
|
@ -41,8 +41,8 @@ const createProps = (
|
|||
expireTimer?: DurationInSeconds
|
||||
): Props => ({
|
||||
acceptConversation: action('acceptConversation'),
|
||||
addMembers: async () => {
|
||||
action('addMembers');
|
||||
addMembersToGroup: async () => {
|
||||
action('addMembersToGroup');
|
||||
},
|
||||
areWeASubscriber: false,
|
||||
blockConversation: action('blockConversation'),
|
||||
|
@ -57,10 +57,12 @@ const createProps = (
|
|||
hasActiveCall: false,
|
||||
hasGroupLink,
|
||||
getPreferredBadge: () => undefined,
|
||||
getProfilesForConversation: action('getProfilesForConversation'),
|
||||
groupsInCommon: [],
|
||||
i18n,
|
||||
isAdmin: false,
|
||||
isGroup: true,
|
||||
leaveGroup: action('leaveGroup'),
|
||||
loadRecentMediaItems: action('loadRecentMediaItems'),
|
||||
memberships: times(32, i => ({
|
||||
isAdmin: i === 1,
|
||||
|
@ -78,7 +80,6 @@ const createProps = (
|
|||
member: getDefaultConversation(),
|
||||
})),
|
||||
setDisappearingMessages: action('setDisappearingMessages'),
|
||||
showAllMedia: action('showAllMedia'),
|
||||
showContactModal: action('showContactModal'),
|
||||
pushPanelForConversation: action('pushPanelForConversation'),
|
||||
showConversation: action('showConversation'),
|
||||
|
@ -86,7 +87,6 @@ const createProps = (
|
|||
updateGroupAttributes: async () => {
|
||||
action('updateGroupAttributes')();
|
||||
},
|
||||
onLeave: action('onLeave'),
|
||||
deleteAvatarFromDisk: action('deleteAvatarFromDisk'),
|
||||
replaceAvatar: action('replaceAvatar'),
|
||||
saveAvatarToDisk: action('saveAvatarToDisk'),
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
// SPDX-License-Identifier: AGPL-3.0-only
|
||||
|
||||
import type { ReactNode } from 'react';
|
||||
import React, { useState } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
|
||||
import { Button, ButtonIconType, ButtonVariant } from '../../Button';
|
||||
import { Tooltip } from '../../Tooltip';
|
||||
|
@ -63,7 +63,6 @@ enum ModalState {
|
|||
}
|
||||
|
||||
export type StateProps = {
|
||||
addMembers: (conversationIds: ReadonlyArray<string>) => Promise<void>;
|
||||
areWeASubscriber: boolean;
|
||||
badges?: ReadonlyArray<BadgeType>;
|
||||
canEditGroupInfo: boolean;
|
||||
|
@ -81,15 +80,6 @@ export type StateProps = {
|
|||
memberships: Array<GroupV2Membership>;
|
||||
pendingApprovalMemberships: ReadonlyArray<GroupV2RequestingMembership>;
|
||||
pendingMemberships: ReadonlyArray<GroupV2PendingMembership>;
|
||||
showAllMedia: () => void;
|
||||
updateGroupAttributes: (
|
||||
_: Readonly<{
|
||||
avatar?: undefined | Uint8Array;
|
||||
description?: string;
|
||||
title?: string;
|
||||
}>
|
||||
) => Promise<void>;
|
||||
onLeave: () => void;
|
||||
theme: ThemeType;
|
||||
userAvatarData: Array<AvatarDataType>;
|
||||
renderChooseGroupMembersModal: (
|
||||
|
@ -102,8 +92,18 @@ export type StateProps = {
|
|||
|
||||
type ActionProps = {
|
||||
acceptConversation: (id: string) => void;
|
||||
addMembersToGroup: (
|
||||
conversationId: string,
|
||||
conversationIds: ReadonlyArray<string>,
|
||||
opts: {
|
||||
onSuccess?: () => unknown;
|
||||
onFailure?: () => unknown;
|
||||
}
|
||||
) => unknown;
|
||||
blockConversation: (id: string) => void;
|
||||
deleteAvatarFromDisk: DeleteAvatarFromDiskActionType;
|
||||
getProfilesForConversation: (id: string) => unknown;
|
||||
leaveGroup: (conversationId: string) => void;
|
||||
loadRecentMediaItems: (id: string, limit: number) => void;
|
||||
onOutgoingAudioCallInConversation: (conversationId: string) => unknown;
|
||||
onOutgoingVideoCallInConversation: (conversationId: string) => unknown;
|
||||
|
@ -117,13 +117,25 @@ type ActionProps = {
|
|||
showConversation: ShowConversationType;
|
||||
toggleAddUserToAnotherGroupModal: (contactId?: string) => void;
|
||||
toggleSafetyNumberModal: (conversationId: string) => unknown;
|
||||
updateGroupAttributes: (
|
||||
conversationId: string,
|
||||
_: Readonly<{
|
||||
avatar?: undefined | Uint8Array;
|
||||
description?: string;
|
||||
title?: string;
|
||||
}>,
|
||||
opts: {
|
||||
onSuccess?: () => unknown;
|
||||
onFailure?: () => unknown;
|
||||
}
|
||||
) => unknown;
|
||||
} & Pick<ConversationDetailsMediaListPropsType, 'showLightboxWithMedia'>;
|
||||
|
||||
export type Props = StateProps & ActionProps;
|
||||
|
||||
export function ConversationDetails({
|
||||
acceptConversation,
|
||||
addMembers,
|
||||
addMembersToGroup,
|
||||
areWeASubscriber,
|
||||
badges,
|
||||
blockConversation,
|
||||
|
@ -133,16 +145,17 @@ export function ConversationDetails({
|
|||
deleteAvatarFromDisk,
|
||||
hasGroupLink,
|
||||
getPreferredBadge,
|
||||
getProfilesForConversation,
|
||||
groupsInCommon,
|
||||
hasActiveCall,
|
||||
i18n,
|
||||
isAdmin,
|
||||
isGroup,
|
||||
leaveGroup,
|
||||
loadRecentMediaItems,
|
||||
memberships,
|
||||
maxGroupSize,
|
||||
maxRecommendedGroupSize,
|
||||
onLeave,
|
||||
onOutgoingAudioCallInConversation,
|
||||
onOutgoingVideoCallInConversation,
|
||||
pendingApprovalMemberships,
|
||||
|
@ -155,7 +168,6 @@ export function ConversationDetails({
|
|||
searchInConversation,
|
||||
setDisappearingMessages,
|
||||
setMuteExpiration,
|
||||
showAllMedia,
|
||||
showContactModal,
|
||||
showConversation,
|
||||
showLightboxWithMedia,
|
||||
|
@ -177,6 +189,10 @@ export function ConversationDetails({
|
|||
throw new Error('ConversationDetails rendered without a conversation');
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
getProfilesForConversation(conversation.id);
|
||||
}, [conversation.id, getProfilesForConversation]);
|
||||
|
||||
const invitesCount =
|
||||
pendingMemberships.length + pendingApprovalMemberships.length;
|
||||
|
||||
|
@ -214,15 +230,17 @@ export function ConversationDetails({
|
|||
) => {
|
||||
setEditGroupAttributesRequestState(RequestState.Active);
|
||||
|
||||
try {
|
||||
await updateGroupAttributes(options);
|
||||
setModalState(ModalState.NothingOpen);
|
||||
setEditGroupAttributesRequestState(RequestState.Inactive);
|
||||
} catch (err) {
|
||||
setEditGroupAttributesRequestState(
|
||||
RequestState.InactiveWithError
|
||||
);
|
||||
}
|
||||
updateGroupAttributes(conversation.id, options, {
|
||||
onSuccess: () => {
|
||||
setModalState(ModalState.NothingOpen);
|
||||
setEditGroupAttributesRequestState(RequestState.Inactive);
|
||||
},
|
||||
onFailure: () => {
|
||||
setEditGroupAttributesRequestState(
|
||||
RequestState.InactiveWithError
|
||||
);
|
||||
},
|
||||
});
|
||||
}}
|
||||
onClose={() => {
|
||||
setModalState(ModalState.NothingOpen);
|
||||
|
@ -259,13 +277,15 @@ export function ConversationDetails({
|
|||
makeRequest={async conversationIds => {
|
||||
setAddGroupMembersRequestState(RequestState.Active);
|
||||
|
||||
try {
|
||||
await addMembers(conversationIds);
|
||||
setModalState(ModalState.NothingOpen);
|
||||
setAddGroupMembersRequestState(RequestState.Inactive);
|
||||
} catch (err) {
|
||||
setAddGroupMembersRequestState(RequestState.InactiveWithError);
|
||||
}
|
||||
addMembersToGroup(conversation.id, conversationIds, {
|
||||
onSuccess: () => {
|
||||
setModalState(ModalState.NothingOpen);
|
||||
setAddGroupMembersRequestState(RequestState.Inactive);
|
||||
},
|
||||
onFailure: () => {
|
||||
setAddGroupMembersRequestState(RequestState.InactiveWithError);
|
||||
},
|
||||
});
|
||||
}}
|
||||
maxGroupSize={maxGroupSize}
|
||||
maxRecommendedGroupSize={maxRecommendedGroupSize}
|
||||
|
@ -545,7 +565,11 @@ export function ConversationDetails({
|
|||
conversation={conversation}
|
||||
i18n={i18n}
|
||||
loadRecentMediaItems={loadRecentMediaItems}
|
||||
showAllMedia={showAllMedia}
|
||||
showAllMedia={() =>
|
||||
pushPanelForConversation(conversation.id, {
|
||||
type: PanelType.AllMedia,
|
||||
})
|
||||
}
|
||||
showLightboxWithMedia={showLightboxWithMedia}
|
||||
/>
|
||||
|
||||
|
@ -570,7 +594,7 @@ export function ConversationDetails({
|
|||
isBlocked={Boolean(conversation.isBlocked)}
|
||||
isGroup={isGroup}
|
||||
left={Boolean(conversation.left)}
|
||||
onLeave={onLeave}
|
||||
onLeave={() => leaveGroup(conversation.id)}
|
||||
/>
|
||||
)}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue