diff --git a/ts/components/session/SessionConfirm.tsx b/ts/components/session/SessionConfirm.tsx index 0d0fb6d98..606a26f05 100644 --- a/ts/components/session/SessionConfirm.tsx +++ b/ts/components/session/SessionConfirm.tsx @@ -39,12 +39,10 @@ const SessionConfirmInner = (props: SessionConfirmDialogProps) => { closeTheme = SessionButtonColor.Primary, onClickOk, onClickClose, - closeAfterClickOk = true, hideCancel = false, sessionIcon, iconSize, shouldShowConfirm, - // updateConfirmModal } = props; const okText = props.okText || window.i18n('ok'); @@ -55,19 +53,6 @@ const SessionConfirmInner = (props: SessionConfirmDialogProps) => { const messageSubText = messageSub ? 'session-confirm-main-message' : 'subtle'; - /** - * 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(); @@ -80,6 +65,9 @@ const SessionConfirmInner = (props: SessionConfirmDialogProps) => { return null; } + /** + * Performs specified on close action then removes the modal. + */ const onClickCancelHandler = () => { if (onClickClose) { onClickClose(); @@ -114,11 +102,9 @@ const SessionConfirmInner = (props: SessionConfirmDialogProps) => {
- {/* */} {!hideCancel && ( - // { showExitIcon, headerIconButtons, headerReverse, - additionalClassName + additionalClassName, } = props; const theme = useTheme(); @@ -75,7 +75,7 @@ export const SessionWrapperModal = (props: SessionWrapperModalType) => { }; return ( -
+
{showHeader ? ( diff --git a/ts/components/session/conversation/SessionCompositionBox.tsx b/ts/components/session/conversation/SessionCompositionBox.tsx index f1fc5900a..40c431a6b 100644 --- a/ts/components/session/conversation/SessionCompositionBox.tsx +++ b/ts/components/session/conversation/SessionCompositionBox.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import _, { debounce } from 'lodash'; +import _, { debounce, update } from 'lodash'; import { Attachment, AttachmentType } from '../../../types/Attachment'; import * as MIME from '../../../types/MIME'; @@ -38,6 +38,11 @@ import { updateMentionsMembers, } from '../../../state/ducks/mentionsInput'; import { getMentionsInput } from '../../../state/selectors/mentionsInput'; +import { useDispatch } from 'react-redux'; +import { updateConfirmModal } from '../../../state/ducks/modalDialog'; +import { SessionButtonColor } from '../SessionButton'; +import { any } from 'underscore'; +import { SessionConfirmDialogProps } from '../SessionConfirm'; export interface ReplyingToMessageProps { convoId: string; @@ -88,6 +93,7 @@ interface Props { showLeftPaneSection: (section: SectionType) => void; showSettingsSection: (category: SessionSettingCategory) => void; theme: DefaultTheme; + updateConfirmModal: (props: SessionConfirmDialogProps) => any; } interface State { @@ -209,9 +215,20 @@ export class SessionCompositionBox extends React.Component { const { items } = e.clipboardData; let imgBlob = null; for (const item of items) { - if (item.type.split('/')[0] === 'image') { + const pasteType = item.type.split('/')[0]; + if (pasteType === 'image') { imgBlob = item.getAsFile(); } + + switch (pasteType) { + case 'image': + imgBlob = item.getAsFile(); + break; + case 'text': + this.showLinkSharingConfirmationModalDialog(e); + break; + default: + } } if (imgBlob !== null) { const file = imgBlob; @@ -223,6 +240,37 @@ export class SessionCompositionBox extends React.Component { } } + /** + * Check if what is pasted is a URL and prompt confirmation for a setting change + * @param e paste event + */ + private showLinkSharingConfirmationModalDialog(e: any) { + const pastedText = e.clipboardData.getData('text'); + if (this.isURL(pastedText)) { + this.props.updateConfirmModal({ + shouldShowConfirm: () => !window.getSettingValue('link-preview-setting'), + title: window.i18n('linkPreviewsTitle'), + message: window.i18n('linkPreviewsConfirmMessage'), + okTheme: SessionButtonColor.Danger, + onClickOk: () => { + window.setSettingValue('link-preview-setting', true); + }, + }); + } + } + + /** + * + * @param str String to evaluate + * @returns boolean if the string is true or false + */ + private isURL(str: string) { + const urlRegex = + '^(?!mailto:)(?:(?:http|https|ftp)://)(?:\\S+(?::\\S*)?@)?(?:(?:(?:[1-9]\\d?|1\\d\\d|2[01]\\d|22[0-3])(?:\\.(?:1?\\d{1,2}|2[0-4]\\d|25[0-5])){2}(?:\\.(?:[0-9]\\d?|1\\d\\d|2[0-4]\\d|25[0-4]))|(?:(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)(?:\\.(?:[a-z\\u00a1-\\uffff0-9]+-?)*[a-z\\u00a1-\\uffff0-9]+)*(?:\\.(?:[a-z\\u00a1-\\uffff]{2,})))|localhost)(?::\\d{2,5})?(?:(/|\\?|#)[^\\s]*)?$'; + const url = new RegExp(urlRegex, 'i'); + return str.length < 2083 && url.test(str); + } + private showEmojiPanel() { document.addEventListener('mousedown', this.handleClick, false); @@ -515,8 +563,6 @@ export class SessionCompositionBox extends React.Component { }} /> ); - - return <>; } private fetchLinkPreview(firstLink: string) { diff --git a/ts/components/session/conversation/SessionConversation.tsx b/ts/components/session/conversation/SessionConversation.tsx index c599965a5..55b01dae2 100644 --- a/ts/components/session/conversation/SessionConversation.tsx +++ b/ts/components/session/conversation/SessionConversation.tsx @@ -304,6 +304,7 @@ export class SessionConversation extends React.Component { removeAttachment={this.removeAttachment} onChoseAttachments={this.onChoseAttachments} theme={this.props.theme} + updateConfirmModal={actions.updateConfirmModal} />
diff --git a/ts/components/session/icon/SessionIcon.tsx b/ts/components/session/icon/SessionIcon.tsx index c0eda6927..2b1bb9934 100644 --- a/ts/components/session/icon/SessionIcon.tsx +++ b/ts/components/session/icon/SessionIcon.tsx @@ -131,7 +131,7 @@ const SessionSvg = (props: { viewBox: props.viewBox, glowDuration: props.glowDuration, glowStartDelay: props.glowStartDelay, - iconColor: props.iconColor + iconColor: props.iconColor, }; return (