use TruncatedList to prevent rendering hundreds/thousands of DOM nodes

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski 2018-07-04 12:57:22 +01:00
parent f429ae5617
commit e5392e2c00
No known key found for this signature in database
GPG key ID: 3F879DA5AD802A5E

View file

@ -242,6 +242,8 @@ class SendAccountData extends GenericEditor {
} }
} }
const INITIAL_LOAD_TILES = 20;
class FilteredList extends React.Component { class FilteredList extends React.Component {
static propTypes = { static propTypes = {
children: PropTypes.any, children: PropTypes.any,
@ -249,31 +251,65 @@ class FilteredList extends React.Component {
onChange: PropTypes.func, onChange: PropTypes.func,
}; };
static filterChildren(children, query) {
if (!query) return children;
const lcQuery = query.toLowerCase();
return children.filter((child) => child.key.toLowerCase().includes(lcQuery));
}
constructor(props, context) { constructor(props, context) {
super(props, context); super(props, context);
this.onQuery = this.onQuery.bind(this);
this.state = {
filteredChildren: FilteredList.filterChildren(this.props.children, this.props.query),
truncateAt: INITIAL_LOAD_TILES,
};
} }
onQuery(ev) { componentWillReceiveProps(nextProps) {
if (this.props.children === nextProps.children && this.props.query === nextProps.query) return;
this.setState({
filteredChildren: FilteredList.filterChildren(nextProps.children, nextProps.query),
truncateAt: INITIAL_LOAD_TILES,
});
}
showAll = () => {
this.setState({
truncateAt: -1,
});
};
createOverflowElement = (overflowCount: number, totalCount: number) => {
return <button className="mx_DevTools_RoomStateExplorer_button" onClick={this.showAll}>
{ _t("and %(count)s others...", { count: overflowCount }) }
</button>;
};
onQuery = (ev) => {
if (this.props.onChange) this.props.onChange(ev.target.value); if (this.props.onChange) this.props.onChange(ev.target.value);
} };
filterChildren() { getChildren = (start: number, end: number) => {
if (this.props.query) { return this.state.filteredChildren.slice(start, end);
const lowerQuery = this.props.query.toLowerCase(); };
return this.props.children.filter((child) => child.key.toLowerCase().includes(lowerQuery));
} getChildCount = (): number => {
return this.props.children; return this.state.filteredChildren.length;
} };
render() { render() {
const TruncatedList = sdk.getComponent("elements.TruncatedList");
return <div> return <div>
<input size="64" <input size="64"
onChange={this.onQuery} onChange={this.onQuery}
value={this.props.query} value={this.props.query}
placeholder={_t('Filter results')} placeholder={_t('Filter results')}
className="mx_TextInputDialog_input mx_DevTools_RoomStateExplorer_query" /> className="mx_TextInputDialog_input mx_DevTools_RoomStateExplorer_query" />
{ this.filterChildren() } <TruncatedList getChildren={this.getChildren}
getChildCount={this.getChildCount}
truncateAt={this.state.truncateAt}
createOverflowElement={this.createOverflowElement} />
</div>; </div>;
} }
} }