Merge branch 'develop' into kegan/lists-as-keys
This commit is contained in:
commit
fcde4b7880
24 changed files with 236 additions and 50 deletions
|
@ -262,6 +262,8 @@ export default class ForgotPassword extends React.Component<Props, State> {
|
|||
|
||||
try {
|
||||
await this.reset.setNewPassword(this.state.password);
|
||||
this.setState({ phase: Phase.Done });
|
||||
return;
|
||||
} catch (err: any) {
|
||||
if (err.httpStatus !== 401) {
|
||||
// 401 = waiting for email verification, else unknown error
|
||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import React, { MouseEventHandler, ReactNode } from "react";
|
||||
import { FormattingFunctions, AllActionStates } from "@matrix-org/matrix-wysiwyg";
|
||||
import { FormattingFunctions, AllActionStates, ActionState } from "@matrix-org/matrix-wysiwyg";
|
||||
import classNames from "classnames";
|
||||
|
||||
import { Icon as BoldIcon } from "../../../../../../res/img/element-icons/room/composer/bold.svg";
|
||||
|
@ -26,6 +26,7 @@ import { Icon as InlineCodeIcon } from "../../../../../../res/img/element-icons/
|
|||
import { Icon as LinkIcon } from "../../../../../../res/img/element-icons/room/composer/link.svg";
|
||||
import { Icon as BulletedListIcon } from "../../../../../../res/img/element-icons/room/composer/bulleted_list.svg";
|
||||
import { Icon as NumberedListIcon } from "../../../../../../res/img/element-icons/room/composer/numbered_list.svg";
|
||||
import { Icon as CodeBlockIcon } from "../../../../../../res/img/element-icons/room/composer/code_block.svg";
|
||||
import AccessibleTooltipButton from "../../../elements/AccessibleTooltipButton";
|
||||
import { Alignment } from "../../../elements/Tooltip";
|
||||
import { KeyboardShortcut } from "../../../settings/KeyboardShortcut";
|
||||
|
@ -53,21 +54,23 @@ function Tooltip({ label, keyCombo }: TooltipProps): JSX.Element {
|
|||
|
||||
interface ButtonProps extends TooltipProps {
|
||||
icon: ReactNode;
|
||||
isActive: boolean;
|
||||
actionState: ActionState;
|
||||
onClick: MouseEventHandler<HTMLButtonElement>;
|
||||
}
|
||||
|
||||
function Button({ label, keyCombo, onClick, isActive, icon }: ButtonProps): JSX.Element {
|
||||
function Button({ label, keyCombo, onClick, actionState, icon }: ButtonProps): JSX.Element {
|
||||
return (
|
||||
<AccessibleTooltipButton
|
||||
element="button"
|
||||
onClick={onClick as (e: ButtonEvent) => void}
|
||||
title={label}
|
||||
className={classNames("mx_FormattingButtons_Button", {
|
||||
mx_FormattingButtons_active: isActive,
|
||||
mx_FormattingButtons_Button_hover: !isActive,
|
||||
mx_FormattingButtons_active: actionState === "reversed",
|
||||
mx_FormattingButtons_Button_hover: actionState === "enabled",
|
||||
mx_FormattingButtons_disabled: actionState === "disabled",
|
||||
})}
|
||||
tooltip={keyCombo && <Tooltip label={label} keyCombo={keyCombo} />}
|
||||
forceHide={actionState === "disabled"}
|
||||
alignment={Alignment.Top}
|
||||
>
|
||||
{icon}
|
||||
|
@ -85,53 +88,59 @@ export function FormattingButtons({ composer, actionStates }: FormattingButtonsP
|
|||
return (
|
||||
<div className="mx_FormattingButtons">
|
||||
<Button
|
||||
isActive={actionStates.bold === "reversed"}
|
||||
actionState={actionStates.bold}
|
||||
label={_td("Bold")}
|
||||
keyCombo={{ ctrlOrCmdKey: true, key: "b" }}
|
||||
onClick={() => composer.bold()}
|
||||
icon={<BoldIcon className="mx_FormattingButtons_Icon" />}
|
||||
/>
|
||||
<Button
|
||||
isActive={actionStates.italic === "reversed"}
|
||||
actionState={actionStates.italic}
|
||||
label={_td("Italic")}
|
||||
keyCombo={{ ctrlOrCmdKey: true, key: "i" }}
|
||||
onClick={() => composer.italic()}
|
||||
icon={<ItalicIcon className="mx_FormattingButtons_Icon" />}
|
||||
/>
|
||||
<Button
|
||||
isActive={actionStates.underline === "reversed"}
|
||||
actionState={actionStates.underline}
|
||||
label={_td("Underline")}
|
||||
keyCombo={{ ctrlOrCmdKey: true, key: "u" }}
|
||||
onClick={() => composer.underline()}
|
||||
icon={<UnderlineIcon className="mx_FormattingButtons_Icon" />}
|
||||
/>
|
||||
<Button
|
||||
isActive={actionStates.strikeThrough === "reversed"}
|
||||
actionState={actionStates.strikeThrough}
|
||||
label={_td("Strikethrough")}
|
||||
onClick={() => composer.strikeThrough()}
|
||||
icon={<StrikeThroughIcon className="mx_FormattingButtons_Icon" />}
|
||||
/>
|
||||
<Button
|
||||
isActive={actionStates.unorderedList === "reversed"}
|
||||
actionState={actionStates.unorderedList}
|
||||
label={_td("Bulleted list")}
|
||||
onClick={() => composer.unorderedList()}
|
||||
icon={<BulletedListIcon className="mx_FormattingButtons_Icon" />}
|
||||
/>
|
||||
<Button
|
||||
isActive={actionStates.orderedList === "reversed"}
|
||||
actionState={actionStates.orderedList}
|
||||
label={_td("Numbered list")}
|
||||
onClick={() => composer.orderedList()}
|
||||
icon={<NumberedListIcon className="mx_FormattingButtons_Icon" />}
|
||||
/>
|
||||
<Button
|
||||
isActive={actionStates.inlineCode === "reversed"}
|
||||
actionState={actionStates.inlineCode}
|
||||
label={_td("Code")}
|
||||
keyCombo={{ ctrlOrCmdKey: true, key: "e" }}
|
||||
onClick={() => composer.inlineCode()}
|
||||
icon={<InlineCodeIcon className="mx_FormattingButtons_Icon" />}
|
||||
/>
|
||||
<Button
|
||||
isActive={actionStates.link === "reversed"}
|
||||
actionState={actionStates.codeBlock}
|
||||
label={_td("Code block")}
|
||||
onClick={() => composer.codeBlock()}
|
||||
icon={<CodeBlockIcon className="mx_FormattingButtons_Icon" />}
|
||||
/>
|
||||
<Button
|
||||
actionState={actionStates.link}
|
||||
label={_td("Link")}
|
||||
onClick={() => openLinkModal(composer, composerContext, actionStates.link === "reversed")}
|
||||
icon={<LinkIcon className="mx_FormattingButtons_Icon" />}
|
||||
|
|
|
@ -19,6 +19,12 @@ import { useCallback } from "react";
|
|||
|
||||
import { useSettingValue } from "../../../../../hooks/useSettings";
|
||||
|
||||
function isEnterPressed(event: KeyboardEvent): boolean {
|
||||
// Ugly but here we need to send the message only if Enter is pressed
|
||||
// And we need to stop the event propagation on enter to avoid the composer to grow
|
||||
return event.key === "Enter" && !event.shiftKey && !event.ctrlKey && !event.metaKey && !event.altKey;
|
||||
}
|
||||
|
||||
export function useInputEventProcessor(onSend: () => void): (event: WysiwygEvent) => WysiwygEvent | null {
|
||||
const isCtrlEnter = useSettingValue<boolean>("MessageComposerInput.ctrlEnterToSend");
|
||||
return useCallback(
|
||||
|
@ -28,12 +34,12 @@ export function useInputEventProcessor(onSend: () => void): (event: WysiwygEvent
|
|||
}
|
||||
|
||||
const isKeyboardEvent = event instanceof KeyboardEvent;
|
||||
const isEnterPress =
|
||||
!isCtrlEnter && (isKeyboardEvent ? event.key === "Enter" : event.inputType === "insertParagraph");
|
||||
// sendMessage is sent when ctrl+enter is pressed
|
||||
const isSendMessage = !isKeyboardEvent && event.inputType === "sendMessage";
|
||||
const isEnterPress = !isCtrlEnter && isKeyboardEvent && isEnterPressed(event);
|
||||
const isInsertParagraph = !isCtrlEnter && !isKeyboardEvent && event.inputType === "insertParagraph";
|
||||
// sendMessage is sent when cmd+enter is pressed
|
||||
const isSendMessage = isCtrlEnter && !isKeyboardEvent && event.inputType === "sendMessage";
|
||||
|
||||
if (isEnterPress || isSendMessage) {
|
||||
if (isEnterPress || isInsertParagraph || isSendMessage) {
|
||||
event.stopPropagation?.();
|
||||
event.preventDefault?.();
|
||||
onSend();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue