feat(web): create my_plugin_web (#10)

This commit is contained in:
Felix Angelov 2022-02-28 15:36:56 -06:00 committed by GitHub
parent 229c2755d7
commit 6791e7e613
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
21 changed files with 398 additions and 91 deletions

View File

@ -20,95 +20,6 @@ jobs:
flutter_version: 2.10.1 flutter_version: 2.10.1
working_directory: src/my_plugin working_directory: src/my_plugin
linux:
runs-on: ubuntu-18.04
defaults:
run:
working-directory: src/my_plugin/example
steps:
- uses: actions/checkout@v2
- uses: subosito/flutter-action@v2
- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libx11-dev pkg-config cmake ninja-build libblkid-dev liblzma-dev
- name: Enable desktop support
run: flutter config --enable-linux-desktop
- name: Flutter Doctor
run: flutter doctor -v
- name: Integration Tests
run: xvfb-run flutter test integration_test -d linux
windows:
runs-on: windows-2019
defaults:
run:
working-directory: src/my_plugin/example
steps:
- uses: actions/checkout@v2
- uses: subosito/flutter-action@v2
- name: Enable desktop support
run: flutter config --enable-windows-desktop
- name: Flutter Doctor
run: flutter doctor -v
- name: Integration Tests
run: flutter test integration_test -d windows
macos:
runs-on: macos-10.15
defaults:
run:
working-directory: src/my_plugin/example
steps:
- uses: actions/checkout@v2
- uses: subosito/flutter-action@v2
- name: Enable desktop support
run: flutter config --enable-macos-desktop
- name: Flutter Doctor
run: flutter doctor -v
- name: Integration Tests
run: flutter test integration_test -d macos
ios:
runs-on: macos-10.15
defaults:
run:
working-directory: src/my_plugin/example
steps:
- uses: actions/checkout@v2
- uses: subosito/flutter-action@v2
- name: Flutter Doctor
run: flutter doctor -v
- name: Start Simulator
run: open -a Simulator.app
- name: Integration Tests
run: flutter test integration_test -d iPhone
android: android:
runs-on: macos-10.15 runs-on: macos-10.15
@ -153,3 +64,118 @@ jobs:
api-level: 29 api-level: 29
script: flutter test integration_test script: flutter test integration_test
working-directory: src/my_plugin/example working-directory: src/my_plugin/example
ios:
runs-on: macos-10.15
defaults:
run:
working-directory: src/my_plugin/example
steps:
- uses: actions/checkout@v2
- uses: subosito/flutter-action@v2
- name: Flutter Doctor
run: flutter doctor -v
- name: Start Simulator
run: open -a Simulator.app
- name: Integration Tests
run: flutter test integration_test -d iPhone
linux:
runs-on: ubuntu-18.04
defaults:
run:
working-directory: src/my_plugin/example
steps:
- uses: actions/checkout@v2
- uses: subosito/flutter-action@v2
- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get install -y libgtk-3-dev libx11-dev pkg-config cmake ninja-build libblkid-dev liblzma-dev
- name: Enable desktop support
run: flutter config --enable-linux-desktop
- name: Flutter Doctor
run: flutter doctor -v
- name: Integration Tests
run: xvfb-run flutter test integration_test -d linux
macos:
runs-on: macos-10.15
defaults:
run:
working-directory: src/my_plugin/example
steps:
- uses: actions/checkout@v2
- uses: subosito/flutter-action@v2
- name: Enable desktop support
run: flutter config --enable-macos-desktop
- name: Flutter Doctor
run: flutter doctor -v
- name: Integration Tests
run: flutter test integration_test -d macos
web:
runs-on: macos-10.15
defaults:
run:
working-directory: src/my_plugin/example
steps:
- uses: actions/checkout@v2
- uses: subosito/flutter-action@v2
- name: Flutter Doctor
run: flutter doctor -v
- name: Run Chromedriver
run: |
git clone https://github.com/felangel/web_installers
cd web_installers/packages/web_drivers
dart pub get
dart lib/web_driver_installer.dart chromedriver --install-only
./chromedriver/chromedriver --port=4444 &
- name: Integration Tests
run: flutter drive --driver test_driver/integration_test.dart --target integration_test/app_test.dart -d web-server --browser-name=chrome
windows:
runs-on: windows-2019
defaults:
run:
working-directory: src/my_plugin/example
steps:
- uses: actions/checkout@v2
- uses: subosito/flutter-action@v2
- name: Enable desktop support
run: flutter config --enable-windows-desktop
- name: Flutter Doctor
run: flutter doctor -v
- name: Integration Tests
run: flutter test integration_test -d windows

21
.github/workflows/my_plugin_web.yaml vendored Normal file
View File

@ -0,0 +1,21 @@
name: my_plugin_web
on:
pull_request:
paths:
- ".github/workflows/my_plugin_web.yaml"
- "src/my_plugin_web/**"
push:
branches:
- main
paths:
- ".github/workflows/my_plugin_web.yaml"
- "src/my_plugin_web/**"
jobs:
build:
uses: VeryGoodOpenSource/very_good_workflows/.github/workflows/flutter_package.yml@v1
with:
flutter_channel: stable
flutter_version: 2.10.1
working_directory: src/my_plugin_web

View File

@ -21,6 +21,7 @@ void main() {
} }
String expectedPlatformName() { String expectedPlatformName() {
if (isWeb) return 'Web';
if (Platform.isAndroid) return 'Android'; if (Platform.isAndroid) return 'Android';
if (Platform.isIOS) return 'iOS'; if (Platform.isIOS) return 'iOS';
if (Platform.isLinux) return 'Linux'; if (Platform.isLinux) return 'Linux';
@ -28,3 +29,5 @@ String expectedPlatformName() {
if (Platform.isWindows) return 'Windows'; if (Platform.isWindows) return 'Windows';
throw UnsupportedError('Unsupported platform ${Platform.operatingSystem}'); throw UnsupportedError('Unsupported platform ${Platform.operatingSystem}');
} }
bool get isWeb => identical(0, 0.0);

View File

@ -4,8 +4,8 @@ version: 0.1.0+1
publish_to: none publish_to: none
environment: environment:
sdk: ">=2.14.0 <3.0.0" sdk: ">=2.16.0 <3.0.0"
flutter: ">=2.5.0" flutter: ">=2.10.0"
dependencies: dependencies:
flutter: flutter:
@ -19,6 +19,8 @@ dependencies:
path: ../ path: ../
dev_dependencies: dev_dependencies:
flutter_driver:
sdk: flutter
flutter_test: flutter_test:
sdk: flutter sdk: flutter
integration_test: integration_test:

View File

@ -0,0 +1,3 @@
import 'package:integration_test/integration_test_driver.dart';
Future<void> main() => integrationDriver();

Binary file not shown.

After

Width:  |  Height:  |  Size: 917 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@ -0,0 +1,104 @@
<!DOCTYPE html>
<html>
<head>
<!--
If you are serving your web app in a path other than the root, change the
href value below to reflect the base path you are serving from.
The path provided below has to start and end with a slash "/" in order for
it to work correctly.
For more details:
* https://developer.mozilla.org/en-US/docs/Web/HTML/Element/base
This is a placeholder for base href that will be replaced by the value of
the `--base-href` argument provided to `flutter build`.
-->
<base href="$FLUTTER_BASE_HREF">
<meta charset="UTF-8">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<meta name="description" content="A new Flutter project.">
<!-- iOS meta tags & icons -->
<meta name="apple-mobile-web-app-capable" content="yes">
<meta name="apple-mobile-web-app-status-bar-style" content="black">
<meta name="apple-mobile-web-app-title" content="example">
<link rel="apple-touch-icon" href="icons/Icon-192.png">
<!-- Favicon -->
<link rel="icon" type="image/png" href="favicon.png"/>
<title>example</title>
<link rel="manifest" href="manifest.json">
</head>
<body>
<!-- This script installs service_worker.js to provide PWA functionality to
application. For more information, see:
https://developers.google.com/web/fundamentals/primers/service-workers -->
<script>
var serviceWorkerVersion = null;
var scriptLoaded = false;
function loadMainDartJs() {
if (scriptLoaded) {
return;
}
scriptLoaded = true;
var scriptTag = document.createElement('script');
scriptTag.src = 'main.dart.js';
scriptTag.type = 'application/javascript';
document.body.append(scriptTag);
}
if ('serviceWorker' in navigator) {
// Service workers are supported. Use them.
window.addEventListener('load', function () {
// Wait for registration to finish before dropping the <script> tag.
// Otherwise, the browser will load the script multiple times,
// potentially different versions.
var serviceWorkerUrl = 'flutter_service_worker.js?v=' + serviceWorkerVersion;
navigator.serviceWorker.register(serviceWorkerUrl)
.then((reg) => {
function waitForActivation(serviceWorker) {
serviceWorker.addEventListener('statechange', () => {
if (serviceWorker.state == 'activated') {
console.log('Installed new service worker.');
loadMainDartJs();
}
});
}
if (!reg.active && (reg.installing || reg.waiting)) {
// No active web worker and we have installed or are installing
// one for the first time. Simply wait for it to activate.
waitForActivation(reg.installing || reg.waiting);
} else if (!reg.active.scriptURL.endsWith(serviceWorkerVersion)) {
// When the app updates the serviceWorkerVersion changes, so we
// need to ask the service worker to update.
console.log('New service worker available.');
reg.update();
waitForActivation(reg.installing);
} else {
// Existing service worker is still good.
console.log('Loading app from service worker.');
loadMainDartJs();
}
});
// If service worker doesn't succeed in a reasonable amount of time,
// fallback to plaint <script> tag.
setTimeout(() => {
if (!scriptLoaded) {
console.warn(
'Failed to load app from service worker. Falling back to plain <script> tag.',
);
loadMainDartJs();
}
}, 4000);
});
} else {
// Service workers not supported. Just drop the <script> tag.
loadMainDartJs();
}
</script>
</body>
</html>

View File

@ -0,0 +1,35 @@
{
"name": "example",
"short_name": "example",
"start_url": ".",
"display": "standalone",
"background_color": "#0175C2",
"theme_color": "#0175C2",
"description": "A new Flutter project.",
"orientation": "portrait-primary",
"prefer_related_applications": false,
"icons": [
{
"src": "icons/Icon-192.png",
"sizes": "192x192",
"type": "image/png"
},
{
"src": "icons/Icon-512.png",
"sizes": "512x512",
"type": "image/png"
},
{
"src": "icons/Icon-maskable-192.png",
"sizes": "192x192",
"type": "image/png",
"purpose": "maskable"
},
{
"src": "icons/Icon-maskable-512.png",
"sizes": "512x512",
"type": "image/png",
"purpose": "maskable"
}
]
}

View File

@ -18,6 +18,8 @@ flutter:
default_package: my_plugin_macos default_package: my_plugin_macos
linux: linux:
default_package: my_plugin_linux default_package: my_plugin_linux
web:
default_package: my_plugin_web
windows: windows:
default_package: my_plugin_windows default_package: my_plugin_windows
@ -34,6 +36,8 @@ dependencies:
path: ../my_plugin_macos path: ../my_plugin_macos
my_plugin_platform_interface: my_plugin_platform_interface:
path: ../my_plugin_platform_interface path: ../my_plugin_platform_interface
my_plugin_web:
path: ../my_plugin_web
my_plugin_windows: my_plugin_windows:
path: ../my_plugin_windows path: ../my_plugin_windows

3
src/my_plugin_web/.gitignore vendored Normal file
View File

@ -0,0 +1,3 @@
.packages
.flutter-plugins
pubspec.lock

View File

@ -0,0 +1,3 @@
# 0.1.0+1
- Initial release of this plugin.

21
src/my_plugin_web/LICENSE Normal file
View File

@ -0,0 +1,21 @@
MIT License
Copyright (c) 2022 Very Good Ventures
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -0,0 +1,14 @@
# my_plugin_web
[![style: very good analysis][very_good_analysis_badge]][very_good_analysis_link]
The web implementation of `my_plugin`.
## Usage
This package is [endorsed][endorsed_link], which means you can simply use `my_plugin`
normally. This package will be automatically included in your app when you do.
[endorsed_link]: https://flutter.dev/docs/development/packages-and-plugins/developing-packages#endorsed-federated-plugin
[very_good_analysis_badge]: https://img.shields.io/badge/style-very_good_analysis-B22C89.svg
[very_good_analysis_link]: https://pub.dev/packages/very_good_analysis

View File

@ -0,0 +1 @@
include: package:very_good_analysis/analysis_options.2.4.0.yaml

View File

@ -0,0 +1,12 @@
import 'package:my_plugin_platform_interface/my_plugin_platform_interface.dart';
/// The Web implementation of [MyPluginPlatform].
class MyPluginWeb extends MyPluginPlatform {
/// Registers this class as the default instance of [MyPluginPlatform]
static void registerWith([Object? registrar]) {
MyPluginPlatform.instance = MyPluginWeb();
}
@override
Future<String?> getPlatformName() async => 'Web';
}

View File

@ -0,0 +1,29 @@
name: my_plugin_web
description: Web implementation of the my_plugin plugin
version: 0.1.0+1
publish_to: none
environment:
sdk: ">=2.16.0 <3.0.0"
flutter: ">=2.10.0"
flutter:
plugin:
implements: my_plugin
platforms:
web:
pluginClass: MyPluginWeb
fileName: my_plugin_web.dart
dependencies:
flutter:
sdk: flutter
flutter_web_plugins:
sdk: flutter
my_plugin_platform_interface:
path: ../my_plugin_platform_interface
dev_dependencies:
flutter_test:
sdk: flutter
very_good_analysis: ^2.4.0

View File

@ -0,0 +1,26 @@
import 'package:flutter_test/flutter_test.dart';
import 'package:my_plugin_platform_interface/my_plugin_platform_interface.dart';
import 'package:my_plugin_web/my_plugin_web.dart';
void main() {
TestWidgetsFlutterBinding.ensureInitialized();
group('MyPluginWeb', () {
const kPlatformName = 'Web';
late MyPluginWeb myPlugin;
setUp(() async {
myPlugin = MyPluginWeb();
});
test('can be registered', () {
MyPluginWeb.registerWith();
expect(MyPluginPlatform.instance, isA<MyPluginWeb>());
});
test('getPlatformName returns correct name', () async {
final name = await myPlugin.getPlatformName();
expect(name, equals(kPlatformName));
});
});
}