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 32 additions and 20 deletions
Showing only changes of commit e9613ed26d - Show all commits

View file

@ -119,7 +119,7 @@ export default function ChannelMentionSuggestions(props: Props) {
comboboxInputRef.current.focus();
}
} else {
if (keyCode === KEYCODES.TAB) {
if ((isRefFocused(comboboxInputRef) || isRefFocused(inputRef)) && keyCode === KEYCODES.TAB) {
event.preventDefault();
const activeValue = activeElement && activeElement.getAttribute('value');
@ -131,7 +131,7 @@ export default function ChannelMentionSuggestions(props: Props) {
handleSelect(mentionTerm);
}
}
inputRef.current.focus();
if (isRefFocused(comboboxInputRef)) inputRef.current.focus();
}
}
@ -186,7 +186,7 @@ export default function ChannelMentionSuggestions(props: Props) {
);
};
return (
return isRefFocused(inputRef) || isRefFocused(comboboxInputRef) ? (
<Form onSubmit={() => handleSelect(mentionTerm)}>
<Combobox className="channel-mention" onSelect={handleSelect}>
<ComboboxInput ref={comboboxInputRef} className="channel-mention__input--none" value={mentionTerm} />
@ -216,5 +216,5 @@ export default function ChannelMentionSuggestions(props: Props) {
)}
</Combobox>
</Form>
);
) : null;
}

View file

@ -84,6 +84,8 @@ export function CommentCreate(props: Props) {
fetchComment,
} = props;
const formFieldRef: ElementRef<any> = React.useRef();
const formFieldInputRef = formFieldRef && formFieldRef.current && formFieldRef.current.input;
const selectionIndex = formFieldInputRef && formFieldInputRef.current.selectionStart;
const buttonRef: ElementRef<any> = React.useRef();
const {
push,
@ -97,15 +99,25 @@ export function CommentCreate(props: Props) {
const [isReviewingSupportComment, setIsReviewingSupportComment] = React.useState();
const [tipAmount, setTipAmount] = React.useState(1);
const [commentValue, setCommentValue] = React.useState('');
const [channelMention, setChannelMention] = React.useState('');
const [advancedEditor, setAdvancedEditor] = usePersistedState('comment-editor-mode', false);
const [activeTab, setActiveTab] = React.useState('');
const [tipError, setTipError] = React.useState();
const [deletedComment, setDeletedComment] = React.useState(false);
const [shouldDisableReviewButton, setShouldDisableReviewButton] = React.useState();
const commentWords = commentValue ? commentValue && commentValue.split(' ') : [];
const lastCommentWord = commentWords && commentWords[commentWords.length - 1];
const selectedMentionIndex =
commentValue.indexOf('@', selectionIndex) === selectionIndex
? commentValue.indexOf('@', selectionIndex)
: commentValue.lastIndexOf('@', selectionIndex);
const mentionLengthIndex =
commentValue.indexOf(' ', selectedMentionIndex) >= 0
? commentValue.indexOf(' ', selectedMentionIndex)
: commentValue.length;
const channelMention =
selectedMentionIndex >= 0 && selectionIndex <= mentionLengthIndex
? commentValue.substring(selectedMentionIndex, mentionLengthIndex)
: '';
const claimId = claim && claim.claim_id;
const signingChannel = (claim && claim.signing_channel) || claim;
const channelUri = signingChannel && signingChannel.permanent_url;
@ -159,16 +171,21 @@ export function CommentCreate(props: Props) {
}
function handleSelectMention(mentionValue) {
const newCommentValue = commentWords.slice(0, -1).join(' ');
let newMentionValue = mentionValue;
if (mentionValue.includes('#')) {
newMentionValue = mentionValue
.substring(0, mentionValue.indexOf('#') + 3)
.replace('lbry://', '')
let newMentionValue = mentionValue.replace('lbry://', '');
if (newMentionValue.includes('#')) {
const fullId = newMentionValue.substring(newMentionValue.indexOf('#') + 1, newMentionValue.length);
newMentionValue = newMentionValue
.substring(0, newMentionValue.indexOf('#') + (fullId.length > 2 ? 2 : newMentionValue.length))
.replace('#', ':');
}
setCommentValue(newCommentValue + (commentWords.length > 1 ? ' ' : '') + `${newMentionValue} `);
setCommentValue(
commentValue.substring(0, selectedMentionIndex) +
`${newMentionValue}` +
(commentValue.length > mentionLengthIndex + 1
? commentValue.substring(mentionLengthIndex, commentValue.length)
: ' ')
);
}
function altEnterListener(e: SyntheticKeyboardEvent<*>) {
@ -399,11 +416,6 @@ export function CommentCreate(props: Props) {
}
}, [fetchComment, shouldFetchComment, parentId]);
React.useEffect(() => {
const isMentioning = lastCommentWord && lastCommentWord.indexOf('@') === 0;
setChannelMention(isMentioning ? lastCommentWord : '');
}, [lastCommentWord]);
// **************************************************************************
// Render
// **************************************************************************
@ -494,7 +506,7 @@ export function CommentCreate(props: Props) {
<ChannelMentionSuggestions
uri={uri}
isLivestream={livestream}
inputRef={formFieldRef && formFieldRef.current && formFieldRef.current.input}
inputRef={formFieldInputRef}
mentionTerm={channelMention}
creatorUri={channelUri}
customSelectAction={handleSelectMention}