Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keyboard focus related bugs #299

Merged
merged 4 commits into from
Feb 8, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion src/app/atoms/input/Input.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ function Input({
id, label, name, value, placeholder,
required, type, onChange, forwardRef,
resizable, minHeight, onResize, state,
onKeyDown, disabled,
onKeyDown, disabled, autoFocus,
}) {
return (
<div className="input-container">
Expand All @@ -30,6 +30,7 @@ function Input({
onResize={onResize}
onKeyDown={onKeyDown}
disabled={disabled}
autoFocus={autoFocus}
/>
) : (
<input
Expand All @@ -45,6 +46,8 @@ function Input({
onChange={onChange}
onKeyDown={onKeyDown}
disabled={disabled}
// eslint-disable-next-line jsx-a11y/no-autofocus
autoFocus={autoFocus}
/>
)}
</div>
Expand All @@ -67,6 +70,7 @@ Input.defaultProps = {
state: 'normal',
onKeyDown: null,
disabled: false,
autoFocus: false,
};

Input.propTypes = {
Expand All @@ -85,6 +89,7 @@ Input.propTypes = {
state: PropTypes.oneOf(['normal', 'success', 'error']),
onKeyDown: PropTypes.func,
disabled: PropTypes.bool,
autoFocus: PropTypes.bool,
};

export default Input;
13 changes: 11 additions & 2 deletions src/app/molecules/message/Message.jsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
/* eslint-disable react/prop-types */
import React, { useState, useEffect, useCallback, useRef } from 'react';
import React, {
useState, useEffect, useCallback, useRef,
} from 'react';
import PropTypes from 'prop-types';
import './Message.scss';

Expand Down Expand Up @@ -245,6 +247,14 @@ MessageBody.propTypes = {
function MessageEdit({ body, onSave, onCancel }) {
const editInputRef = useRef(null);

useEffect(() => {
editInputRef.current.focus();

// Setting the value here instead of using the value prop below
// makes the cursor end up at the end of the line instead of the begining
editInputRef.current.value = body;
}, []);

const handleKeyDown = (e) => {
if (e.keyCode === 13 && e.shiftKey === false) {
e.preventDefault();
Expand All @@ -257,7 +267,6 @@ function MessageEdit({ body, onSave, onCancel }) {
<Input
forwardRef={editInputRef}
onKeyDown={handleKeyDown}
value={body}
placeholder="Edit message"
required
resizable
Expand Down
11 changes: 9 additions & 2 deletions src/app/molecules/room-members/RoomMembers.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import React, { useState, useEffect, useCallback } from 'react';
import React, {
useState, useEffect, useCallback, useRef,
} from 'react';
import PropTypes from 'prop-types';
import './RoomMembers.scss';

Expand All @@ -14,6 +16,7 @@ import Input from '../../atoms/input/Input';
import { MenuHeader } from '../../atoms/context-menu/ContextMenu';
import SegmentedControls from '../../atoms/segmented-controls/SegmentedControls';
import PeopleSelector from '../people-selector/PeopleSelector';
import settings from '../../../client/state/settings';

const PER_PAGE_MEMBER = 50;

Expand Down Expand Up @@ -138,7 +141,11 @@ function RoomMembers({ roomId }) {
return (
<div className="room-members">
<MenuHeader>Search member</MenuHeader>
<Input onChange={handleSearch} placeholder="Search for name" />
<Input
onChange={handleSearch}
placeholder="Search for name"
autoFocus={!settings.isTouchScreenDevice}
/>
<div className="room-members__header">
<MenuHeader>{`${searchMembers ? `Found — ${mList.length}` : members.length} members`}</MenuHeader>
<SegmentedControls
Expand Down
3 changes: 2 additions & 1 deletion src/app/molecules/room-search/RoomSearch.jsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import React, { useState, useEffect } from 'react';
import React, { useState, useEffect, useRef } from 'react';
import PropTypes from 'prop-types';
import './RoomSearch.scss';

Expand Down Expand Up @@ -145,6 +145,7 @@ function RoomSearch({ roomId }) {
placeholder="Search for keywords"
name="room-search-input"
disabled={isRoomEncrypted}
autoFocus
/>
<Button iconSrc={SearchIC} variant="primary" type="submit">Search</Button>
</div>
Expand Down
15 changes: 11 additions & 4 deletions src/app/organisms/emoji-board/EmojiBoard.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,7 @@ function SearchedEmoji() {
return <EmojiGroup key="-1" name={searchedEmojis.emojis.length === 0 ? 'No search result found' : 'Search results'} groupEmojis={searchedEmojis.emojis} />;
}

function EmojiBoard({ onSelect }) {
const searchRef = useRef(null);
function EmojiBoard({ onSelect, searchRef }) {
const scrollEmojisRef = useRef(null);
const emojiInfo = useRef(null);

Expand Down Expand Up @@ -182,8 +181,8 @@ function EmojiBoard({ onSelect }) {
setEmojiInfo({ shortcode: shortcodes[0], src, unicode });
}

function handleSearchChange(e) {
const term = e.target.value;
function handleSearchChange() {
const term = searchRef.current.value;
asyncSearch.search(term);
scrollEmojisRef.current.scrollTop = 0;
}
Expand Down Expand Up @@ -213,9 +212,16 @@ function EmojiBoard({ onSelect }) {
setAvailableEmojis(packs);
};

const onOpen = () => {
searchRef.current.value = '';
handleSearchChange();
};

navigation.on(cons.events.navigation.ROOM_SELECTED, updateAvailableEmoji);
navigation.on(cons.events.navigation.EMOJIBOARD_OPENED, onOpen);
return () => {
navigation.removeListener(cons.events.navigation.ROOM_SELECTED, updateAvailableEmoji);
navigation.removeListener(cons.events.navigation.EMOJIBOARD_OPENED, onOpen);
};
}, []);

Expand Down Expand Up @@ -312,6 +318,7 @@ function EmojiBoard({ onSelect }) {

EmojiBoard.propTypes = {
onSelect: PropTypes.func.isRequired,
searchRef: PropTypes.shape({}).isRequired,
};

export default EmojiBoard;
8 changes: 6 additions & 2 deletions src/app/organisms/emoji-board/EmojiBoardOpener.jsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useEffect, useRef } from 'react';

import cons from '../../../client/state/cons';
import navigation from '../../../client/state/navigation';
import settings from '../../../client/state/settings';

import ContextMenu from '../../atoms/context-menu/ContextMenu';
import EmojiBoard from './EmojiBoard';
Expand All @@ -10,6 +11,7 @@ let requestCallback = null;
let isEmojiBoardVisible = false;
function EmojiBoardOpener() {
const openerRef = useRef(null);
const searchRef = useRef(null);

function openEmojiBoard(cords, requestEmojiCallback) {
if (requestCallback !== null || isEmojiBoardVisible) {
Expand All @@ -25,7 +27,9 @@ function EmojiBoardOpener() {

function afterEmojiBoardToggle(isVisible) {
isEmojiBoardVisible = isVisible;
if (!isVisible) {
if (isVisible) {
if (!settings.isTouchScreenDevice) searchRef.current.focus();
} else {
setTimeout(() => {
if (!isEmojiBoardVisible) requestCallback = null;
}, 500);
Expand All @@ -46,7 +50,7 @@ function EmojiBoardOpener() {
return (
<ContextMenu
content={(
<EmojiBoard onSelect={addEmoji} />
<EmojiBoard onSelect={addEmoji} searchRef={searchRef} />
)}
afterToggle={afterEmojiBoardToggle}
render={(toggleMenu) => (
Expand Down