diff --git a/native/account/logged-out-modal.react.js b/native/account/logged-out-modal.react.js --- a/native/account/logged-out-modal.react.js +++ b/native/account/logged-out-modal.react.js @@ -49,6 +49,7 @@ type NavigationRoute, LoggedOutModalRouteName, RegistrationRouteName, + QRCodeSignInNavigatorRouteName, } from '../navigation/route-names.js'; import { useSelector } from '../redux/redux-utils.js'; import { usePersistedStateLoaded } from '../selectors/app-state-selectors.js'; @@ -572,7 +573,7 @@ if (__DEV__) { signInButtons.push( <TouchableOpacity - onPress={null} + onPress={this.onPressQRCodeSignIn} style={[styles.button, styles.classicAuthButton]} activeOpacity={0.6} key="qr-code-login" @@ -672,6 +673,10 @@ this.setMode('log-in'); }; + onPressQRCodeSignIn = () => { + this.props.navigation.navigate(QRCodeSignInNavigatorRouteName); + }; + onPressRegister = () => { this.keyboardHeightValue.setValue(-1); this.setMode('register'); diff --git a/native/navigation/root-navigator.react.js b/native/navigation/root-navigator.react.js --- a/native/navigation/root-navigator.react.js +++ b/native/navigation/root-navigator.react.js @@ -44,6 +44,7 @@ InviteLinkNavigatorRouteName, CommunityCreationRouteName, RolesNavigatorRouteName, + QRCodeSignInNavigatorRouteName, } from './route-names.js'; import LoggedOutModal from '../account/logged-out-modal.react.js'; import RegistrationNavigator from '../account/registration/registration-navigator.react.js'; @@ -59,6 +60,7 @@ import CommunityCreationNavigator from '../community-creation/community-creation-navigator.react.js'; import InviteLinksNavigator from '../invite-links/invite-links-navigator.react.js'; import CustomServerModal from '../profile/custom-server-modal.react.js'; +import QRCodeSignInNavigator from '../qr-code/qr-code-sign-in-navigator.react.js'; import RolesNavigator from '../roles/roles-navigator.react.js'; enableScreens(); @@ -205,6 +207,11 @@ component={RegistrationNavigator} options={disableGesturesScreenOptions} /> + <Root.Screen + name={QRCodeSignInNavigatorRouteName} + component={QRCodeSignInNavigator} + options={disableGesturesScreenOptions} + /> <Root.Screen name={CommunityCreationRouteName} component={CommunityCreationNavigator} diff --git a/native/navigation/route-names.js b/native/navigation/route-names.js --- a/native/navigation/route-names.js +++ b/native/navigation/route-names.js @@ -130,6 +130,8 @@ export const RolesNavigatorRouteName = 'RolesNavigator'; export const CommunityRolesScreenRouteName = 'CommunityRolesScreen'; export const CreateRolesScreenRouteName = 'CreateRolesScreen'; +export const QRCodeSignInNavigatorRouteName = 'QRCodeSignInNavigator'; +export const QRCodeScreenRouteName = 'QRCodeScreen'; export type RootParamList = { +LoggedOutModal: void, @@ -149,6 +151,7 @@ +InviteLinkModal: InviteLinkModalParams, +InviteLinkNavigator: void, +RolesNavigator: void, + +QRCodeSignInNavigator: void, }; export type MessageTooltipRouteNames = @@ -252,6 +255,10 @@ +CreateRolesScreen: CreateRolesScreenParams, }; +export type QRCodeSignInParamList = { + +QRCodeScreen: void, +}; + export type ScreenParamList = { ...RootParamList, ...OverlayParamList, @@ -264,12 +271,17 @@ ...InviteLinkParamList, ...CommunityCreationParamList, ...RolesParamList, + ...QRCodeSignInParamList, }; export type NavigationRoute<RouteName: string = $Keys<ScreenParamList>> = RouteProp<ScreenParamList, RouteName>; -export const accountModals = [LoggedOutModalRouteName, RegistrationRouteName]; +export const accountModals = [ + LoggedOutModalRouteName, + RegistrationRouteName, + QRCodeSignInNavigatorRouteName, +]; export const scrollBlockingModals = [ ImageModalRouteName, diff --git a/native/qr-code/qr-code-screen.react.js b/native/qr-code/qr-code-screen.react.js new file mode 100644 --- /dev/null +++ b/native/qr-code/qr-code-screen.react.js @@ -0,0 +1,86 @@ +// @flow + +import * as React from 'react'; +import { View, Text } from 'react-native'; +import QRCode from 'react-native-qrcode-svg'; + +import type { QRCodeSignInNavigationProp } from './qr-code-sign-in-navigator.react.js'; +import type { NavigationRoute } from '../navigation/route-names.js'; +import { useStyles } from '../themes/colors.js'; + +type QRCodeScreenProps = { + +navigation: QRCodeSignInNavigationProp<'QRCodeScreen'>, + +route: NavigationRoute<'QRCodeScreen'>, +}; + +// eslint-disable-next-line no-unused-vars +function QRCodeScreen(props: QRCodeScreenProps): React.Node { + const styles = useStyles(unboundStyles); + return ( + <View style={styles.container}> + <Text style={styles.heading}>Log in to Comm</Text> + <Text style={styles.headingSubtext}> + Open the Comm app on your phone and scan the QR code below + </Text> + <QRCode value="https://www.google.com" size={200} /> + <View style={styles.instructionsBox}> + <Text style={styles.instructionsTitle}>How to find the scanner:</Text> + <Text style={styles.instructionsStep}> + <Text>Go to </Text> + <Text style={styles.instructionsBold}>Profile</Text> + </Text> + <Text style={styles.instructionsStep}> + <Text>Select </Text> + <Text style={styles.instructionsBold}>Linked devices </Text> + </Text> + <Text style={styles.instructionsStep}> + <Text>Click </Text> + <Text style={styles.instructionsBold}>Add </Text> + <Text>on the top right</Text> + </Text> + </View> + </View> + ); +} + +const unboundStyles = { + container: { + flex: 1, + alignItems: 'center', + marginTop: 125, + }, + heading: { + fontSize: 24, + color: 'panelForegroundLabel', + paddingBottom: 12, + }, + headingSubtext: { + fontSize: 12, + color: 'panelForegroundLabel', + paddingBottom: 30, + }, + instructionsBox: { + alignItems: 'center', + width: 300, + marginTop: 40, + padding: 15, + borderColor: 'panelForegroundLabel', + borderWidth: 2, + borderRadius: 8, + }, + instructionsTitle: { + fontSize: 12, + color: 'panelForegroundLabel', + paddingBottom: 15, + }, + instructionsStep: { + fontSize: 12, + padding: 1, + color: 'panelForegroundLabel', + }, + instructionsBold: { + fontWeight: 'bold', + }, +}; + +export default QRCodeScreen; diff --git a/native/qr-code/qr-code-sign-in-navigator.react.js b/native/qr-code/qr-code-sign-in-navigator.react.js new file mode 100644 --- /dev/null +++ b/native/qr-code/qr-code-sign-in-navigator.react.js @@ -0,0 +1,77 @@ +// @flow + +import { + createStackNavigator, + type StackNavigationProp, + type StackNavigationHelpers, +} from '@react-navigation/stack'; +import * as React from 'react'; +import { SafeAreaView } from 'react-native-safe-area-context'; + +import QRCodeScreen from './qr-code-screen.react.js'; +import type { RootNavigationProp } from '../navigation/root-navigator.react.js'; +import { + type ScreenParamList, + type QRCodeSignInParamList, + QRCodeScreenRouteName, +} from '../navigation/route-names.js'; +import { useStyles, useColors } from '../themes/colors.js'; + +const safeAreaEdges = ['bottom']; + +export type QRCodeSignInNavigationProp< + RouteName: $Keys<QRCodeSignInParamList>, +> = StackNavigationProp<ScreenParamList, RouteName>; + +const QRCodeSignInStack = createStackNavigator< + ScreenParamList, + QRCodeSignInParamList, + StackNavigationHelpers<ScreenParamList>, +>(); + +type QRCodeSignInNavigatorProps = { + +navigation: RootNavigationProp<'QRCodeSignInNavigator'>, + ... +}; + +// eslint-disable-next-line no-unused-vars +function QRCodeSignInNavigator(props: QRCodeSignInNavigatorProps): React.Node { + const styles = useStyles(unboundStyles); + const colors = useColors(); + + const screenOptions = React.useMemo( + () => ({ + headerTransparent: true, + headerBackTitleVisible: false, + headerTitle: '', + headerTintColor: colors.panelForegroundLabel, + headerLeftContainerStyle: { + paddingLeft: 12, + }, + }), + [colors.panelForegroundLabel], + ); + + return ( + <SafeAreaView style={styles.safeArea} edges={safeAreaEdges}> + <QRCodeSignInStack.Navigator screenOptions={screenOptions}> + <QRCodeSignInStack.Screen + name={QRCodeScreenRouteName} + component={QRCodeScreen} + /> + </QRCodeSignInStack.Navigator> + </SafeAreaView> + ); +} + +const unboundStyles = { + safeArea: { + flex: 1, + backgroundColor: 'modalBackground', + }, + headerLeftStyle: { + paddingLeft: 12, + }, +}; + +export default QRCodeSignInNavigator;