Page MenuHomePhabricator

D6051.id20601.diff
No OneTemporary

D6051.id20601.diff

diff --git a/web/chat/chat-input-bar.react.js b/web/chat/chat-input-bar.react.js
--- a/web/chat/chat-input-bar.react.js
+++ b/web/chat/chat-input-bar.react.js
@@ -109,6 +109,16 @@
if (inputState.draft !== prevInputState.draft) {
this.updateHeight();
}
+
+ if (
+ inputState.draft !== prevInputState.draft ||
+ inputState.textCursorPosition !== prevInputState.textCursorPosition
+ ) {
+ inputState.setTypeaheadState({
+ canBeVisible: true,
+ });
+ }
+
const curUploadIDs = ChatInputBar.unassignedUploadIDs(
inputState.pendingUploads,
);
@@ -330,6 +340,7 @@
let typeaheadTooltip;
if (
+ this.props.inputState.typeaheadState.canBeVisible &&
this.props.suggestedUsers.length > 0 &&
this.props.typeaheadMatchedStrings &&
this.textarea
@@ -405,7 +416,28 @@
};
onKeyDown = (event: SyntheticKeyboardEvent<HTMLTextAreaElement>) => {
- if (event.key === 'Enter' && !event.shiftKey) {
+ const {
+ accept,
+ close,
+ moveChoiceUp,
+ moveChoiceDown,
+ } = this.props.inputState.typeaheadState;
+
+ const actions = {
+ Enter: accept,
+ Tab: accept,
+ ArrowDown: moveChoiceDown,
+ ArrowUp: moveChoiceUp,
+ Escape: close,
+ };
+
+ if (
+ this.props.inputState.typeaheadState.canBeVisible &&
+ actions[event.key]
+ ) {
+ event.preventDefault();
+ actions[event.key]();
+ } else if (event.key === 'Enter' && !event.shiftKey) {
event.preventDefault();
this.send();
}
diff --git a/web/chat/typeahead-tooltip.css b/web/chat/typeahead-tooltip.css
--- a/web/chat/typeahead-tooltip.css
+++ b/web/chat/typeahead-tooltip.css
@@ -53,7 +53,7 @@
white-space: nowrap;
}
-.suggestion:hover {
+.suggestionHover {
background-color: var(--typeahead-overlay-light);
}
diff --git a/web/chat/typeahead-tooltip.react.js b/web/chat/typeahead-tooltip.react.js
--- a/web/chat/typeahead-tooltip.react.js
+++ b/web/chat/typeahead-tooltip.react.js
@@ -81,8 +81,13 @@
);
const tooltipButtons = React.useMemo(
- () => getTypeaheadTooltipButtons(actions),
- [actions],
+ () =>
+ getTypeaheadTooltipButtons(
+ setChosenPositionInOverlay,
+ chosenPositionInOverlay,
+ actions,
+ ),
+ [setChosenPositionInOverlay, actions, chosenPositionInOverlay],
);
const close = React.useCallback(() => {
diff --git a/web/utils/typeahead-utils.js b/web/utils/typeahead-utils.js
--- a/web/utils/typeahead-utils.js
+++ b/web/utils/typeahead-utils.js
@@ -1,9 +1,11 @@
// @flow
+import classNames from 'classnames';
import * as React from 'react';
import { oldValidUsernameRegexString } from 'lib/shared/account-utils';
import { stringForUserExplicit } from 'lib/shared/user-utils';
+import type { SetState } from 'lib/types/hook-types';
import type { RelativeMemberInfo } from 'lib/types/thread-types';
import { typeaheadStyle } from '../chat/chat-constants';
@@ -123,14 +125,35 @@
}
function getTypeaheadTooltipButtons(
+ setChosenPositionInOverlay: SetState<number>,
+ chosenPositionInOverlay: number,
actions: $ReadOnlyArray<TypeaheadTooltipAction>,
): $ReadOnlyArray<React.Node> {
- return actions.map(({ key, execute, actionButtonContent }) => (
- <Button key={key} onClick={execute} className={css.suggestion}>
- <span>@{actionButtonContent}</span>
- </Button>
- ));
+ return actions.map((action, idx) => {
+ const { key, execute, actionButtonContent } = action;
+ const buttonClasses = classNames(css.suggestion, {
+ [css.suggestionHover]: idx === chosenPositionInOverlay,
+ });
+
+ const onMouseMove: (
+ event: SyntheticEvent<HTMLButtonElement>,
+ ) => mixed = () => {
+ setChosenPositionInOverlay(idx);
+ };
+
+ return (
+ <Button
+ key={key}
+ onClick={execute}
+ onMouseMove={onMouseMove}
+ className={buttonClasses}
+ >
+ <span>@{actionButtonContent}</span>
+ </Button>
+ );
+ });
}
+
function getTypeaheadTooltipPosition(
textarea: HTMLTextAreaElement,
actionsLength: number,

File Metadata

Mime Type
text/plain
Expires
Mon, Nov 25, 2:52 AM (20 h, 40 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2577749
Default Alt Text
D6051.id20601.diff (4 KB)

Event Timeline