feat: improve emoji autocomplete (#3923)

* feat: improve emoji autocomplete
* chore: improve dropdown header
This commit is contained in:
Sami Mazouz 2023-11-11 19:31:53 +01:00 committed by GitHub
parent 60ffa78531
commit 1c0e0933b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 34 deletions

View File

@ -1,6 +0,0 @@
{
"printWidth": 150,
"singleQuote": true,
"tabWidth": 2,
"trailingComma": "es5"
}

View File

@ -1,6 +1,7 @@
import { extend } from 'flarum/common/extend';
import TextEditorButton from 'flarum/common/components/TextEditorButton';
import KeyboardNavigatable from 'flarum/common/utils/KeyboardNavigatable';
import Tooltip from 'flarum/common/components/Tooltip';
import AutocompleteDropdown from './fragments/AutocompleteDropdown';
import getEmojiIconCode from './helpers/getEmojiIconCode';
@ -11,6 +12,13 @@ export default function addComposerAutocomplete() {
extend('flarum/common/components/TextEditor', 'oninit', function () {
this._loaders.push(async () => await import('./emojiMap').then((m) => (emojiMap = m.default)));
// prettier-ignore
this.commonEmoji = [
'😀', '😁', '😂', '😃', '😄', '😅', '😆', '😇', '😈', '😉', '😊', '😋', '😌', '😍', '😎', '😏', '😐️', '😑', '😒',
'😓', '😔', '😕', '😖', '😗', '😘', '😙', '😚', '😛', '😜', '😝', '😞', '😟', '😠', '😡', '😢', '😣', '😤', '😥',
'😦', '😧', '😨', '😩', '😪', '😫', '😬', '😭', '😮', '😮‍💨', '😯', '😰', '😱', '😲', '😳', '😴', '😵', '😵‍💫',
'😶', '😶‍🌫️', '😷', '😸', '😹', '😺', '😻', '😼', '😽', '😾', '😿', '🙀', '🙁', '🙂', '🙃', '🙄',
];
});
extend('flarum/common/components/TextEditor', 'onbuild', function () {
@ -75,16 +83,17 @@ export default function addComposerAutocomplete() {
const makeSuggestion = function ({ emoji, name, code }) {
return (
<button
key={emoji}
onclick={() => applySuggestion(emoji)}
onmouseenter={function () {
this.emojiDropdown.setIndex($(this).parent().index() - 1);
}}
>
<img alt={emoji} className="emoji" draggable="false" loading="lazy" src={`${cdn}72x72/${code}.png`} />
{name}
</button>
<Tooltip text={name}>
<button
key={emoji}
onclick={() => applySuggestion(emoji)}
onmouseenter={function () {
this.emojiDropdown.setIndex($(this).parent().index() - 1);
}}
>
<img alt={emoji} className="emoji" draggable="false" loading="lazy" src={`${cdn}72x72/${code}.png`} title={name} />
</button>
</Tooltip>
);
};
@ -98,7 +107,7 @@ export default function addComposerAutocomplete() {
};
const regTyped = fuzzyRegexp(typed);
let maxSuggestions = 7;
let maxSuggestions = 40;
const findMatchingEmojis = (matcher) => {
for (let i = 0; i < emojiKeys.length && maxSuggestions > 0; i++) {
@ -107,7 +116,7 @@ export default function addComposerAutocomplete() {
if (similarEmoji.indexOf(curEmoji) === -1) {
const names = emojiMap[curEmoji];
for (let name of names) {
if (matcher(name)) {
if (matcher(name, curEmoji)) {
--maxSuggestions;
similarEmoji.push(curEmoji);
break;
@ -118,10 +127,17 @@ export default function addComposerAutocomplete() {
};
// First, try to find all emojis starting with the given string
findMatchingEmojis((emoji) => emoji.indexOf(typed) === 0);
findMatchingEmojis((emojiName, emoji) => {
// If no input is provided yet, match the most common emojis.
if (!typed) {
return this.commonEmoji?.includes(emoji);
}
return emojiName.indexOf(typed) === 0;
});
// If there are still suggestions left, try for some fuzzy matches
findMatchingEmojis((emoji) => regTyped.test(emoji));
findMatchingEmojis((emojiName) => regTyped.test(emojiName));
const suggestions = similarEmoji
.map((emoji) => ({

View File

@ -7,29 +7,28 @@ img.emoji {
.EmojiDropdown {
max-width: 500px;
max-height: 200px;
overflow: auto;
overflow: visible;
position: absolute;
margin: 5px 0 !important;
padding: 8px;
> li > button {
color: var(--text-color);
font-weight: bold;
padding-top: 6px;
padding-bottom: 6px;
padding-left: 45px;
> li {
display: inline-block;
.emoji {
float: left;
margin-left: -30px;
> button {
color: var(--text-color);
font-weight: bold;
padding: 8px;
border-radius: var(--border-radius);
}
}
.Dropdown-header {
> .Dropdown-header {
display: block;
color: var(--muted-more-color);
text-transform: none;
font-weight: normal;
padding-bottom: 5px;
font-size: 11px;
padding: 4px 8px;
margin: 0 0 4px 0;
}
}