diff --git a/CHANGELOG.md b/CHANGELOG.md index 41cc7d8..260d5d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ +##0.1.0-nullsafety-0 + +- Implemented Sound Null Safety 💪 + ## 0.0.1 -* TODO: Describe initial release. +- Inported code from the parent package, https://github.com/mmcc007/modal_progress_hud diff --git a/README.md b/README.md index e183073..125aa39 100644 --- a/README.md +++ b/README.md @@ -1,15 +1,144 @@ -# modal_progress_hud_nsn +# modal_progress_hud -A new flutter plugin project. +A simple widget wrapper to enable modal progress HUD (a modal progress indicator, HUD = Heads Up Display) -## Getting Started +[![pub package](https://img.shields.io/pub/v/modal_progress_hud_nsn.svg)](https://pub.dartlang.org/packages/modal_progress_hud_nsn) -This project is a starting point for a Flutter -[plug-in package](https://flutter.dev/developing-packages/), -a specialized package that includes platform-specific implementation code for -Android and/or iOS. +Inspired by [this](https://codingwithjoe.com/flutter-how-to-build-a-modal-progress-indicator/) article. -For help getting started with Flutter, view our -[online documentation](https://flutter.dev/docs), which offers tutorials, -samples, guidance on mobile development, and a full API reference. +A fork of [this](https://github.com/mmcc007/modal_progress_hud) with support for Null Safety. +## Demo + +![Demo](https://raw.githubusercontent.com/mmcc007/modal_progress_hud/master/modal_progress_hud.gif) + +_See example for details_ + +## Usage + +Add the package to your `pubspec.yml` file. + +```yml +dependencies: + modal_progress_hud_nsn: ^0.1.0-nullsafety-0 +``` + +Next, import the library into your widget. + +```dart +import 'package:modal_progress_hud/modal_progress_hud.dart'; +``` + +Now, all you have to do is simply wrap your widget as a child of `ModalProgressHUD`, typically a form, together with a boolean that is maintained in local state. + +```dart +... +bool _saving = false +... + +@override +Widget build(BuildContext context) { + return Scaffold( + body: ModalProgressHUD(child: Container( + Form(...) + ), inAsyncCall: _saving), + ); +} +``` + +## Options + +The current parameters are customizable in the constructor + +```dart +ModalProgressHUD( + @required inAsyncCall: bool, + @required child: Widget, + opacity: double, + color: Color, + progressIndicator: CircularProgressIndicator, + offset: double + dismissible: bool, +); +``` + +## Example + +Here is an example app that demonstrates the usage. + +1. On initial load, `_saving` is false which causes your child widget to display +2. When the form is submitted, `_saving` is set to true, which will display the modal +3. Once the async call is complete, `_saving` is set back to false, hiding the modal + +```dart +class SettingsPage extends StatefulWidget { + @override + _SettingsPageState createState() => new _SettingsPageState(); +} + +class _SettingsPageState extends State { + bool _saving = false; + + void _submit() { + + setState(() { + _saving = true; + }); + + //Simulate a service call + print('submitting to backend...'); + new Future.delayed(new Duration(seconds: 4), () { + setState(() { + _saving = false; + }); + }); + } + + Widget _buildWidget() { + return new Form( + child: new Column( + children: [ + new SwitchListTile( + title: const Text('Bedroom'), + value: _bedroom, + onChanged: (bool value) { + setState(() { + _bedroom = value; + }); + }, + secondary: const Icon(Icons.hotel), + ), + new RaisedButton( + onPressed: _submit, + child: new Text('Save'), + ), + ], + ), + ); + } + + @override + Widget build(BuildContext context) { + return new Scaffold( + appBar: new AppBar( + title: new Text('Flutter Progress Indicator Demo'), + backgroundColor: Colors.blue, + ), + body: ModalProgressHUD(child: _buildWidget(), inAsyncCall: _saving), + ); + } +} + +``` + +Update: See this [article](https://medium.com/@nocnoc/the-secret-to-async-validation-on-flutter-forms-4b273c667c03) on Medium about async form validation + +See the [example application](https://github.com/kphanipavan/modal_progress_hud_nsn/tree/master/example) source +for a complete sample app using the modal progress HUD. Included in the +example is a method for using a form's validators while making async +calls (see [flutter/issues/9688](https://github.com/flutter/flutter/issues/9688) for details). + +### Issues and feedback + +Please file [issues](https://github.com/kphanipavan/modal_progress_hud_nsn/issues/new) +to send feedback or report a bug. Thank you! diff --git a/example/lib/main.dart b/example/lib/main.dart index 0359d99..5eac13f 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -22,7 +22,7 @@ class MyApp extends StatelessWidget { class LoginPage extends StatefulWidget { final VoidCallback _onSignIn; - LoginPage({@required onSignIn}) + LoginPage({required onSignIn}) : assert(onSignIn != null), _onSignIn = onSignIn; @@ -40,13 +40,13 @@ class _LoginPageState extends State { bool _isInvalidAsyncUser = false; // managed after response from server bool _isInvalidAsyncPass = false; // managed after response from server - String _username; - String _password; + String? _username; + String? _password; bool _isLoggedIn = false; // validate user name - String _validateUserName(String userName) { - if (userName.length < 8) { + String? _validateUserName(String? userName) { + if (userName!.length < 8) { return 'Username must be at least 8 characters'; } @@ -60,8 +60,8 @@ class _LoginPageState extends State { } // validate password - String _validatePassword(String password) { - if (password.length < 8) { + String? _validatePassword(String? password) { + if (password!.length < 8) { return 'Password must be at least 8 characters'; } @@ -75,8 +75,8 @@ class _LoginPageState extends State { } void _submit() { - if (_loginFormKey.currentState.validate()) { - _loginFormKey.currentState.save(); + if (_loginFormKey.currentState!.validate()) { + _loginFormKey.currentState!.save(); // dismiss keyboard during async call FocusScope.of(context).requestFocus(new FocusNode()); @@ -154,7 +154,7 @@ class _LoginPageState extends State { key: Key('username'), decoration: InputDecoration( hintText: 'enter username', labelText: 'User Name'), - style: TextStyle(fontSize: 20.0, color: textTheme.button.color), + style: TextStyle(fontSize: 20.0, color: textTheme.button!.color), validator: _validateUserName, onSaved: (value) => _username = value, ), @@ -166,7 +166,7 @@ class _LoginPageState extends State { obscureText: true, decoration: InputDecoration( hintText: 'enter password', labelText: 'Password'), - style: TextStyle(fontSize: 20.0, color: textTheme.button.color), + style: TextStyle(fontSize: 20.0, color: textTheme.button!.color), validator: _validatePassword, onSaved: (value) => _password = value, ), diff --git a/example/pubspec.lock b/example/pubspec.lock index ae22759..a6dc2cc 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -157,5 +157,5 @@ packages: source: hosted version: "2.1.0" sdks: - dart: ">=2.12.0-0.0 <3.0.0" + dart: ">=2.12.0 <3.0.0" flutter: ">=1.20.0" diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 65c3af7..2fb652c 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -6,7 +6,7 @@ description: Demonstrates how to use the modal_progress_hud_nsn plugin. publish_to: 'none' # Remove this line if you wish to publish to pub.dev environment: - sdk: ">=2.7.0 <3.0.0" + sdk: '>=2.12.0 <3.0.0' dependencies: flutter: diff --git a/example/test/widget_test.dart b/example/test/widget_test.dart index 078f291..99ebb15 100644 --- a/example/test/widget_test.dart +++ b/example/test/widget_test.dart @@ -19,7 +19,7 @@ void main() { expect( find.byWidgetPredicate( (Widget widget) => widget is Text && - widget.data.startsWith('Running on:'), + widget.data!.startsWith('Running on:'), ), findsOneWidget, ); diff --git a/lib/modal_progress_hud_nsn.dart b/lib/modal_progress_hud_nsn.dart index da9186d..1f4da3f 100644 --- a/lib/modal_progress_hud_nsn.dart +++ b/lib/modal_progress_hud_nsn.dart @@ -27,22 +27,20 @@ class ModalProgressHUD extends StatelessWidget { final double opacity; final Color color; final Widget progressIndicator; - final Offset offset; + final Offset? offset; final bool dismissible; final Widget child; ModalProgressHUD({ - Key key, - @required this.inAsyncCall, + Key? key, + required this.inAsyncCall, this.opacity = 0.3, this.color = Colors.grey, this.progressIndicator = const CircularProgressIndicator(), this.offset, this.dismissible = false, - @required this.child, - }) : assert(child != null), - assert(inAsyncCall != null), - super(key: key); + required this.child, + }) : super(key: key); @override Widget build(BuildContext context) { @@ -54,8 +52,8 @@ class ModalProgressHUD extends StatelessWidget { else { layOutProgressIndicator = Positioned( child: progressIndicator, - left: offset.dx, - top: offset.dy, + left: offset!.dx, + top: offset!.dy, ); } diff --git a/pubspec.lock b/pubspec.lock index ef01c9f..6870ad1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,6 +1,27 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + url: "https://pub.dartlang.org" + source: hosted + version: "16.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" async: dependency: transitive description: @@ -29,6 +50,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" + cli_util: + dependency: transitive + description: + name: cli_util + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.0" clock: dependency: transitive description: @@ -43,6 +71,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.15.0" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" + coverage: + dependency: transitive + description: + name: coverage + url: "https://pub.dartlang.org" + source: hosted + version: "0.15.2" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" fake_async: dependency: transitive description: @@ -50,6 +99,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.0" flutter: dependency: "direct main" description: flutter @@ -60,6 +116,48 @@ packages: description: flutter source: sdk version: "0.0.0" + glob: + dependency: transitive + description: + name: glob + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" + http_parser: + dependency: transitive + description: + name: http_parser + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" + io: + dependency: transitive + description: + name: io + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.4" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.3" + logging: + dependency: transitive + description: + name: logging + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" matcher: dependency: transitive description: @@ -74,6 +172,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.3.0" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + node_preamble: + dependency: transitive + description: + name: node_preamble + url: "https://pub.dartlang.org" + source: hosted + version: "1.4.13" + package_config: + dependency: transitive + description: + name: package_config + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" path: dependency: transitive description: @@ -81,11 +200,74 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.8.0" + pedantic: + dependency: transitive + description: + name: pedantic + url: "https://pub.dartlang.org" + source: hosted + version: "1.10.0" + pool: + dependency: transitive + description: + name: pool + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + pub_semver: + dependency: transitive + description: + name: pub_semver + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" + shelf: + dependency: transitive + description: + name: shelf + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + shelf_packages_handler: + dependency: transitive + description: + name: shelf_packages_handler + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" + shelf_static: + dependency: transitive + description: + name: shelf_static + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.9+2" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + url: "https://pub.dartlang.org" + source: hosted + version: "0.2.4" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.99" + source_map_stack_trace: + dependency: transitive + description: + name: source_map_stack_trace + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" + source_maps: + dependency: transitive + description: + name: source_maps + url: "https://pub.dartlang.org" + source: hosted + version: "0.10.10" source_span: dependency: transitive description: @@ -121,6 +303,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" + test: + dependency: "direct dev" + description: + name: test + url: "https://pub.dartlang.org" + source: hosted + version: "1.16.2" test_api: dependency: transitive description: @@ -128,6 +317,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.2.19" + test_core: + dependency: transitive + description: + name: test_core + url: "https://pub.dartlang.org" + source: hosted + version: "0.3.13" typed_data: dependency: transitive description: @@ -142,6 +338,41 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + vm_service: + dependency: transitive + description: + name: vm_service + url: "https://pub.dartlang.org" + source: hosted + version: "6.0.1" + watcher: + dependency: transitive + description: + name: watcher + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + webkit_inspection_protocol: + dependency: transitive + description: + name: webkit_inspection_protocol + url: "https://pub.dartlang.org" + source: hosted + version: "0.7.5" + yaml: + dependency: transitive + description: + name: yaml + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.0" sdks: - dart: ">=2.12.0-0.0 <3.0.0" + dart: ">=2.12.0 <3.0.0" flutter: ">=1.20.0" diff --git a/pubspec.yaml b/pubspec.yaml index 77db342..1df2abb 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,11 +1,11 @@ name: modal_progress_hud_nsn description: A modal progress indicator widget with Sound Null Safety. A fork of https://github.com/mmcc007/modal_progress_hud version: 0.1.0-nullsafety-0 -author: Phani Pavan K -homepage: +#author: Phani Pavan K +homepage: https://github.com/kphanipavan/modal_progress_hud_nsn environment: - sdk: ">=2.7.0 <3.0.0" + sdk: '>=2.12.0 <3.0.0' flutter: ">=1.20.0" dependencies: @@ -15,6 +15,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter + test: ^1.16.2 flutter: plugin: diff --git a/test/modal_progress_hud_nsn_test.dart b/test/modal_progress_hud_nsn_test.dart index 53371a9..66aad5e 100644 --- a/test/modal_progress_hud_nsn_test.dart +++ b/test/modal_progress_hud_nsn_test.dart @@ -5,7 +5,7 @@ import 'package:modal_progress_hud_nsn/modal_progress_hud_nsn.dart'; void main() { group('Modal Progress HUD', () { - Widget sut(bool inAsyncCall, Offset offset) { + Widget sut(bool inAsyncCall, Offset? offset) { return MaterialApp( home: new ModalProgressHUD( inAsyncCall: inAsyncCall,