Skip to content
This repository has been archived by the owner on Feb 22, 2023. It is now read-only.

[url_launcher] Update README to use code excerpts. #6042

Merged
merged 10 commits into from
Jul 13, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions packages/url_launcher/url_launcher/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
## 6.1.5

* Migrates `README.md` examples to the [`code-excerpt` system](https://github.com/flutter/flutter/wiki/Contributing-to-Plugins-and-Packages#readme-code).

## 6.1.4

* Adopts new platform interface method for launching URLs.
Expand Down
60 changes: 43 additions & 17 deletions packages/url_launcher/url_launcher/README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
<?code-excerpt path-base="excerpts/packages/url_launcher_example"?>

# url_launcher

[![pub package](https://img.shields.io/pub/v/url_launcher.svg)](https://pub.dev/packages/url_launcher)
Expand All @@ -14,6 +16,7 @@ To use this plugin, add `url_launcher` as a [dependency in your pubspec.yaml fil

### Example

<?code-excerpt "basic.dart (basic-example)"?>
``` dart
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';
Expand All @@ -24,7 +27,7 @@ void main() => runApp(
const MaterialApp(
home: Material(
child: Center(
child: RaisedButton(
child: ElevatedButton(
onPressed: _launchUrl,
child: Text('Show Flutter homepage'),
),
Expand All @@ -33,8 +36,10 @@ void main() => runApp(
),
);

void _launchUrl() async {
if (!await launchUrl(_url)) throw 'Could not launch $_url';
Future<void> _launchUrl() async {
if (!await launchUrl(_url)) {
throw 'Could not launch $_url';
}
}
```

Expand Down Expand Up @@ -65,7 +70,10 @@ on Android 11 (API 30) or higher. A `<queries>`
element must be added to your manifest as a child of the root element.

Example:

<?code-excerpt "../../android/app/src/main/AndroidManifest.xml (android-queries)" plaster="none"?>
``` xml
<!-- Provide required visibility configuration for API level 30 and above -->
<queries>
<!-- If your app checks for SMS support -->
<intent>
Expand Down Expand Up @@ -133,22 +141,37 @@ due to [a bug](https://github.com/dart-lang/sdk/issues/43838) in the way `Uri`
encodes query parameters. Using `queryParameters` will result in spaces being
converted to `+` in many cases.

<?code-excerpt "encoding.dart (encode-query-parameters)"?>
```dart
String? encodeQueryParameters(Map<String, String> params) {
return params.entries
.map((e) => '${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
.map((MapEntry<String, String> e) =>
'${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
.join('&');
}
// ···
final Uri emailLaunchUri = Uri(
scheme: 'mailto',
path: '[email protected]',
query: encodeQueryParameters(<String, String>{
'subject': 'Example Subject & Symbols are allowed!',
}),
);

launchUrl(emailLaunchUri);
```

final Uri emailLaunchUri = Uri(
scheme: 'mailto',
path: '[email protected]',
query: encodeQueryParameters(<String, String>{
'subject': 'Example Subject & Symbols are allowed!'
}),
);
Encoding for `sms` is slightly different:

launchUrl(emailLaunchUri);
<?code-excerpt "encoding.dart (sms)"?>
```dart
final Uri smsLaunchUri = Uri(
scheme: 'sms',
path: '0118 999 881 999 119 7253',
Copy link
Contributor

Choose a reason for hiding this comment

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

🤣

I was about to ask why this wasn't using some obviously fake number (like 123456789) when I realized what it was 🙂

Copy link
Member

Choose a reason for hiding this comment

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

I tried to find a cool "555" number, but ended up going for the easy to remember 0118 999 881 999 119 725... 3

(Turns out I'm almost 7 years late, yikes!)

queryParameters: <String, String>{
'body': Uri.encodeComponent('Example Subject & Symbols are allowed!'),
},
);
```

### URLs not handled by `Uri`
Expand All @@ -168,14 +191,17 @@ original APIs.
We recommend checking first whether the directory or file exists before calling `launchUrl`.

Example:

<?code-excerpt "files.dart (file)"?>
```dart
var filePath = '/path/to/file';
final String filePath = testFile.absolute.path;
final Uri uri = Uri.file(filePath);

if (await File(uri.toFilePath()).exists()) {
if (!await launchUrl(uri)) {
throw 'Could not launch $uri';
}
if (!File(uri.toFilePath()).existsSync()) {
throw '$uri does not exist!';
}
if (!await launchUrl(uri)) {
throw 'Could not launch $uri';
}
```

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,29 @@
-->
<uses-permission android:name="android.permission.INTERNET"/>

<!--#docregion android-queries-->
<!-- Provide required visibility configuration for API level 30 and above -->
<queries>
<!-- If your app checks for SMS support -->
<intent>
Copy link
Contributor

Choose a reason for hiding this comment

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

It's probably worth adding a comment saying this is only here for integration tests, and shouldn't be needed in most actual apps, so it doesn't confuse anyone else in the future.

Copy link
Member

Choose a reason for hiding this comment

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

Agreed; I've added a comment to the https scheme bit of the XML, in addition to excluding it from the relevant docregion.

<action android:name="android.intent.action.VIEW" />
<data android:scheme="https" />
<data android:scheme="sms" />
</intent>
<!-- If your app checks for call support -->
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="tel" />
</intent>
<!--#enddocregion android-queries-->
<!-- The "https" scheme is only required for integration tests of this package.
It shouldn't be needed in most actual apps, or show up in the README! -->
<intent>
<action android:name="android.intent.action.VIEW" />
<data android:scheme="sms" />
<data android:scheme="https" />
</intent>
<!--#docregion android-queries-->
</queries>
<!--#enddocregion android-queries-->

<application
android:icon="@mipmap/ic_launcher"
Expand Down
20 changes: 20 additions & 0 deletions packages/url_launcher/url_launcher/example/build.excerpt.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
targets:
$default:
sources:
include:
- lib/**
- android/app/src/main/**
# Some default includes that aren't really used here but will prevent
# false-negative warnings:
- $package$
- lib/$lib$
exclude:
- '**/.*/**'
- '**/build/**'
- 'android/app/src/main/res/**'
builders:
code_excerpter|code_excerpter:
enabled: true
generate_for:
- '**/*.dart'
- android/**/*.xml
34 changes: 34 additions & 0 deletions packages/url_launcher/url_launcher/example/lib/basic.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Run this example with: flutter run -t lib/basic.dart -d emulator

// This file is used to extract code samples for the README.md file.
// Run update-excerpts if you modify this file.

// #docregion basic-example
import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';

final Uri _url = Uri.parse('https://flutter.dev');

void main() => runApp(
const MaterialApp(
home: Material(
child: Center(
child: ElevatedButton(
onPressed: _launchUrl,
child: Text('Show Flutter homepage'),
),
),
),
),
);

Future<void> _launchUrl() async {
if (!await launchUrl(_url)) {
throw 'Could not launch $_url';
}
}
// #enddocregion basic-example
70 changes: 70 additions & 0 deletions packages/url_launcher/url_launcher/example/lib/encoding.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Run this example with: flutter run -t lib/encoding.dart -d emulator

// This file is used to extract code samples for the README.md file.
// Run update-excerpts if you modify this file.

import 'package:flutter/material.dart';
import 'package:url_launcher/url_launcher.dart';

/// Encode [params] so it produces a correct query string.
/// Workaround for: https://github.com/dart-lang/sdk/issues/43838
// #docregion encode-query-parameters
String? encodeQueryParameters(Map<String, String> params) {
return params.entries
.map((MapEntry<String, String> e) =>
'${Uri.encodeComponent(e.key)}=${Uri.encodeComponent(e.value)}')
.join('&');
}
// #enddocregion encode-query-parameters

void main() => runApp(
MaterialApp(
home: Material(
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: const <Widget>[
ElevatedButton(
onPressed: _composeMail,
child: Text('Compose an email'),
),
ElevatedButton(
onPressed: _composeSms,
child: Text('Compose a SMS'),
),
],
),
),
),
);

void _composeMail() {
// #docregion encode-query-parameters
final Uri emailLaunchUri = Uri(
scheme: 'mailto',
path: '[email protected]',
query: encodeQueryParameters(<String, String>{
'subject': 'Example Subject & Symbols are allowed!',
}),
);

launchUrl(emailLaunchUri);
// #enddocregion encode-query-parameters
}

void _composeSms() {
// #docregion sms
final Uri smsLaunchUri = Uri(
scheme: 'sms',
path: '0118 999 881 999 119 7253',
queryParameters: <String, String>{
'body': Uri.encodeComponent('Example Subject & Symbols are allowed!'),
},
);
// #enddocregion sms

launchUrl(smsLaunchUri);
}
47 changes: 47 additions & 0 deletions packages/url_launcher/url_launcher/example/lib/files.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

// Run this example with: flutter run -t lib/files.dart -d linux

// This file is used to extract code samples for the README.md file.
// Run update-excerpts if you modify this file.
import 'dart:io';

import 'package:flutter/material.dart';
import 'package:path/path.dart' as p;
import 'package:url_launcher/url_launcher.dart';

void main() => runApp(
const MaterialApp(
home: Material(
child: Center(
child: ElevatedButton(
onPressed: _openFile,
child: Text('Open File'),
),
),
),
),
);

Future<void> _openFile() async {
// Prepare a file within tmp
final String tempFilePath = p.joinAll(<String>[
...p.split(Directory.systemTemp.path),
'flutter_url_launcher_example.txt'
]);
final File testFile = File(tempFilePath);
await testFile.writeAsString('Hello, world!');
// #docregion file
final String filePath = testFile.absolute.path;
final Uri uri = Uri.file(filePath);

if (!File(uri.toFilePath()).existsSync()) {
throw '$uri does not exist!';
}
if (!await launchUrl(uri)) {
throw 'Could not launch $uri';
}
// #enddocregion file
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ list(APPEND FLUTTER_PLUGIN_LIST
url_launcher_linux
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
)

set(PLUGIN_BUNDLED_LIBRARIES)

foreach(plugin ${FLUTTER_PLUGIN_LIST})
Expand All @@ -14,3 +17,8 @@ foreach(plugin ${FLUTTER_PLUGIN_LIST})
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
endforeach(plugin)

foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/linux plugins/${ffi_plugin})
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
endforeach(ffi_plugin)
2 changes: 2 additions & 0 deletions packages/url_launcher/url_launcher/example/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ environment:
dependencies:
flutter:
sdk: flutter
path: ^1.8.0
url_launcher:
# When depending on this package from a real application you should use:
# url_launcher: ^x.y.z
Expand All @@ -18,6 +19,7 @@ dependencies:
path: ../

dev_dependencies:
build_runner: ^2.1.10
flutter_driver:
sdk: flutter
integration_test:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@ list(APPEND FLUTTER_PLUGIN_LIST
url_launcher_windows
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
)

set(PLUGIN_BUNDLED_LIBRARIES)

foreach(plugin ${FLUTTER_PLUGIN_LIST})
Expand All @@ -14,3 +17,8 @@ foreach(plugin ${FLUTTER_PLUGIN_LIST})
list(APPEND PLUGIN_BUNDLED_LIBRARIES $<TARGET_FILE:${plugin}_plugin>)
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${plugin}_bundled_libraries})
endforeach(plugin)

foreach(ffi_plugin ${FLUTTER_FFI_PLUGIN_LIST})
add_subdirectory(flutter/ephemeral/.plugin_symlinks/${ffi_plugin}/windows plugins/${ffi_plugin})
list(APPEND PLUGIN_BUNDLED_LIBRARIES ${${ffi_plugin}_bundled_libraries})
endforeach(ffi_plugin)
2 changes: 1 addition & 1 deletion packages/url_launcher/url_launcher/pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ description: Flutter plugin for launching a URL. Supports
web, phone, SMS, and email schemes.
repository: https://github.com/flutter/plugins/tree/main/packages/url_launcher/url_launcher
issue_tracker: https://github.com/flutter/flutter/issues?q=is%3Aissue+is%3Aopen+label%3A%22p%3A+url_launcher%22
version: 6.1.4
version: 6.1.5

environment:
sdk: ">=2.14.0 <3.0.0"
Expand Down
Loading