Skip to content

Instantly share code, notes, and snippets.

@hoc081098
Created October 2, 2019 16:24
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hoc081098/5e68efa923c98566143c9028b3748dc1 to your computer and use it in GitHub Desktop.
Save hoc081098/5e68efa923c98566143c9028b3748dc1 to your computer and use it in GitHub Desktop.
rx_redux todo
import 'package:flutter/material.dart';
import 'package:rx_redux/rx_redux.dart';
import 'package:rxdart/rxdart.dart';
import 'package:random_string/random_string.dart';
void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(primarySwatch: Colors.red),
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({Key key}) : super(key: key);
@override
_MyHomePageState createState() => _MyHomePageState();
}
// actions
abstract class Action {}
class AddTodo implements Action {
final Todo todo;
AddTodo(this.todo);
}
class RemoveTodo implements Action {
final Todo todo;
RemoveTodo(this.todo);
}
class ToggleTodo implements Action {
final Todo todo;
ToggleTodo(this.todo);
}
class TodoAdded implements Action {
final Todo todo;
TodoAdded(this.todo);
}
class TodoRemoved implements Action {
final Todo todo;
TodoRemoved(this.todo);
}
class TodoToggled implements Action {
final Todo todo;
TodoToggled(this.todo);
}
// view state
class Todo {
final int id;
final String title;
final bool completed;
const Todo(this.id, this.title, this.completed);
}
class ViewState {
final List<Todo> todos;
const ViewState(this.todos);
}
class _MyHomePageState extends State<MyHomePage> {
static var _id = 0;
final actionS = PublishSubject<Action>();
ValueObservable<ViewState> state$;
@override
void initState() {
super.initState();
const initialVS = ViewState([]);
state$ = actionS
.transform(
ReduxStoreStreamTransformer<Action, ViewState>(
initialStateSupplier: () => initialVS,
reducer: (ViewState vs, Action action) {
if (action is AddTodo) return vs;
if (action is RemoveTodo) return vs;
if (action is ToggleTodo) return vs;
if (action is TodoAdded) {
return ViewState([...vs.todos, action.todo]);
}
if (action is TodoRemoved) {
return ViewState(
vs.todos.where((t) => t.id != action.todo.id).toList(),
);
}
if (action is TodoToggled) {
return ViewState(
vs.todos.map((t) {
if (t.id != action.todo.id) {
return t;
} else {
return Todo(
t.id,
t.title,
!t.completed,
);
}
}).toList(),
);
}
return vs;
},
sideEffects: [
(action$, state) {
return action$
.whereType<AddTodo>()
.map((action) => action.todo)
.flatMap((todo) async* {
await Future.delayed(const Duration(milliseconds: 500));
yield TodoAdded(todo);
});
},
(action$, state) {
return action$
.whereType<RemoveTodo>()
.map((action) => action.todo)
.flatMap((todo) async* {
await Future.delayed(const Duration(milliseconds: 500));
yield TodoRemoved(todo);
});
},
(action$, state) {
return action$
.whereType<ToggleTodo>()
.map((action) => action.todo)
.flatMap((todo) async* {
await Future.delayed(const Duration(milliseconds: 500));
yield TodoToggled(todo);
});
},
],
),
)
.shareValueSeeded(initialVS);
}
@override
void dispose() {
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('RxRedux demo'),
),
body: StreamBuilder<ViewState>(
initialData: state$.value,
stream: state$,
builder: (context, snapshot) {
final todos = snapshot.data.todos;
return ListView.builder(
itemCount: todos.length,
itemBuilder: (context, index) {
final todo = todos[index];
return CheckboxListTile(
title: Text(todo.title),
onChanged: (_) => actionS.add(ToggleTodo(todo)),
value: todo.completed,
secondary: IconButton(
icon: Icon(
Icons.delete,
color: Theme.of(context).accentColor,
),
onPressed: () => actionS.add(RemoveTodo(todo)),
),
);
},
);
},
),
floatingActionButton: FloatingActionButton(
child: Icon(Icons.add),
onPressed: () {
actionS.add(
AddTodo(
Todo(
++_id,
randomString(10),
false,
),
),
);
},
),
);
}
}
name: test_flutter
description: A new Flutter project.
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 1.0.0+1
environment:
sdk: ">=2.2.2 <3.0.0"
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^0.1.2
rx_redux: ^1.0.1
rxdart: ^0.22.2
random_string: ^1.1.0
dependency_overrides:
meta: 1.1.6
dev_dependencies:
flutter_test:
sdk: flutter
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware.
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment