1
0
Fork 0

Implement bloc for user switch

bloc
Jonas Franz 2 years ago
parent 3708677863
commit dac07065ff
  1. 10
      lib/app.dart
  2. 37
      lib/bloc/user_bloc.dart
  3. 53
      lib/bloc_provider.dart
  4. 5
      lib/utils/disposable.dart
  5. 33
      lib/widgets/user_switch.dart

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:thesis_shop/bloc/user_bloc.dart';
import 'package:thesis_shop/bloc_provider.dart';
import 'package:thesis_shop/route_key.dart';
import 'package:thesis_shop/screens/cart/cart_screen.dart';
@ -11,11 +12,16 @@ class ThesisShopApp extends StatelessWidget {
const ThesisShopApp({Key? key, required this.productService})
: super(key: key);
BlocProvider setupBlocs() {
return BlocProvider(
userBloc: UserBloc(),
);
}
@override
Widget build(BuildContext context) {
final blocProvider = BlocProvider();
return AppState(
blocs: blocProvider,
blocProvider: setupBlocs(),
child: MaterialApp(
title: 'Thesis Shop',
theme: ThemeData(primarySwatch: Colors.red),

@ -0,0 +1,37 @@
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:thesis_shop/utils/disposable.dart';
@immutable
class UserEvent {
final bool isSignedIn;
const UserEvent({required this.isSignedIn});
}
class UserBloc implements Disposable {
bool _isSignedIn = false;
bool get isSignedIn => _isSignedIn;
final _isSignedInController = StreamController<bool>.broadcast();
Stream<bool> get isSignedInStream => _isSignedInController.stream;
final _userEventController = StreamController<UserEvent>.broadcast();
Sink<UserEvent> get userEventSink => _userEventController.sink;
UserBloc() {
_userEventController.stream.listen(_handleEvent);
}
void _handleEvent(UserEvent event) {
_isSignedIn = event.isSignedIn;
_isSignedInController.add(event.isSignedIn);
}
@override
Future<void> dispose() async {
await _isSignedInController.close();
await _userEventController.close();
}
}

@ -1,26 +1,51 @@
import 'package:flutter/material.dart';
import 'package:flutter/widgets.dart';
import 'package:thesis_shop/bloc/user_bloc.dart';
class BlocProvider {
// TODO TBD
import 'utils/disposable.dart';
class BlocProvider implements Disposable {
final UserBloc userBloc;
const BlocProvider({required this.userBloc});
@override
Future<void> dispose() async {
await Future.wait<void>([
userBloc.dispose(),
]);
}
}
class AppState extends InheritedWidget {
final BlocProvider blocs;
class AppState extends StatefulWidget {
final Widget child;
final BlocProvider blocProvider;
const AppState({
Key? key,
required this.blocs,
required Widget child,
}) : super(key: key, child: child);
required this.blocProvider,
required this.child,
}) : super(key: key);
static AppState of(BuildContext context) {
final AppState? result =
context.dependOnInheritedWidgetOfExactType<AppState>();
assert(result != null, 'No AppState found in context');
return result!;
final AppState? state = context.findAncestorWidgetOfExactType();
if (state == null) {
throw Exception("AppState is not an ancestor of this widget");
}
return state;
}
@override
_AppStateState createState() => _AppStateState();
}
class _AppStateState extends State<AppState> {
@override
Widget build(BuildContext context) {
return widget.child;
}
@override
bool updateShouldNotify(AppState oldWidget) {
return true;
void dispose() {
widget.blocProvider.dispose();
super.dispose();
}
}

@ -0,0 +1,5 @@
import 'dart:async';
abstract class Disposable {
FutureOr<void> dispose();
}

@ -1,5 +1,7 @@
import 'package:flutter/material.dart';
import 'package:thesis_shop/benchmark_counter.dart';
import 'package:thesis_shop/bloc/user_bloc.dart';
import 'package:thesis_shop/bloc_provider.dart';
class UserSwitch extends StatelessWidget {
final bool isOn;
@ -11,17 +13,26 @@ class UserSwitch extends StatelessWidget {
@override
Widget build(BuildContext context) {
BenchmarkCounters.userSwitch++;
return Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.account_circle),
Switch(
value: isOn,
onChanged: onChanged,
activeColor: Colors.green,
)
],
final UserBloc userBloc = AppState.of(context).blocProvider.userBloc;
return StreamBuilder<bool>(
stream: userBloc.isSignedInStream,
initialData: userBloc.isSignedIn,
builder: (context, snapshot) {
BenchmarkCounters.userSwitch++;
return Row(
mainAxisSize: MainAxisSize.min,
children: [
const Icon(Icons.account_circle),
Switch(
value: snapshot.data ?? false,
onChanged: (newValue) => userBloc.userEventSink.add(
UserEvent(isSignedIn: newValue),
),
activeColor: Colors.green,
)
],
);
},
);
}
}

Loading…
Cancel
Save