cubix 0.1.5+2 cubix: ^0.1.5+2 copied to clipboard
A predictable state management library that based on BLoc library. Easy to use and maintenance.
import 'dart:math';
import 'package:cubix/cubix.dart';
import 'package:cubix/cubix_widgets.dart';
import 'package:flutter/material.dart';
void main() {
runApp(const MyApp());
}
class User {
final String name;
final String id;
User(this.id, this.name);
}
final anonymousUser = User('', 'anonymous');
class CurrentUserCubix extends Cubix<User> {
CurrentUserCubix() : super(anonymousUser);
@override
void onInit() {
when((action) {
// listen logout action
if (action is LogoutAction) {
state = anonymousUser;
}
});
}
void rename() {
state = User(state.id, generateUsername());
}
}
String generateUsername() =>
(Random().nextDouble() * 100000).toInt().toRadixString(5);
class LogoutAction {}
class LoginAction extends AsyncAction<void, User> {
@override
Future<void> body() async {
await Future.delayed(const Duration(seconds: 1));
state = User(Random().nextInt(10).toString(), generateUsername());
}
}
class Article {
final String title;
final User author;
Article(this.title, this.author);
}
class ArticleListCubix extends Cubix<List<Article>> {
ArticleListCubix() : super([]);
@override
void onInit() {
final currentUser$ = resolve(CurrentUserCubix.new);
// when current user is changed, update article list
User? lastUser;
watch([currentUser$], (cancelToken) {
// user info is updated only
if (currentUser$.state.id == lastUser?.id) {
updateAuthor(currentUser$.state);
} else {
// user is changed
dispatch(LoadArticleListAction(), cancelToken: cancelToken);
}
lastUser = currentUser$.state;
});
dispatch(LoadArticleListAction());
}
void updateAuthor(User author) {
state = [
for (final article in state) Article(article.title, author),
];
}
}
class LoadArticleListAction extends VoidAsyncAction<List<Article>> {
@override
Future<void> body() async {
final currentUser$ = resolve(CurrentUserCubix.new);
// wait for user ready
final user = await currentUser$.wait();
if (user == anonymousUser) {
// no article for anonymous user
state = [];
} else {
final length = Random().nextInt(10) + 1;
state = [for (var i = 0; i < length; i++) Article('Article $i', user)];
}
}
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Cubix Demo',
theme: ThemeData(primarySwatch: Colors.teal),
home: CubixProvider(
child: Builder(
// make sure the context contains CubixProvider
builder: (context) {
return Scaffold(
appBar: AppBar(
title: const Text('Cubix demo'),
),
body: Center(
child: CurrentUserCubix.new.build((context, cubix) {
if (cubix.loading()) {
return const Text('Loading user profile...');
}
return Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Text('Username: ${cubix.state.name}'),
if (cubix.state != anonymousUser) ...[
ElevatedButton(
// emit event
onPressed: () => cubix.emit(LogoutAction()),
child: const Text('Logout')),
ElevatedButton(
// dispatch method base action
onPressed: () => cubix.rename(),
child: const Text('Rename'))
],
if (cubix.state == anonymousUser)
ElevatedButton(
// dispatch class base action
onPressed: () => cubix.dispatch(LoginAction()),
child: const Text('Login')),
const Text('Articles:'),
ArticleListCubix.new.build((context, cubix) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
children: [
if (cubix.state.isEmpty) const Text('No article'),
for (final article in cubix.state)
Text(
'${article.title} (${article.author.name} - ${article.author.id})'),
],
);
})
],
);
}),
),
);
},
),
),
);
}
}