forked from vergnet/application-amicale
Greatly increased performance
This commit is contained in:
parent
7998fa47ca
commit
ef23280493
3 changed files with 109 additions and 52 deletions
|
@ -1,11 +1,12 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {IconButton, List, withTheme} from 'react-native-paper';
|
import {List, withTheme} from 'react-native-paper';
|
||||||
import {FlatList, View} from "react-native";
|
import {FlatList, View} from "react-native";
|
||||||
import {stringMatchQuery} from "../../utils/Search";
|
import {stringMatchQuery} from "../../utils/Search";
|
||||||
import Collapsible from "react-native-collapsible";
|
import Collapsible from "react-native-collapsible";
|
||||||
import * as Animatable from "react-native-animatable";
|
import * as Animatable from "react-native-animatable";
|
||||||
|
import GroupListItem from "./GroupListItem";
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
item: Object,
|
item: Object,
|
||||||
|
@ -42,7 +43,8 @@ class GroupListAccordion extends React.Component<Props, State> {
|
||||||
|
|
||||||
return (nextProps.currentSearchString !== this.props.currentSearchString)
|
return (nextProps.currentSearchString !== this.props.currentSearchString)
|
||||||
|| (nextSate.expanded !== this.state.expanded)
|
|| (nextSate.expanded !== this.state.expanded)
|
||||||
|| (nextProps.favoriteNumber !== this.props.favoriteNumber);
|
|| (nextProps.favoriteNumber !== this.props.favoriteNumber)
|
||||||
|
|| (nextProps.item.content.length !== this.props.item.content.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
onPress = () => {
|
onPress = () => {
|
||||||
|
@ -52,35 +54,16 @@ class GroupListAccordion extends React.Component<Props, State> {
|
||||||
|
|
||||||
keyExtractor = (item: Object) => item.id.toString();
|
keyExtractor = (item: Object) => item.id.toString();
|
||||||
|
|
||||||
isItemFavorite(item: Object) {
|
|
||||||
return item.isFav !== undefined && item.isFav;
|
|
||||||
}
|
|
||||||
|
|
||||||
renderItem = ({item}: Object) => {
|
renderItem = ({item}: Object) => {
|
||||||
if (stringMatchQuery(item.name, this.props.currentSearchString)) {
|
if (stringMatchQuery(item.name, this.props.currentSearchString)) {
|
||||||
|
|
||||||
const onPress = () => this.props.onGroupPress(item);
|
const onPress = () => this.props.onGroupPress(item);
|
||||||
const onStartPress = () => this.props.onFavoritePress(item);
|
const onStartPress = () => this.props.onFavoritePress(item);
|
||||||
return (
|
return (
|
||||||
<List.Item
|
<GroupListItem
|
||||||
title={item.name}
|
height={LIST_ITEM_HEIGHT}
|
||||||
|
item={item}
|
||||||
onPress={onPress}
|
onPress={onPress}
|
||||||
left={props =>
|
onStartPress={onStartPress}/>
|
||||||
<List.Icon
|
|
||||||
{...props}
|
|
||||||
icon={"chevron-right"}/>}
|
|
||||||
right={props =>
|
|
||||||
<IconButton
|
|
||||||
{...props}
|
|
||||||
icon={"star"}
|
|
||||||
onPress={onStartPress}
|
|
||||||
color={this.isItemFavorite(item) ? this.props.theme.colors.tetrisScore : props.color}
|
|
||||||
/>}
|
|
||||||
style={{
|
|
||||||
height: LIST_ITEM_HEIGHT,
|
|
||||||
justifyContent: 'center',
|
|
||||||
}}
|
|
||||||
/>
|
|
||||||
);
|
);
|
||||||
} else
|
} else
|
||||||
return null;
|
return null;
|
||||||
|
@ -90,16 +73,20 @@ class GroupListAccordion extends React.Component<Props, State> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
const item = this.props.item;
|
const item = this.props.item;
|
||||||
|
const accordionColor = this.state.expanded
|
||||||
|
? this.props.theme.colors.primary
|
||||||
|
: this.props.theme.colors.text;
|
||||||
|
// console.log(item.id);
|
||||||
return (
|
return (
|
||||||
<View>
|
<View>
|
||||||
<List.Item
|
<List.Item
|
||||||
title={item.name}
|
title={item.name}
|
||||||
expanded={this.state.expanded}
|
|
||||||
onPress={this.onPress}
|
onPress={this.onPress}
|
||||||
style={{
|
style={{
|
||||||
height: this.props.height,
|
height: this.props.height,
|
||||||
justifyContent: 'center',
|
justifyContent: 'center',
|
||||||
}}
|
}}
|
||||||
|
titleStyle={{color: accordionColor}}
|
||||||
left={props =>
|
left={props =>
|
||||||
item.id === "0"
|
item.id === "0"
|
||||||
? <List.Icon
|
? <List.Icon
|
||||||
|
@ -112,13 +99,19 @@ class GroupListAccordion extends React.Component<Props, State> {
|
||||||
ref={this.chevronRef}
|
ref={this.chevronRef}
|
||||||
{...props}
|
{...props}
|
||||||
icon={"chevron-down"}
|
icon={"chevron-down"}
|
||||||
|
color={this.state.expanded
|
||||||
|
? this.props.theme.colors.primary
|
||||||
|
: props.color
|
||||||
|
}
|
||||||
useNativeDriver
|
useNativeDriver
|
||||||
/>}
|
/>}
|
||||||
/>
|
/>
|
||||||
<Collapsible
|
<Collapsible
|
||||||
collapsed={!this.state.expanded}
|
collapsed={!this.state.expanded}
|
||||||
|
ease={"easeInOut"}
|
||||||
>
|
>
|
||||||
<FlatList
|
{this.state.expanded // Only render list if expanded for increased performance
|
||||||
|
? <FlatList
|
||||||
data={item.content}
|
data={item.content}
|
||||||
extraData={this.props.currentSearchString}
|
extraData={this.props.currentSearchString}
|
||||||
renderItem={this.renderItem}
|
renderItem={this.renderItem}
|
||||||
|
@ -128,6 +121,8 @@ class GroupListAccordion extends React.Component<Props, State> {
|
||||||
getItemLayout={this.itemLayout} // Broken with search
|
getItemLayout={this.itemLayout} // Broken with search
|
||||||
removeClippedSubviews={true}
|
removeClippedSubviews={true}
|
||||||
/>
|
/>
|
||||||
|
: null}
|
||||||
|
|
||||||
</Collapsible>
|
</Collapsible>
|
||||||
</View>
|
</View>
|
||||||
);
|
);
|
||||||
|
|
66
src/components/Lists/GroupListItem.js
Normal file
66
src/components/Lists/GroupListItem.js
Normal file
|
@ -0,0 +1,66 @@
|
||||||
|
// @flow
|
||||||
|
|
||||||
|
import * as React from 'react';
|
||||||
|
import {IconButton, List, withTheme} from 'react-native-paper';
|
||||||
|
|
||||||
|
type Props = {
|
||||||
|
theme: Object,
|
||||||
|
onPress: Function,
|
||||||
|
onStartPress: Function,
|
||||||
|
item: Object,
|
||||||
|
height: number,
|
||||||
|
}
|
||||||
|
|
||||||
|
type State = {
|
||||||
|
isFav: boolean,
|
||||||
|
}
|
||||||
|
|
||||||
|
class GroupListItem extends React.Component<Props, State> {
|
||||||
|
|
||||||
|
colors: Object;
|
||||||
|
|
||||||
|
constructor(props) {
|
||||||
|
super(props);
|
||||||
|
this.colors = props.theme.colors;
|
||||||
|
this.state = {
|
||||||
|
isFav: (props.item.isFav !== undefined && props.item.isFav),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
shouldComponentUpdate(prevProps: Props, prevState: State) {
|
||||||
|
return (prevState.isFav !== this.state.isFav);
|
||||||
|
}
|
||||||
|
|
||||||
|
onStarPress = () => {
|
||||||
|
this.setState({isFav: !this.state.isFav});
|
||||||
|
this.props.onStartPress();
|
||||||
|
}
|
||||||
|
|
||||||
|
render() {
|
||||||
|
return (
|
||||||
|
<List.Item
|
||||||
|
title={this.props.item.name}
|
||||||
|
onPress={this.props.onPress}
|
||||||
|
left={props =>
|
||||||
|
<List.Icon
|
||||||
|
{...props}
|
||||||
|
icon={"chevron-right"}/>}
|
||||||
|
right={props =>
|
||||||
|
<IconButton
|
||||||
|
{...props}
|
||||||
|
icon={"star"}
|
||||||
|
onPress={this.onStarPress}
|
||||||
|
color={this.state.isFav
|
||||||
|
? this.props.theme.colors.tetrisScore
|
||||||
|
: props.color}
|
||||||
|
/>}
|
||||||
|
style={{
|
||||||
|
height: this.props.height,
|
||||||
|
justifyContent: 'center',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export default withTheme(GroupListItem);
|
|
@ -1,7 +1,7 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
|
||||||
import * as React from 'react';
|
import * as React from 'react';
|
||||||
import {Platform, View} from "react-native";
|
import {Platform} from "react-native";
|
||||||
import i18n from "i18n-js";
|
import i18n from "i18n-js";
|
||||||
import {Searchbar, withTheme} from "react-native-paper";
|
import {Searchbar, withTheme} from "react-native-paper";
|
||||||
import {stringMatchQuery} from "../utils/Search";
|
import {stringMatchQuery} from "../utils/Search";
|
||||||
|
@ -206,9 +206,6 @@ class GroupSelectionScreen extends React.Component<Props, State> {
|
||||||
|
|
||||||
render() {
|
render() {
|
||||||
return (
|
return (
|
||||||
<View style={{
|
|
||||||
height: '100%'
|
|
||||||
}}>
|
|
||||||
<WebSectionList
|
<WebSectionList
|
||||||
{...this.props}
|
{...this.props}
|
||||||
createDataset={this.createDataset}
|
createDataset={this.createDataset}
|
||||||
|
@ -219,7 +216,6 @@ class GroupSelectionScreen extends React.Component<Props, State> {
|
||||||
updateData={this.state.currentSearchString + this.state.favoriteGroups.length}
|
updateData={this.state.currentSearchString + this.state.favoriteGroups.length}
|
||||||
itemHeight={LIST_ITEM_HEIGHT}
|
itemHeight={LIST_ITEM_HEIGHT}
|
||||||
/>
|
/>
|
||||||
</View>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue