Page Menu
Home
Phabricator
Search
Configure Global Search
Log In
Files
F3509078
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Size
7 KB
Referenced Files
None
Subscribers
None
View Options
diff --git a/native/community-creation/community-creation-members.react.js b/native/community-creation/community-creation-members.react.js
index 2018c7e93..b822ee3ed 100644
--- a/native/community-creation/community-creation-members.react.js
+++ b/native/community-creation/community-creation-members.react.js
@@ -1,186 +1,196 @@
// @flow
import * as React from 'react';
-import { ActivityIndicator } from 'react-native';
+import { ActivityIndicator, StyleSheet, View } from 'react-native';
import {
useChangeThreadSettings,
changeThreadSettingsActionTypes,
} from 'lib/actions/thread-actions.js';
import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import { threadInfoSelector } from 'lib/selectors/thread-selectors.js';
import { userInfoSelectorForPotentialMembers } from 'lib/selectors/user-selectors.js';
import { usePotentialMemberItems } from 'lib/shared/search-utils.js';
import type { LoadingStatus } from 'lib/types/loading-types.js';
import { threadTypes } from 'lib/types/thread-types-enum.js';
import type { AccountUserInfo } from 'lib/types/user-types.js';
import { useDispatchActionPromise } from 'lib/utils/redux-promise-utils.js';
import CommunityCreationContentContainer from './community-creation-content-container.react.js';
import CommunityCreationKeyserverLabel from './community-creation-keyserver-label.react.js';
import type { CommunityCreationNavigationProp } from './community-creation-navigator.react.js';
import RegistrationContainer from '../account/registration/registration-container.react.js';
import { useNavigateToThread } from '../chat/message-list-types.js';
import LinkButton from '../components/link-button.react.js';
import {
createTagInput,
type BaseTagInput,
} from '../components/tag-input.react.js';
import UserList from '../components/user-list.react.js';
import type { NavigationRoute } from '../navigation/route-names.js';
import { useSelector } from '../redux/redux-utils.js';
export type CommunityCreationMembersScreenParams = {
+announcement: boolean,
+threadID: string,
};
const TagInput = createTagInput<AccountUserInfo>();
const tagInputProps = {
placeholder: 'username',
autoFocus: true,
returnKeyType: 'go',
};
const tagDataLabelExtractor = (userInfo: AccountUserInfo) => userInfo.username;
type Props = {
+navigation: CommunityCreationNavigationProp<'CommunityCreationMembers'>,
+route: NavigationRoute<'CommunityCreationMembers'>,
};
const changeThreadSettingsLoadingStatusSelector = createLoadingStatusSelector(
changeThreadSettingsActionTypes,
);
function CommunityCreationMembers(props: Props): React.Node {
const { announcement, threadID } = props.route.params;
const dispatchActionPromise = useDispatchActionPromise();
const callChangeThreadSettings = useChangeThreadSettings();
const changeThreadSettingsLoadingStatus: LoadingStatus = useSelector(
changeThreadSettingsLoadingStatusSelector,
);
const { navigation } = props;
const { setOptions } = navigation;
const otherUserInfos = useSelector(userInfoSelectorForPotentialMembers);
const [usernameInputText, setUsernameInputText] = React.useState<string>('');
const [selectedUsers, setSelectedUsers] = React.useState<
$ReadOnlyArray<AccountUserInfo>,
>([]);
const selectedUserIDs = React.useMemo(
() => selectedUsers.map(userInfo => userInfo.id),
[selectedUsers],
);
const navigateToThread = useNavigateToThread();
const threadInfos = useSelector(threadInfoSelector);
const communityThreadInfo = threadInfos[threadID];
const addSelectedUsersToCommunity = React.useCallback(() => {
void dispatchActionPromise(
changeThreadSettingsActionTypes,
(async () => {
const result = await callChangeThreadSettings({
threadID,
changes: { newMemberIDs: selectedUserIDs },
});
navigateToThread({ threadInfo: communityThreadInfo });
return result;
})(),
);
}, [
callChangeThreadSettings,
communityThreadInfo,
dispatchActionPromise,
navigateToThread,
selectedUserIDs,
threadID,
]);
const exitCommunityCreationFlow = React.useCallback(() => {
navigateToThread({ threadInfo: communityThreadInfo });
}, [communityThreadInfo, navigateToThread]);
const activityIndicatorStyle = React.useMemo(
() => ({ paddingRight: 20 }),
[],
);
React.useEffect(() => {
setOptions({
headerRight: () => {
if (changeThreadSettingsLoadingStatus === 'loading') {
return (
<ActivityIndicator size="small" style={activityIndicatorStyle} />
);
}
return (
<LinkButton
text={selectedUserIDs.length === 0 ? 'Skip' : 'Done'}
onPress={
selectedUserIDs.length === 0
? exitCommunityCreationFlow
: addSelectedUsersToCommunity
}
/>
);
},
});
}, [
activityIndicatorStyle,
addSelectedUsersToCommunity,
changeThreadSettingsLoadingStatus,
exitCommunityCreationFlow,
selectedUserIDs.length,
setOptions,
]);
const userSearchResults = usePotentialMemberItems({
text: usernameInputText,
userInfos: otherUserInfos,
excludeUserIDs: selectedUserIDs,
threadType: announcement
? threadTypes.COMMUNITY_ANNOUNCEMENT_ROOT
: threadTypes.COMMUNITY_ROOT,
});
const onSelectUser = React.useCallback(
({ id }: AccountUserInfo) => {
if (selectedUserIDs.some(existingUserID => id === existingUserID)) {
return;
}
setSelectedUsers(oldUserInfoInputArray => [
...oldUserInfoInputArray,
otherUserInfos[id],
]);
setUsernameInputText('');
},
[otherUserInfos, selectedUserIDs],
);
const tagInputRef = React.useRef<?BaseTagInput<AccountUserInfo>>();
return (
<RegistrationContainer>
<CommunityCreationContentContainer>
<CommunityCreationKeyserverLabel />
- <TagInput
- value={selectedUsers}
- onChange={setSelectedUsers}
- text={usernameInputText}
- onChangeText={setUsernameInputText}
- labelExtractor={tagDataLabelExtractor}
- inputProps={tagInputProps}
- ref={tagInputRef}
- />
- <UserList userInfos={userSearchResults} onSelect={onSelectUser} />
+ <View style={styles.addMembersContainer}>
+ <TagInput
+ value={selectedUsers}
+ onChange={setSelectedUsers}
+ text={usernameInputText}
+ onChangeText={setUsernameInputText}
+ labelExtractor={tagDataLabelExtractor}
+ inputProps={tagInputProps}
+ ref={tagInputRef}
+ />
+ <UserList userInfos={userSearchResults} onSelect={onSelectUser} />
+ </View>
</CommunityCreationContentContainer>
</RegistrationContainer>
);
}
+const styles = StyleSheet.create({
+ addMembersContainer: {
+ flex: 1,
+ paddingHorizontal: 20,
+ paddingVertical: 8,
+ },
+});
+
export default CommunityCreationMembers;
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Dec 23, 12:54 AM (3 h, 47 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2690120
Default Alt Text
(7 KB)
Attached To
Mode
rCOMM Comm
Attached
Detach File
Event Timeline
Log In to Comment