Skip to content

Commit 513fa89

Browse files
committed
RealmInputScreen [nfc]: Convert to a function component
1 parent cbdc035 commit 513fa89

File tree

1 file changed

+59
-67
lines changed

1 file changed

+59
-67
lines changed

src/start/RealmInputScreen.js

Lines changed: 59 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/* @flow strict-local */
2-
import React, { PureComponent } from 'react';
2+
import React, { useCallback } from 'react';
33
import type { Node } from 'react';
44
import { Keyboard } from 'react-native';
55

@@ -13,18 +13,13 @@ import Screen from '../common/Screen';
1313
import ZulipButton from '../common/ZulipButton';
1414
import { tryParseUrl } from '../utils/url';
1515
import * as api from '../api';
16+
import { createStyleSheet } from '../styles';
1617

1718
type Props = $ReadOnly<{|
1819
navigation: AppNavigationProp<'realm-input'>,
1920
route: RouteProp<'realm-input', {| initial: boolean | void |}>,
2021
|}>;
2122

22-
type State = {|
23-
realmInputValue: string,
24-
error: string | null,
25-
progress: boolean,
26-
|};
27-
2823
const urlFromInputValue = (realmInputValue: string): URL | void => {
2924
const withScheme = /^https?:\/\//.test(realmInputValue)
3025
? realmInputValue
@@ -33,88 +28,85 @@ const urlFromInputValue = (realmInputValue: string): URL | void => {
3328
return tryParseUrl(withScheme);
3429
};
3530

36-
export default class RealmInputScreen extends PureComponent<Props, State> {
37-
state: State = {
38-
progress: false,
39-
realmInputValue: '',
40-
error: null,
41-
};
31+
export default function RealmInputScreen(props: Props): Node {
32+
const { navigation, route } = props;
4233

43-
tryRealm: () => Promise<void> = async () => {
44-
const { realmInputValue } = this.state;
34+
const [progress, setProgress] = React.useState(false);
35+
const [realmInputValue, setRealmInputValue] = React.useState('');
36+
const [error, setError] = React.useState(null);
4537

38+
const tryRealm = React.useCallback(async () => {
4639
const parsedRealm = urlFromInputValue(realmInputValue);
4740
if (!parsedRealm) {
48-
this.setState({ error: 'Please enter a valid URL' });
41+
setError('Please enter a valid URL');
4942
return;
5043
}
5144
if (parsedRealm.username !== '') {
52-
this.setState({ error: 'Please enter the server URL, not your email' });
45+
setError('Please enter the server URL, not your email');
5346
return;
5447
}
5548

56-
this.setState({
57-
progress: true,
58-
error: null,
59-
});
49+
setProgress(true);
50+
setError(null);
6051
try {
6152
const serverSettings: ApiResponseServerSettings = await api.getServerSettings(parsedRealm);
62-
this.props.navigation.push('auth', { serverSettings });
53+
navigation.push('auth', { serverSettings });
6354
Keyboard.dismiss();
6455
} catch (errorIllTyped) {
6556
const err: mixed = errorIllTyped; // https://github.com/facebook/flow/issues/2470
66-
this.setState({ error: 'Cannot connect to server' });
57+
setError('Cannot connect to server');
6758
/* eslint-disable no-console */
6859
console.warn('RealmInputScreen: failed to connect to server:', err);
6960
// $FlowFixMe[incompatible-cast]: assuming caught exception was Error
7061
console.warn((err: Error).stack);
7162
} finally {
72-
this.setState({ progress: false });
63+
setProgress(false);
7364
}
74-
};
75-
76-
handleRealmChange: string => void = value => this.setState({ realmInputValue: value });
65+
}, [navigation, realmInputValue]);
7766

78-
render(): Node {
79-
const { navigation } = this.props;
80-
const { progress, error, realmInputValue } = this.state;
67+
const handleRealmChange = useCallback(value => {
68+
setRealmInputValue(value);
69+
}, []);
8170

82-
const styles = {
83-
input: { marginTop: 16, marginBottom: 8 },
84-
hintText: { paddingLeft: 2, fontSize: 12 },
85-
button: { marginTop: 8 },
86-
};
71+
const styles = React.useMemo(
72+
() =>
73+
createStyleSheet({
74+
input: { marginTop: 16, marginBottom: 8 },
75+
hintText: { paddingLeft: 2, fontSize: 12 },
76+
button: { marginTop: 8 },
77+
}),
78+
[],
79+
);
8780

88-
return (
89-
<Screen
90-
title="Welcome"
91-
canGoBack={!this.props.route.params.initial}
92-
padding
93-
centerContent
94-
keyboardShouldPersistTaps="always"
95-
shouldShowLoadingBanner={false}
96-
>
97-
<ZulipTextIntl text="Enter your Zulip server URL:" />
98-
<SmartUrlInput
99-
style={styles.input}
100-
navigation={navigation}
101-
onChangeText={this.handleRealmChange}
102-
onSubmitEditing={this.tryRealm}
103-
enablesReturnKeyAutomatically
104-
/>
105-
{error !== null ? (
106-
<ErrorMsg error={error} />
107-
) : (
108-
<ZulipTextIntl text="e.g. zulip.example.com" style={styles.hintText} />
109-
)}
110-
<ZulipButton
111-
style={styles.button}
112-
text="Enter"
113-
progress={progress}
114-
onPress={this.tryRealm}
115-
disabled={urlFromInputValue(realmInputValue) === undefined}
116-
/>
117-
</Screen>
118-
);
119-
}
81+
return (
82+
<Screen
83+
title="Welcome"
84+
canGoBack={!route.params.initial}
85+
padding
86+
centerContent
87+
keyboardShouldPersistTaps="always"
88+
shouldShowLoadingBanner={false}
89+
>
90+
<ZulipTextIntl text="Enter your Zulip server URL:" />
91+
<SmartUrlInput
92+
style={styles.input}
93+
navigation={navigation}
94+
onChangeText={handleRealmChange}
95+
onSubmitEditing={tryRealm}
96+
enablesReturnKeyAutomatically
97+
/>
98+
{error !== null ? (
99+
<ErrorMsg error={error} />
100+
) : (
101+
<ZulipTextIntl text="e.g. zulip.example.com" style={styles.hintText} />
102+
)}
103+
<ZulipButton
104+
style={styles.button}
105+
text="Enter"
106+
progress={progress}
107+
onPress={tryRealm}
108+
disabled={urlFromInputValue(realmInputValue) === undefined}
109+
/>
110+
</Screen>
111+
);
120112
}

0 commit comments

Comments
 (0)