diff --git a/native/community-creation/community-configuration.react.js b/native/community-creation/community-configuration.react.js
index 764303ff1..60417c960 100644
--- a/native/community-creation/community-configuration.react.js
+++ b/native/community-creation/community-configuration.react.js
@@ -1,259 +1,267 @@
// @flow
import * as React from 'react';
import { Text, TouchableOpacity, View } from 'react-native';
import { newThread, newThreadActionTypes } from 'lib/actions/thread-actions.js';
import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import type { LoadingStatus } from 'lib/types/loading-types.js';
import { threadTypes } from 'lib/types/thread-types-enum.js';
import type { NewThreadResult } from 'lib/types/thread-types.js';
import {
useDispatchActionPromise,
useServerCall,
} from 'lib/utils/action-utils.js';
import CommunityCreationKeyserverLabel from './community-creation-keyserver-label.react.js';
import type { CommunityCreationNavigationProp } from './community-creation-navigator.react.js';
import RegistrationButtonContainer from '../account/registration/registration-button-container.react.js';
import RegistrationButton from '../account/registration/registration-button.react.js';
import RegistrationContainer from '../account/registration/registration-container.react.js';
import RegistrationContentContainer from '../account/registration/registration-content-container.react.js';
import {
ThreadSettingsCategoryFooter,
ThreadSettingsCategoryHeader,
} from '../chat/settings/thread-settings-category.react.js';
import CommIcon from '../components/comm-icon.react.js';
import TextInput from '../components/text-input.react.js';
import { useCalendarQuery } from '../navigation/nav-selectors.js';
import {
CommunityCreationMembersRouteName,
type NavigationRoute,
} from '../navigation/route-names.js';
import { useSelector } from '../redux/redux-utils.js';
import { useColors, useStyles } from '../themes/colors.js';
type Props = {
+navigation: CommunityCreationNavigationProp<'CommunityConfiguration'>,
+route: NavigationRoute<'CommunityConfiguration'>,
};
const createNewCommunityLoadingStatusSelector =
createLoadingStatusSelector(newThreadActionTypes);
// eslint-disable-next-line no-unused-vars
function CommunityConfiguration(props: Props): React.Node {
const styles = useStyles(unboundStyles);
const colors = useColors();
const { navigate } = props.navigation;
const dispatchActionPromise = useDispatchActionPromise();
const callNewThread = useServerCall(newThread);
const calendarQueryFunc = useCalendarQuery();
const createNewCommunityLoadingStatus: LoadingStatus = useSelector(
createNewCommunityLoadingStatusSelector,
);
const [pendingCommunityName, setPendingCommunityName] = React.useState('');
const [announcementSetting, setAnnouncementSetting] = React.useState(false);
const [errorMessage, setErrorMessage] = React.useState();
const onChangePendingCommunityName = React.useCallback(newValue => {
setErrorMessage();
setPendingCommunityName(newValue);
}, []);
const callCreateNewCommunity = React.useCallback(async () => {
const calendarQuery = calendarQueryFunc();
try {
const newThreadResult: NewThreadResult = await callNewThread({
name: pendingCommunityName,
type: announcementSetting
? threadTypes.COMMUNITY_ANNOUNCEMENT_ROOT
: threadTypes.COMMUNITY_ROOT,
calendarQuery,
});
return newThreadResult;
} catch (e) {
setErrorMessage('Community creation failed. Please try again.');
throw e;
}
}, [
announcementSetting,
calendarQueryFunc,
callNewThread,
pendingCommunityName,
]);
const createNewCommunity = React.useCallback(async () => {
setErrorMessage();
const newThreadResultPromise = callCreateNewCommunity();
dispatchActionPromise(newThreadActionTypes, newThreadResultPromise);
await newThreadResultPromise;
- navigate(CommunityCreationMembersRouteName);
- }, [callCreateNewCommunity, dispatchActionPromise, navigate]);
+ navigate<'CommunityCreationMembers'>({
+ name: CommunityCreationMembersRouteName,
+ params: { announcement: announcementSetting },
+ });
+ }, [
+ announcementSetting,
+ callCreateNewCommunity,
+ dispatchActionPromise,
+ navigate,
+ ]);
const onCheckBoxPress = React.useCallback(() => {
setErrorMessage();
setAnnouncementSetting(!announcementSetting);
}, [announcementSetting]);
let checkBoxFill;
if (announcementSetting) {
checkBoxFill = ;
}
return (
Name
You may edit your community’s image and name later.
Announcement root
Make it so that only admins can post to the root channel of the
community.
{checkBoxFill}
{errorMessage}
);
}
const unboundStyles = {
containerPaddingOverride: {
padding: 0,
},
communityNameRow: {
backgroundColor: 'panelForeground',
flexDirection: 'row',
paddingHorizontal: 24,
paddingVertical: 8,
},
communityNameLabel: {
color: 'panelForegroundTertiaryLabel',
fontSize: 16,
width: 96,
},
communityNamePendingValue: {
color: 'panelForegroundSecondaryLabel',
flex: 1,
fontFamily: 'Arial',
fontSize: 16,
margin: 0,
paddingLeft: 4,
paddingRight: 0,
paddingVertical: 0,
borderBottomColor: 'transparent',
},
communityNameNoticeContainer: {
display: 'flex',
flexDirection: 'row',
justifyContent: 'center',
},
communityNameNoticeText: {
color: 'panelForegroundTertiaryLabel',
},
enumCell: {
flexDirection: 'row',
height: 96,
backgroundColor: 'panelForeground',
},
enumIcon: {
padding: 16,
},
enumInfoContainer: {
flex: 1,
flexDirection: 'column',
justifyContent: 'space-evenly',
padding: 8,
},
enumInfoName: {
color: 'panelForegroundLabel',
fontSize: 18,
lineHeight: 24,
},
enumInfoDescription: {
color: 'panelForegroundSecondaryLabel',
lineHeight: 18,
},
enumCheckBoxContainer: {
padding: 22,
justifyContent: 'center',
alignItems: 'center',
},
enumCheckBox: {
height: 32,
width: 32,
borderRadius: 3.5,
borderWidth: 1,
borderColor: 'panelSecondaryForegroundBorder',
justifyContent: 'center',
alignItems: 'center',
},
enumCheckBoxFill: {
height: 20,
width: 20,
borderRadius: 2.1875,
backgroundColor: 'panelForegroundSecondaryLabel',
},
errorMessageContainer: {
alignItems: 'center',
},
errorMessageText: {
color: 'redText',
},
};
export default CommunityConfiguration;
diff --git a/native/community-creation/community-creation-members.react.js b/native/community-creation/community-creation-members.react.js
index c8e3ef606..63570d4a5 100644
--- a/native/community-creation/community-creation-members.react.js
+++ b/native/community-creation/community-creation-members.react.js
@@ -1,99 +1,112 @@
// @flow
import * as React from 'react';
import {
userInfoSelectorForPotentialMembers,
userSearchIndexForPotentialMembers,
} from 'lib/selectors/user-selectors.js';
import { getPotentialMemberItems } from 'lib/shared/search-utils.js';
import { threadTypes } from 'lib/types/thread-types-enum.js';
import type { AccountUserInfo } from 'lib/types/user-types.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 { createTagInput } 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,
+};
+
const TagInput = createTagInput();
const tagInputProps = {
placeholder: 'username',
autoFocus: true,
returnKeyType: 'go',
};
const tagDataLabelExtractor = (userInfo: AccountUserInfo) => userInfo.username;
type Props = {
+navigation: CommunityCreationNavigationProp<'CommunityCreationMembers'>,
+route: NavigationRoute<'CommunityCreationMembers'>,
};
-// eslint-disable-next-line no-unused-vars
function CommunityCreationMembers(props: Props): React.Node {
+ const { announcement } = props.route.params;
+
const otherUserInfos = useSelector(userInfoSelectorForPotentialMembers);
const userSearchIndex = useSelector(userSearchIndexForPotentialMembers);
const [usernameInputText, setUsernameInputText] = React.useState('');
const [selectedUsers, setSelectedUsers] = React.useState<
$ReadOnlyArray,
>([]);
const selectedUserIDs = React.useMemo(
() => selectedUsers.map(userInfo => userInfo.id),
[selectedUsers],
);
const userSearchResults = React.useMemo(
() =>
getPotentialMemberItems(
usernameInputText,
otherUserInfos,
userSearchIndex,
selectedUserIDs,
null,
null,
- threadTypes.COMMUNITY_ROOT,
+ announcement
+ ? threadTypes.COMMUNITY_ANNOUNCEMENT_ROOT
+ : threadTypes.COMMUNITY_ROOT,
),
- [otherUserInfos, selectedUserIDs, userSearchIndex, usernameInputText],
+ [
+ announcement,
+ otherUserInfos,
+ selectedUserIDs,
+ userSearchIndex,
+ usernameInputText,
+ ],
);
const onSelectUser = React.useCallback(
userID => {
if (selectedUserIDs.some(existingUserID => userID === existingUserID)) {
return;
}
setSelectedUsers(oldUserInfoInputArray => [
...oldUserInfoInputArray,
otherUserInfos[userID],
]);
setUsernameInputText('');
},
[otherUserInfos, selectedUserIDs],
);
const tagInputRef = React.useRef();
return (
);
}
export default CommunityCreationMembers;
diff --git a/native/navigation/route-names.js b/native/navigation/route-names.js
index bae428788..28f6568cb 100644
--- a/native/navigation/route-names.js
+++ b/native/navigation/route-names.js
@@ -1,275 +1,276 @@
// @flow
import type { RouteProp } from '@react-navigation/native';
import type { ActionResultModalParams } from './action-result-modal.react.js';
import type { InviteLinkModalParams } from './invite-link-modal.react';
import type { AvatarSelectionParams } from '../account/registration/avatar-selection.react.js';
import type { ConnectEthereumParams } from '../account/registration/connect-ethereum.react.js';
import type { EmojiAvatarSelectionParams } from '../account/registration/emoji-avatar-selection.react.js';
import type { ExistingEthereumAccountParams } from '../account/registration/existing-ethereum-account.react.js';
import type { KeyserverSelectionParams } from '../account/registration/keyserver-selection.react.js';
import type { PasswordSelectionParams } from '../account/registration/password-selection.react.js';
import type { UsernameSelectionParams } from '../account/registration/username-selection.react.js';
import type { TermsAndPrivacyModalParams } from '../account/terms-and-privacy-modal.react.js';
import type { ThreadPickerModalParams } from '../calendar/thread-picker-modal.react.js';
import type { ComposeSubchannelParams } from '../chat/compose-subchannel.react.js';
import type { FullScreenThreadMediaGalleryParams } from '../chat/fullscreen-thread-media-gallery.react.js';
import type { ImagePasteModalParams } from '../chat/image-paste-modal.react.js';
import type { MessageListParams } from '../chat/message-list-types.js';
import type { MessageReactionsModalParams } from '../chat/message-reactions-modal.react.js';
import type { MessageResultsScreenParams } from '../chat/message-results-screen.react.js';
import type { MultimediaMessageTooltipModalParams } from '../chat/multimedia-message-tooltip-modal.react.js';
import type { RobotextMessageTooltipModalParams } from '../chat/robotext-message-tooltip-modal.react.js';
import type { AddUsersModalParams } from '../chat/settings/add-users-modal.react.js';
import type { ColorSelectorModalParams } from '../chat/settings/color-selector-modal.react.js';
import type { ComposeSubchannelModalParams } from '../chat/settings/compose-subchannel-modal.react.js';
import type { DeleteThreadParams } from '../chat/settings/delete-thread.react.js';
import type { EmojiThreadAvatarCreationParams } from '../chat/settings/emoji-thread-avatar-creation.react.js';
import type { ThreadSettingsMemberTooltipModalParams } from '../chat/settings/thread-settings-member-tooltip-modal.react.js';
import type { ThreadSettingsParams } from '../chat/settings/thread-settings.react.js';
import type { SidebarListModalParams } from '../chat/sidebar-list-modal.react.js';
import type { SubchannelListModalParams } from '../chat/subchannels-list-modal.react.js';
import type { TextMessageTooltipModalParams } from '../chat/text-message-tooltip-modal.react.js';
import type { TogglePinModalParams } from '../chat/toggle-pin-modal.react.js';
+import type { CommunityCreationMembersScreenParams } from '../community-creation/community-creation-members.react.js';
import type { ManagePublicLinkScreenParams } from '../invite-links/manage-public-link-screen.react.js';
import type { ViewInviteLinksScreenParams } from '../invite-links/view-invite-links-screen.react.js';
import type { ChatCameraModalParams } from '../media/chat-camera-modal.react.js';
import type { ImageModalParams } from '../media/image-modal.react.js';
import type { ThreadAvatarCameraModalParams } from '../media/thread-avatar-camera-modal.react.js';
import type { VideoPlaybackModalParams } from '../media/video-playback-modal.react.js';
import type { CustomServerModalParams } from '../profile/custom-server-modal.react.js';
import type { RelationshipListItemTooltipModalParams } from '../profile/relationship-list-item-tooltip-modal.react.js';
import type { MessageSearchParams } from '../search/message-search.react.js';
export const ActionResultModalRouteName = 'ActionResultModal';
export const AddUsersModalRouteName = 'AddUsersModal';
export const AppearancePreferencesRouteName = 'AppearancePreferences';
export const AppRouteName = 'App';
export const AppsRouteName = 'Apps';
export const BackgroundChatThreadListRouteName = 'BackgroundChatThreadList';
export const BlockListRouteName = 'BlockList';
export const BuildInfoRouteName = 'BuildInfo';
export const CalendarRouteName = 'Calendar';
export const ChatCameraModalRouteName = 'ChatCameraModal';
export const ChatRouteName = 'Chat';
export const ChatThreadListRouteName = 'ChatThreadList';
export const ColorSelectorModalRouteName = 'ColorSelectorModal';
export const ComposeSubchannelModalRouteName = 'ComposeSubchannelModal';
export const ComposeSubchannelRouteName = 'ComposeSubchannel';
export const CommunityDrawerNavigatorRouteName = 'CommunityDrawerNavigator';
export const CustomServerModalRouteName = 'CustomServerModal';
export const DefaultNotificationsPreferencesRouteName = 'DefaultNotifications';
export const DeleteAccountRouteName = 'DeleteAccount';
export const DeleteThreadRouteName = 'DeleteThread';
export const DevToolsRouteName = 'DevTools';
export const EditPasswordRouteName = 'EditPassword';
export const EmojiThreadAvatarCreationRouteName = 'EmojiThreadAvatarCreation';
export const EmojiUserAvatarCreationRouteName = 'EmojiUserAvatarCreation';
export const FriendListRouteName = 'FriendList';
export const FullScreenThreadMediaGalleryRouteName =
'FullScreenThreadMediaGallery';
export const HomeChatThreadListRouteName = 'HomeChatThreadList';
export const ImageModalRouteName = 'ImageModal';
export const ImagePasteModalRouteName = 'ImagePasteModal';
export const InviteLinkModalRouteName = 'InviteLinkModal';
export const InviteLinkNavigatorRouteName = 'InviteLinkNavigator';
export const LoggedOutModalRouteName = 'LoggedOutModal';
export const ManagePublicLinkRouteName = 'ManagePublicLink';
export const MessageListRouteName = 'MessageList';
export const MessageReactionsModalRouteName = 'MessageReactionsModal';
export const MessageResultsScreenRouteName = 'MessageResultsScreen';
export const MultimediaMessageTooltipModalRouteName =
'MultimediaMessageTooltipModal';
export const PrivacyPreferencesRouteName = 'PrivacyPreferences';
export const ProfileRouteName = 'Profile';
export const ProfileScreenRouteName = 'ProfileScreen';
export const RelationshipListItemTooltipModalRouteName =
'RelationshipListItemTooltipModal';
export const RobotextMessageTooltipModalRouteName =
'RobotextMessageTooltipModal';
export const SidebarListModalRouteName = 'SidebarListModal';
export const SubchannelsListModalRouteName = 'SubchannelsListModal';
export const TabNavigatorRouteName = 'TabNavigator';
export const TextMessageTooltipModalRouteName = 'TextMessageTooltipModal';
export const ThreadAvatarCameraModalRouteName = 'ThreadAvatarCameraModal';
export const ThreadPickerModalRouteName = 'ThreadPickerModal';
export const ThreadSettingsMemberTooltipModalRouteName =
'ThreadSettingsMemberTooltipModal';
export const ThreadSettingsRouteName = 'ThreadSettings';
export const UserAvatarCameraModalRouteName = 'UserAvatarCameraModal';
export const TogglePinModalRouteName = 'TogglePinModal';
export const VideoPlaybackModalRouteName = 'VideoPlaybackModal';
export const ViewInviteLinksRouteName = 'ViewInviteLinks';
export const TermsAndPrivacyRouteName = 'TermsAndPrivacyModal';
export const RegistrationRouteName = 'Registration';
export const KeyserverSelectionRouteName = 'KeyserverSelection';
export const CoolOrNerdModeSelectionRouteName = 'CoolOrNerdModeSelection';
export const ConnectEthereumRouteName = 'ConnectEthereum';
export const ExistingEthereumAccountRouteName = 'ExistingEthereumAccount';
export const UsernameSelectionRouteName = 'UsernameSelection';
export const CommunityCreationRouteName = 'CommunityCreation';
export const CommunityConfigurationRouteName = 'CommunityConfiguration';
export const CommunityCreationMembersRouteName = 'CommunityCreationMembers';
export const MessageSearchRouteName = 'MessageSearch';
export const PasswordSelectionRouteName = 'PasswordSelection';
export const AvatarSelectionRouteName = 'AvatarSelection';
export const EmojiAvatarSelectionRouteName = 'EmojiAvatarSelection';
export const RegistrationUserAvatarCameraModalRouteName =
'RegistrationUserAvatarCameraModal';
export type RootParamList = {
+LoggedOutModal: void,
+App: void,
+ThreadPickerModal: ThreadPickerModalParams,
+AddUsersModal: AddUsersModalParams,
+CustomServerModal: CustomServerModalParams,
+ColorSelectorModal: ColorSelectorModalParams,
+ComposeSubchannelModal: ComposeSubchannelModalParams,
+SidebarListModal: SidebarListModalParams,
+ImagePasteModal: ImagePasteModalParams,
+TermsAndPrivacyModal: TermsAndPrivacyModalParams,
+SubchannelsListModal: SubchannelListModalParams,
+MessageReactionsModal: MessageReactionsModalParams,
+Registration: void,
+CommunityCreation: void,
+InviteLinkModal: InviteLinkModalParams,
+InviteLinkNavigator: void,
};
export type MessageTooltipRouteNames =
| typeof RobotextMessageTooltipModalRouteName
| typeof MultimediaMessageTooltipModalRouteName
| typeof TextMessageTooltipModalRouteName;
export const PinnableMessageTooltipRouteNames = [
TextMessageTooltipModalRouteName,
MultimediaMessageTooltipModalRouteName,
];
export type TooltipModalParamList = {
+MultimediaMessageTooltipModal: MultimediaMessageTooltipModalParams,
+TextMessageTooltipModal: TextMessageTooltipModalParams,
+ThreadSettingsMemberTooltipModal: ThreadSettingsMemberTooltipModalParams,
+RelationshipListItemTooltipModal: RelationshipListItemTooltipModalParams,
+RobotextMessageTooltipModal: RobotextMessageTooltipModalParams,
};
export type OverlayParamList = {
+CommunityDrawerNavigator: void,
+ImageModal: ImageModalParams,
+ActionResultModal: ActionResultModalParams,
+ChatCameraModal: ChatCameraModalParams,
+UserAvatarCameraModal: void,
+ThreadAvatarCameraModal: ThreadAvatarCameraModalParams,
+VideoPlaybackModal: VideoPlaybackModalParams,
+TogglePinModal: TogglePinModalParams,
...TooltipModalParamList,
};
export type TabParamList = {
+Calendar: void,
+Chat: void,
+Profile: void,
+Apps: void,
};
export type ChatParamList = {
+ChatThreadList: void,
+MessageList: MessageListParams,
+ComposeSubchannel: ComposeSubchannelParams,
+ThreadSettings: ThreadSettingsParams,
+EmojiThreadAvatarCreation: EmojiThreadAvatarCreationParams,
+DeleteThread: DeleteThreadParams,
+FullScreenThreadMediaGallery: FullScreenThreadMediaGalleryParams,
+MessageResultsScreen: MessageResultsScreenParams,
+MessageSearch: MessageSearchParams,
};
export type ChatTopTabsParamList = {
+HomeChatThreadList: void,
+BackgroundChatThreadList: void,
};
export type ProfileParamList = {
+ProfileScreen: void,
+EmojiUserAvatarCreation: void,
+EditPassword: void,
+DeleteAccount: void,
+BuildInfo: void,
+DevTools: void,
+AppearancePreferences: void,
+PrivacyPreferences: void,
+DefaultNotifications: void,
+FriendList: void,
+BlockList: void,
};
export type CommunityDrawerParamList = { +TabNavigator: void };
export type RegistrationParamList = {
+CoolOrNerdModeSelection: void,
+KeyserverSelection: KeyserverSelectionParams,
+ConnectEthereum: ConnectEthereumParams,
+ExistingEthereumAccount: ExistingEthereumAccountParams,
+UsernameSelection: UsernameSelectionParams,
+PasswordSelection: PasswordSelectionParams,
+AvatarSelection: AvatarSelectionParams,
+EmojiAvatarSelection: EmojiAvatarSelectionParams,
+RegistrationUserAvatarCameraModal: void,
};
export type InviteLinkParamList = {
+ViewInviteLinks: ViewInviteLinksScreenParams,
+ManagePublicLink: ManagePublicLinkScreenParams,
};
export type CommunityCreationParamList = {
+CommunityConfiguration: void,
- +CommunityCreationMembers: void,
+ +CommunityCreationMembers: CommunityCreationMembersScreenParams,
};
export type ScreenParamList = {
...RootParamList,
...OverlayParamList,
...TabParamList,
...ChatParamList,
...ChatTopTabsParamList,
...ProfileParamList,
...CommunityDrawerParamList,
...RegistrationParamList,
...InviteLinkParamList,
...CommunityCreationParamList,
};
export type NavigationRoute> =
RouteProp;
export const accountModals = [LoggedOutModalRouteName, RegistrationRouteName];
export const scrollBlockingModals = [
ImageModalRouteName,
MultimediaMessageTooltipModalRouteName,
TextMessageTooltipModalRouteName,
ThreadSettingsMemberTooltipModalRouteName,
RelationshipListItemTooltipModalRouteName,
RobotextMessageTooltipModalRouteName,
VideoPlaybackModalRouteName,
];
export const chatRootModals = [
AddUsersModalRouteName,
ColorSelectorModalRouteName,
ComposeSubchannelModalRouteName,
];
export const threadRoutes = [
MessageListRouteName,
ThreadSettingsRouteName,
DeleteThreadRouteName,
ComposeSubchannelRouteName,
FullScreenThreadMediaGalleryRouteName,
MessageResultsScreenRouteName,
MessageSearchRouteName,
EmojiThreadAvatarCreationRouteName,
];