Improve emoji autocomplete dropdown

- Add a key to each list item so that Mithril's diffing algorithm is used correctly. This prevents the emoji images from remaining for half a second before they update to a new suggestion.
- Clean up styles. The `PostPreview` doesn't really belong here.
This commit is contained in:
Toby Zerner 2016-02-07 11:47:49 +10:30
parent 7359407b54
commit 50d88d4547
4 changed files with 17 additions and 31 deletions

View File

@ -202,19 +202,16 @@ System.register('flarum/emoji/addComposerAutocomplete', ['flarum/extend', 'flaru
var imageName = (emojiMap[key].indexOf('-20e3') != -1 || emojiMap[key] == 'a9' || emojiMap[key] == 'ae' ? '00' : '') + emojiMap[key];
return m(
'button',
{ className: 'PostPreview',
{
key: key,
onclick: function () {
return applySuggestion(code);
},
onmouseenter: function () {
dropdown.setIndex($(this).parent().index());
} },
m(
'span',
{ className: 'PostPreview-content' },
m('img', { alt: code, 'class': 'emoji', draggable: 'false', src: '//cdn.jsdelivr.net/emojione/assets/png/' + imageName + '.png' }),
key
)
m('img', { alt: code, 'class': 'emoji', draggable: 'false', src: '//cdn.jsdelivr.net/emojione/assets/png/' + imageName + '.png' }),
key
);
};
@ -340,7 +337,7 @@ System.register('flarum/emoji/components/AutocompleteDropdown', ['flarum/Compone
this.props.items.map(function (item) {
return m(
'li',
null,
{ key: item.attrs.key },
item
);
})

View File

@ -68,15 +68,14 @@ export default function addComposerAutocomplete() {
const code = ':' + key + ':';
const imageName = (emojiMap[key].indexOf('-20e3') != -1 || emojiMap[key] == 'a9' || emojiMap[key] == 'ae' ? '00' : '') + emojiMap[key];
return (
<button className={'PostPreview'}
<button
key={key}
onclick={() => applySuggestion(code)}
onmouseenter={function() {
dropdown.setIndex($(this).parent().index());
}}>
<span className="PostPreview-content">
<img alt={code} class="emoji" draggable="false" src={'//cdn.jsdelivr.net/emojione/assets/png/' + imageName + '.png'}></img>
<img alt={code} class="emoji" draggable="false" src={'//cdn.jsdelivr.net/emojione/assets/png/' + imageName + '.png'}/>
{key}
</span>
</button>
);
};
@ -88,7 +87,7 @@ export default function addComposerAutocomplete() {
const fuzzyRegexp = function(str) {
const reEscape = new RegExp('\\(([' + ('+.*?[]{}()^$|\\'.replace(/(.)/g, '\\$1')) + '])\\)', 'g');
return new RegExp('(.*)' + (str.toLowerCase().replace(/(.)/g, '($1)(.*?)')).replace(reEscape, '(\\$1)') + '$', 'i');
}
};
const regTyped = fuzzyRegexp(typed);
for (var i=0, maxSuggestions = 7; i < emojiKeys.length && maxSuggestions > 0; i++) {
@ -102,7 +101,7 @@ export default function addComposerAutocomplete() {
return a.length - b.length
});
for(let key of similarEmoji) {
for (let key of similarEmoji) {
suggestions.push(makeSuggestion(key));
}

View File

@ -10,7 +10,7 @@ export default class AutocompleteDropdown extends Component {
view() {
return (
<ul className="Dropdown-menu EmojiDropdown">
{this.props.items.map(item => <li>{item}</li>)}
{this.props.items.map(item => <li key={item.attrs.key}>{item}</li>)}
</ul>
);
}

View File

@ -11,28 +11,18 @@ img.emoji {
position: absolute;
margin: 5px 0 !important;
> li > a {
white-space: normal;
border-bottom: 0;
}
> li > a:hover {
background: none;
}
.PostPreview {
> li > button {
color: @text-color;
font-weight: bold;
padding-top: 6px;
padding-bottom: 6px;
padding-left: 45px;
.emoji {
margin-right: 5px;
float: left;
margin-left: -30px;
}
}
.PostPreview-content {
overflow: hidden;
line-height: 1.7em;
display: block;
}
}
.ComposerBody-emojiWrapper {