|
1 | 1 | /* @flow strict-local */
|
2 |
| -import React, { PureComponent } from 'react'; |
| 2 | +import React, { useState, useRef, useEffect } from 'react'; |
3 | 3 | import { View, FlatList } from 'react-native';
|
4 | 4 | import { createSelector } from 'reselect';
|
5 | 5 |
|
| 6 | +import { usePrevious } from '../utils/react'; |
6 | 7 | import type { User, UserId, UserOrBot, PresenceState, Selector, Dispatch } from '../types';
|
7 | 8 | import { createStyleSheet } from '../styles';
|
8 | 9 | import { connect } from '../react-redux';
|
@@ -33,71 +34,61 @@ type Props = $ReadOnly<{|
|
33 | 34 | onComplete: (selected: UserOrBot[]) => void,
|
34 | 35 | |}>;
|
35 | 36 |
|
36 |
| -type State = {| |
37 |
| - selected: UserOrBot[], |
38 |
| -|}; |
| 37 | +function UserPickerCard(props: Props) { |
| 38 | + const { filter, users, presences } = props; |
39 | 39 |
|
40 |
| -class UserPickerCard extends PureComponent<Props, State> { |
41 |
| - state = { |
42 |
| - selected: [], |
43 |
| - }; |
| 40 | + const [selectedState, setSelectedState] = useState<UserOrBot[]>([]); |
| 41 | + const listRef = useRef<React$ElementRef<typeof FlatList> | null>(null); |
44 | 42 |
|
45 |
| - listRef = React.createRef<React$ElementRef<typeof FlatList>>(); |
46 |
| - |
47 |
| - componentDidUpdate = (prevProps: Props, prevState: State) => { |
48 |
| - if (this.listRef.current && this.state.selected.length > prevState.selected.length) { |
| 43 | + const prevSelectedState = usePrevious(selectedState); |
| 44 | + useEffect(() => { |
| 45 | + if (selectedState.length > prevSelectedState.length) { |
49 | 46 | setTimeout(() => {
|
50 |
| - this.listRef.current?.scrollToEnd(); |
| 47 | + listRef.current?.scrollToEnd(); |
51 | 48 | });
|
52 | 49 | }
|
53 |
| - }; |
| 50 | + }, [selectedState, prevSelectedState, listRef]); |
54 | 51 |
|
55 |
| - render() { |
56 |
| - const { filter, users, presences } = this.props; |
57 |
| - const { selected } = this.state; |
58 |
| - return ( |
59 |
| - <View style={styles.wrapper}> |
60 |
| - <AnimatedScaleComponent visible={selected.length > 0}> |
61 |
| - <AvatarList |
62 |
| - listRef={this.listRef} |
63 |
| - users={selected} |
64 |
| - onPress={(userId: UserId) => { |
65 |
| - this.setState(state => ({ |
66 |
| - selected: state.selected.filter(x => x.user_id !== userId), |
67 |
| - })); |
68 |
| - }} |
69 |
| - /> |
70 |
| - </AnimatedScaleComponent> |
71 |
| - {selected.length > 0 && <LineSeparator />} |
72 |
| - <UserList |
73 |
| - filter={filter} |
74 |
| - users={users} |
75 |
| - presences={presences} |
76 |
| - selected={selected} |
77 |
| - onPress={(user: UserOrBot) => { |
78 |
| - this.setState(state => { |
79 |
| - if (state.selected.find(x => x.user_id === user.user_id)) { |
80 |
| - return { selected: state.selected.filter(x => x.user_id !== user.user_id) }; |
81 |
| - } else { |
82 |
| - return { selected: [...state.selected, user] }; |
83 |
| - } |
84 |
| - }); |
| 52 | + return ( |
| 53 | + <View style={styles.wrapper}> |
| 54 | + <AnimatedScaleComponent visible={selectedState.length > 0}> |
| 55 | + <AvatarList |
| 56 | + listRef={listRef} |
| 57 | + users={selectedState} |
| 58 | + onPress={(userId: UserId) => { |
| 59 | + setSelectedState(state => state.filter(x => x.user_id !== userId)); |
| 60 | + }} |
| 61 | + /> |
| 62 | + </AnimatedScaleComponent> |
| 63 | + {selectedState.length > 0 && <LineSeparator />} |
| 64 | + <UserList |
| 65 | + filter={filter} |
| 66 | + users={users} |
| 67 | + presences={presences} |
| 68 | + selected={selectedState} |
| 69 | + onPress={(user: UserOrBot) => { |
| 70 | + setSelectedState(state => { |
| 71 | + if (state.find(x => x.user_id === user.user_id)) { |
| 72 | + return state.filter(x => x.user_id !== user.user_id); |
| 73 | + } else { |
| 74 | + return [...state, user]; |
| 75 | + } |
| 76 | + }); |
| 77 | + }} |
| 78 | + /> |
| 79 | + <AnimatedScaleComponent style={styles.button} visible={selectedState.length > 0}> |
| 80 | + <FloatingActionButton |
| 81 | + Icon={IconDone} |
| 82 | + size={50} |
| 83 | + disabled={selectedState.length === 0} |
| 84 | + onPress={() => { |
| 85 | + const { onComplete } = props; |
| 86 | + onComplete(selectedState); |
85 | 87 | }}
|
86 | 88 | />
|
87 |
| - <AnimatedScaleComponent style={styles.button} visible={selected.length > 0}> |
88 |
| - <FloatingActionButton |
89 |
| - Icon={IconDone} |
90 |
| - size={50} |
91 |
| - disabled={selected.length === 0} |
92 |
| - onPress={() => { |
93 |
| - const { onComplete } = this.props; |
94 |
| - onComplete(selected); |
95 |
| - }} |
96 |
| - /> |
97 |
| - </AnimatedScaleComponent> |
98 |
| - </View> |
99 |
| - ); |
100 |
| - } |
| 89 | + </AnimatedScaleComponent> |
| 90 | + </View> |
| 91 | + ); |
101 | 92 | }
|
102 | 93 |
|
103 | 94 | // The users we want to show in this particular UI.
|
|
0 commit comments