Keep number field in focus when pressing dialpad buttons (#6520)
parent
1a1a76e2d7
commit
1ad35b1564
|
@ -14,8 +14,9 @@ See the License for the specific language governing permissions and
|
|||
limitations under the License.
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import * as React from "react";
|
||||
import { createRef } from "react";
|
||||
import AccessibleButton, { ButtonEvent } from "../elements/AccessibleButton";
|
||||
import { ContextMenu, IProps as IContextMenuProps } from '../../structures/ContextMenu';
|
||||
import { MatrixCall } from 'matrix-js-sdk/src/webrtc/call';
|
||||
import Field from "../elements/Field";
|
||||
|
@ -32,6 +33,8 @@ interface IState {
|
|||
|
||||
@replaceableComponent("views.context_menus.DialpadContextMenu")
|
||||
export default class DialpadContextMenu extends React.Component<IProps, IState> {
|
||||
private numberEntryFieldRef: React.RefObject<Field> = createRef();
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
|
||||
|
@ -40,9 +43,16 @@ export default class DialpadContextMenu extends React.Component<IProps, IState>
|
|||
};
|
||||
}
|
||||
|
||||
onDigitPress = (digit) => {
|
||||
onDigitPress = (digit: string, ev: ButtonEvent) => {
|
||||
this.props.call.sendDtmfDigit(digit);
|
||||
this.setState({ value: this.state.value + digit });
|
||||
|
||||
// Keep the number field focused so that keyboard entry is still available
|
||||
// However, don't focus if this wasn't the result of directly clicking on the button,
|
||||
// i.e someone using keyboard navigation.
|
||||
if (ev.type === "click") {
|
||||
this.numberEntryFieldRef.current?.focus();
|
||||
}
|
||||
};
|
||||
|
||||
onCancelClick = () => {
|
||||
|
@ -68,6 +78,7 @@ export default class DialpadContextMenu extends React.Component<IProps, IState>
|
|||
</div>
|
||||
<div className="mx_DialPadContextMenu_header">
|
||||
<Field
|
||||
ref={this.numberEntryFieldRef}
|
||||
className="mx_DialPadContextMenu_dialled"
|
||||
value={this.state.value}
|
||||
autoFocus={true}
|
||||
|
|
|
@ -55,7 +55,7 @@ import { replaceableComponent } from "../../../utils/replaceableComponent";
|
|||
import { mediaFromMxc } from "../../../customisations/Media";
|
||||
import { getAddressType } from "../../../UserAddress";
|
||||
import BaseAvatar from '../avatars/BaseAvatar';
|
||||
import AccessibleButton from '../elements/AccessibleButton';
|
||||
import AccessibleButton, { ButtonEvent } from '../elements/AccessibleButton';
|
||||
import { compare } from '../../../utils/strings';
|
||||
import { IInvite3PID } from "matrix-js-sdk/src/@types/requests";
|
||||
import AccessibleTooltipButton from "../elements/AccessibleTooltipButton";
|
||||
|
@ -394,6 +394,7 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
|
|||
private closeCopiedTooltip: () => void;
|
||||
private debounceTimer: number = null; // actually number because we're in the browser
|
||||
private editorRef = createRef<HTMLInputElement>();
|
||||
private numberEntryFieldRef: React.RefObject<Field> = createRef();
|
||||
private unmounted = false;
|
||||
|
||||
constructor(props) {
|
||||
|
@ -1283,13 +1284,27 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
|
|||
this.setState({ dialPadValue: ev.currentTarget.value });
|
||||
};
|
||||
|
||||
private onDigitPress = digit => {
|
||||
private onDigitPress = (digit: string, ev: ButtonEvent) => {
|
||||
this.setState({ dialPadValue: this.state.dialPadValue + digit });
|
||||
|
||||
// Keep the number field focused so that keyboard entry is still available
|
||||
// However, don't focus if this wasn't the result of directly clicking on the button,
|
||||
// i.e someone using keyboard navigation.
|
||||
if (ev.type === "click") {
|
||||
this.numberEntryFieldRef.current?.focus();
|
||||
}
|
||||
};
|
||||
|
||||
private onDeletePress = () => {
|
||||
private onDeletePress = (ev: ButtonEvent) => {
|
||||
if (this.state.dialPadValue.length === 0) return;
|
||||
this.setState({ dialPadValue: this.state.dialPadValue.slice(0, -1) });
|
||||
|
||||
// Keep the number field focused so that keyboard entry is still available
|
||||
// However, don't focus if this wasn't the result of directly clicking on the button,
|
||||
// i.e someone using keyboard navigation.
|
||||
if (ev.type === "click") {
|
||||
this.numberEntryFieldRef.current?.focus();
|
||||
}
|
||||
};
|
||||
|
||||
private onTabChange = (tabId: TabId) => {
|
||||
|
@ -1543,6 +1558,7 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
|
|||
let dialPadField;
|
||||
if (this.state.dialPadValue.length !== 0) {
|
||||
dialPadField = <Field
|
||||
ref={this.numberEntryFieldRef}
|
||||
className="mx_InviteDialog_dialPadField"
|
||||
id="dialpad_number"
|
||||
value={this.state.dialPadValue}
|
||||
|
@ -1552,6 +1568,7 @@ export default class InviteDialog extends React.PureComponent<IInviteDialogProps
|
|||
/>;
|
||||
} else {
|
||||
dialPadField = <Field
|
||||
ref={this.numberEntryFieldRef}
|
||||
className="mx_InviteDialog_dialPadField"
|
||||
id="dialpad_number"
|
||||
value={this.state.dialPadValue}
|
||||
|
|
|
@ -15,11 +15,11 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import * as React from "react";
|
||||
import AccessibleButton from "./AccessibleButton";
|
||||
import AccessibleButton, { ButtonEvent } from "./AccessibleButton";
|
||||
|
||||
interface IProps {
|
||||
// Callback for when the button is pressed
|
||||
onBackspacePress: () => void;
|
||||
onBackspacePress: (ev: ButtonEvent) => void;
|
||||
}
|
||||
|
||||
export default class DialPadBackspaceButton extends React.PureComponent<IProps> {
|
||||
|
|
|
@ -15,7 +15,7 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import * as React from "react";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import AccessibleButton, { ButtonEvent } from "../elements/AccessibleButton";
|
||||
import { replaceableComponent } from "../../../utils/replaceableComponent";
|
||||
|
||||
const BUTTONS = ['1', '2', '3', '4', '5', '6', '7', '8', '9', '*', '0', '#'];
|
||||
|
@ -30,12 +30,12 @@ interface IButtonProps {
|
|||
kind: DialPadButtonKind;
|
||||
digit?: string;
|
||||
digitSubtext?: string;
|
||||
onButtonPress: (string) => void;
|
||||
onButtonPress: (digit: string, ev: ButtonEvent) => void;
|
||||
}
|
||||
|
||||
class DialPadButton extends React.PureComponent<IButtonProps> {
|
||||
onClick = () => {
|
||||
this.props.onButtonPress(this.props.digit);
|
||||
onClick = (ev: ButtonEvent) => {
|
||||
this.props.onButtonPress(this.props.digit, ev);
|
||||
};
|
||||
|
||||
render() {
|
||||
|
@ -54,10 +54,10 @@ class DialPadButton extends React.PureComponent<IButtonProps> {
|
|||
}
|
||||
|
||||
interface IProps {
|
||||
onDigitPress: (string) => void;
|
||||
onDigitPress: (digit: string, ev: ButtonEvent) => void;
|
||||
hasDial: boolean;
|
||||
onDeletePress?: (string) => void;
|
||||
onDialPress?: (string) => void;
|
||||
onDeletePress?: (ev: ButtonEvent) => void;
|
||||
onDialPress?: () => void;
|
||||
}
|
||||
|
||||
@replaceableComponent("views.voip.DialPad")
|
||||
|
|
|
@ -15,7 +15,8 @@ limitations under the License.
|
|||
*/
|
||||
|
||||
import * as React from "react";
|
||||
import AccessibleButton from "../elements/AccessibleButton";
|
||||
import { createRef } from "react";
|
||||
import AccessibleButton, { ButtonEvent } from "../elements/AccessibleButton";
|
||||
import Field from "../elements/Field";
|
||||
import DialPad from './DialPad';
|
||||
import dis from '../../../dispatcher/dispatcher';
|
||||
|
@ -34,6 +35,8 @@ interface IState {
|
|||
|
||||
@replaceableComponent("views.voip.DialPadModal")
|
||||
export default class DialpadModal extends React.PureComponent<IProps, IState> {
|
||||
private numberEntryFieldRef: React.RefObject<Field> = createRef();
|
||||
|
||||
constructor(props) {
|
||||
super(props);
|
||||
this.state = {
|
||||
|
@ -54,13 +57,27 @@ export default class DialpadModal extends React.PureComponent<IProps, IState> {
|
|||
this.onDialPress();
|
||||
};
|
||||
|
||||
onDigitPress = (digit) => {
|
||||
onDigitPress = (digit: string, ev: ButtonEvent) => {
|
||||
this.setState({ value: this.state.value + digit });
|
||||
|
||||
// Keep the number field focused so that keyboard entry is still available.
|
||||
// However, don't focus if this wasn't the result of directly clicking on the button,
|
||||
// i.e someone using keyboard navigation.
|
||||
if (ev.type === "click") {
|
||||
this.numberEntryFieldRef.current?.focus();
|
||||
}
|
||||
};
|
||||
|
||||
onDeletePress = () => {
|
||||
onDeletePress = (ev: ButtonEvent) => {
|
||||
if (this.state.value.length === 0) return;
|
||||
this.setState({ value: this.state.value.slice(0, -1) });
|
||||
|
||||
// Keep the number field focused so that keyboard entry is still available
|
||||
// However, don't focus if this wasn't the result of directly clicking on the button,
|
||||
// i.e someone using keyboard navigation.
|
||||
if (ev.type === "click") {
|
||||
this.numberEntryFieldRef.current?.focus();
|
||||
}
|
||||
};
|
||||
|
||||
onDialPress = async () => {
|
||||
|
@ -82,6 +99,7 @@ export default class DialpadModal extends React.PureComponent<IProps, IState> {
|
|||
let dialPadField;
|
||||
if (this.state.value.length !== 0) {
|
||||
dialPadField = <Field
|
||||
ref={this.numberEntryFieldRef}
|
||||
className="mx_DialPadModal_field"
|
||||
id="dialpad_number"
|
||||
value={this.state.value}
|
||||
|
@ -91,6 +109,7 @@ export default class DialpadModal extends React.PureComponent<IProps, IState> {
|
|||
/>;
|
||||
} else {
|
||||
dialPadField = <Field
|
||||
ref={this.numberEntryFieldRef}
|
||||
className="mx_DialPadModal_field"
|
||||
id="dialpad_number"
|
||||
value={this.state.value}
|
||||
|
|
Loading…
Reference in New Issue