diff --git a/native/account/registration/avatar-selection.react.js b/native/account/registration/avatar-selection.react.js
new file mode 100644
index 000000000..fc108ab8f
--- /dev/null
+++ b/native/account/registration/avatar-selection.react.js
@@ -0,0 +1,69 @@
+// @flow
+
+import * as React from 'react';
+import { Text } from 'react-native';
+
+import type { SIWEResult } from 'lib/types/siwe-types.js';
+
+import RegistrationButtonContainer from './registration-button-container.react.js';
+import RegistrationButton from './registration-button.react.js';
+import RegistrationContainer from './registration-container.react.js';
+import RegistrationContentContainer from './registration-content-container.react.js';
+import type { RegistrationNavigationProp } from './registration-navigator.react.js';
+import type { CoolOrNerdMode } from './registration-types.js';
+import type { NavigationRoute } from '../../navigation/route-names.js';
+import { useStyles } from '../../themes/colors.js';
+
+type EthereumAccountSelections = {
+ +accountType: 'ethereum',
+ ...SIWEResult,
+};
+
+type UsernameAccountSelections = {
+ +accountType: 'username',
+ +username: string,
+ +password: string,
+};
+
+export type AvatarSelectionParams = {
+ +userSelections: {
+ +coolOrNerdMode: CoolOrNerdMode,
+ +keyserverUsername: string,
+ +accountSelections: EthereumAccountSelections | UsernameAccountSelections,
+ },
+};
+
+type Props = {
+ +navigation: RegistrationNavigationProp<'AvatarSelection'>,
+ +route: NavigationRoute<'AvatarSelection'>,
+};
+// eslint-disable-next-line no-unused-vars
+function AvatarSelection(props: Props): React.Node {
+ const onProceed = React.useCallback(() => {}, []);
+
+ const styles = useStyles(unboundStyles);
+ return (
+
+
+ Pick an avatar
+
+
+
+
+
+ );
+}
+
+const unboundStyles = {
+ header: {
+ fontSize: 24,
+ color: 'panelForegroundLabel',
+ paddingBottom: 16,
+ },
+};
+
+export default AvatarSelection;
diff --git a/native/account/registration/connect-ethereum.react.js b/native/account/registration/connect-ethereum.react.js
index b6ca1dfc6..db588c355 100644
--- a/native/account/registration/connect-ethereum.react.js
+++ b/native/account/registration/connect-ethereum.react.js
@@ -1,241 +1,253 @@
// @flow
import * as React from 'react';
import { Text, View } from 'react-native';
import {
exactSearchUser,
exactSearchUserActionTypes,
} from 'lib/actions/user-actions.js';
import { createLoadingStatusSelector } from 'lib/selectors/loading-selectors.js';
import type { SIWEResult } from 'lib/types/siwe-types.js';
import {
useServerCall,
useDispatchActionPromise,
} from 'lib/utils/action-utils.js';
import RegistrationButtonContainer from './registration-button-container.react.js';
import RegistrationButton from './registration-button.react.js';
import RegistrationContainer from './registration-container.react.js';
import RegistrationContentContainer from './registration-content-container.react.js';
import type { RegistrationNavigationProp } from './registration-navigator.react.js';
import type { CoolOrNerdMode } from './registration-types.js';
import {
type NavigationRoute,
ExistingEthereumAccountRouteName,
UsernameSelectionRouteName,
+ AvatarSelectionRouteName,
} from '../../navigation/route-names.js';
import { useSelector } from '../../redux/redux-utils.js';
import { useStyles } from '../../themes/colors.js';
import EthereumLogoDark from '../../vectors/ethereum-logo-dark.react.js';
import SIWEPanel from '../siwe-panel.react.js';
const exactSearchUserLoadingStatusSelector = createLoadingStatusSelector(
exactSearchUserActionTypes,
);
export type ConnectEthereumParams = {
+userSelections: {
+coolOrNerdMode: CoolOrNerdMode,
+keyserverUsername: string,
},
};
type PanelState = 'closed' | 'opening' | 'open' | 'closing';
type Props = {
+navigation: RegistrationNavigationProp<'ConnectEthereum'>,
+route: NavigationRoute<'ConnectEthereum'>,
};
function ConnectEthereum(props: Props): React.Node {
const { params } = props.route;
const { userSelections } = props.route.params;
const isNerdMode = userSelections.coolOrNerdMode === 'nerd';
const styles = useStyles(unboundStyles);
let body;
if (!isNerdMode) {
body = (
Connecting your Ethereum wallet allows you to use your ENS name and
avatar in the app. You’ll also be able to log in with your wallet
instead of a password.
);
} else {
body = (
<>
Connecting your Ethereum wallet has three benefits:
{'1. '}
Your peers will be able to cryptographically verify that your Comm
account is associated with your Ethereum wallet.
{'2. '}
You’ll be able to use your ENS name and avatar in the app.
{'3. '}
You can choose to skip setting a password, and to log in with your
Ethereum wallet instead.
>
);
}
const [panelState, setPanelState] = React.useState('closed');
const openPanel = React.useCallback(() => {
setPanelState('opening');
}, []);
const onPanelClosed = React.useCallback(() => {
setPanelState('closed');
}, []);
const onPanelClosing = React.useCallback(() => {
setPanelState('closing');
}, []);
const siwePanelSetLoading = React.useCallback(
(loading: boolean) => {
if (panelState === 'closing' || panelState === 'closed') {
return;
}
setPanelState(loading ? 'opening' : 'open');
},
[panelState],
);
const { navigate } = props.navigation;
const onSkip = React.useCallback(() => {
navigate<'UsernameSelection'>({
name: UsernameSelectionRouteName,
params,
});
}, [navigate, params]);
const exactSearchUserCall = useServerCall(exactSearchUser);
const dispatchActionPromise = useDispatchActionPromise();
const onSuccessfulWalletSignature = React.useCallback(
async (result: SIWEResult) => {
const searchPromise = exactSearchUserCall(result.address);
dispatchActionPromise(exactSearchUserActionTypes, searchPromise);
const { userInfo } = await searchPromise;
if (userInfo) {
navigate<'ExistingEthereumAccount'>({
name: ExistingEthereumAccountRouteName,
params: result,
});
- } else {
- // show avatar selection screen
+ return;
}
+
+ const newUserSelections = {
+ ...userSelections,
+ accountSelections: {
+ accountType: 'ethereum',
+ ...result,
+ },
+ };
+ navigate<'AvatarSelection'>({
+ name: AvatarSelectionRouteName,
+ params: { userSelections: newUserSelections },
+ });
},
- [exactSearchUserCall, dispatchActionPromise, navigate],
+ [userSelections, exactSearchUserCall, dispatchActionPromise, navigate],
);
let siwePanel;
if (panelState !== 'closed') {
siwePanel = (
);
}
const exactSearchUserCallLoading = useSelector(
state => exactSearchUserLoadingStatusSelector(state) === 'loading',
);
const connectButtonVariant =
exactSearchUserCallLoading || panelState === 'opening'
? 'loading'
: 'enabled';
return (
<>
Do you want to connect an Ethereum wallet?
{body}
{siwePanel}
>
);
}
const unboundStyles = {
scrollViewContentContainer: {
flexGrow: 1,
},
header: {
fontSize: 24,
color: 'panelForegroundLabel',
paddingBottom: 16,
},
body: {
fontFamily: 'Arial',
fontSize: 15,
lineHeight: 20,
color: 'panelForegroundSecondaryLabel',
paddingBottom: 16,
},
ethereumLogoContainer: {
flexGrow: 1,
alignItems: 'center',
justifyContent: 'center',
},
list: {
paddingBottom: 16,
},
listItem: {
flexDirection: 'row',
},
listItemNumber: {
fontFamily: 'Arial',
fontWeight: 'bold',
fontSize: 15,
lineHeight: 20,
color: 'panelForegroundSecondaryLabel',
},
listItemContent: {
fontFamily: 'Arial',
flexShrink: 1,
fontSize: 15,
lineHeight: 20,
color: 'panelForegroundSecondaryLabel',
},
};
export default ConnectEthereum;
diff --git a/native/account/registration/password-selection.react.js b/native/account/registration/password-selection.react.js
index 5e679368b..e2f6bb77f 100644
--- a/native/account/registration/password-selection.react.js
+++ b/native/account/registration/password-selection.react.js
@@ -1,206 +1,225 @@
// @flow
import * as React from 'react';
import { View, Text, Platform } from 'react-native';
import sleep from 'lib/utils/sleep.js';
import RegistrationButtonContainer from './registration-button-container.react.js';
import RegistrationButton from './registration-button.react.js';
import RegistrationContainer from './registration-container.react.js';
import RegistrationContentContainer from './registration-content-container.react.js';
import type { RegistrationNavigationProp } from './registration-navigator.react.js';
import RegistrationTextInput from './registration-text-input.react.js';
import type { CoolOrNerdMode } from './registration-types.js';
-import type { NavigationRoute } from '../../navigation/route-names.js';
+import {
+ type NavigationRoute,
+ AvatarSelectionRouteName,
+} from '../../navigation/route-names.js';
import { useStyles } from '../../themes/colors.js';
import type { KeyPressEvent } from '../../types/react-native.js';
export type PasswordSelectionParams = {
+userSelections: {
+coolOrNerdMode: CoolOrNerdMode,
+keyserverUsername: string,
+username: string,
},
};
type PasswordError = 'passwords_dont_match' | 'empty_password';
type Props = {
+navigation: RegistrationNavigationProp<'PasswordSelection'>,
+route: NavigationRoute<'PasswordSelection'>,
};
-// eslint-disable-next-line no-unused-vars
function PasswordSelection(props: Props): React.Node {
const [password, setPassword] = React.useState('');
const [confirmPassword, setConfirmPassword] = React.useState('');
const passwordsMatch = password === confirmPassword;
const passwordIsEmpty = password === '';
const [passwordError, setPasswordError] = React.useState();
const potentiallyClearErrors = React.useCallback(() => {
if (!passwordsMatch || passwordIsEmpty) {
return false;
}
setPasswordError(null);
return true;
}, [passwordsMatch, passwordIsEmpty]);
const checkPasswordValidity = React.useCallback(() => {
if (!passwordsMatch) {
setPasswordError('passwords_dont_match');
return false;
} else if (passwordIsEmpty) {
setPasswordError('empty_password');
return false;
}
return potentiallyClearErrors();
}, [passwordsMatch, passwordIsEmpty, potentiallyClearErrors]);
+ const { userSelections } = props.route.params;
+ const { navigate } = props.navigation;
const onProceed = React.useCallback(() => {
if (!checkPasswordValidity()) {
return;
}
- }, [checkPasswordValidity]);
+
+ const { coolOrNerdMode, keyserverUsername, username } = userSelections;
+ const newUserSelections = {
+ coolOrNerdMode,
+ keyserverUsername,
+ accountSelections: {
+ accountType: 'username',
+ username,
+ password,
+ },
+ };
+ navigate<'AvatarSelection'>({
+ name: AvatarSelectionRouteName,
+ params: { userSelections: newUserSelections },
+ });
+ }, [checkPasswordValidity, userSelections, password, navigate]);
const styles = useStyles(unboundStyles);
let errorText;
if (passwordError === 'passwords_dont_match') {
errorText = (
Passwords don’t match
);
} else if (passwordError === 'empty_password') {
errorText = Password cannot be empty;
}
const confirmPasswordInputRef = React.useRef();
const focusConfirmPasswordInput = React.useCallback(() => {
confirmPasswordInputRef.current?.focus();
}, []);
const iosPasswordBeingAutoFilled = React.useRef(false);
const confirmPasswordEmpty = confirmPassword.length === 0;
const onPasswordKeyPress = React.useCallback(
(event: KeyPressEvent) => {
const { key } = event.nativeEvent;
// On iOS, paste doesn't trigger onKeyPress, but password autofill does
// Password autofill calls onKeyPress with `key` set to the whole password
if (
key.length > 1 &&
key !== 'Backspace' &&
key !== 'Enter' &&
confirmPasswordEmpty
) {
iosPasswordBeingAutoFilled.current = true;
}
},
[confirmPasswordEmpty],
);
const passwordInputRef = React.useRef();
const passwordLength = password.length;
const onChangePasswordInput = React.useCallback(
(input: string) => {
setPassword(input);
if (iosPasswordBeingAutoFilled.current) {
// On iOS, paste doesn't trigger onKeyPress, but password autofill does
iosPasswordBeingAutoFilled.current = false;
setConfirmPassword(input);
passwordInputRef.current?.blur();
} else if (
Platform.OS === 'android' &&
input.length - passwordLength > 1 &&
confirmPasswordEmpty
) {
// On Android, password autofill doesn't trigger onKeyPress. Instead we
// rely on observing when the password field changes by more than one
// character at a time. This means we treat paste the same way as
// password autofill
setConfirmPassword(input);
passwordInputRef.current?.blur();
}
},
[passwordLength, confirmPasswordEmpty],
);
/* eslint-disable react-hooks/rules-of-hooks */
if (Platform.OS === 'android') {
// It's okay to call this hook conditionally because
// the condition is guaranteed to never change
React.useEffect(() => {
(async () => {
await sleep(250);
passwordInputRef.current?.focus();
})();
}, []);
}
/* eslint-enable react-hooks/rules-of-hooks */
return (
Pick a password
{errorText}
);
}
const unboundStyles = {
header: {
fontSize: 24,
color: 'panelForegroundLabel',
paddingBottom: 16,
},
error: {
marginTop: 16,
},
errorText: {
fontFamily: 'Arial',
fontSize: 15,
lineHeight: 20,
color: 'redText',
},
confirmPassword: {
marginTop: 16,
},
};
export default PasswordSelection;
diff --git a/native/account/registration/registration-navigator.react.js b/native/account/registration/registration-navigator.react.js
index 06b6234bb..43f861ea7 100644
--- a/native/account/registration/registration-navigator.react.js
+++ b/native/account/registration/registration-navigator.react.js
@@ -1,84 +1,90 @@
// @flow
import {
createStackNavigator,
type StackNavigationProp,
type StackNavigationHelpers,
} from '@react-navigation/stack';
import * as React from 'react';
+import AvatarSelection from './avatar-selection.react.js';
import ConnectEthereum from './connect-ethereum.react.js';
import CoolOrNerdModeSelection from './cool-or-nerd-mode-selection.react.js';
import ExistingEthereumAccount from './existing-ethereum-account.react.js';
import KeyserverSelection from './keyserver-selection.react.js';
import PasswordSelection from './password-selection.react.js';
import UsernameSelection from './username-selection.react.js';
import type { RootNavigationProp } from '../../navigation/root-navigator.react.js';
import {
KeyserverSelectionRouteName,
CoolOrNerdModeSelectionRouteName,
ConnectEthereumRouteName,
ExistingEthereumAccountRouteName,
UsernameSelectionRouteName,
PasswordSelectionRouteName,
+ AvatarSelectionRouteName,
type ScreenParamList,
type RegistrationParamList,
} from '../../navigation/route-names.js';
export type RegistrationNavigationProp<
RouteName: $Keys = $Keys,
> = StackNavigationProp;
const Registration = createStackNavigator<
ScreenParamList,
RegistrationParamList,
StackNavigationHelpers,
>();
const screenOptions = {
headerTransparent: true,
headerBackTitleVisible: false,
headerTitle: '',
headerTintColor: 'white',
headerLeftContainerStyle: {
paddingLeft: 12,
},
};
type Props = {
+navigation: RootNavigationProp<'Registration'>,
...
};
// eslint-disable-next-line no-unused-vars
function RegistrationNavigator(props: Props): React.Node {
return (
+
);
}
export default RegistrationNavigator;
diff --git a/native/navigation/route-names.js b/native/navigation/route-names.js
index 189ad2ab5..7eec308b7 100644
--- a/native/navigation/route-names.js
+++ b/native/navigation/route-names.js
@@ -1,265 +1,268 @@
// @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 { 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 { 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 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,
};
export type InviteLinkParamList = {
+ViewInviteLinks: ViewInviteLinksScreenParams,
+ManagePublicLink: ManagePublicLinkScreenParams,
};
export type CommunityCreationParamList = {
+CommunityConfiguration: void,
+CommunityCreationMembers: void,
};
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,
];