From fcbdf6449cae0a0340f6d46c67e4975443161181 Mon Sep 17 00:00:00 2001 From: buijs Date: Sat, 15 Apr 2023 22:25:24 +0200 Subject: [PATCH 1/6] Move tests to test/src. Bump dartdoc version. Add example implementations in readme for pub/sub. --- .github/workflows/codecov.yml | 2 +- README.md | 73 +++++++++++++++++++++++++-- lib/src/adapter.dart | 2 +- lib/src/subscriber.dart | 6 ++- pubspec.yaml | 2 +- {src => test/src}/adapter_test.dart | 0 {src => test/src}/publisher_test.dart | 0 7 files changed, 77 insertions(+), 8 deletions(-) rename {src => test/src}/adapter_test.dart (100%) rename {src => test/src}/publisher_test.dart (100%) diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index 32a834f..ec02951 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -15,7 +15,7 @@ jobs: # Get dependencies - name: Install dependencies - run: dart pub get + run: flutter pub get # Run all tests with coverage - name: Run tests with coverage diff --git a/README.md b/README.md index 8ab15ca..1aafeea 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,76 @@ [![](https://img.shields.io/badge/Buijs-Software-blue)](https://pub.dev/publishers/buijs.dev/packages) [![GitHub license](https://img.shields.io/github/license/buijs-dev/klutter-dart?color=black&logoColor=black)](https://github.com/buijs-dev/klutter-dart/blob/main/LICENSE) - -
+[![pub](https://img.shields.io/pub/v/klutter-ui)](https://pub.dev/packages/klutter-ui) +[![codecov](https://img.shields.io/codecov/c/github/buijs-dev/klutter-dart-ui?logo=codecov)](https://codecov.io/gh/buijs-dev/klutter-dart-ui) +[![CodeScene Code Health](https://codescene.io/projects/38075/status-badges/code-health)](https://codescene.io/projects/38075) buijs software logo Flutter Widgets to be used in conjunction with the [klutter plugin](https://github.com/buijs-dev/klutter-dart). -Not yet published to pub... \ No newline at end of file +Full support for: +- [MethodChannel (synchronous)](#MethodChannel) +- [EventChannel (asynchronous)](#EventChannel) + +## MethodChannel +Example function which invokes method foo on the given channel and returns a String value. + +```dart +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; +import 'package:klutter_ui/klutter_ui.dart'; + +const MethodChannel _channel = + MethodChannel('foo.bar.plugin/channel/my_simple_controller'); + +void foo({ + State? state, + void Function(String)? onSuccess, + void Function(Exception)? onFailure, +}) => + doEvent( + state: state, + event: "foo", + channel: _channel, + onSuccess: onSuccess, + onFailure: onFailure, + ); +``` + +Using the function as a tearoff requires just a single line of code: + +```dart +TextButton(onPressed: foo, child: Text("Click")) +``` + +## EventChannel +Example implementation of a Subscriber (statefull widget) which subscribes to a channel and updates it state +everytime a new counter value is received. + +```dart +import 'package:flutter/services.dart'; +import 'package:flutter/widgets.dart'; +import 'package:klutter_ui/klutter_ui.dart'; + +const _stream = EventChannel('foo.bar.plugin/channel/counter'); + +class Counter extends Subscriber { + const Counter({ + required Widget Function(int?) child, + Key? key, + }) : super( + child: child, + channel: _stream, + topic: "counter", + key: key, + ); + + @override + int decode(dynamic json) => json as int; +} +``` + +All that is required to use the returned data is to wrap any widget with the Counter widget and then use it's value. + +```dart +Counter(child: (res) => Text("$res")), +``` \ No newline at end of file diff --git a/lib/src/adapter.dart b/lib/src/adapter.dart index c66e4db..7e17907 100644 --- a/lib/src/adapter.dart +++ b/lib/src/adapter.dart @@ -18,7 +18,7 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -/// Wrapper class for transfering response data from Platform to Flutter. +/// Wrapper class for transferring response data from Platform to Flutter. /// /// Wraps an [exception] if calling the platform method has failed to be logged by the consumer. /// Or wraps an [object] of type T when platform method has returned a response and diff --git a/lib/src/subscriber.dart b/lib/src/subscriber.dart index 3d58ba1..3f500b0 100644 --- a/lib/src/subscriber.dart +++ b/lib/src/subscriber.dart @@ -7,11 +7,13 @@ abstract class Subscriber extends StatefulWidget { const Subscriber({ required this.child, required this.channel, + required this.topic, Key? key, }) : super(key: key); final Widget Function(T?) child; final EventChannel channel; + final String topic; T decode(dynamic json); @@ -25,7 +27,7 @@ class _SubscriberState extends State> { void _start() { _streamSubscription ??= - widget.channel.receiveBroadcastStream().listen(_update); + widget.channel.receiveBroadcastStream(widget.topic).listen(_update); } void _stop() { @@ -36,7 +38,7 @@ class _SubscriberState extends State> { } void _update(dynamic data) { - setState(() => _data = widget.decode(data as String)); + setState(() => _data = widget.decode(data)); } @override diff --git a/pubspec.yaml b/pubspec.yaml index c778428..37b548c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -13,5 +13,5 @@ dependencies: dev_dependencies: coverage: ^1.3.2 - dartdoc: ^5.1.2 + dartdoc: ^6.2.1 test: ^1.19.5 \ No newline at end of file diff --git a/src/adapter_test.dart b/test/src/adapter_test.dart similarity index 100% rename from src/adapter_test.dart rename to test/src/adapter_test.dart diff --git a/src/publisher_test.dart b/test/src/publisher_test.dart similarity index 100% rename from src/publisher_test.dart rename to test/src/publisher_test.dart From 46d2f90fb314ee9e9d9ca454ad35e49ff7f5c417 Mon Sep 17 00:00:00 2001 From: buijs Date: Sat, 15 Apr 2023 22:32:18 +0200 Subject: [PATCH 2/6] Run tests with flutter SDK. --- .github/workflows/codecov.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index ec02951..c4439f5 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -19,11 +19,11 @@ jobs: # Run all tests with coverage - name: Run tests with coverage - run: dart run test --coverage="coverage" + run: flutter test --coverage # Convert to LCOV - name: Convert coverage to LCOV - run: dart pub run coverage:format_coverage --lcov --in=coverage --out=coverage.lcov --packages=.dart_tool/package_config.json --report-on=lib + run: dart run coverage:format_coverage --lcov --in=coverage --out=coverage.lcov --packages=.dart_tool/package_config.json --report-on=lib # Upload coverage data - name: Upload coverage to Codecov From 0d23c33000e17c1885c251bd40e435072f09c92e Mon Sep 17 00:00:00 2001 From: buijs Date: Sat, 15 Apr 2023 22:49:26 +0200 Subject: [PATCH 3/6] remove lcov conversion step and upload lcov.info directly --- .github/workflows/codecov.yml | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/.github/workflows/codecov.yml b/.github/workflows/codecov.yml index c4439f5..c9816e1 100644 --- a/.github/workflows/codecov.yml +++ b/.github/workflows/codecov.yml @@ -21,14 +21,10 @@ jobs: - name: Run tests with coverage run: flutter test --coverage - # Convert to LCOV - - name: Convert coverage to LCOV - run: dart run coverage:format_coverage --lcov --in=coverage --out=coverage.lcov --packages=.dart_tool/package_config.json --report-on=lib - # Upload coverage data - name: Upload coverage to Codecov uses: codecov/codecov-action@v2 env: CODECOV_TOKEN: ${{secrets.CODECOV_TOKEN}} with: - file: coverage.lcov \ No newline at end of file + file: coverage/lcov.info \ No newline at end of file From 66bfb94e136b80465a1fdb911cb4f891f100798c Mon Sep 17 00:00:00 2001 From: buijs Date: Wed, 26 Apr 2023 20:40:00 +0200 Subject: [PATCH 4/6] Docs, test and codecov config. --- README.md | 2 +- codecov.yml | 2 + lib/src/adapter.dart | 4 +- lib/src/publisher.dart | 74 +++++++++++++++++ lib/src/subscriber.dart | 65 ++++++++++++++- test/adapter_test.dart | 39 --------- test/src/publisher_test.dart | 149 +++++++++++++++++++++++++++++++---- 7 files changed, 275 insertions(+), 60 deletions(-) create mode 100644 codecov.yml delete mode 100644 test/adapter_test.dart diff --git a/README.md b/README.md index 1aafeea..48f3146 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ [![](https://img.shields.io/badge/Buijs-Software-blue)](https://pub.dev/publishers/buijs.dev/packages) [![GitHub license](https://img.shields.io/github/license/buijs-dev/klutter-dart?color=black&logoColor=black)](https://github.com/buijs-dev/klutter-dart/blob/main/LICENSE) [![pub](https://img.shields.io/pub/v/klutter-ui)](https://pub.dev/packages/klutter-ui) -[![codecov](https://img.shields.io/codecov/c/github/buijs-dev/klutter-dart-ui?logo=codecov)](https://codecov.io/gh/buijs-dev/klutter-dart-ui) +[![codecov](https://codecov.io/gh/buijs-dev/klutter-dart-ui/branch/main/graph/badge.svg?token=z0HCTKNLn5)](https://codecov.io/gh/buijs-dev/klutter-dart-ui) [![CodeScene Code Health](https://codescene.io/projects/38075/status-badges/code-health)](https://codescene.io/projects/38075) buijs software logo diff --git a/codecov.yml b/codecov.yml new file mode 100644 index 0000000..7d36dd4 --- /dev/null +++ b/codecov.yml @@ -0,0 +1,2 @@ +ignore: + - "lib/src/subscriber.dart" \ No newline at end of file diff --git a/lib/src/adapter.dart b/lib/src/adapter.dart index 7e17907..7b69867 100644 --- a/lib/src/adapter.dart +++ b/lib/src/adapter.dart @@ -1,4 +1,4 @@ -// Copyright (c) 2021 - 2022 Buijs Software +// Copyright (c) 2021 - 2023 Buijs Software // // Permission is hereby granted, free of charge, to any person obtaining a copy // of this software and associated documentation files (the "Software"), to deal @@ -42,7 +42,7 @@ class AdapterResponse { /// Get a non-null object value. T get object => _object!; - ///Exception which occurred when calling a platform method failed. + /// Exception which occurred when calling a platform method failed. Exception? _exception; /// Set the exception value. diff --git a/lib/src/publisher.dart b/lib/src/publisher.dart index 6551a29..5fdb52f 100644 --- a/lib/src/publisher.dart +++ b/lib/src/publisher.dart @@ -1,3 +1,22 @@ +// Copyright (c) 2021 - 2023 Buijs Software +// +// 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. import "dart:async"; import "package:flutter/services.dart"; @@ -5,25 +24,80 @@ import "package:flutter/widgets.dart"; import "adapter.dart"; +/// Send an event to Android/iOS platform and wait for a response [AdapterResponse]. +/// +/// Example implementation: +/// +/// ```dart +/// const MethodChannel _channel = +/// MethodChannel('foo.bar.plugin/channel/my_simple_controller'); +/// +/// void foo({ +/// State? state, +/// void Function(String)? onSuccess, +/// void Function(Exception)? onFailure, +/// }) => +/// doEvent( +/// state: state, +/// event: "foo", +/// channel: _channel, +/// onSuccess: onSuccess, +/// onFailure: onFailure, +/// ); +/// ``` Future> doEvent({ + /// Name of the event. + /// + /// This name is used on the platform-side to determine which method to invoke. required String event, + + /// MethodChannel where the event is to be published. required MethodChannel channel, + + /// (Optional) Data to be send with the event. + /// + /// E.g. if the method to be invoked requires parameters then add them as message. dynamic message, + + /// (Optional) State of widget from where the event is send. + /// + /// Used to determine if the state is mounted. + /// If not then callbacks are not executed. State? state, + + /// (Optional) Decoding function used to decode the received response. OUT Function(String)? decode, + + /// (Optional) Encoding function used to encode message if is not + /// a StandardMessageCodec Type. String Function(dynamic)? encode, + + /// (Optional) Function to be executed if the event is processed successfully. void Function(OUT)? onSuccess, + + /// (Optional) Function to be executed if the event is processed unsuccessfully. void Function(Exception)? onFailure, + + /// (Optional) Function to be executed if the received response data is null. void Function()? onNullValue, + + /// (Optional) Function to be executed when the event is processed, regardless success (or NOT). void Function(AdapterResponse)? onComplete, }) async { + /// Create a request message. + /// + /// If [message] is null then [request] is also null. final dynamic request = _toRequestMessage(message, encode); + /// Send the event and wait for a response. final response = await _sendEvent( sendRequest: () => channel.invokeMethod(event, request), deserialize: decode, ); + /// Check if state is mounted. + /// + /// if not then skip all callbacks and return the response. if (state?.mounted ?? true) { onComplete?.call(response); if (response.isSuccess) { diff --git a/lib/src/subscriber.dart b/lib/src/subscriber.dart index 3f500b0..dcede0c 100644 --- a/lib/src/subscriber.dart +++ b/lib/src/subscriber.dart @@ -1,9 +1,52 @@ -import 'dart:async'; +// Copyright (c) 2021 - 2023 Buijs Software +// +// 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. +import "dart:async"; -import 'package:flutter/services.dart'; -import 'package:flutter/widgets.dart'; +import "package:flutter/services.dart"; +import "package:flutter/widgets.dart"; +/// A widget that receives 0 or more messages of type [T] +/// and automatically updates it and it's dependents state. +/// +/// Example implementation: +/// +/// ```dart +/// const _stream = EventChannel('foo.bar.plugin/channel/counter'); +/// +/// class Counter extends Subscriber { +/// const Counter({ +/// required Widget Function(int?) child, +/// Key? key, +/// }) : super( +/// child: child, +/// channel: _stream, +/// topic: "counter", +/// key: key, +/// ); +/// +/// @override +/// int decode(dynamic json) => json as int; +/// } +/// ``` abstract class Subscriber extends StatefulWidget { + /// Construct a new instance. const Subscriber({ required this.child, required this.channel, @@ -11,10 +54,26 @@ abstract class Subscriber extends StatefulWidget { Key? key, }) : super(key: key); + /// Any widget which wants access to the [T] data stream. final Widget Function(T?) child; + + /// Channel on which to subscribe. final EventChannel channel; + + /// Topic on which to subscribe. + /// + /// Topic values are used to determine if data on a channel + /// is intended for this [Subscriber]. final String topic; + /// Decoding function used to decode data of Type [T]. + /// + /// If [T] is a StandardMessageCodec Type then a simple cast will suffice: + /// + /// ```dart + /// @override + /// int decode(dynamic json) => json as int; + /// ``` T decode(dynamic json); @override diff --git a/test/adapter_test.dart b/test/adapter_test.dart deleted file mode 100644 index 91c25d2..0000000 --- a/test/adapter_test.dart +++ /dev/null @@ -1,39 +0,0 @@ -// Copyright (c) 2021 - 2022 Buijs Software -// -// 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. - -import "package:klutter_ui/klutter_ui.dart"; -import "package:test/test.dart"; - -void main() { - test("Verify factory methods", () { - final ok = AdapterResponse.success("yay"); - expect(ok.isSuccess, true); - expect(ok.object, "yay"); - ok - ..exception = Exception("nay") - ..object = "pff"; - expect(ok.isSuccess, true); - expect(ok.object, "pff"); - - final nok = AdapterResponse.failure(Exception("o shucks")); - expect(nok.isSuccess, false); - expect(nok.exception.toString(), "Exception: o shucks"); - }); -} diff --git a/test/src/publisher_test.dart b/test/src/publisher_test.dart index 318fb72..846561c 100644 --- a/test/src/publisher_test.dart +++ b/test/src/publisher_test.dart @@ -23,28 +23,18 @@ import "package:flutter/widgets.dart"; import "package:klutter_ui/klutter_ui.dart"; import "package:test/test.dart"; -class FakeChannel extends MethodChannel { - FakeChannel(String name) : super(name); - - dynamic expected; - - @override - Future invokeMethod(String method, [ dynamic arguments ]) { - return Future.value(expected as T); - } - -} - void main() { - late MethodChannel channel; - + late MethodChannel brokenChannel; setUp(() { channel = FakeChannel("klutter.foo/publisher/stream"); + brokenChannel = BrokenChannel("klutter.foo/publisher/stream/says/boom"); WidgetsFlutterBinding.ensureInitialized(); }); - test("Execute an event which has no message and expects a standard type response", () async { + test( + "Execute an event which has no message and expects a standard type response", + () async { // given: const configuredEvent = "sayHi"; const expectedResult = "Hi!"; @@ -61,7 +51,136 @@ void main() { // then: expect(result.isSuccess, true); expect(result.object, expectedResult); + }); + + test("All callbacks are ignored if state is not mounted", () async { + // given: + const configuredEvent = "sayHi"; + const expectedResult = "Hi!"; + + // and: + (channel as FakeChannel).expected = expectedResult; + + // when: + final result = await doEvent( + state: const NeverMounted().createState(), + event: configuredEvent, + channel: channel, + onComplete: (str) => throw Exception("Complete!"), + onSuccess: (str) => throw Exception("Success!"), + onFailure: (str) => throw Exception("Failure!"), + ); + + // then: + expect(result.isSuccess, true); + }); + + test("OnFailure is ignored if event was successfully processed", () async { + // given: + const configuredEvent = "sayHi"; + const expectedResult = "Hi!"; + + var success = false; + var completed = false; + + // and: + (channel as FakeChannel).expected = expectedResult; + + // when: + final result = await doEvent( + state: const AlwaysMounted().createState(), + event: configuredEvent, + channel: channel, + onComplete: (str) => completed = true, + onSuccess: (str) => success = true, + onFailure: (str) => throw Exception("Failure!"), + ); + + // then: + expect(result.isSuccess, true); + expect(success, true); + expect(completed, true); + }); + + test("OnSuccess is ignored if event was a failure", () async { + // given: + const configuredEvent = "sayHi"; + + var failure = false; + var completed = false; + + // and: + (brokenChannel as BrokenChannel).message = "Boom!"; + // when: + final result = await doEvent( + state: const AlwaysMounted().createState(), + event: configuredEvent, + channel: channel, + onComplete: (str) => completed = true, + onSuccess: (str) => throw Exception("Success!"), + onFailure: (str) => failure =true, + ); + + // then: + expect(result.isSuccess, false); + expect(failure, true); + expect(completed, true); }); +} + +class FakeChannel extends MethodChannel { + FakeChannel(String name) : super(name); + + dynamic expected; + + @override + Future invokeMethod(String method, [dynamic arguments]) { + return Future.value(expected as T); + } +} + +class BrokenChannel extends MethodChannel { + BrokenChannel(String name) : super(name); + + String? message; + + @override + Future invokeMethod(String method, [dynamic arguments]) { + throw Exception(message); + } +} +class NeverMounted extends StatefulWidget { + const NeverMounted({Key? key}) : super(key: key); + + @override + State createState() => _NeverMountedState(); +} + +class _NeverMountedState extends State { + @override + Widget build(BuildContext context) { + return const Placeholder(); + } + + @override + bool get mounted => false; +} + +class AlwaysMounted extends StatefulWidget { + const AlwaysMounted({Key? key}) : super(key: key); + + @override + State createState() => _AlwaysMountedState(); +} + +class _AlwaysMountedState extends State { + @override + Widget build(BuildContext context) { + return const Placeholder(); + } + + @override + bool get mounted => true; } From 22fa1aaeb62f5ecefdcf6657639d95ff7a3e402d Mon Sep 17 00:00:00 2001 From: buijs Date: Wed, 26 Apr 2023 20:42:04 +0200 Subject: [PATCH 5/6] Release 0.0.1 --- CHANGELOG.md | 2 +- pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a5528c1..d66ffe7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -## 0.1.0 +## 0.0.1 * Initial version containing: * publisher widget * subscriber widget \ No newline at end of file diff --git a/pubspec.yaml b/pubspec.yaml index 37b548c..f196f39 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: klutter_ui description: Flutter widgets to be used in conjunction with the klutter plugin. -version: 0.1.0 +version: 0.0.1 homepage: https://buijs.dev repository: https://github.com/buijs-dev/klutter-dart-ui From 83bb3b1e9b15a42648ca304e37af136c3bcf867e Mon Sep 17 00:00:00 2001 From: buijs Date: Thu, 27 Apr 2023 22:02:27 +0200 Subject: [PATCH 6/6] Release 0.0.2 --- CHANGELOG.md | 3 +++ README.md | 8 ++++---- pubspec.yaml | 2 +- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index d66ffe7..660a93c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,6 @@ +## 0.0.2 +* Cosmetic changes for PUB. + ## 0.0.1 * Initial version containing: * publisher widget diff --git a/README.md b/README.md index 48f3146..b0fc79e 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,6 @@ [![](https://img.shields.io/badge/Buijs-Software-blue)](https://pub.dev/publishers/buijs.dev/packages) -[![GitHub license](https://img.shields.io/github/license/buijs-dev/klutter-dart?color=black&logoColor=black)](https://github.com/buijs-dev/klutter-dart/blob/main/LICENSE) -[![pub](https://img.shields.io/pub/v/klutter-ui)](https://pub.dev/packages/klutter-ui) +[![GitHub license](https://img.shields.io/github/license/buijs-dev/klutter-dart-ui?color=black&logoColor=black)](https://github.com/buijs-dev/klutter-dart-ui/blob/main/LICENSE) +[![pub](https://img.shields.io/pub/v/klutter_ui)](https://pub.dev/packages/klutter_ui) [![codecov](https://codecov.io/gh/buijs-dev/klutter-dart-ui/branch/main/graph/badge.svg?token=z0HCTKNLn5)](https://codecov.io/gh/buijs-dev/klutter-dart-ui) [![CodeScene Code Health](https://codescene.io/projects/38075/status-badges/code-health)](https://codescene.io/projects/38075) @@ -8,8 +8,8 @@ Flutter Widgets to be used in conjunction with the [klutter plugin](https://github.com/buijs-dev/klutter-dart). Full support for: -- [MethodChannel (synchronous)](#MethodChannel) -- [EventChannel (asynchronous)](#EventChannel) +- [MethodChannel](#MethodChannel) +- [EventChannel](#EventChannel) ## MethodChannel Example function which invokes method foo on the given channel and returns a String value. diff --git a/pubspec.yaml b/pubspec.yaml index f196f39..7d0f03d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,6 +1,6 @@ name: klutter_ui description: Flutter widgets to be used in conjunction with the klutter plugin. -version: 0.0.1 +version: 0.0.2 homepage: https://buijs.dev repository: https://github.com/buijs-dev/klutter-dart-ui