diff --git a/src/components/views/rooms/EditMessageComposer.js b/src/components/views/rooms/EditMessageComposer.js index 6fc1d3e1ad..c59b3555b9 100644 --- a/src/components/views/rooms/EditMessageComposer.js +++ b/src/components/views/rooms/EditMessageComposer.js @@ -29,9 +29,10 @@ import EditorStateTransfer from '../../../utils/EditorStateTransfer'; import classNames from 'classnames'; import {EventStatus} from 'matrix-js-sdk'; import BasicMessageComposer from "./BasicMessageComposer"; -import {Key} from "../../../Keyboard"; +import {Key, isOnlyCtrlOrCmdKeyEvent} from "../../../Keyboard"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; import {Action} from "../../../dispatcher/actions"; +import SettingsStore from "../../../settings/SettingsStore"; import CountlyAnalytics from "../../../CountlyAnalytics"; function _isReply(mxEvent) { @@ -136,7 +137,10 @@ export default class EditMessageComposer extends React.Component { if (event.metaKey || event.altKey || event.shiftKey) { return; } - if (event.key === Key.ENTER) { + const ctrlEnterToSend = !!SettingsStore.getValue('MessageComposerInput.ctrlEnterToSend'); + const send = ctrlEnterToSend ? event.key === Key.ENTER && isOnlyCtrlOrCmdKeyEvent(event) + : event.key === Key.ENTER; + if (send) { this._sendEdit(); event.preventDefault(); } else if (event.key === Key.ESCAPE) { diff --git a/src/components/views/rooms/SendMessageComposer.js b/src/components/views/rooms/SendMessageComposer.js index 78b1dd85db..e88060304a 100644 --- a/src/components/views/rooms/SendMessageComposer.js +++ b/src/components/views/rooms/SendMessageComposer.js @@ -38,10 +38,11 @@ import * as sdk from '../../../index'; import Modal from '../../../Modal'; import {_t, _td} from '../../../languageHandler'; import ContentMessages from '../../../ContentMessages'; -import {Key} from "../../../Keyboard"; +import {Key, isOnlyCtrlOrCmdKeyEvent} from "../../../Keyboard"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; import RateLimitedFunc from '../../../ratelimitedfunc'; import {Action} from "../../../dispatcher/actions"; +import SettingsStore from "../../../settings/SettingsStore"; import CountlyAnalytics from "../../../CountlyAnalytics"; function addReplyToMessageContent(content, repliedToEvent, permalinkCreator) { @@ -122,7 +123,11 @@ export default class SendMessageComposer extends React.Component { return; } const hasModifier = event.altKey || event.ctrlKey || event.metaKey || event.shiftKey; - if (event.key === Key.ENTER && !hasModifier) { + const ctrlEnterToSend = !!SettingsStore.getValue('MessageComposerInput.ctrlEnterToSend'); + const send = ctrlEnterToSend + ? event.key === Key.ENTER && isOnlyCtrlOrCmdKeyEvent(event) + : event.key === Key.ENTER && !hasModifier; + if (send) { this._sendMessage(); event.preventDefault(); } else if (event.key === Key.ARROW_UP) { diff --git a/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.js b/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.js index bba337ee85..d6a4921f1a 100644 --- a/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.js +++ b/src/components/views/settings/tabs/user/PreferencesUserSettingsTab.js @@ -33,6 +33,7 @@ export default class PreferencesUserSettingsTab extends React.Component { 'MessageComposerInput.autoReplaceEmoji', 'MessageComposerInput.suggestEmoji', 'sendTypingNotifications', + 'MessageComposerInput.ctrlEnterToSend', ]; static TIMELINE_SETTINGS = [ diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 9eb3a2cb87..ff8c854866 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -730,6 +730,8 @@ "Enable big emoji in chat": "Enable big emoji in chat", "Send typing notifications": "Send typing notifications", "Show typing notifications": "Show typing notifications", + "Use Command + Enter to send a message": "Use Command + Enter to send a message", + "Use Ctrl + Enter to send a message": "Use Ctrl + Enter to send a message", "Automatically replace plain text Emoji": "Automatically replace plain text Emoji", "Mirror local video feed": "Mirror local video feed", "Enable Community Filter Panel": "Enable Community Filter Panel", diff --git a/src/settings/Settings.ts b/src/settings/Settings.ts index 6f4357973a..cc6fd29fe3 100644 --- a/src/settings/Settings.ts +++ b/src/settings/Settings.ts @@ -32,6 +32,7 @@ import UseSystemFontController from './controllers/UseSystemFontController'; import { SettingLevel } from "./SettingLevel"; import SettingController from "./controllers/SettingController"; import { RightPanelPhases } from "../stores/RightPanelStorePhases"; +import { isMac } from '../Keyboard'; import UIFeatureController from "./controllers/UIFeatureController"; import { UIFeature } from "./UIFeature"; import { OrderedMultiController } from "./controllers/OrderedMultiController"; @@ -324,6 +325,11 @@ export const SETTINGS: {[setting: string]: ISetting} = { displayName: _td("Show typing notifications"), default: true, }, + "MessageComposerInput.ctrlEnterToSend": { + supportedLevels: LEVELS_ACCOUNT_SETTINGS, + displayName: isMac ? _td("Use Command + Enter to send a message") : _td("Use Ctrl + Enter to send a message"), + default: false, + }, "MessageComposerInput.autoReplaceEmoji": { supportedLevels: LEVELS_ACCOUNT_SETTINGS, displayName: _td('Automatically replace plain text Emoji'),