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 (