Skip to content

Commit

Permalink
Proxy provider (rrousselGit#59)
Browse files Browse the repository at this point in the history
  • Loading branch information
rrousselGit authored Jun 1, 2019
1 parent 486f74c commit 59231f1
Show file tree
Hide file tree
Showing 30 changed files with 2,045 additions and 260 deletions.
6 changes: 6 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,10 +12,16 @@ before_script:
script:
# abort on error
- set -e

- flutter packages get
- flutter format --set-exit-if-changed lib example test
- flutter analyze --no-current-package lib test/ example/
- flutter test --no-pub --coverage
- set +e # disable abort on error for the `cd`, otherwise the CI unexpectedly stops
- cd example/
- set -e
- flutter test --no-pub --coverage

# export coverage
- bash <(curl -s https://codecov.io/bash)
cache:
Expand Down
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@

## non-breaking:

- Added `ProxyProvider`, `ListenableProxyProvider`, and `ChangeNotifierProxyProvider`.
These providers allows building values that depends on other providers,
without loosing reactivity or manually handling the state.
- Added `DelegateWidget` and a few related classes to help building custom providers.
- Exposed the internal generic `InheritedWidget` to help building custom providers.

Expand Down
70 changes: 70 additions & 0 deletions example/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
# Miscellaneous
*.class
*.log
*.pyc
*.swp
.DS_Store
.atom/
.buildlog/
.history
.svn/

# IntelliJ related
*.iml
*.ipr
*.iws
.idea/

# Visual Studio Code related
.vscode/

# Flutter/Dart/Pub related
**/doc/api/
.dart_tool/
.flutter-plugins
.packages
.pub-cache/
.pub/
/build/

# Android related
**/android/**/gradle-wrapper.jar
**/android/.gradle
**/android/captures/
**/android/gradlew
**/android/gradlew.bat
**/android/local.properties
**/android/**/GeneratedPluginRegistrant.java

# iOS/XCode related
**/ios/**/*.mode1v3
**/ios/**/*.mode2v3
**/ios/**/*.moved-aside
**/ios/**/*.pbxuser
**/ios/**/*.perspectivev3
**/ios/**/*sync/
**/ios/**/.sconsign.dblite
**/ios/**/.tags*
**/ios/**/.vagrant/
**/ios/**/DerivedData/
**/ios/**/Icon?
**/ios/**/Pods/
**/ios/**/.symlinks/
**/ios/**/profile
**/ios/**/xcuserdata
**/ios/.generated/
**/ios/Flutter/App.framework
**/ios/Flutter/Flutter.framework
**/ios/Flutter/Generated.xcconfig
**/ios/Flutter/app.flx
**/ios/Flutter/app.zip
**/ios/Flutter/flutter_assets/
**/ios/ServiceDefinitions.json
**/ios/Runner/GeneratedPluginRegistrant.*

# Exceptions to above rules.
!**/ios/**/default.mode1v3
!**/ios/**/default.mode2v3
!**/ios/**/default.pbxuser
!**/ios/**/default.perspectivev3
!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages
10 changes: 10 additions & 0 deletions example/.metadata
Original file line number Diff line number Diff line change
@@ -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: b593f5167bce84fb3cad5c258477bf3abc1b14eb
channel: unknown

project_type: app
125 changes: 125 additions & 0 deletions example/lib/main.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
// ignore_for_file: public_member_api_docs
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';

void main() => runApp(MyApp());

class Counter with ChangeNotifier {
int _count = 0;
int get count => _count;

void increment() {
_count++;
notifyListeners();
}
}

class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MultiProvider(
providers: [
ChangeNotifierProvider(builder: (_) => Counter()),
],
child: Consumer<Counter>(
builder: (context, counter, _) {
return MaterialApp(
supportedLocales: const [Locale('en')],
localizationsDelegates: [
DefaultMaterialLocalizations.delegate,
DefaultWidgetsLocalizations.delegate,
_ExampleLocalizationsDelegate(counter.count),
],
home: const MyHomePage(),
);
},
),
);
}
}

class ExampleLocalizations {
static ExampleLocalizations of(BuildContext context) =>
Localizations.of<ExampleLocalizations>(context, ExampleLocalizations);

const ExampleLocalizations(this._count);

final int _count;

String get title => 'Tapped $_count times';
}

class _ExampleLocalizationsDelegate
extends LocalizationsDelegate<ExampleLocalizations> {
const _ExampleLocalizationsDelegate(this.count);

final int count;

@override
bool isSupported(Locale locale) => locale.languageCode == 'en';

@override
Future<ExampleLocalizations> load(Locale locale) =>
SynchronousFuture(ExampleLocalizations(count));

@override
bool shouldReload(_ExampleLocalizationsDelegate old) => old.count != count;
}

class MyHomePage extends StatelessWidget {
const MyHomePage({Key key}) : super(key: key);

@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Title()),
body: const Center(child: CounterLabel()),
floatingActionButton: const IncrementCounterButton(),
);
}
}

class IncrementCounterButton extends StatelessWidget {
const IncrementCounterButton({Key key}) : super(key: key);

@override
Widget build(BuildContext context) {
return FloatingActionButton(
onPressed: Provider.of<Counter>(context).increment,
tooltip: 'Increment',
child: const Icon(Icons.add),
);
}
}

class CounterLabel extends StatelessWidget {
const CounterLabel({Key key}) : super(key: key);

@override
Widget build(BuildContext context) {
final counter = Provider.of<Counter>(context);
return Column(
mainAxisSize: MainAxisSize.min,
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'${counter.count}',
style: Theme.of(context).textTheme.display1,
),
],
);
}
}

class Title extends StatelessWidget {
const Title({Key key}) : super(key: key);

@override
Widget build(BuildContext context) {
return Text(ExampleLocalizations.of(context).title);
}
}
51 changes: 0 additions & 51 deletions example/provider.dart

This file was deleted.

28 changes: 0 additions & 28 deletions example/provider_value.dart

This file was deleted.

9 changes: 6 additions & 3 deletions example/pubspec.yaml
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
name: example
version: 1.0.0
homepage: https://github.com/rrousselGit/provider
homepage: https://github.com/rrousselGit/provider
author: Remi Rousselet <[email protected]>

environment:
sdk: ">=2.0.0 <3.0.0"
sdk: ">=2.1.0 <3.0.0"

dependencies:
flutter:
sdk: flutter
provider: 1.1.1
provider:

dev_dependencies:
flutter_test:
Expand All @@ -18,3 +18,6 @@ dev_dependencies:
dependency_overrides:
provider:
path: ../

flutter:
uses-material-design: true
35 changes: 35 additions & 0 deletions example/test/widget_test.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// This is a basic Flutter widget test.
//
// To perform an interaction with a widget in your test, use the WidgetTester
// utility that Flutter provides. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.

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

import 'package:example/main.dart' as example;

void main() {
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
// Build our app and trigger a frame.

example.main();

// Verify that our counter starts at 0.
expect(find.text('0'), findsOneWidget);
expect(find.text('1'), findsNothing);
expect(find.text('Tapped 0 times'), findsOneWidget);
expect(find.text('Tapped 1 times'), findsNothing);

// Tap the '+' icon and trigger a frame.
await tester.tap(find.byIcon(Icons.add));
await tester.pump();

// Verify that our counter has incremented.
expect(find.text('0'), findsNothing);
expect(find.text('1'), findsOneWidget);
expect(find.text('Tapped 0 times'), findsNothing);
expect(find.text('Tapped 1 times'), findsOneWidget);
});
}
3 changes: 3 additions & 0 deletions lib/provider.dart
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
library provider;

export 'src/async_provider.dart';
export 'src/change_notifier_provider.dart';
export 'src/consumer.dart';
export 'src/delegate_widget.dart';
export 'src/listenable_provider.dart';
export 'src/provider.dart';
export 'src/proxy_provider.dart' hide NumericProxyProvider, Void;
export 'src/value_listenable_provider.dart';
Loading

0 comments on commit 59231f1

Please sign in to comment.