diff --git a/packages/connectivity/connectivity_for_web/.gitignore b/packages/connectivity/connectivity_for_web/.gitignore new file mode 100644 index 000000000000..d7dee828a6b9 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/.gitignore @@ -0,0 +1,8 @@ +.DS_Store +.dart_tool/ + +.packages +.pub/ + +build/ +lib/generated_plugin_registrant.dart diff --git a/packages/connectivity/connectivity_for_web/.metadata b/packages/connectivity/connectivity_for_web/.metadata new file mode 100644 index 000000000000..23eb55ba6da2 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/.metadata @@ -0,0 +1,10 @@ +# This file tracks properties of this Flutter project. +# Used by Flutter tool to assess capabilities and perform upgrades etc. +# +# This file should be version controlled and should not be manually edited. + +version: + revision: 52ee8a6c6565cd421dfa32042941eb40691f4746 + channel: master + +project_type: plugin diff --git a/packages/connectivity/connectivity_for_web/CHANGELOG.md b/packages/connectivity/connectivity_for_web/CHANGELOG.md new file mode 100644 index 000000000000..89e186abe1cb --- /dev/null +++ b/packages/connectivity/connectivity_for_web/CHANGELOG.md @@ -0,0 +1,11 @@ +## 0.3.0 + +* Rename from "experimental_connectivity_web" to "connectivity_for_web", and move to flutter/plugins master. + +## 0.2.0 + +* Add fallback on dart:html for browsers where NetworkInformationAPI is not supported. + +## 0.1.0 + +* Initial release. diff --git a/packages/connectivity/connectivity_for_web/LICENSE b/packages/connectivity/connectivity_for_web/LICENSE new file mode 100644 index 000000000000..4da9688730d1 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/LICENSE @@ -0,0 +1,26 @@ +Copyright 2016, the Flutter project authors. All rights reserved. +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of Google Inc. nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/packages/connectivity/connectivity_for_web/README.md b/packages/connectivity/connectivity_for_web/README.md new file mode 100644 index 000000000000..66efc49fc840 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/README.md @@ -0,0 +1,62 @@ +# connectivity_for_web + +A web implementation of [connectivity](https://pub.dev/connectivity/connectivity). Currently this package uses an experimental API, with a fallback to dart:html, so not all features may be available to all browsers. + +## Usage + +### Import the package + +This package is a non-endorsed implementation of `connectivity` for the web platform, so you need to modify your `pubspec.yaml` to use it: + +```yaml +... +dependencies: + ... + connectivity: ^0.4.9 + connectivity_for_web: ^0.3.0 + ... +... +``` + +## Example + +Find the example wiring in the [Google sign-in example application](https://github.com/ditman/plugins/blob/connectivity-web/packages/connectivity/connectivity/example/lib/main.dart). + +## Limitations on the web platform + +In order to retrieve information about the quality/speed of a browser's connection, the web implementation of the `connectivity` plugin uses the browser's [**NetworkInformation** Web API](https://developer.mozilla.org/en-US/docs/Web/API/NetworkInformation), which as of this writing (June 2020) is still "experimental", and not available in all browsers: + +![Data on support for the netinfo feature across the major browsers from caniuse.com](https://caniuse.bitsofco.de/image/netinfo.png) + +On desktop browsers, this API only returns a very broad set of connectivity statuses (One of `'slow-2g', '2g', '3g', or '4g'`), and may *not* provide a Stream of changes. Firefox still hasn't enabled this feature by default. + +**Fallback to `navigator.onLine`** + +For those browsers where the NetworkInformation Web API is not available, the plugin falls back to the [**NavigatorOnLine** Web API](https://developer.mozilla.org/en-US/docs/Web/API/NavigatorOnLine), which is more broadly supported: + +![Data on support for the online-status feature across the major browsers from caniuse.com](https://caniuse.bitsofco.de/image/online-status.png) + + +The NavigatorOnLine API is [provided by `dart:html`](https://api.dart.dev/stable/2.7.2/dart-html/Navigator/onLine.html), and only supports a boolean connectivity status (either online or offline), with no network speed information. In those cases the plugin will return either `wifi` (when the browser is online) or `none` (when it's not). + +Other than the approximate "downlink" speed, where available, and due to security and privacy concerns, **no Web browser will provide** any specific information about the actual network your users' device is connected to, like **the SSID on a Wi-Fi, or the MAC address of their device.** + +## Contributions and Testing + +Tests are crucial to contributions to this package. All new contributions should be reasonably tested. + +In order to run tests in this package, do: + +``` +cd test +flutter run -d chrome +``` + +All contributions to this package are welcome. Read the [Contributing to Flutter Plugins](https://github.com/flutter/plugins/blob/master/CONTRIBUTING.md) guide to get started. + +## Issues and feedback + +Please file an [issue](https://github.com/ditman/plugins/issues/new) +to send feedback or report a bug. + +**Thank you!** diff --git a/packages/connectivity/connectivity_for_web/ios/connectivity_for_web.podspec b/packages/connectivity/connectivity_for_web/ios/connectivity_for_web.podspec new file mode 100644 index 000000000000..75b891c56533 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/ios/connectivity_for_web.podspec @@ -0,0 +1,23 @@ +# +# To learn more about a Podspec see http://guides.cocoapods.org/syntax/podspec.html. +# Run `pod lib lint connectivity_web.podspec' to validate before publishing. +# +Pod::Spec.new do |s| + s.name = 'connectivity_for_web' + s.version = '0.1.0' + s.summary = 'No-op implementation of connectivity web plugin to avoid build issues on iOS' + s.description = <<-DESC +temp fake connectivity_web plugin + DESC + s.homepage = 'https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_for_web' + s.license = { :file => '../LICENSE' } + s.author = { 'Flutter Team' => 'flutter-dev@googlegroups.com' } + s.source = { :path => '.' } + s.source_files = 'Classes/**/*' + s.dependency 'Flutter' + s.platform = :ios, '8.0' + + # Flutter.framework does not contain a i386 slice. Only x86_64 simulators are supported. + s.pod_target_xcconfig = { 'DEFINES_MODULE' => 'YES', 'VALID_ARCHS[sdk=iphonesimulator*]' => 'x86_64' } + s.swift_version = '5.0' +end diff --git a/packages/connectivity/connectivity_for_web/lib/connectivity_for_web.dart b/packages/connectivity/connectivity_for_web/lib/connectivity_for_web.dart new file mode 100644 index 000000000000..fd061a878867 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/lib/connectivity_for_web.dart @@ -0,0 +1,63 @@ +import 'dart:async'; + +import 'package:connectivity_platform_interface/connectivity_platform_interface.dart'; +import 'package:flutter/services.dart'; +import 'package:flutter_web_plugins/flutter_web_plugins.dart'; + +import 'src/network_information_api_connectivity_plugin.dart'; +import 'src/dart_html_connectivity_plugin.dart'; + +/// The web implementation of the ConnectivityPlatform of the Connectivity plugin. +class ConnectivityPlugin extends ConnectivityPlatform { + /// Factory method that initializes the connectivity plugin platform with an instance + /// of the plugin for the web. + static void registerWith(Registrar registrar) { + if (NetworkInformationApiConnectivityPlugin.isSupported()) { + ConnectivityPlatform.instance = NetworkInformationApiConnectivityPlugin(); + } else { + ConnectivityPlatform.instance = DartHtmlConnectivityPlugin(); + } + } + + // The following are completely unsupported methods on the web platform. + + // Creates an "unsupported_operation" PlatformException for a given `method` name. + Object _unsupported(String method) { + return PlatformException( + code: 'UNSUPPORTED_OPERATION', + message: '$method() is not supported on the web platform.', + ); + } + + /// Obtains the wifi name (SSID) of the connected network + @override + Future getWifiName() { + throw _unsupported('getWifiName'); + } + + /// Obtains the wifi BSSID of the connected network. + @override + Future getWifiBSSID() { + throw _unsupported('getWifiBSSID'); + } + + /// Obtains the IP address of the connected wifi network + @override + Future getWifiIP() { + throw _unsupported('getWifiIP'); + } + + /// Request to authorize the location service (Only on iOS). + @override + Future requestLocationServiceAuthorization({ + bool requestAlwaysLocationUsage = false, + }) { + throw _unsupported('requestLocationServiceAuthorization'); + } + + /// Get the current location service authorization (Only on iOS). + @override + Future getLocationServiceAuthorization() { + throw _unsupported('getLocationServiceAuthorization'); + } +} diff --git a/packages/connectivity/connectivity_for_web/lib/src/dart_html_connectivity_plugin.dart b/packages/connectivity/connectivity_for_web/lib/src/dart_html_connectivity_plugin.dart new file mode 100644 index 000000000000..5caa5679d6ad --- /dev/null +++ b/packages/connectivity/connectivity_for_web/lib/src/dart_html_connectivity_plugin.dart @@ -0,0 +1,34 @@ +import 'dart:async'; +import 'dart:html' as html show window; + +import 'package:connectivity_platform_interface/connectivity_platform_interface.dart'; +import 'package:connectivity_for_web/connectivity_for_web.dart'; + +/// The web implementation of the ConnectivityPlatform of the Connectivity plugin. +class DartHtmlConnectivityPlugin extends ConnectivityPlugin { + /// Checks the connection status of the device. + @override + Future checkConnectivity() async { + return html.window.navigator.onLine + ? ConnectivityResult.wifi + : ConnectivityResult.none; + } + + StreamController _connectivityResult; + + /// Returns a Stream of ConnectivityResults changes. + @override + Stream get onConnectivityChanged { + if (_connectivityResult == null) { + _connectivityResult = StreamController(); + // Fallback to dart:html window.onOnline / window.onOffline + html.window.onOnline.listen((event) { + _connectivityResult.add(ConnectivityResult.wifi); + }); + html.window.onOffline.listen((event) { + _connectivityResult.add(ConnectivityResult.none); + }); + } + return _connectivityResult.stream; + } +} diff --git a/packages/connectivity/connectivity_for_web/lib/src/generated/network_information_types.dart b/packages/connectivity/connectivity_for_web/lib/src/generated/network_information_types.dart new file mode 100644 index 000000000000..c4045b3ec1fc --- /dev/null +++ b/packages/connectivity/connectivity_for_web/lib/src/generated/network_information_types.dart @@ -0,0 +1,78 @@ +@JS() +library network_information_types; + +import "package:js/js.dart"; +import "dart:html" show EventListener, EventTarget; + +/// W3C Spec Draft http://wicg.github.io/netinfo/ +/// Edition: Draft Community Group Report 20 February 2019 + +/// http://wicg.github.io/netinfo/#navigatornetworkinformation-interface +@anonymous +@JS() +abstract class Navigator implements NavigatorNetworkInformation {} + +@anonymous +@JS() +abstract class WorkerNavigator implements NavigatorNetworkInformation { + external factory WorkerNavigator({NetworkInformation connection}); +} + +/// http://wicg.github.io/netinfo/#navigatornetworkinformation-interface +@anonymous +@JS() +abstract class NavigatorNetworkInformation { + external NetworkInformation get connection; + external factory NavigatorNetworkInformation({NetworkInformation connection}); +} + +/// http://wicg.github.io/netinfo/#connection-types +/*type ConnectionType = + | 'bluetooth' + | 'cellular' + | 'ethernet' + | 'mixed' + | 'none' + | 'other' + | 'unknown' + | 'wifi' + | 'wimax'; +*/ + +/// http://wicg.github.io/netinfo/#effectiveconnectiontype-enum +/*type EffectiveConnectionType = '2g' | '3g' | '4g' | 'slow-2g';*/ + +/// http://wicg.github.io/netinfo/#dom-megabit +/*type Megabit = number;*/ +/// http://wicg.github.io/netinfo/#dom-millisecond +/*type Millisecond = number;*/ + +/// http://wicg.github.io/netinfo/#networkinformation-interface +@anonymous +@JS() +abstract class NetworkInformation implements EventTarget { + /// http://wicg.github.io/netinfo/#type-attribute + external String /*'bluetooth'|'cellular'|'ethernet'|'mixed'|'none'|'other'|'unknown'|'wifi'|'wimax'*/ get type; + + /// http://wicg.github.io/netinfo/#effectivetype-attribute + external String /*'2g'|'3g'|'4g'|'slow-2g'*/ get effectiveType; + + /// http://wicg.github.io/netinfo/#downlinkmax-attribute + external num get downlinkMax; + + /// http://wicg.github.io/netinfo/#downlink-attribute + external num get downlink; + + /// http://wicg.github.io/netinfo/#rtt-attribute + external num get rtt; + + /// http://wicg.github.io/netinfo/#savedata-attribute + external bool get saveData; + + /// http://wicg.github.io/netinfo/#handling-changes-to-the-underlying-connection + external EventListener get onchange; + external set onchange(EventListener v); +} + +@JS() +external Navigator get navigator; diff --git a/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart b/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart new file mode 100644 index 000000000000..d88487b9c406 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/lib/src/network_information_api_connectivity_plugin.dart @@ -0,0 +1,48 @@ +import 'dart:async'; + +import 'package:connectivity_platform_interface/connectivity_platform_interface.dart'; +import 'package:connectivity_for_web/connectivity_for_web.dart'; +import 'package:flutter/foundation.dart'; +import 'package:js/js.dart'; + +import 'generated/network_information_types.dart' as dom; +import 'utils/connectivity_result.dart'; + +/// The web implementation of the ConnectivityPlatform of the Connectivity plugin. +class NetworkInformationApiConnectivityPlugin extends ConnectivityPlugin { + final dom.NetworkInformation _networkInformation; + + /// A check to determine if this version of the plugin can be used. + static bool isSupported() => dom.navigator?.connection != null; + + /// The constructor of the plugin. + NetworkInformationApiConnectivityPlugin() + : this.withConnection(dom.navigator?.connection); + + /// Creates the plugin, with an override of the NetworkInformation object. + @visibleForTesting + NetworkInformationApiConnectivityPlugin.withConnection( + dom.NetworkInformation connection) + : _networkInformation = connection; + + /// Checks the connection status of the device. + @override + Future checkConnectivity() async { + return networkInformationToConnectivityResult(_networkInformation); + } + + StreamController _connectivityResult; + + /// Returns a Stream of ConnectivityResults changes. + @override + Stream get onConnectivityChanged { + if (_connectivityResult == null) { + _connectivityResult = StreamController(); + _networkInformation.onchange = allowInterop((_) { + _connectivityResult + .add(networkInformationToConnectivityResult(_networkInformation)); + }); + } + return _connectivityResult.stream; + } +} diff --git a/packages/connectivity/connectivity_for_web/lib/src/utils/connectivity_result.dart b/packages/connectivity/connectivity_for_web/lib/src/utils/connectivity_result.dart new file mode 100644 index 000000000000..28943ef5c7e1 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/lib/src/utils/connectivity_result.dart @@ -0,0 +1,56 @@ +import 'package:connectivity_platform_interface/connectivity_platform_interface.dart'; + +/// Converts an incoming NetworkInformation object into the correct ConnectivityResult. +// +// We can't be more specific on the signature of this method because the API is odd, +// data can come from a static value in the DOM, or as the 'target' of a DOM Event. +// +// If we type info as `NetworkInformation`, Dart will complain with: +// "Uncaught Error: Expected a value of type 'NetworkInformation', +// but got one of type 'NetworkInformation'" +ConnectivityResult networkInformationToConnectivityResult( + dynamic /* NetworkInformation */ info) { + if (info == null) { + return ConnectivityResult.none; + } + if (info.downlink == 0 && info.rtt == 0) { + return ConnectivityResult.none; + } + if (info.type != null) { + return _typeToConnectivityResult(info.type); + } + if (info.effectiveType != null) { + return _effectiveTypeToConnectivityResult(info.effectiveType); + } + return ConnectivityResult.none; +} + +ConnectivityResult _effectiveTypeToConnectivityResult(String effectiveType) { + // Possible values: + /*'2g'|'3g'|'4g'|'slow-2g'*/ + switch (effectiveType) { + case 'slow-2g': + case '2g': + case '3g': + return ConnectivityResult.mobile; + default: + return ConnectivityResult.wifi; + } +} + +ConnectivityResult _typeToConnectivityResult(String type) { + // Possible values: + /*'bluetooth'|'cellular'|'ethernet'|'mixed'|'none'|'other'|'unknown'|'wifi'|'wimax'*/ + switch (type) { + case 'none': + return ConnectivityResult.none; + case 'bluetooth': + case 'cellular': + case 'mixed': + case 'other': + case 'unknown': + return ConnectivityResult.mobile; + default: + return ConnectivityResult.wifi; + } +} diff --git a/packages/connectivity/connectivity_for_web/pubspec.yaml b/packages/connectivity/connectivity_for_web/pubspec.yaml new file mode 100644 index 000000000000..e4a1673e40c2 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/pubspec.yaml @@ -0,0 +1,31 @@ +name: connectivity_for_web +description: An implementation for the web platform of the Flutter `connectivity` plugin. This uses the NetworkInformation Web API, with a fallback to Navigator.onLine. +version: 0.3.0 +homepage: https://github.com/ditman/plugins/tree/connectivity-web/packages/connectivity/experimental_connectivity_web + +flutter: + plugin: + platforms: + web: + pluginClass: ConnectivityPlugin + fileName: connectivity_for_web.dart + +dependencies: + connectivity_platform_interface: ^1.0.3 + js: ^0.6.1+1 + flutter_web_plugins: + sdk: flutter + flutter: + sdk: flutter + +dev_dependencies: + test: any + flutter_driver: + sdk: flutter + flutter_test: + sdk: flutter + e2e: ^0.2.4+3 + +environment: + sdk: ">=2.6.0 <3.0.0" + flutter: ">=1.12.13+hotfix.4" diff --git a/packages/connectivity/connectivity_for_web/test/.gitignore b/packages/connectivity/connectivity_for_web/test/.gitignore new file mode 100644 index 000000000000..d7dee828a6b9 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/test/.gitignore @@ -0,0 +1,8 @@ +.DS_Store +.dart_tool/ + +.packages +.pub/ + +build/ +lib/generated_plugin_registrant.dart diff --git a/packages/connectivity/connectivity_for_web/test/lib/main.dart b/packages/connectivity/connectivity_for_web/test/lib/main.dart new file mode 100644 index 000000000000..21621a947ee6 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/test/lib/main.dart @@ -0,0 +1,74 @@ +import 'package:e2e/e2e.dart'; +import 'package:flutter_test/flutter_test.dart'; +import 'package:connectivity_platform_interface/connectivity_platform_interface.dart'; +import 'package:connectivity_for_web/src/network_information_api_connectivity_plugin.dart'; + +import 'src/connectivity_mocks.dart'; + +void main() { + E2EWidgetsFlutterBinding.ensureInitialized(); + + group('checkConnectivity', () { + void testCheckConnectivity({ + String type, + String effectiveType, + num downlink = 10, + num rtt = 50, + ConnectivityResult expected, + }) { + MockNetworkInformation connection = MockNetworkInformation( + type: type, + effectiveType: effectiveType, + downlink: downlink, + rtt: rtt); + NetworkInformationApiConnectivityPlugin plugin = + NetworkInformationApiConnectivityPlugin.withConnection(connection); + expect(plugin.checkConnectivity(), completion(equals(expected))); + } + + test('0 downlink and rtt -> none', () { + testCheckConnectivity( + effectiveType: '4g', + downlink: 0, + rtt: 0, + expected: ConnectivityResult.none); + }); + test('slow-2g -> mobile', () { + testCheckConnectivity( + effectiveType: 'slow-2g', expected: ConnectivityResult.mobile); + }); + test('2g -> mobile', () { + testCheckConnectivity( + effectiveType: '2g', expected: ConnectivityResult.mobile); + }); + test('3g -> mobile', () { + testCheckConnectivity( + effectiveType: '3g', expected: ConnectivityResult.mobile); + }); + test('4g -> wifi', () { + testCheckConnectivity( + effectiveType: '4g', expected: ConnectivityResult.wifi); + }); + }); + + group('get onConnectivityChanged', () { + test('puts change events in a Stream', () async { + MockNetworkInformation connection = + MockNetworkInformation(effectiveType: '4g', downlink: 10, rtt: 50); + NetworkInformationApiConnectivityPlugin plugin = + NetworkInformationApiConnectivityPlugin.withConnection(connection); + + Stream results = plugin.onConnectivityChanged; + + // Fake a disconnect-reconnect + connection.mockChangeValue(downlink: 0, rtt: 0); + connection.mockChangeValue(downlink: 10, rtt: 50); + + // The stream of results is infinite, so we need to .take(2) for this test to complete. + expect( + results.take(2).toList(), + completion( + equals([ConnectivityResult.none, ConnectivityResult.wifi]))); + }); + }); +} diff --git a/packages/connectivity/connectivity_for_web/test/lib/src/connectivity_mocks.dart b/packages/connectivity/connectivity_for_web/test/lib/src/connectivity_mocks.dart new file mode 100644 index 000000000000..9ce2e811d461 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/test/lib/src/connectivity_mocks.dart @@ -0,0 +1,60 @@ +import 'dart:html'; + +import 'package:connectivity_for_web/src/generated/network_information_types.dart' + as dom; + +/// A Mock implementation of the NetworkInformation API that allows +/// for external modification of its values. +class MockNetworkInformation extends dom.NetworkInformation { + @override + String type; + + @override + String effectiveType; + + @override + num downlink; + + @override + num rtt; + + @override + EventListener onchange; + + /// Constructor of mocked instances... + MockNetworkInformation({ + this.type, + this.effectiveType, + this.downlink, + this.rtt, + }); + + /// Changes the desired values, and triggers the change event listener. + void mockChangeValue({ + String type, + String effectiveType, + num downlink, + num rtt, + }) { + this.type = type ?? this.type; + this.effectiveType = effectiveType ?? this.effectiveType; + this.downlink = downlink ?? this.downlink; + this.rtt = rtt ?? this.rtt; + + onchange(Event('change')); + } + + @override + void addEventListener(String type, listener, [bool useCapture]) {} + + @override + bool dispatchEvent(Event event) { + return true; + } + + @override + Events get on => null; + + @override + void removeEventListener(String type, listener, [bool useCapture]) {} +} diff --git a/packages/connectivity/connectivity_for_web/test/pubspec.yaml b/packages/connectivity/connectivity_for_web/test/pubspec.yaml new file mode 100644 index 000000000000..4d7d10a775e2 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/test/pubspec.yaml @@ -0,0 +1,24 @@ +name: connectivity_web_example +description: Example web app for the connectivity plugin +version: 0.1.0 +homepage: https://github.com/flutter/plugins/tree/master/packages/connectivity/connectivity_web + +dependencies: + connectivity_for_web: + path: ../ + js: ^0.6.1+1 + flutter_web_plugins: + sdk: flutter + flutter: + sdk: flutter + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_driver: + sdk: flutter + e2e: ^0.2.4+3 + +environment: + sdk: ">=2.6.0 <3.0.0" + flutter: ">=1.12.13+hotfix.4" diff --git a/packages/connectivity/connectivity_for_web/test/web/index.html b/packages/connectivity/connectivity_for_web/test/web/index.html new file mode 100644 index 000000000000..6eff9a740d43 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/test/web/index.html @@ -0,0 +1,10 @@ + + + + + example + + + + + diff --git a/packages/connectivity/connectivity_for_web/ts/.gitignore b/packages/connectivity/connectivity_for_web/ts/.gitignore new file mode 100644 index 000000000000..de4d1f007dd1 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/ts/.gitignore @@ -0,0 +1,2 @@ +dist +node_modules diff --git a/packages/connectivity/connectivity_for_web/ts/README.md b/packages/connectivity/connectivity_for_web/ts/README.md new file mode 100644 index 000000000000..3372ad2f3790 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/ts/README.md @@ -0,0 +1,25 @@ +# JS Facade generator + +This npm script takes the `network-information-types` npm package, and runs it through Dart's `dart_js_facade_gen` to auto-generate (most) of the JS facades used by this plugin. + +The process is not completely automated yet, but it should be pretty close. + +To generate the facades, and after [installing `npm`](https://www.npmjs.com/get-npm), do: + +``` +npm install +npm run build +``` + +The above will fetch the required dependencies, and generate a `dist/network_information_types.dart` file that you can use with the plugin. + +``` +cp dist/*.dart ../lib/src/generated +``` + +This script should come handy once the Network Information Web API changes, or becomes stable, so the JS-interop part of this plugin can be regenerated more easily. + +Read more: + +* [Dart JS Interop](https://dart.dev/web/js-interop) +* [dart_js_facade_gen](https://www.npmjs.com/package/dart_js_facade_gen) \ No newline at end of file diff --git a/packages/connectivity/connectivity_for_web/ts/package-lock.json b/packages/connectivity/connectivity_for_web/ts/package-lock.json new file mode 100644 index 000000000000..45293a400492 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/ts/package-lock.json @@ -0,0 +1,117 @@ +{ + "name": "network-information-types-to-dart-generator", + "version": "1.0.0", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@types/chai": { + "version": "4.2.9", + "resolved": "https://registry.npmjs.org/@types/chai/-/chai-4.2.9.tgz", + "integrity": "sha512-NeXgZj+MFL4izGqA4sapdYzkzQG+MtGra9vhQ58dnmDY++VgJaRUws+aLVV5zRJCYJl/8s9IjMmhiUw1WsKSmw==" + }, + "@types/fs-extra": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/@types/fs-extra/-/fs-extra-8.1.0.tgz", + "integrity": "sha512-UoOfVEzAUpeSPmjm7h1uk5MH6KZma2z2O7a75onTGjnNvAvMVrPzPL/vBbT65iIGHWj6rokwfmYcmxmlSf2uwg==", + "requires": { + "@types/node": "*" + } + }, + "@types/minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-aaI6OtKcrwCX8G7aWbNh7i8GOfY=" + }, + "@types/mocha": { + "version": "5.2.7", + "resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz", + "integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==" + }, + "@types/node": { + "version": "12.12.28", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.28.tgz", + "integrity": "sha512-g73GJYJDXgf0jqg+P9S8h2acWbDXNkoCX8DLtJVu7Fkn788pzQ/oJsrdJz/2JejRf/SjfZaAhsw+3nd1D5EWGg==" + }, + "@types/source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/@types/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha512-LrnsgZIfJaysFkv9rRJp4/uAyqw87oVed3s1hhF83nwbo9c7MG9g5DqR0seHP+lkX4ldmMrVolPjQSe2ZfD0yA==", + "requires": { + "source-map": "*" + } + }, + "@types/source-map-support": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@types/source-map-support/-/source-map-support-0.5.1.tgz", + "integrity": "sha512-VDqnZe9D2zR19qbeRvwYyHSp7AtUtCkTaRVFQ8wzwH9TXw9kKKq/vBhfEnFEXVupO2M0lBMA9mr/XyQ6gEkUOA==", + "requires": { + "@types/node": "*" + } + }, + "buffer-from": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz", + "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==" + }, + "dart-style": { + "version": "1.3.2-dev", + "resolved": "https://registry.npmjs.org/dart-style/-/dart-style-1.3.2-dev.tgz", + "integrity": "sha512-NFI4UQYvG32t/cEkQAdkXT2ZT72tjF61tMWoALmnGwj03d2Co94zwGfbnFfdQUQvrhUNx8Wz2jKSVxGrmFaVJQ==" + }, + "dart_js_facade_gen": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/dart_js_facade_gen/-/dart_js_facade_gen-0.0.7.tgz", + "integrity": "sha512-AZiWsccbzhgJWmBjbFTPuvBhwGXk7AN8nOP91/I8PqUfSvVALiWshDc66TvywNkdNogAE5X8zlxjodw1C3iHpA==", + "requires": { + "@types/chai": "^4.2.3", + "@types/fs-extra": "^8.0.0", + "@types/minimist": "^1.2.0", + "@types/mocha": "^5.2.7", + "@types/node": "^12.7.8", + "@types/source-map": "^0.5.7", + "@types/source-map-support": "^0.5.0", + "dart-style": "^1.3.2-dev", + "minimist": "^1.2.0", + "source-map": "^0.7.3", + "source-map-support": "^0.5.13", + "typescript": "^3.6.3" + } + }, + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=" + }, + "network-information-types": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/network-information-types/-/network-information-types-0.1.0.tgz", + "integrity": "sha512-cRUCYZoRHTMjYcgk5MbwqM0h0Za34panRxAJKY8n+mQ+NLMuRIw7aKzmaZqkC/cte7bnRcdfTwFA27GgN62EtQ==" + }, + "source-map": { + "version": "0.7.3", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.3.tgz", + "integrity": "sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==" + }, + "source-map-support": { + "version": "0.5.16", + "resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.16.tgz", + "integrity": "sha512-efyLRJDr68D9hBBNIPWFjhpFzURh+KJykQwvMyW5UiZzYwoF6l4YMMDIJJEyFWxWCqfyxLzz6tSfUFR+kXXsVQ==", + "requires": { + "buffer-from": "^1.0.0", + "source-map": "^0.6.0" + }, + "dependencies": { + "source-map": { + "version": "0.6.1", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", + "integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==" + } + } + }, + "typescript": { + "version": "3.8.2", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.8.2.tgz", + "integrity": "sha512-EgOVgL/4xfVrCMbhYKUQTdF37SQn4Iw73H5BgCrF1Abdun7Kwy/QZsE/ssAy0y4LxBbvua3PIbFsbRczWWnDdQ==" + } + } +} diff --git a/packages/connectivity/connectivity_for_web/ts/package.json b/packages/connectivity/connectivity_for_web/ts/package.json new file mode 100644 index 000000000000..665c89d6afbb --- /dev/null +++ b/packages/connectivity/connectivity_for_web/ts/package.json @@ -0,0 +1,17 @@ +{ + "name": "network-information-types-to-dart-generator", + "version": "1.0.0", + "description": "Use dart_js_facade_gen to generate the facade for the network-information-types package.", + "main": "index.js", + "private": true, + "scripts": { + "build": "./scripts/run_facade_gen.sh", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "MIT", + "dependencies": { + "network-information-types": "0.1.0", + "dart_js_facade_gen": "^0.0.7" + } +} diff --git a/packages/connectivity/connectivity_for_web/ts/scripts/run_facade_gen.sh b/packages/connectivity/connectivity_for_web/ts/scripts/run_facade_gen.sh new file mode 100755 index 000000000000..c74b8ba171b2 --- /dev/null +++ b/packages/connectivity/connectivity_for_web/ts/scripts/run_facade_gen.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +INDEX_PATH=node_modules/network-information-types/dist-types/index.d.ts +WORK_PATH=network_information_types.d.ts +DIST_PATH=dist + +# Create dist if it doesn't exist already +mkdir -p $DIST_PATH + +# Copy the input file(s) into our work path +cp $INDEX_PATH $WORK_PATH + +# Run dart_js_facade_gen +dart_js_facade_gen $WORK_PATH --trust-js-types --generate-html --destination . + +# Move output to the right place, and clean after yourself +mv *.dart $DIST_PATH +rm $WORK_PATH