Refactoring subcomponents. Adjusting conditional inbox filters to always apply msg request logic.

pull/2170/head
warrickct 4 years ago
parent ac8c4ac2eb
commit 07f6681aae

@ -0,0 +1,83 @@
import React from 'react';
import styled from 'styled-components';
import {
acceptConversation,
blockConvoById,
declineConversation,
} from '../../interactions/conversationInteractions';
import { forceSyncConfigurationNowIfNeeded } from '../../session/utils/syncUtils';
import { ReduxConversationType } from '../../state/ducks/conversations';
import { updateConfirmModal } from '../../state/ducks/modalDialog';
import { SessionButton, SessionButtonColor, SessionButtonType } from '../basic/SessionButton';
export const ConversationMessageRequestButtons = (props: {
selectedConversation: ReduxConversationType;
}) => {
const { selectedConversation } = props;
const { isApproved, type } = selectedConversation;
const showMsgRequestUI = !isApproved && type === 'private';
const handleDeclineConversationRequest = async () => {
window.inboxStore?.dispatch(
updateConfirmModal({
okText: window.i18n('decline'),
cancelText: window.i18n('cancel'),
message: window.i18n('declineRequestMessage'),
onClickOk: async () => {
await declineConversation(selectedConversation.id, false);
await blockConvoById(selectedConversation.id);
await forceSyncConfigurationNowIfNeeded();
},
onClickCancel: () => {
window.inboxStore?.dispatch(updateConfirmModal(null));
},
onClickClose: () => {
window.inboxStore?.dispatch(updateConfirmModal(null));
},
})
);
};
const handleAcceptConversationRequest = async () => {
const { id } = selectedConversation;
await acceptConversation(id, true);
};
if (!showMsgRequestUI) {
return null;
}
return (
<ConversationRequestBanner>
<ConversationBannerRow>
<SessionButton
buttonColor={SessionButtonColor.Green}
buttonType={SessionButtonType.BrandOutline}
onClick={handleAcceptConversationRequest}
text={window.i18n('accept')}
/>
<SessionButton
buttonColor={SessionButtonColor.Danger}
buttonType={SessionButtonType.BrandOutline}
text={window.i18n('decline')}
onClick={handleDeclineConversationRequest}
/>
</ConversationBannerRow>
</ConversationRequestBanner>
);
};
const ConversationBannerRow = styled.div`
display: flex;
flex-direction: row;
gap: var(--margins-lg);
justify-content: center;
`;
const ConversationRequestBanner = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
padding: var(--margins-lg);
gap: var(--margins-lg);
`;

@ -0,0 +1,34 @@
import React from 'react';
import styled from 'styled-components';
import { ReduxConversationType } from '../../state/ducks/conversations';
export const ConversationRequestinfo = (props: { selectedConversation: ReduxConversationType }) => {
const { selectedConversation } = props;
const { isApproved, type } = selectedConversation;
const showMsgRequestUI = !isApproved && type === 'private';
if (!showMsgRequestUI) {
return null;
}
return (
<ConversationRequestTextBottom>
<ConversationRequestTextInner>
{window.i18n('respondingToRequestWarning')}
</ConversationRequestTextInner>
</ConversationRequestTextBottom>
);
};
const ConversationRequestTextBottom = styled.div`
display: flex;
flex-direction: row;
justify-content: center;
padding: var(--margins-lg);
`;
const ConversationRequestTextInner = styled.div`
color: var(--color-text-subtle);
text-align: center;
max-width: 390px;
`;

@ -34,7 +34,7 @@ import { addStagedAttachmentsInConversation } from '../../state/ducks/stagedAtta
import { MIME } from '../../types'; import { MIME } from '../../types';
import { AttachmentTypeWithPath } from '../../types/Attachment'; import { AttachmentTypeWithPath } from '../../types/Attachment';
import { arrayBufferToObjectURL, AttachmentUtil, GoogleChrome } from '../../util'; import { arrayBufferToObjectURL, AttachmentUtil, GoogleChrome } from '../../util';
import { SessionButton, SessionButtonColor, SessionButtonType } from '../basic/SessionButton'; import { SessionButtonColor } from '../basic/SessionButton';
import { MessageView } from '../MainViewController'; import { MessageView } from '../MainViewController';
import { ConversationHeaderWithDetails } from './ConversationHeader'; import { ConversationHeaderWithDetails } from './ConversationHeader';
import { MessageDetail } from './message/message-item/MessageDetail'; import { MessageDetail } from './message/message-item/MessageDetail';
@ -47,13 +47,8 @@ import {
} from '../../types/attachments/VisualAttachment'; } from '../../types/attachments/VisualAttachment';
import { blobToArrayBuffer } from 'blob-util'; import { blobToArrayBuffer } from 'blob-util';
import { MAX_ATTACHMENT_FILESIZE_BYTES } from '../../session/constants'; import { MAX_ATTACHMENT_FILESIZE_BYTES } from '../../session/constants';
import styled from 'styled-components'; import { ConversationMessageRequestButtons } from './ConversationRequestButtons';
import { import { ConversationRequestinfo } from './ConversationRequestInfo';
acceptConversation,
blockConvoById,
declineConversation,
} from '../../interactions/conversationInteractions';
import { forceSyncConfigurationNowIfNeeded } from '../../session/utils/syncUtils';
// tslint:disable: jsx-curly-spacing // tslint:disable: jsx-curly-spacing
interface State { interface State {
@ -228,36 +223,7 @@ export class SessionConversation extends React.Component<Props, State> {
return <MessageView />; return <MessageView />;
} }
const isApproved = selectedConversation.isApproved;
const selectionMode = selectedMessages.length > 0; const selectionMode = selectedMessages.length > 0;
const useMsgRequests = window.inboxStore?.getState().userConfig.messageRequests;
const showMsgRequestUI = useMsgRequests && !isApproved && messagesProps.length > 0;
const handleDeclineConversationRequest = async () => {
window.inboxStore?.dispatch(
updateConfirmModal({
okText: window.i18n('decline'),
cancelText: window.i18n('cancel'),
message: window.i18n('declineRequestMessage'),
onClickOk: async () => {
await declineConversation(selectedConversation.id, false);
await blockConvoById(selectedConversation.id);
await forceSyncConfigurationNowIfNeeded();
},
onClickCancel: () => {
window.inboxStore?.dispatch(updateConfirmModal(null));
},
onClickClose: () => {
window.inboxStore?.dispatch(updateConfirmModal(null));
},
})
);
};
const handleAcceptConversationRequest = async () => {
const { id } = selectedConversation;
await acceptConversation(id, true);
};
return ( return (
<SessionTheme> <SessionTheme>
@ -277,24 +243,7 @@ export class SessionConversation extends React.Component<Props, State> {
{lightBoxOptions?.media && this.renderLightBox(lightBoxOptions)} {lightBoxOptions?.media && this.renderLightBox(lightBoxOptions)}
<div className="conversation-messages"> <div className="conversation-messages">
{showMsgRequestUI && ( <ConversationMessageRequestButtons selectedConversation={selectedConversation} />
<ConversationRequestBanner>
<ConversationBannerRow>
<SessionButton
buttonColor={SessionButtonColor.Green}
buttonType={SessionButtonType.BrandOutline}
onClick={handleAcceptConversationRequest}
text={window.i18n('accept')}
/>
<SessionButton
buttonColor={SessionButtonColor.Danger}
buttonType={SessionButtonType.BrandOutline}
text={window.i18n('decline')}
onClick={handleDeclineConversationRequest}
/>
</ConversationBannerRow>
</ConversationRequestBanner>
)}
<SplitViewContainer <SplitViewContainer
top={<InConversationCallContainer />} top={<InConversationCallContainer />}
bottom={ bottom={
@ -306,14 +255,7 @@ export class SessionConversation extends React.Component<Props, State> {
{isDraggingFile && <SessionFileDropzone />} {isDraggingFile && <SessionFileDropzone />}
</div> </div>
{showMsgRequestUI && ( <ConversationRequestinfo selectedConversation={selectedConversation} />
<ConversationRequestTextBottom>
<ConversationRequestTextInner>
{window.i18n('respondingToRequestWarning')}
</ConversationRequestTextInner>
</ConversationRequestTextBottom>
)}
<CompositionBox <CompositionBox
sendMessage={this.sendMessageFn} sendMessage={this.sendMessageFn}
stagedAttachments={this.props.stagedAttachments} stagedAttachments={this.props.stagedAttachments}
@ -568,41 +510,6 @@ const renderVideoPreview = async (contentType: string, file: File, fileName: str
} }
}; };
const ConversationBannerRow = styled.div`
display: flex;
flex-direction: row;
gap: var(--margins-lg);
justify-content: center;
`;
const ConversationRequestTextBottom = styled.div`
display: flex;
flex-direction: row;
justify-content: center;
padding: var(--margins-lg);
`;
const ConversationRequestTextInner = styled.div`
color: var(--color-text-subtle);
text-align: center;
max-width: 390px;
`;
const ConversationRequestBanner = styled.div`
display: flex;
flex-direction: column;
justify-content: center;
padding: var(--margins-lg);
gap: var(--margins-lg);
.conversation-request-banner__row {
display: flex;
flex-direction: row;
gap: var(--margins-lg);
justify-content: center;
}
`;
const renderImagePreview = async (contentType: string, file: File, fileName: string) => { const renderImagePreview = async (contentType: string, file: File, fileName: string) => {
if (!MIME.isJPEG(contentType)) { if (!MIME.isJPEG(contentType)) {
const urlImage = URL.createObjectURL(file); const urlImage = URL.createObjectURL(file);

@ -2,6 +2,7 @@ import React from 'react';
import { useSelector } from 'react-redux'; import { useSelector } from 'react-redux';
import styled from 'styled-components'; import styled from 'styled-components';
import { getConversationRequests } from '../../state/selectors/conversations'; import { getConversationRequests } from '../../state/selectors/conversations';
import { getIsMessageRequestsEnabled } from '../../state/selectors/userConfig';
import { SessionIcon, SessionIconSize, SessionIconType } from '../icon'; import { SessionIcon, SessionIconSize, SessionIconType } from '../icon';
const StyledMessageRequestBanner = styled.div` const StyledMessageRequestBanner = styled.div`
@ -84,8 +85,9 @@ export const CirclularIcon = (props: { iconType: SessionIconType; iconSize: Sess
export const MessageRequestsBanner = (props: { handleOnClick: () => any }) => { export const MessageRequestsBanner = (props: { handleOnClick: () => any }) => {
const { handleOnClick } = props; const { handleOnClick } = props;
const conversationRequests = useSelector(getConversationRequests); const conversationRequests = useSelector(getConversationRequests);
const showRequestBannerEnabled = useSelector(getIsMessageRequestsEnabled);
if (!conversationRequests.length) { if (!conversationRequests.length || !showRequestBannerEnabled) {
return null; return null;
} }

@ -657,11 +657,11 @@ export class ConversationModel extends Backbone.Model<ConversationAttributes> {
} }
// TODO: remove once dev-tested // TODO: remove once dev-tested
// if (chatMessageParams.body?.includes('unapprove')) { if (chatMessageParams.body?.includes('unapprove')) {
// await this.setIsApproved(false); await this.setIsApproved(false);
// await this.setDidApproveMe(false); await this.setDidApproveMe(false);
// // void forceSyncConfigurationNowIfNeeded(); // void forceSyncConfigurationNowIfNeeded();
// } }
if (this.isOpenGroupV2()) { if (this.isOpenGroupV2()) {
const chatMessageOpenGroupV2 = new OpenGroupVisibleMessage(chatMessageParams); const chatMessageOpenGroupV2 = new OpenGroupVisibleMessage(chatMessageParams);

@ -328,8 +328,7 @@ export const getConversationComparator = createSelector(getIntl, _getConversatio
// export only because we use it in some of our tests // export only because we use it in some of our tests
// tslint:disable-next-line: cyclomatic-complexity // tslint:disable-next-line: cyclomatic-complexity
export const _getLeftPaneLists = ( export const _getLeftPaneLists = (
sortedConversations: Array<ReduxConversationType>, sortedConversations: Array<ReduxConversationType>
isMessageRequestEnabled?: boolean
): { ): {
conversations: Array<ReduxConversationType>; conversations: Array<ReduxConversationType>;
contacts: Array<ReduxConversationType>; contacts: Array<ReduxConversationType>;
@ -344,7 +343,7 @@ export const _getLeftPaneLists = (
directConversations.push(conversation); directConversations.push(conversation);
} }
if (isMessageRequestEnabled && !conversation.isApproved && !conversation.isBlocked) { if (!conversation.isApproved && !conversation.isBlocked) {
// dont increase unread counter, don't push to convo list. // dont increase unread counter, don't push to convo list.
continue; continue;
} }
@ -424,16 +423,13 @@ export const getSortedConversations = createSelector(
/** /**
* *
* @param sortedConversations List of conversations that are valid for both requests and regular conversation inbox * @param sortedConversations List of conversations that are valid for both requests and regular conversation inbox
* @param isMessageRequestEnabled Apply message request filtering.
* @returns A list of message request conversations. * @returns A list of message request conversations.
*/ */
const _getConversationRequests = ( const _getConversationRequests = (
sortedConversations: Array<ReduxConversationType>, sortedConversations: Array<ReduxConversationType>
isMessageRequestEnabled?: boolean
): Array<ReduxConversationType> => { ): Array<ReduxConversationType> => {
return _.filter(sortedConversations, conversation => { return _.filter(sortedConversations, conversation => {
return ( return (
isMessageRequestEnabled &&
!conversation.isApproved && !conversation.isApproved &&
!conversation.isBlocked && !conversation.isBlocked &&
conversation.isPrivate && conversation.isPrivate &&
@ -449,16 +445,15 @@ export const getConversationRequests = createSelector(
); );
const _getPrivateContactsPubkeys = ( const _getPrivateContactsPubkeys = (
sortedConversations: Array<ReduxConversationType>, sortedConversations: Array<ReduxConversationType>
isMessageRequestEnabled?: boolean
): Array<string> => { ): Array<string> => {
return _.filter(sortedConversations, conversation => { return _.filter(sortedConversations, conversation => {
return ( return (
conversation.isPrivate && conversation.isPrivate &&
!conversation.isBlocked && !conversation.isBlocked &&
!conversation.isMe && !conversation.isMe &&
(conversation.didApproveMe || !isMessageRequestEnabled) && conversation.didApproveMe &&
(conversation.isApproved || !isMessageRequestEnabled) && conversation.isApproved &&
Boolean(conversation.activeAt) Boolean(conversation.activeAt)
); );
}).map(convo => convo.id); }).map(convo => convo.id);

1
ts/window.d.ts vendored

@ -42,7 +42,6 @@ declare global {
log: any; log: any;
lokiFeatureFlags: { lokiFeatureFlags: {
useOnionRequests: boolean; useOnionRequests: boolean;
useMessageRequests: boolean;
useCallMessage: boolean; useCallMessage: boolean;
}; };
lokiSnodeAPI: LokiSnodeAPI; lokiSnodeAPI: LokiSnodeAPI;

Loading…
Cancel
Save