Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Web browser improvements #7221

Merged
merged 10 commits into from Mar 4, 2020
2 changes: 2 additions & 0 deletions CHANGELOG.md
Expand Up @@ -10,6 +10,8 @@ This is the log of notable changes to the Expo client that are developer-facing.

### 🎉 New features

- Add `readerMode` and `dismissButtonStyle` (iOS) and `enableDefaultShare` (Android) flags for `WebBrowser` ([#7221](https://github.com/expo/expo/pull/7221) by [@LinusU](https://github.com/LinusU)) & [@mczernek](https://github.com/mczernek))

### 🐛 Bug fixes

## 37.0.0
Expand Down
54 changes: 42 additions & 12 deletions apps/native-component-list/src/screens/WebBrowserScreen.tsx
Expand Up @@ -20,6 +20,8 @@ interface State {
lastWarmedPackage?: string;
barCollapsing: boolean;
showInRecents: boolean;
readerMode: boolean;
enableDefaultShare: boolean;
}

export default class WebBrowserScreen extends React.Component<{}, State> {
Expand Down Expand Up @@ -53,6 +55,14 @@ export default class WebBrowserScreen extends React.Component<{}, State> {
this.setState({ barCollapsing });
};

readerModeSwitchChanged = (readerMode: boolean) => {
this.setState({ readerMode });
};

enableDefaultShareChanged = (enableDefaultShare: boolean) => {
this.setState({ enableDefaultShare });
};

showPackagesAlert = async () => {
const result = await WebBrowser.getCustomTabsSupportingBrowsersAsync();
Alert.alert('Result', JSON.stringify(result, null, 2));
Expand All @@ -67,7 +77,7 @@ export default class WebBrowserScreen extends React.Component<{}, State> {
Alert.alert('Result', JSON.stringify(result, null, 2));
};

handleMayInitWithUrlClicke = async () => {
handleMayInitWithUrlClicked = async () => {
const { selectedPackage: lastWarmedPackage } = this.state;
this.setState({
lastWarmedPackage,
Expand All @@ -89,8 +99,10 @@ export default class WebBrowserScreen extends React.Component<{}, State> {
browserPackage: this.state.selectedPackage,
enableBarCollapsing: this.state.barCollapsing,
showInRecents: this.state.showInRecents,
readerMode: this.state.readerMode,
enableDefaultShareMenuItem: this.state.enableDefaultShare,
};
const result = await WebBrowser.openBrowserAsync(url, args);
const result = await WebBrowser.openBrowserAsync('https://expo.io', args);
setTimeout(() => Alert.alert('Result', JSON.stringify(result, null, 2)), 1000);
};

Expand All @@ -109,15 +121,25 @@ export default class WebBrowserScreen extends React.Component<{}, State> {

renderIOSChoices = () =>
Platform.OS === 'ios' && (
<View style={styles.label}>
<Text>Controls color (#rrggbb):</Text>
<TextInput
style={styles.input}
placeholder="RRGGBB"
onChangeText={this.handleControlsColorInputChanged}
value={this.state.controlsColorText}
/>
</View>
<>
<View style={styles.label}>
<Text>Controls color (#rrggbb):</Text>
<TextInput
style={styles.input}
placeholder="RRGGBB"
onChangeText={this.handleControlsColorInputChanged}
value={this.state.controlsColorText}
/>
</View>
<View style={styles.label}>
<Text>Reader mode</Text>
<Switch
style={styles.switch}
onValueChange={this.readerModeSwitchChanged}
value={this.state.readerMode}
/>
</View>
</>
);

renderAndroidChoices = () =>
Expand All @@ -139,6 +161,14 @@ export default class WebBrowserScreen extends React.Component<{}, State> {
value={this.state.showInRecents}
/>
</View>
<View style={styles.label}>
<Text>Default share</Text>
<Switch
style={styles.switch}
onValueChange={this.enableDefaultShareChanged}
value={this.state.enableDefaultShare}
/>
</View>
<View style={styles.label}>
<Text>Force package:</Text>
<Picker
Expand All @@ -160,7 +190,7 @@ export default class WebBrowserScreen extends React.Component<{}, State> {
<Button style={styles.button} onPress={this.handleWarmUpClicked} title="Warm up." />
<Button
style={styles.button}
onPress={this.handleMayInitWithUrlClicke}
onPress={this.handleMayInitWithUrlClicked}
title="May init with url."
/>
<Button style={styles.button} onPress={this.handleCoolDownClicked} title="Cool down." />
Expand Down
11 changes: 7 additions & 4 deletions docs/pages/versions/unversioned/sdk/webbrowser.md
Expand Up @@ -68,12 +68,15 @@ Opens the url with Safari in a modal on iOS using [`SFSafariViewController`](htt
- **browserParams (_object_)** (_optional_) --
A dictionary with following key-value pairs:

- **toolbarColor (_optional_) (_string_)** -- color of the toolbar in either `#AARRGGBB` or `#RRGGBB` format.
- **enableBarCollapsing (_optional_) (_boolean_)** -- a boolean determining whether the toolbar should be hiding when a user scrolls the website
- **showInRecents (_optional_) (_boolean_)** -- (_Android only_) a boolean determining whether browsed website should be shown as separate entry in Android recents/multitasking view. Default: `false`
- **controlsColor (_optional_) (_string_)** -- (_iOS only_) tint color for controls in SKSafariViewController in `#AARRGGBB` or `#RRGGBB` format.
- **showTitle (_optional_) (_boolean_)** -- (_Android only_) a boolean determining whether the browser should show the title of website on the toolbar
- **dismissButtonStyle (_optional_) (_string_)** -- (_iOS only_) The style of the dismiss button. Should be one of: `done`, `close`, or `cancel`.
- **enableBarCollapsing (_optional_) (_boolean_)** -- a boolean determining whether the toolbar should be hiding when a user scrolls the website.
- **enableDefaultShare (_optional_) (_boolean_)** -- (_Android only_) a boolean determining whether a default share item should be added to the menu.
- **package (_optional_) (_string_)** -- (_Android only_). Package name of a browser to be used to handle Custom Tabs. List of available packages is to be queried by [getCustomTabsSupportingBrowsers](#webbrowsergetcustomtabssupportingbrowsers) method.
- **readerMode (_optional_) (_boolean_)** -- (_iOS only_) a boolean determining whether Safari should enter Reader mode, if it is available.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering if we should make it a mode: "default" | "reader"?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like a boolean in here, since it reflects exactly native API.

- **showInRecents (_optional_) (_boolean_)** -- (_Android only_) a boolean determining whether browsed website should be shown as separate entry in Android recents/multitasking view. Default: `false`
- **showTitle (_optional_) (_boolean_)** -- (_Android only_) a boolean determining whether the browser should show the title of website on the toolbar.
- **toolbarColor (_optional_) (_string_)** -- color of the toolbar in either `#AARRGGBB` or `#RRGGBB` format.

Note that behavior customization options depend on the actual browser and its version. Some or all of the arguments may be ignored.

Expand Down
Expand Up @@ -31,10 +31,10 @@ public class WebBrowserModule extends ExportedModule {
private final static String SERVICE_PACKAGES_KEY = "servicePackages";
private final static String PREFERRED_BROWSER_PACKAGE = "preferredBrowserPackage";
private final static String DEFAULT_BROWSER_PACKAGE = "defaultBrowserPackage";

private final static String SHOW_IN_RECENTS = "showInRecents";

private final static String DEFAULT_SHARE_MENU_ITEM = "enableDefaultShareMenuItem";
private final static String TOOLBAR_COLOR_KEY = "toolbarColor";

private final static String ERROR_CODE = "EXWebBrowser";
private static final String TAG = "ExpoWebBrowser";
private static final String SHOW_TITLE_KEY = "showTitle";
Expand Down Expand Up @@ -163,6 +163,10 @@ private Intent createCustomTabsIntent(ReadableArguments arguments) {

builder.setShowTitle(arguments.getBoolean(SHOW_TITLE_KEY, false));

if (arguments.containsKey(DEFAULT_SHARE_MENU_ITEM) && arguments.getBoolean(DEFAULT_SHARE_MENU_ITEM)) {
builder.addDefaultShareMenuItem();
}

Intent intent = builder.build().intent;

// We cannot use builder's method enableUrlBarHiding, because there is no corresponding disable method and some browsers enables it by default.
Expand Down
3 changes: 3 additions & 0 deletions packages/expo-web-browser/build/WebBrowser.types.d.ts

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion packages/expo-web-browser/build/WebBrowser.types.js.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

20 changes: 18 additions & 2 deletions packages/expo-web-browser/ios/EXWebBrowser/EXWebBrowser.m
Expand Up @@ -89,13 +89,29 @@ - (dispatch_queue_t)methodQueue
}

NSURL *url = [[NSURL alloc] initWithString:authURL];
BOOL readerMode = [arguments[@"readerMode"] boolValue];
BOOL enableBarCollapsing = [arguments[@"enableBarCollapsing"] boolValue];
SFSafariViewController *safariVC = nil;
if (@available(iOS 11, *)) {
SFSafariViewControllerConfiguration *config = [[SFSafariViewControllerConfiguration alloc] init];
config.barCollapsingEnabled = [arguments[@"enableBarCollapsing"] boolValue];
config.barCollapsingEnabled = enableBarCollapsing;
config.entersReaderIfAvailable = readerMode;
safariVC = [[SFSafariViewController alloc] initWithURL:url configuration:config];
} else {
safariVC = [[SFSafariViewController alloc] initWithURL:url];
safariVC = [[SFSafariViewController alloc] initWithURL:url entersReaderIfAvailable:readerMode];
}

if (@available(iOS 11.0, *)) {
NSString *dismissButtonStyle = [arguments valueForKey:@"dismissButtonStyle"];
if ([@"done" isEqualToString:dismissButtonStyle]) {
safariVC.dismissButtonStyle = SFSafariViewControllerDismissButtonStyleDone;
}
else if ([@"close" isEqualToString:dismissButtonStyle]) {
safariVC.dismissButtonStyle = SFSafariViewControllerDismissButtonStyleClose;
}
else if ([@"cancel" isEqualToString:dismissButtonStyle]) {
safariVC.dismissButtonStyle = SFSafariViewControllerDismissButtonStyleCancel;
}
}

if([[arguments allKeys] containsObject:WebBrowserToolbarColorKey]) {
Expand Down
3 changes: 3 additions & 0 deletions packages/expo-web-browser/src/WebBrowser.types.ts
Expand Up @@ -9,10 +9,13 @@ export type WebBrowserOpenOptions = {
showTitle?: boolean;

/** Android only */
enableDefaultShareMenuItem?: boolean;
showInRecents?: boolean;

/** iOS only */
controlsColor?: string;
dismissButtonStyle?: 'done' | 'close' | 'cancel';
readerMode?: boolean;

// Web
windowName?: string;
Expand Down