osam_flutter 3.4.7 copy "osam_flutter: ^3.4.7" to clipboard
osam_flutter: ^3.4.7 copied to clipboard

discontinued

Navigation and UI elements which fits with Osam library

example/lib/main.dart

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(MaterialApp(home: FadeThroughTransitionDemo(),));

  runApp(OsamProvider(
    appState: appState,
    uiState: uiState,
    version: version,
    child: PersistLifecycleWrapper(
      persist: persist,
      child: PresenterProvider(
        presenter: AppPresenter(),
        child: OsamNotification(
          child: MaterialApp(
            navigatorKey: navKey,
            home: PresenterProvider(
              child: Screen(),
              presenter: ScreenPresenter(FirstRoute),
            ),
          ),
        ),
      ),
    ),
  ));
}

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 OsamTabNavigator<ScreenPresenter>(
      tabBarHeight: 50,
      tabDecoration: BoxDecoration(color: Colors.blue),
      pages: {
        tabs.first: GestureDetector(
          key: ValueKey(123),
          child: Container(color: Colors.red),
          onTap: () => presenter.uiState.appTabNavigation.tab = tabs.second,
        ),
        tabs.second: GestureDetector(
          key: ValueKey(321),
          child: Container(color: Colors.green),
          onTap: () => presenter.uiState.appTabNavigation.tab = tabs.first,
        ),
      },
      tabs: {
        tabs.first: Icon(Icons.chat),
        tabs.second: Icon(Icons.bookmark_border)
      },
      selectedTabs: {
        tabs.first: Icon(Icons.chat),
        tabs.second: Icon(Icons.bookmark_border)
      },
    );

    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, TabNavigationPresenter {
  final Type route;

  ScreenPresenter(this.route);

  @override
  Navigation get navigation => uiState.appNavigation;

  @override
  TabNavigation get tabNavigation => uiState.appTabNavigation;

  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;
}

class FadeThroughTransitionDemo extends StatefulWidget {
  @override
  _FadeThroughTransitionDemoState createState() =>
      _FadeThroughTransitionDemoState();
}

class _FadeThroughTransitionDemoState extends State<FadeThroughTransitionDemo> {
  final pageIndex = ValueNotifier(0);

  List<Widget> pageList = <Widget>[
    _FirstPage(),
    _SecondPage(),
    _ThirdPage(),
  ];

  @override
  Widget build(BuildContext context) {
    return Stack(
      children: <Widget>[
        ValueListenableBuilder(
            valueListenable: pageIndex,
            builder: (_, pageIndex, __) {
              return PageTransitionSwitcher(
                transitionBuilder: (
                  Widget child,
                  Animation<double> animation,
                  Animation<double> secondaryAnimation,
                ) {
                  return FadeThroughTransition(
                    animation: animation,
                    secondaryAnimation: secondaryAnimation,
                    child: child,
                  );
                },
                child: pageList[pageIndex],
              );
            }),
        Positioned(
          bottom: 0,
          child: Row(
            children: <Widget>[
              RaisedButton(
                onPressed: () => pageIndex.value = 0,
              ),
              RaisedButton(
                onPressed: () => pageIndex.value = 1,
              ),
              RaisedButton(
                onPressed: () => pageIndex.value = 2,
              ),
            ],
          ),
        )
      ],
    );
  }
}

class _FirstPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.green,
    );
  }
}

class _SecondPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.yellow,
    );
  }
}

class _ThirdPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Container(
      color: Colors.blueAccent,
    );
  }
}