use LazyRenderList in emoji picker Category
This commit is contained in:
parent
3e360c156a
commit
00b1816986
1 changed files with 41 additions and 7 deletions
|
@ -16,9 +16,11 @@ limitations under the License.
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import { CATEGORY_HEADER_HEIGHT, EMOJI_HEIGHT, EMOJIS_PER_ROW } from "./EmojiPicker";
|
||||||
import sdk from '../../../index';
|
import sdk from '../../../index';
|
||||||
|
|
||||||
|
const OVERFLOW_ROWS = 3;
|
||||||
|
|
||||||
class Category extends React.PureComponent {
|
class Category extends React.PureComponent {
|
||||||
static propTypes = {
|
static propTypes = {
|
||||||
emojis: PropTypes.arrayOf(PropTypes.object).isRequired,
|
emojis: PropTypes.arrayOf(PropTypes.object).isRequired,
|
||||||
|
@ -30,22 +32,54 @@ class Category extends React.PureComponent {
|
||||||
selectedEmojis: PropTypes.instanceOf(Set),
|
selectedEmojis: PropTypes.instanceOf(Set),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
_renderEmojiRow = (rowIndex) => {
|
||||||
|
const { onClick, onMouseEnter, onMouseLeave, selectedEmojis, emojis } = this.props;
|
||||||
|
const emojisForRow = emojis.slice(rowIndex * 8, (rowIndex + 1) * 8);
|
||||||
|
const Emoji = sdk.getComponent("emojipicker.Emoji");
|
||||||
|
return (<div key={rowIndex}>{
|
||||||
|
emojisForRow.map(emoji =>
|
||||||
|
<Emoji key={emoji.hexcode} emoji={emoji} selectedEmojis={selectedEmojis}
|
||||||
|
onClick={onClick} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} />)
|
||||||
|
}</div>);
|
||||||
|
};
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const { onClick, onMouseEnter, onMouseLeave, emojis, name, selectedEmojis } = this.props;
|
const { emojis, name, heightBefore, viewportHeight, scrollTop } = this.props;
|
||||||
if (!emojis || emojis.length === 0) {
|
if (!emojis || emojis.length === 0) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
const rows = new Array(Math.ceil(emojis.length / EMOJIS_PER_ROW));
|
||||||
|
for (let counter = 0; counter < rows.length; ++counter) {
|
||||||
|
rows[counter] = counter;
|
||||||
|
}
|
||||||
|
const LazyRenderList = sdk.getComponent('elements.LazyRenderList');
|
||||||
|
|
||||||
|
const viewportTop = scrollTop;
|
||||||
|
const viewportBottom = viewportTop + viewportHeight;
|
||||||
|
const listTop = heightBefore + CATEGORY_HEADER_HEIGHT;
|
||||||
|
const listBottom = listTop + (rows.length * EMOJI_HEIGHT);
|
||||||
|
const top = Math.max(viewportTop, listTop);
|
||||||
|
const bottom = Math.min(viewportBottom, listBottom);
|
||||||
|
// the viewport height and scrollTop passed to the LazyRenderList
|
||||||
|
// is capped at the intersection with the real viewport, so lists
|
||||||
|
// out of view are passed height 0, so they won't render any items.
|
||||||
|
const localHeight = Math.max(0, bottom - top);
|
||||||
|
const localScrollTop = Math.max(0, scrollTop - listTop);
|
||||||
|
|
||||||
const Emoji = sdk.getComponent("emojipicker.Emoji");
|
|
||||||
return (
|
return (
|
||||||
<section className="mx_EmojiPicker_category" data-category-id={this.props.id}>
|
<section className="mx_EmojiPicker_category" data-category-id={this.props.id}>
|
||||||
<h2 className="mx_EmojiPicker_category_label">
|
<h2 className="mx_EmojiPicker_category_label">
|
||||||
{name}
|
{name}
|
||||||
</h2>
|
</h2>
|
||||||
<ul className="mx_EmojiPicker_list">
|
<LazyRenderList
|
||||||
{emojis.map(emoji => <Emoji key={emoji.hexcode} emoji={emoji} selectedEmojis={selectedEmojis}
|
element="ul" className="mx_EmojiPicker_list"
|
||||||
onClick={onClick} onMouseEnter={onMouseEnter} onMouseLeave={onMouseLeave} />)}
|
itemHeight={EMOJI_HEIGHT} items={rows}
|
||||||
</ul>
|
scrollTop={localScrollTop}
|
||||||
|
height={localHeight}
|
||||||
|
overflowItems={OVERFLOW_ROWS}
|
||||||
|
overflowMargin={0}
|
||||||
|
renderItem={this._renderEmojiRow}>
|
||||||
|
</LazyRenderList>
|
||||||
</section>
|
</section>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue