Skip to content

Commit 4b1099e

Browse files
chrisbobbegnprice
authored andcommitted
NavRow: Show external-link icon when the action is to open a URL
And rename it from NestedNavRow, making the "nested" mode the default, but allowing callers to specify "external".
1 parent 2ae6f79 commit 4b1099e

File tree

10 files changed

+47
-31
lines changed

10 files changed

+47
-31
lines changed

src/account-info/ProfileScreen.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ import { getUserStatus } from '../user-statuses/userStatusesModel';
2424
import SwitchRow from '../common/SwitchRow';
2525
import * as api from '../api';
2626
import { identityOfAccount } from '../account/accountMisc';
27-
import NestedNavRow from '../common/NestedNavRow';
27+
import NavRow from '../common/NavRow';
2828
import { emojiTypeFromReactionType } from '../emoji/data';
2929

3030
const styles = createStyleSheet({
@@ -135,7 +135,7 @@ export default function ProfileScreen(props: Props): Node {
135135
<OfflineNoticePlaceholder />
136136
<ScrollView>
137137
<AccountDetails user={ownUser} showEmail={false} showStatus={false} />
138-
<NestedNavRow
138+
<NavRow
139139
leftElement={
140140
status_emoji != null
141141
? {

src/common/InputRowRadioButtons.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -77,10 +77,10 @@ type Props<TItemKey> = $ReadOnly<{|
7777
* `.title`. When tapped, opens the selectable-options screen, where the
7878
* user can change the selection or read more about each selection.
7979
*/
80-
// This has the navigate-to-nested-screen semantics of NestedNavRow,
81-
// represented by IconRight. NestedNavRow would probably be the wrong
82-
// abstraction, though, because it isn't an imput component; it doesn't have
83-
// a value to display.
80+
// This has the navigate-to-nested-screen semantics of
81+
// <NavRow type="nested" … />, represented by IconRight. NavRow would
82+
// probably be the wrong abstraction, though, because it isn't an input
83+
// component; it doesn't have a value to display.
8484
export default function InputRowRadioButtons<TItemKey: string | number>(
8585
props: Props<TItemKey>,
8686
): Node {

src/common/NestedNavRow.js renamed to src/common/NavRow.js

Lines changed: 23 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { View } from 'react-native';
66
import type { EmojiType, LocalizableReactText } from '../types';
77
import ZulipTextIntl from './ZulipTextIntl';
88
import Touchable from './Touchable';
9-
import { IconRight } from './Icons';
9+
import { Icon, IconRight } from './Icons';
1010
import type { SpecificIconType } from './Icons';
1111
import globalStyles, { ThemeContext, createStyleSheet } from '../styles';
1212
import Emoji from '../emoji/Emoji';
@@ -33,18 +33,28 @@ type Props = $ReadOnly<{|
3333
// components, with and without this?
3434
titleBoldUppercase?: true,
3535

36-
/** Use this to navigate to a "nested" screen. */
36+
type?: 'nested' | 'external',
37+
38+
/**
39+
* Press handler for the whole row.
40+
*
41+
* The behavior should correspond to `type`:
42+
* 'nested': navigate to a "nested" screen.
43+
* 'external': open a URL with the user's `BrowserPreference`
44+
*/
3745
onPress: () => void,
3846
|}>;
3947

4048
/**
41-
* A button that navigates to a "nested" screen.
49+
* When tapped, this row navigates to a "nested" screen or opens a URL.
50+
*
51+
* 'nested' type: shows a right-facing arrow.
52+
* 'external' type: shows an "external link" icon.
4253
*
43-
* Shows a right-facing arrow to indicate its purpose. If you need a
44-
* selectable option row instead, use `SelectableOptionRow`.
54+
* If you need a selectable option row instead, use `SelectableOptionRow`.
4555
*/
46-
export default function NestedNavRow(props: Props): Node {
47-
const { title, subtitle, titleBoldUppercase, onPress, leftElement } = props;
56+
export default function NavRow(props: Props): Node {
57+
const { title, subtitle, titleBoldUppercase, type = 'nested', onPress, leftElement } = props;
4858

4959
const themeContext = useContext(ThemeContext);
5060

@@ -77,7 +87,7 @@ export default function NestedNavRow(props: Props): Node {
7787
fontWeight: '300',
7888
fontSize: 13,
7989
},
80-
iconRightFacingArrow: {
90+
iconRight: {
8191
textAlign: 'center',
8292
marginLeft: 8,
8393
color: themeContext.color,
@@ -117,7 +127,11 @@ export default function NestedNavRow(props: Props): Node {
117127
{subtitle !== undefined && <ZulipTextIntl style={styles.subtitle} text={subtitle} />}
118128
</View>
119129
<View style={globalStyles.rightItem}>
120-
<IconRight size={24} style={styles.iconRightFacingArrow} />
130+
{type === 'nested' ? (
131+
<IconRight size={24} style={styles.iconRight} />
132+
) : (
133+
<Icon name="external-link" size={24} style={styles.iconRight} />
134+
)}
121135
</View>
122136
</View>
123137
</Touchable>

src/common/SwitchRow.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ const componentStyles = createStyleSheet({
2323
paddingHorizontal: 16,
2424

2525
// For uniformity with other rows this might share a screen with, e.g.,
26-
// NestedNavRow and InputRowRadioButtons on the settings screen. See
26+
// NavRow and InputRowRadioButtons on the settings screen. See
2727
// height-related attributes on those rows.
2828
minHeight: 48,
2929
},

src/common/TextRow.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ type Props = $ReadOnly<{|
2424
/**
2525
* A row with a title, and optional icon, subtitle, and press handler.
2626
*
27-
* See also NestedNavRow, SwitchRow, etc.
27+
* See also NavRow, SwitchRow, etc.
2828
*/
2929
export default function TextRow(props: Props): React.Node {
3030
const { title, subtitle, onPress, icon } = props;

src/settings/LegalScreen.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import type { RouteProp } from '../react-navigation';
77
import type { AppNavigationProp } from '../nav/AppNavigator';
88
import { useGlobalSelector, useSelector } from '../react-redux';
99
import Screen from '../common/Screen';
10-
import NestedNavRow from '../common/NestedNavRow';
10+
import NavRow from '../common/NavRow';
1111
import ZulipText from '../common/ZulipText';
1212
import { openLinkWithUserPreference } from '../utils/openLink';
1313
import { getRealmUrl, getRealmName, getGlobalSettings } from '../selectors';
@@ -34,8 +34,8 @@ export default function LegalScreen(props: Props): Node {
3434

3535
return (
3636
<Screen title="Legal">
37-
<NestedNavRow title="Zulip terms" onPress={openZulipPolicies} />
38-
<NestedNavRow
37+
<NavRow title="Zulip terms" onPress={openZulipPolicies} type="external" />
38+
<NavRow
3939
// These are really terms set by the server admin responsible for
4040
// hosting the org, and that server admin may or may not represent
4141
// the org itself, as this text might be read to imply. (E.g.,
@@ -51,6 +51,7 @@ export default function LegalScreen(props: Props): Node {
5151
values: { realmName: <ZulipText style={{ fontWeight: 'bold' }} text={realmName} /> },
5252
}}
5353
onPress={openRealmPolicies}
54+
type="external"
5455
/>
5556
</Screen>
5657
);

src/settings/NotificationsScreen.js

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ import SwitchRow from '../common/SwitchRow';
1313
import Screen from '../common/Screen';
1414
import * as api from '../api';
1515
import ServerPushSetupBanner from '../common/ServerPushSetupBanner';
16-
import NestedNavRow from '../common/NestedNavRow';
16+
import NavRow from '../common/NavRow';
1717
import { IconAlertTriangle } from '../common/Icons';
1818
import type { LocalizableText } from '../types';
1919
import { TranslationContext } from '../boot/TranslationProvider';
@@ -139,7 +139,7 @@ export default function NotificationsScreen(props: Props): Node {
139139
return (
140140
<Screen title="Notifications">
141141
<ServerPushSetupBanner isDismissable={false} />
142-
<NestedNavRow
142+
<NavRow
143143
leftElement={
144144
systemSettingsWarnings.length > 0
145145
? {
@@ -161,6 +161,7 @@ export default function NotificationsScreen(props: Props): Node {
161161
}
162162
})()}
163163
onPress={handleSystemSettingsPress}
164+
type="external"
164165
/>
165166
{!notificationReport.problems.includes(NotificationProblem.SystemSettingsDisabled) && (
166167
<>
@@ -189,7 +190,7 @@ export default function NotificationsScreen(props: Props): Node {
189190
value={streamNotification}
190191
onValueChange={handleStreamNotificationChange}
191192
/>
192-
<NestedNavRow
193+
<NavRow
193194
{...(() =>
194195
notificationReport.problems.length > 0 && {
195196
leftElement: {
@@ -205,7 +206,7 @@ export default function NotificationsScreen(props: Props): Node {
205206
</SettingsGroup>
206207
)}
207208
{otherAccounts.length > 0 && (
208-
<NestedNavRow
209+
<NavRow
209210
{...(() => {
210211
const problemAccountsCount = otherAccounts.filter(a => {
211212
// eslint-disable-next-line no-underscore-dangle

src/settings/SettingsGroup.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import * as React from 'react';
44
import { View } from 'react-native';
55

66
import SwitchRow from '../common/SwitchRow';
7-
import NestedNavRow from '../common/NestedNavRow';
7+
import NavRow from '../common/NavRow';
88
import type { LocalizableReactText } from '../types';
99
import { createStyleSheet } from '../styles';
1010
import { QUARTER_COLOR } from '../styles/constants';
@@ -18,7 +18,7 @@ type Props = $ReadOnly<{|
1818
// layout in some subtle way.
1919
title: LocalizableReactText,
2020

21-
children: $ReadOnlyArray<React$Element<typeof SwitchRow> | React$Element<typeof NestedNavRow>>,
21+
children: $ReadOnlyArray<React$Element<typeof SwitchRow> | React$Element<typeof NavRow>>,
2222
|}>;
2323

2424
export default function SettingsGroup(props: Props): React.Node {

src/settings/SettingsScreen.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ import type { RouteProp } from '../react-navigation';
99
import type { AppNavigationProp } from '../nav/AppNavigator';
1010
import { useSelector, useGlobalSelector, useDispatch } from '../react-redux';
1111
import { getGlobalSettings } from '../selectors';
12-
import NestedNavRow from '../common/NestedNavRow';
12+
import NavRow from '../common/NavRow';
1313
import InputRowRadioButtons from '../common/InputRowRadioButtons';
1414
import SwitchRow from '../common/SwitchRow';
1515
import Screen from '../common/Screen';
@@ -89,7 +89,7 @@ export default function SettingsScreen(props: Props): Node {
8989
dispatch(setGlobalSettings({ markMessagesReadOnScroll: value }));
9090
}}
9191
/>
92-
<NestedNavRow
92+
<NavRow
9393
leftElement={{ type: 'icon', Component: IconNotifications }}
9494
title="Notifications"
9595
{...(() =>
@@ -116,7 +116,7 @@ export default function SettingsScreen(props: Props): Node {
116116
}}
117117
search
118118
/>
119-
<NestedNavRow
119+
<NavRow
120120
leftElement={{ type: 'icon', Component: IconMoreHorizontal }}
121121
title="Legal"
122122
onPress={() => {

src/streams/SubscriptionsScreen.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ import { doNarrow } from '../actions';
2020
import { caseInsensitiveCompareFunc } from '../utils/misc';
2121
import StreamItem from './StreamItem';
2222
import ModalNavBar from '../nav/ModalNavBar';
23-
import NestedNavRow from '../common/NestedNavRow';
23+
import NavRow from '../common/NavRow';
2424

2525
const styles = createStyleSheet({
2626
container: {
@@ -46,7 +46,7 @@ function AllStreamsButton(props: FooterProps): Node {
4646
navigation.push('all-streams');
4747
}, [navigation]);
4848

49-
return <NestedNavRow title="All streams" titleBoldUppercase onPress={handlePressAllScreens} />;
49+
return <NavRow title="All streams" titleBoldUppercase onPress={handlePressAllScreens} />;
5050
}
5151

5252
export default function SubscriptionsScreen(props: Props): Node {

0 commit comments

Comments
 (0)