Add Channel Mention selection ability #7151
4 changed files with 55 additions and 25 deletions
|
@ -22,8 +22,8 @@ export default function ChannelMentionSuggestion(props: Props) {
|
|||
<div className="channel-mention__suggestion">
|
||||
<ChannelThumbnail xsmall uri={uri} />
|
||||
<span className="channel-mention__suggestion-label">
|
||||
<div className="channel-mention__suggestion-name">{claim.name}</div>
|
||||
<div className="channel-mention__suggestion-title">{(claim.value && claim.value.title) || claim.name}</div>
|
||||
<div className="channel-mention__suggestion-name">{claim.name}</div>
|
||||
</span>
|
||||
</div>
|
||||
)}
|
||||
|
|
|
@ -45,6 +45,7 @@ export default function ChannelMentionSuggestions(props: Props) {
|
|||
const comboboxInputRef: ElementRef<any> = React.useRef();
|
||||
const comboboxListRef: ElementRef<any> = React.useRef();
|
||||
const [debouncedTerm, setDebouncedTerm] = React.useState('');
|
||||
const mainEl = document.querySelector('.channel-mention__suggestions');
|
||||
|
||||
const isRefFocused = (ref) => ref && ref.current === document.activeElement;
|
||||
|
||||
|
@ -95,14 +96,25 @@ export default function ChannelMentionSuggestions(props: Props) {
|
|||
}, [isTyping, mentionTerm, hasMinLength, possibleMatches.length]);
|
||||
|
||||
React.useEffect(() => {
|
||||
|
||||
if (!inputRef) return;
|
||||
if (!mainEl) return;
|
||||
const header = document.querySelector('.header__navigation');
|
||||
|
||||
if (mentionTerm && isUriFromTermValid) {
|
||||
inputRef.current.classList.add('textarea-mention');
|
||||
} else {
|
||||
inputRef.current.classList.remove('textarea-mention');
|
||||
function handleReflow() {
|
||||
const boxAtTopOfPage = header && mainEl.getBoundingClientRect().top <= header.offsetHeight;
|
||||
const boxAtBottomOfPage = mainEl.getBoundingClientRect().bottom >= window.innerHeight;
|
||||
|
||||
if (boxAtTopOfPage) {
|
||||
mainEl.setAttribute('flow-bottom', '');
|
||||
}
|
||||
}, [inputRef, isUriFromTermValid, mentionTerm]);
|
||||
if (mainEl.getAttribute('flow-bottom') !== null && boxAtBottomOfPage) {
|
||||
mainEl.removeAttribute('flow-bottom');
|
||||
}
|
||||
}
|
||||
handleReflow();
|
||||
|
||||
window.addEventListener('scroll', handleReflow);
|
||||
return () => window.removeEventListener('scroll', handleReflow);
|
||||
}, [mainEl]);
|
||||
|
||||
React.useEffect(() => {
|
||||
if (!inputRef || !comboboxInputRef || !mentionTerm) return;
|
||||
|
@ -117,6 +129,7 @@ export default function ChannelMentionSuggestions(props: Props) {
|
|||
const selectedItem = selectedId && document.querySelector(`li[id="${selectedId}"]`);
|
||||
if (selectedItem) selectedItem.scrollIntoView({ block: 'nearest', inline: 'nearest' });
|
||||
} else {
|
||||
// $FlowFixMe
|
||||
comboboxInputRef.current.focus();
|
||||
}
|
||||
} else {
|
||||
|
@ -132,7 +145,10 @@ export default function ChannelMentionSuggestions(props: Props) {
|
|||
handleSelect(mentionTerm, keyCode);
|
||||
}
|
||||
}
|
||||
if (isRefFocused(comboboxInputRef)) inputRef.current.focus();
|
||||
if (isRefFocused(comboboxInputRef)) {
|
||||
// $FlowFixMe
|
||||
inputRef.current.focus();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -44,6 +44,17 @@
|
|||
}
|
||||
}
|
||||
|
||||
.channel-mention__suggestions[flow-bottom] {
|
||||
top: 4rem;
|
||||
bottom: auto;
|
||||
border-top-right-radius: 0;
|
||||
border-top-left-radius: 0;
|
||||
border-top: none;
|
||||
border-bottom-right-radius: var(--border-radius);
|
||||
border-bottom-left-radius: var(--border-radius);
|
||||
border-bottom: auto;
|
||||
}
|
||||
|
||||
.channel-mention__input--none {
|
||||
opacity: 0;
|
||||
width: 0;
|
||||
|
@ -59,7 +70,10 @@
|
|||
}
|
||||
|
||||
.channel-mention__suggestion {
|
||||
@extend .wunderbar__suggestion;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
padding: 0 var(--spacing-xxs);
|
||||
margin-left: var(--spacing-xxs);
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
|
||||
|
@ -81,35 +95,31 @@
|
|||
}
|
||||
|
||||
.channel-mention__suggestion-name {
|
||||
display: inline;
|
||||
@extend .wunderbar__suggestion-name;
|
||||
margin-left: calc(var(--spacing-l) - var(--spacing-xxs));
|
||||
|
||||
&::after {
|
||||
margin-left: var(--spacing-xxs);
|
||||
content: '•';
|
||||
}
|
||||
}
|
||||
|
||||
.channel-mention__suggestion-title {
|
||||
display: inline;
|
||||
margin-left: var(--spacing-xxs);
|
||||
@extend .wunderbar__suggestion-title;
|
||||
margin-left: calc(var(--spacing-l) - var(--spacing-xxs));
|
||||
}
|
||||
|
||||
.channel-mention__placeholder-suggestion {
|
||||
@extend .wunderbar__suggestion-name;
|
||||
@extend .wunderbar__placeholder-suggestion;
|
||||
padding: 0 var(--spacing-xxs);
|
||||
margin-left: var(--spacing-xxs);
|
||||
}
|
||||
|
||||
.channel-mention__placeholder-label {
|
||||
@extend .wunderbar__suggestion-name;
|
||||
@extend .wunderbar__placeholder-label;
|
||||
margin-left: var(--spacing-m);
|
||||
}
|
||||
|
||||
.channel-mention__placeholder-thumbnail {
|
||||
@extend .wunderbar__suggestion-name;
|
||||
@extend .wunderbar__placeholder-thumbnail;
|
||||
margin-left: var(--spacing-m);
|
||||
}
|
||||
.channel-mention__placeholder-info {
|
||||
@extend .wunderbar__suggestion-name;
|
||||
}
|
||||
|
||||
.textarea-mention {
|
||||
color: var(--color-primary);
|
||||
@extend .wunderbar__placeholder-info;
|
||||
margin-left: var(--spacing-m);
|
||||
}
|
||||
|
|
|
@ -40,6 +40,10 @@ $thumbnailWidthSmall: 1rem;
|
|||
.form-field--SimpleMDE {
|
||||
margin-top: 0;
|
||||
}
|
||||
|
||||
.form-field__two-column {
|
||||
column-count: 2;
|
||||
}
|
||||
}
|
||||
|
||||
.comment__create--reply {
|
||||
|
|
Loading…
Reference in a new issue
https://github.com/lbryio/lbry-desktop/blob/master/ui/effects/use-throttle.js would this work here?