Add Channel Mention selection ability #7151

Merged
saltrafael merged 9 commits from channel-mention into master 2021-09-30 23:30:32 +02:00
2 changed files with 24 additions and 10 deletions
Showing only changes of commit 7f6968b39c - Show all commits

View file

@ -26,7 +26,7 @@ type Props = {
subscriptionUris: Array<string>,
unresolvedSubscriptions: Array<string>,
doResolveUris: (Array<string>) => void,
customSelectAction?: (string) => void,
customSelectAction?: (string, number) => void,
};
export default function ChannelMentionSuggestions(props: Props) {
@ -75,14 +75,13 @@ export default function ChannelMentionSuggestions(props: Props) {
const showPlaceholder = isTyping || loading;
const handleSelect = React.useCallback(
(value) => {
(value, key) => {
if (customSelectAction) {
// Give them full results, as our resolved one might truncate the claimId.
customSelectAction(value || (results && results.find((r) => r.startsWith(value))) || '');
customSelectAction(value || (results && results.find((r) => r.startsWith(value))) || '', Number(key));
}
if (inputRef && inputRef.current) inputRef.current.focus();
},
[customSelectAction, inputRef, results]
[customSelectAction, results]
);
React.useEffect(() => {
@ -124,11 +123,11 @@ export default function ChannelMentionSuggestions(props: Props) {
const activeValue = activeElement && activeElement.getAttribute('value');
if (activeValue) {
handleSelect(activeValue);
handleSelect(activeValue, keyCode);
} else if (possibleMatches.length) {
handleSelect(possibleMatches[0]);
handleSelect(possibleMatches[0], keyCode);
} else if (results) {
handleSelect(mentionTerm);
handleSelect(mentionTerm, keyCode);
}
}
if (isRefFocused(comboboxInputRef)) inputRef.current.focus();

View file

@ -28,6 +28,7 @@ let stripeEnvironment = getStripeEnvironment();
const TAB_FIAT = 'TabFiat';
const TAB_LBC = 'TabLBC';
const MENTION_DEBOUNCE_MS = 100;
type Props = {
uri: string,
@ -103,6 +104,7 @@ export function CommentCreate(props: Props) {
const [activeTab, setActiveTab] = React.useState('');
const [tipError, setTipError] = React.useState();
const [deletedComment, setDeletedComment] = React.useState(false);
const [pauseQuickSend, setPauseQuickSend] = React.useState(false);
const [shouldDisableReviewButton, setShouldDisableReviewButton] = React.useState();
const selectedMentionIndex =
@ -123,7 +125,7 @@ export function CommentCreate(props: Props) {
const channelUri = signingChannel && signingChannel.permanent_url;
const hasChannels = channels && channels.length;
const charCount = commentValue ? commentValue.length : 0;
const disabled = deletedComment || isSubmitting || isFetchingChannels || !commentValue.length;
const disabled = deletedComment || isSubmitting || isFetchingChannels || !commentValue.length || pauseQuickSend;
const channelId = getChannelIdFromClaim(claim);
const channelSettings = channelId ? settingsByChannelId[channelId] : undefined;
const minSuper = (channelSettings && channelSettings.min_tip_amount_super_chat) || 0;
@ -170,7 +172,7 @@ export function CommentCreate(props: Props) {
setCommentValue(commentValue);
}
function handleSelectMention(mentionValue) {
function handleSelectMention(mentionValue, key) {
let newMentionValue = mentionValue.replace('lbry://', '');
if (newMentionValue.includes('#')) {
const fullId = newMentionValue.substring(newMentionValue.indexOf('#') + 1, newMentionValue.length);
@ -179,6 +181,7 @@ export function CommentCreate(props: Props) {
.replace('#', ':');
}
if (livestream && key !== KEYCODES.TAB) setPauseQuickSend(true);
setCommentValue(
commentValue.substring(0, selectedMentionIndex) +
`${newMentionValue}` +
@ -416,6 +419,18 @@ export function CommentCreate(props: Props) {
}
}, [fetchComment, shouldFetchComment, parentId]);
// Debounce for disabling the submit button when mentioning a user with Enter
// so that the comment isn't sent at the same time
React.useEffect(() => {
const timer = setTimeout(() => {
if (pauseQuickSend) {
setPauseQuickSend(false);
}
}, MENTION_DEBOUNCE_MS);
return () => clearTimeout(timer);
}, [pauseQuickSend]);
// **************************************************************************
// Render
// **************************************************************************