Merge pull request #2955 from KeeJef/settings-update

feat: Allow enter to break line in settings
pull/2994/head
Audric Ackermann 1 year ago committed by GitHub
commit f65895f013
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -411,6 +411,10 @@
"open": "Open", "open": "Open",
"audioMessageAutoplayTitle": "Autoplay Audio Messages", "audioMessageAutoplayTitle": "Autoplay Audio Messages",
"audioMessageAutoplayDescription": "Autoplay consecutive audio messages.", "audioMessageAutoplayDescription": "Autoplay consecutive audio messages.",
"enterKeySettingTitle": "Enter Key",
"enterKeySettingDescription": "Function of the enter key when typing in a conversation.",
"enterSendNewMessageDescription": "ENTER sends a message, SHIFT + ENTER starts a new line",
"enterNewLineDescription": "SHIFT + ENTER sends a message, ENTER starts a new line",
"clickToTrustContact": "Click to download media", "clickToTrustContact": "Click to download media",
"trustThisContactDialogTitle": "Trust $name$?", "trustThisContactDialogTitle": "Trust $name$?",
"trustThisContactDialogDescription": "Are you sure you want to download media sent by $name$?", "trustThisContactDialogDescription": "Are you sure you want to download media sent by $name$?",

@ -8,7 +8,7 @@ interface Props {
initialItem: string; initialItem: string;
items: Array<{ value: string; label: string }>; items: Array<{ value: string; label: string }>;
group: string; group: string;
onClick: (selectedValue: string) => any; onClick: (selectedValue: string) => void;
style?: CSSProperties; style?: CSSProperties;
} }

@ -832,8 +832,19 @@ class CompositionBoxInner extends React.Component<Props, State> {
} }
private async onKeyDown(event: any) { private async onKeyDown(event: any) {
if (event.key === 'Enter' && !event.shiftKey && !event.nativeEvent.isComposing) { const isEnter = event.key === 'Enter';
// If shift, newline. If in IME composing mode, leave it to IME. Else send message. const isShiftEnter = event.shiftKey && isEnter;
const isShiftSendEnabled = window.getSettingValue(SettingsKey.hasShiftSendEnabled) as boolean;
const isNotComposing = !event.nativeEvent.isComposing;
if (isShiftSendEnabled && isEnter && isNotComposing) {
event.preventDefault();
if (isShiftEnter) {
await this.onSendMessage();
} else {
this.insertNewLine();
}
} else if (isEnter && !event.shiftKey && isNotComposing) {
event.preventDefault(); event.preventDefault();
await this.onSendMessage(); await this.onSendMessage();
} else if (event.key === 'Escape' && this.state.showEmojiPanel) { } else if (event.key === 'Escape' && this.state.showEmojiPanel) {
@ -845,6 +856,34 @@ class CompositionBoxInner extends React.Component<Props, State> {
} }
} }
private insertNewLine() {
const messageBox = this.textarea.current;
if (!messageBox) {
return;
}
const { draft } = this.state;
const { selectedConversationKey } = this.props;
if (!selectedConversationKey) {
return; // add this check to prevent undefined from being used
}
const currentSelectionStart = Number(messageBox.selectionStart);
const realSelectionStart = getSelectionBasedOnMentions(draft, currentSelectionStart);
const before = draft.slice(0, realSelectionStart);
const after = draft.slice(realSelectionStart);
const updatedDraft = `${before}\n${after}`;
this.setState({ draft: updatedDraft });
updateDraftForConversation({
conversationKey: selectedConversationKey,
draft: updatedDraft,
});
}
private async onKeyUp() { private async onKeyUp() {
if (!this.props.selectedConversationKey) { if (!this.props.selectedConversationKey) {
throw new Error('selectedConversationKey is needed'); throw new Error('selectedConversationKey is needed');

@ -6,10 +6,13 @@ import { SettingsKey } from '../../../data/settings-key';
import { ToastUtils } from '../../../session/utils'; import { ToastUtils } from '../../../session/utils';
import { toggleAudioAutoplay } from '../../../state/ducks/userConfig'; import { toggleAudioAutoplay } from '../../../state/ducks/userConfig';
import { getAudioAutoplay } from '../../../state/selectors/userConfig'; import { getAudioAutoplay } from '../../../state/selectors/userConfig';
import { SessionRadioGroup } from '../../basic/SessionRadioGroup';
import { BlockedContactsList } from '../BlockedList'; import { BlockedContactsList } from '../BlockedList';
import {
import { SessionToggleWithDescription } from '../SessionSettingListItem'; SessionSettingsItemWrapper,
SessionToggleWithDescription,
} from '../SessionSettingListItem';
import { useHasEnterSendEnabled } from '../../../state/selectors/settings';
async function toggleCommunitiesPruning() { async function toggleCommunitiesPruning() {
try { try {
@ -81,13 +84,49 @@ const AudioMessageAutoPlaySetting = () => {
); );
}; };
const EnterKeyFunctionSetting = () => {
const initialSetting = useHasEnterSendEnabled();
const selectedWithSettingTrue = 'enterForNewLine';
const items = [
{
label: window.i18n('enterSendNewMessageDescription'),
value: 'enterForSend',
},
{
label: window.i18n('enterNewLineDescription'),
value: selectedWithSettingTrue,
},
];
return (
<SessionSettingsItemWrapper
title={window.i18n('enterKeySettingTitle')}
description={window.i18n('enterKeySettingDescription')}
inline={false}
>
<SessionRadioGroup
initialItem={initialSetting ? 'enterForNewLine' : 'enterForSend'}
group={SettingsKey.hasShiftSendEnabled} // make sure to define this key in your SettingsKey enum
items={items}
onClick={(selectedRadioValue: string) => {
void window.setSettingValue(
SettingsKey.hasShiftSendEnabled,
selectedRadioValue === selectedWithSettingTrue
);
}}
/>
</SessionSettingsItemWrapper>
);
};
export const CategoryConversations = () => { export const CategoryConversations = () => {
return ( return (
<> <>
<CommunitiesPruningSetting /> <CommunitiesPruningSetting />
<SpellCheckSetting /> <SpellCheckSetting />
<AudioMessageAutoPlaySetting /> <AudioMessageAutoPlaySetting />
<EnterKeyFunctionSetting />
<BlockedContactsList /> <BlockedContactsList />
</> </>
); );

@ -1,7 +1,7 @@
const settingsReadReceipt = 'read-receipt-setting'; const settingsReadReceipt = 'read-receipt-setting';
const settingsTypingIndicator = 'typing-indicators-setting'; const settingsTypingIndicator = 'typing-indicators-setting';
const settingsAutoUpdate = 'auto-update'; const settingsAutoUpdate = 'auto-update';
const hasShiftSendEnabled = 'hasShiftSendEnabled';
const settingsMenuBar = 'hide-menu-bar'; const settingsMenuBar = 'hide-menu-bar';
const settingsSpellCheck = 'spell-check'; const settingsSpellCheck = 'spell-check';
const settingsLinkPreview = 'link-preview-setting'; const settingsLinkPreview = 'link-preview-setting';
@ -24,6 +24,7 @@ export const SettingsKey = {
settingsReadReceipt, settingsReadReceipt,
settingsTypingIndicator, settingsTypingIndicator,
settingsAutoUpdate, settingsAutoUpdate,
hasShiftSendEnabled,
settingsMenuBar, settingsMenuBar,
settingsSpellCheck, settingsSpellCheck,
settingsLinkPreview, settingsLinkPreview,

@ -8,6 +8,7 @@ const SettingsBoolsKeyTrackedInRedux = [
SettingsKey.someDeviceOutdatedSyncing, SettingsKey.someDeviceOutdatedSyncing,
SettingsKey.settingsLinkPreview, SettingsKey.settingsLinkPreview,
SettingsKey.hasBlindedMsgRequestsEnabled, SettingsKey.hasBlindedMsgRequestsEnabled,
SettingsKey.hasShiftSendEnabled,
] as const; ] as const;
export type SettingsState = { export type SettingsState = {
@ -20,6 +21,7 @@ export function getSettingsInitialState() {
someDeviceOutdatedSyncing: false, someDeviceOutdatedSyncing: false,
'link-preview-setting': false, // this is the value of SettingsKey.settingsLinkPreview 'link-preview-setting': false, // this is the value of SettingsKey.settingsLinkPreview
hasBlindedMsgRequestsEnabled: false, hasBlindedMsgRequestsEnabled: false,
hasShiftSendEnabled: false,
}, },
}; };
} }
@ -47,6 +49,8 @@ const settingsSlice = createSlice({
SettingsKey.hasBlindedMsgRequestsEnabled, SettingsKey.hasBlindedMsgRequestsEnabled,
false false
); );
const hasShiftSendEnabled = Storage.get(SettingsKey.hasShiftSendEnabled, false);
state.settingsBools.someDeviceOutdatedSyncing = isBoolean(outdatedSync) state.settingsBools.someDeviceOutdatedSyncing = isBoolean(outdatedSync)
? outdatedSync ? outdatedSync
: false; : false;
@ -54,6 +58,9 @@ const settingsSlice = createSlice({
state.settingsBools.hasBlindedMsgRequestsEnabled = isBoolean(hasBlindedMsgRequestsEnabled) state.settingsBools.hasBlindedMsgRequestsEnabled = isBoolean(hasBlindedMsgRequestsEnabled)
? hasBlindedMsgRequestsEnabled ? hasBlindedMsgRequestsEnabled
: false; : false;
state.settingsBools.hasShiftSendEnabled = isBoolean(hasShiftSendEnabled)
? hasShiftSendEnabled
: false;
return state; return state;
}, },
updateSettingsBoolValue(state, action: PayloadAction<{ id: string; value: boolean }>) { updateSettingsBoolValue(state, action: PayloadAction<{ id: string; value: boolean }>) {

@ -11,6 +11,9 @@ const getHasDeviceOutdatedSyncing = (state: StateType) =>
const getHasBlindedMsgRequestsEnabled = (state: StateType) => const getHasBlindedMsgRequestsEnabled = (state: StateType) =>
state.settings.settingsBools[SettingsKey.hasBlindedMsgRequestsEnabled]; state.settings.settingsBools[SettingsKey.hasBlindedMsgRequestsEnabled];
const getHasShiftSendEnabled = (state: StateType) =>
state.settings.settingsBools[SettingsKey.hasShiftSendEnabled];
export const useHasLinkPreviewEnabled = () => { export const useHasLinkPreviewEnabled = () => {
const value = useSelector(getLinkPreviewEnabled); const value = useSelector(getLinkPreviewEnabled);
return Boolean(value); return Boolean(value);
@ -25,3 +28,8 @@ export const useHasBlindedMsgRequestsEnabled = () => {
const value = useSelector(getHasBlindedMsgRequestsEnabled); const value = useSelector(getHasBlindedMsgRequestsEnabled);
return Boolean(value); return Boolean(value);
}; };
export const useHasEnterSendEnabled = () => {
const value = useSelector(getHasShiftSendEnabled);
return Boolean(value);
};

@ -169,9 +169,13 @@ export type LocalizerKeys =
| 'endCall' | 'endCall'
| 'enterAnOpenGroupURL' | 'enterAnOpenGroupURL'
| 'enterDisplayName' | 'enterDisplayName'
| 'enterKeySettingDescription'
| 'enterKeySettingTitle'
| 'enterNewLineDescription'
| 'enterNewPassword' | 'enterNewPassword'
| 'enterPassword' | 'enterPassword'
| 'enterRecoveryPhrase' | 'enterRecoveryPhrase'
| 'enterSendNewMessageDescription'
| 'enterSessionID' | 'enterSessionID'
| 'enterSessionIDOfRecipient' | 'enterSessionIDOfRecipient'
| 'enterSessionIDOrONSName' | 'enterSessionIDOrONSName'

Loading…
Cancel
Save