osam_flutter 3.3.2 osam_flutter: ^3.3.2 copied to clipboard
Navigation and UI elements which fits with Osam library
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:osam_flutter/osam_flutter.dart';
part 'main.g.dart';
final navKey = GlobalKey<NavigatorState>();
final currentContext = navKey.currentState.overlay.context;
EdgeInsets logicalPadding;
const version = 5;
void main() async {
WidgetsFlutterBinding.ensureInitialized();
final persist = Persist<AppState, UIState>(appName: 'test');
registerOsamFlutterAdapters();
Hive.registerAdapter(AppStateAdapter());
Hive.registerAdapter(UIStateAdapter());
Hive.registerAdapter(FirstRouteAdapter());
Hive.registerAdapter(SecondRouteAdapter());
Hive.registerAdapter(DialogRouteAdapter());
Hive.registerAdapter(CounterAdapter());
final persistedVersion = await persist.version;
if ((persistedVersion ?? -1) < version) {
await persist.delete();
}
await persist.init();
final appState = persist.appState ?? AppState();
final uiState = persist.uiState ?? UIState();
final window = WidgetsBinding.instance.window;
final devicePR = window.devicePixelRatio;
logicalPadding = EdgeInsets.fromWindowPadding(window.padding, devicePR);
runApp(OsamProvider(
appState: appState,
uiState: uiState,
version: version,
child: PersistLifecycleWrapper(
persist: persist,
child: PresenterProvider(
presenter: AppPresenter(),
child: OsamNotification(
child: MaterialApp(
navigatorKey: navKey,
home: RootScreen(),
),
),
),
),
));
}
class RootScreen extends StatelessWidget {
@override
Widget build(BuildContext context) {
return OsamNavigator<AppPresenter>(
routes: {
FirstRoute: (ctx) => PresenterProvider(
child: Screen(),
presenter: ScreenPresenter(FirstRoute),
),
SecondRoute: (ctx) => PresenterProvider(
child: Screen(),
presenter: ScreenPresenter(SecondRoute),
),
},
dialogs: {
DialogRoute: (ctx) async => showDialog(
context: ctx,
child: PresenterProvider(
presenter: DialogPresenter(),
child: Builder(
builder: (context) {
final presenter = context.presenter<DialogPresenter>();
return Material(
child: Column(
children: <Widget>[
Text(presenter.cameFrom),
RaisedButton(
onPressed: () {
presenter.findRoute<DialogRoute>().result =
'result from dialog';
},
)
],
),
);
},
),
))
},
);
}
}
class Screen extends StatefulWidget {
@override
_ScreenState createState() => _ScreenState();
}
class _ScreenState extends State<Screen> with AfterLayoutMixin {
TextEditingController textEditingController;
@override
void initState() {
textEditingController = TextEditingController();
super.initState();
}
@override
void afterFirstLayout(BuildContext context) {
final presenter = context.presenter<ScreenPresenter>();
textEditingController.addListener(() {
presenter.uiState.login = textEditingController.text;
});
textEditingController.text = presenter.uiState.login;
}
@override
Widget build(BuildContext context) {
final presenter = context.presenter<ScreenPresenter>();
return Scaffold(
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
if (presenter.route == FirstRoute)
CupertinoSwitch(
value: presenter.uiState.isSelected,
onChanged: (value) {
setState(() {
presenter.uiState.isSelected =
!presenter.uiState.isSelected;
});
},
),
if (presenter.route == FirstRoute)
TextField(
controller: textEditingController,
),
if (presenter.route == FirstRoute)
RaisedButton(
child: Text('to other screen'),
onPressed: () {
presenter.pushOther();
// showNotification(
// padding: EdgeInsets.all(200),
// safeAreaPadding: logicalPadding,
// animationDuration: Duration(seconds: 2),
// child: Container(
// width: 200,
// height: 300,
// color: Colors.red,
// child: Icon(Icons.notification_important),
// alignment: Alignment.center,
// ));
},
),
if (presenter.route == SecondRoute)
RaisedButton(
child: Text('set result'),
onPressed: () => presenter.setResult(),
),
RaisedButton(
onPressed: presenter.increment,
child: ValueListenableBuilder(
valueListenable: presenter.counterValue,
builder: (_, value, __) => Text(value.toString()),
),
)
],
),
),
floatingActionButton: FloatingActionButton(
onPressed: () {
presenter.showDialog();
},
),
);
}
}
// presenters
class AppPresenter extends Presenter<UIState, AppState>
with NavigationPresenter {
@override
Navigation get navigation => uiState.appNavigation;
}
class ScreenPresenter extends Presenter<UIState, AppState>
with NavigationPresenter {
final Type route;
ScreenPresenter(this.route);
@override
Navigation get navigation => uiState.appNavigation;
IProperty<int> get counterValue => appState.counter.value;
void increment() => appState.counter.increment();
@override
void init() {
if (route == FirstRoute) {
findRoute<SecondRoute>()?.whenComplete?.then(handleRouteResult);
}
super.init();
}
void pushOther() =>
push(SecondRoute('arg from other screen')).then(handleRouteResult);
void handleRouteResult(int value) {
push(DialogRoute(value)).then((value) {
print('got result from dialog $value');
});
}
void setResult() {
if (currentRoute is SecondRoute) {
setRouteResult<SecondRoute>(123);
}
}
Future<String> showDialog() => push(DialogRoute(0));
}
class DialogPresenter extends Presenter<UIState, AppState>
with NavigationPresenter {
@override
Navigation get navigation => uiState.appNavigation;
String get cameFrom {
return findRoute<DialogRoute>().argument.toString();
}
}
@HiveType(typeId: hiveID.appState)
class AppState {
@HiveField(0)
var counter = Counter();
}
@HiveType(typeId: hiveID.counter)
class Counter extends PropertyChanger {
@HiveField(0)
final IProperty<int> value;
Counter({IProperty<int> value}) : value = value ?? IProperty(0);
void increment() => let(value).apply((value) => value++);
}
@HiveType(typeId: hiveID.UIState)
class UIState {
@HiveField(0)
var appNavigation = Navigation([FirstRoute()]);
@HiveField(1)
var appTabNavigation = TabNavigation(tabs.first);
@HiveField(2)
var isSelected = false;
@HiveField(3)
var login = '';
}
@HiveType(typeId: hiveID.firstRoute)
class FirstRoute extends OsamRoute {}
@HiveType(typeId: hiveID.secondRoute)
class SecondRoute extends OsamRoute<int> {
@HiveField(0)
final String argument;
@HiveField(1)
@override
var result = 0;
SecondRoute(this.argument);
}
@HiveType(typeId: hiveID.dialog)
class DialogRoute extends OsamRoute<String> {
@HiveField(0)
final int argument;
@HiveField(1)
@override
var result = '';
DialogRoute(this.argument);
}
// ignore: camel_case_types
abstract class tabs {
static const first = 'first';
static const second = 'second';
}
// ignore: camel_case_types
abstract class hiveID {
static const appState = 0;
static const counter = 1;
static const UIState = 2;
static const firstRoute = 3;
static const secondRoute = 4;
static const dialog = 5;
}