Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

- Updated library to null-safety #21

Merged
merged 3 commits into from
May 26, 2021
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file removed build/testfile.dill
Binary file not shown.
Binary file removed build/testfile.dill.track.dill
Binary file not shown.
3 changes: 2 additions & 1 deletion example/analysis_options.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,8 @@ analyzer:
unused_local_variable: error
dead_code: error
exclude:
- example/lib/json/weather_in_cities.g.dart
- lib/service/json/weather_in_cities.g.dart


linter:
rules:
Expand Down
3 changes: 0 additions & 3 deletions example/android/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@ android {
}

defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId "com.example.flutterweatherdemo"
minSdkVersion 16
targetSdkVersion 27
Expand All @@ -33,8 +32,6 @@ android {

buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig signingConfigs.debug
}
}
Expand Down
5 changes: 2 additions & 3 deletions example/ios/Flutter/flutter_export_environment.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,10 @@ export "FLUTTER_APPLICATION_PATH=/Users/oleksandr.babich/development/rx/rx_widge
export "FLUTTER_TARGET=/Users/oleksandr.babich/development/rx/rx_widgets/example/lib/main.dart"
export "FLUTTER_BUILD_DIR=build"
export "SYMROOT=${SOURCE_ROOT}/../build/ios"
export "OTHER_LDFLAGS=$(inherited) -framework Flutter"
export "FLUTTER_FRAMEWORK_DIR=/Users/oleksandr.babich/development/flutter/bin/cache/artifacts/engine/ios"
export "FLUTTER_BUILD_NAME=1.0.0"
export "FLUTTER_BUILD_NUMBER=1"
export "DART_DEFINES=flutter.inspector.structuredErrors%3Dtrue"
export "DART_OBFUSCATION=false"
export "TRACK_WIDGET_CREATION=true"
export "TREE_SHAKE_ICONS=false"
export "PACKAGE_CONFIG=.packages"
export "PACKAGE_CONFIG=/Users/oleksandr.babich/development/rx/rx_widgets/example/.dart_tool/package_config.json"

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

156 changes: 156 additions & 0 deletions example/lib/homepage/home_page.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
import 'package:flutter/material.dart';
import 'package:rx_widget_demo/homepage/weather_list_view.dart';
import 'package:rx_widget_demo/keys.dart';
import 'package:rx_widget_demo/model_provider.dart';
import 'package:rx_widget_demo/service/weather_entry.dart';
import 'package:rx_widgets/rx_widgets.dart';

// ignore_for_file: deprecated_member_use

const noResultsText = 'No matching city data found. Try refining search.';

class HomePage extends StatelessWidget {
final TextEditingController _controller = TextEditingController();

HomePage({
Key? key,
}) : super(key: key);

@override
Widget build(BuildContext context) {
final homePageModel = ModelProvider.of(context);
/*return Scaffold(
appBar: AppBar(title: AppBar(title: Text('WeatherDemo'))),
resizeToAvoidBottomInset: false,
body: SafeArea(
child: Column(
children: [
Padding(
padding: const EdgeInsets.all(16.0),
child: TextField(
key: AppKeys.textField,
autocorrect: false,
controller: _controller,
decoration: InputDecoration(
hintText: "Filter cities",
),
style: TextStyle(
fontSize: 20.0,
),
onChanged: (s) => homePageModel.textChangedCommand(s),
// onChanged: ModelProvider.of(context).textChangedCommand,
),
),
Text('My Message'),
],
),
),
);*/
return Scaffold(
appBar: AppBar(title: Text("WeatherDemo")),
resizeToAvoidBottomInset: false,
body: SafeArea(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.all(16.0),
child: TextField(
key: AppKeys.textField,
autocorrect: false,
controller: _controller,
decoration: InputDecoration(hintText: "Filter cities"),
style: TextStyle(
fontSize: 20.0,
),
onChanged: (s) => homePageModel.textChangedCommand(s),
),
),
Expanded(
child: RxLoader<List<WeatherEntry>>(
spinnerKey: AppKeys.loadingSpinner,
radius: 25.0,
commandResults: homePageModel.updateWeatherCommand.results,
dataBuilder: (_, data) {
if (data.isEmpty) return Center(child: Text(noResultsText));
return WeatherListView(data, key: AppKeys.weatherList);
},
placeHolderBuilder: (_) => Center(
key: AppKeys.loaderPlaceHolder, child: Text("No Data")),
errorBuilder: (_, ex) => Center(
key: AppKeys.loaderError,
child: Text("Error: ${ex.toString()}")),
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: <Widget>[
Expanded(
// This might be solved with a StreamBuilder to but it should show `WidgetSelector`
child: WidgetSelector(
key: AppKeys.widgetSelector,
buildEvents:
homePageModel.updateWeatherCommand.canExecute,
//We access our ViewModel through the inherited Widget
onTrue: RaisedButton(
key: AppKeys.updateButtonEnabled,
child: Text("Update"),
onPressed: () {
_controller.clear();
homePageModel.updateWeatherCommand('');
},
),
onFalse: RaisedButton(
key: AppKeys.updateButtonDisabled,
child: Text("Please Wait"),
onPressed: null,
),
),
),
StateFullSwitch(
state: true,
onChanged: (b) => homePageModel.switchChangedCommand(b),
// onChanged: homePageModel.switchChangedCommand,
),
],
),
),
],
),
),
);
}
}

/// As the normal switch does not even remember and display its current state
/// we us this one
class StateFullSwitch extends StatefulWidget {
final bool state;
final ValueChanged<bool> onChanged;

StateFullSwitch({required this.state, required this.onChanged});

@override
StateFullSwitchState createState() {
return StateFullSwitchState(state, onChanged);
}
}

class StateFullSwitchState extends State<StateFullSwitch> {
bool state;
ValueChanged<bool> handler;

StateFullSwitchState(this.state, this.handler);

@override
Widget build(BuildContext context) {
return Switch(
key: AppKeys.updateSwitch,
value: state,
onChanged: (b) {
setState(() => state = b);
handler(b);
},
);
}
}
120 changes: 0 additions & 120 deletions example/lib/homepage/homepage.dart

This file was deleted.

15 changes: 8 additions & 7 deletions example/lib/homepage/homepage_model.dart
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@

import 'package:rx_command/rx_command.dart';
import 'package:rxdart/rxdart.dart';
import 'package:rx_widget_demo/service/weather_service.dart';
import 'package:rx_widget_demo/service/weather_entry.dart';
import 'package:rx_widget_demo/service/weather_service.dart';
import 'package:rxdart/rxdart.dart';

class HomePageModel {
final WeatherService service;
Expand All @@ -17,7 +16,7 @@ class HomePageModel {
this.service,
);

factory HomePageModel(WeatherService service ) {
factory HomePageModel(WeatherService service) {
// Command expects a bool value when executed and issues the value on it's
// result Observable (stream)
final _switchChangedCommand = RxCommand.createSync<bool, bool>((b) => b);
Expand All @@ -26,22 +25,24 @@ class HomePageModel {
// the updateWeatherCommand
final _updateWeatherCommand =
RxCommand.createAsync<String, List<WeatherEntry>>(
service.getWeatherEntriesForCity, canExecute: _switchChangedCommand);
(city) => service.getWeatherEntriesForCity(city),
restriction: _switchChangedCommand,
);

// Will be called on every change of the search field
final _textChangedCommand = RxCommand.createSync<String, String>((s) => s);

// When the user starts typing
_textChangedCommand
// Wait for the user to stop typing for 500ms
.debounceTime( Duration(milliseconds: 500))
.debounceTime(Duration(milliseconds: 500))
// Then call the updateWeatherCommand
.listen(_updateWeatherCommand);

// Update data on startup
_updateWeatherCommand('');

return HomePageModel._(
return HomePageModel._(
_updateWeatherCommand,
_switchChangedCommand,
_textChangedCommand,
Expand Down
Loading