beamer icon indicating copy to clipboard operation
beamer copied to clipboard

Bug ------ !isWaitingForEnteringDecision && isWaitingForExitingDecision && isPresent

Open wenchaosong opened this issue 2 years ago • 7 comments

The latest version 1.5.2

import 'package:beamer/beamer.dart';
import 'package:flutter/material.dart';
import 'util/sp_util.dart';

void main() async {
  WidgetsFlutterBinding.ensureInitialized();
  await SpUtils.getInstance();
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  final routerDelegate = BeamerDelegate(
    transitionDelegate: NoAnimationTransitionDelegate(),
    guards: [
      BeamGuard(
          pathPatterns: ['/main'],
          check: (context, state) {
            return SpUtils.getString("token").isNotEmpty;
          },
          beamToNamed: (_, __) => '/login'),
      BeamGuard(
          pathPatterns: ['/login'],
          check: (context, state) {
            return SpUtils.getString("token").isEmpty;
          },
          beamToNamed: (_, __) => '/main'),
    ],
    initialPath: '/login',
    locationBuilder: (routeInformation, _) => BeamerLocation(routeInformation),
  );

  @override
  Widget build(BuildContext context) {
    return MaterialApp.router(
      debugShowCheckedModeBanner: false,
      title: "MerchantManagePlatform",
      routeInformationParser: BeamerParser(),
      routerDelegate: routerDelegate,
    );
  }
}

class BeamerLocation extends BeamLocation<BeamState> {
  BeamerLocation(RouteInformation routeInformation) : super(routeInformation);

  @override
  List<Pattern> get pathPatterns => ['/login', '/main'];

  @override
  List<BeamPage> buildPages(BuildContext context, BeamState state) {
    return [
      if (state.uri.pathSegments.contains('login'))
        BeamPage(
          key: ValueKey('login'),
          title: 'Login',
          child: LoginPage(),
        ),
      if (state.uri.pathSegments.contains('main'))
        BeamPage(
          key: ValueKey('main'),
          title: 'Main',
          child: MainPage(),
        ),
    ];
  }
}

class LoginPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: ElevatedButton(
        child: Text('Login'),
        onPressed: () {
          SpUtils.putString('token', "123");
          Beamer.of(context).update();
        },
      ),
    );
  }
}

class MainPage extends StatelessWidget {
  final _beamerKey = GlobalKey<BeamerState>();
  final _routerDelegate = BeamerDelegate(
      transitionDelegate: NoAnimationTransitionDelegate(),
      locationBuilder: (routeInformation, _) {
        if (routeInformation.location!.contains('deep')) {
          return DeepLocation(routeInformation);
        }
        return HomeLocation(routeInformation);
      });

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        actions: [
          PopupMenuButton<int>(
            onSelected: (index) {
              if (index == 1) {
                SpUtils.putString('token', "");
                Beamer.of(context).update();
              }
            },
            position: PopupMenuPosition.under,
            itemBuilder: (context) => [
              PopupMenuItem(
                value: 1,
                height: 50,
                child: Container(
                  alignment: Alignment.center,
                  child: Row(
                    children: [
                      Container(
                        child: Text(
                          "Logout",
                        ),
                      ),
                    ],
                  ),
                ),
              ),
            ],
            child: Container(
              width: 100,
              child: Icon(Icons.menu, size: 20, color: Colors.white),
            ),
          ),
        ],
      ),
      body: Beamer(
        key: _beamerKey,
        routerDelegate: _routerDelegate,
      ),
    );
  }
}

class HomeLocation extends BeamLocation<BeamState> {
  HomeLocation(RouteInformation routeInformation) : super(routeInformation);

  @override
  List<Pattern> get pathPatterns => ['/main/home'];

  @override
  List<BeamPage> buildPages(BuildContext context, BeamState state) {
    return [
      BeamPage(
        key: ValueKey('home'),
        title: 'Home',
        child: HomePage(),
      ),
    ];
  }
}

class HomePage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: ElevatedButton(
        child: Text('To deep'),
        onPressed: () {
          Beamer.of(context).beamToNamed("/main/deep");
        },
      ),
    );
  }
}

class DeepLocation extends BeamLocation<BeamState> {
  DeepLocation(RouteInformation routeInformation) : super(routeInformation);

  @override
  List<Pattern> get pathPatterns => ['/main/deep'];

  @override
  List<BeamPage> buildPages(BuildContext context, BeamState state) {
    return [
      BeamPage(
        key: ValueKey('deep'),
        title: 'Deep',
        child: DeepPage(),
      ),
    ];
  }
}

class DeepPage extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Center(
      child: Text('DeepBody'),
    );
  }
}

First question:

I found #220 already pointed this bug, but didn't reslove yet. And if use

  Future.delayed(const Duration(milliseconds: 500))
 .then((value) => Beamer.of(context).beamToNamed("/url"));

it is a bad experience, user must wait milliseconds.

Second question:

If go to the deep page, then click menu to loginout, nothing happened How to login out in deep location?

wenchaosong avatar Aug 18 '22 17:08 wenchaosong

First question Unfortunately no work has been done yet into investigating #220. Do you have any additional insights into what may be a better solution?

Second question Usually, it's best to have some "authentication status notifier" somewhere above and then you can register it into updateListenable property of your top BeamerDelegate so it will call guards whenever that notifier notifies. Or, you can have your top BeamerDelegate globally accessible and manually call rootBeamerDelegate.update() (which will re-run the guards) whenever your authentication status changes.

slovnicki avatar Sep 06 '22 21:09 slovnicki

@wenchaosong @slovnicki

Test this fix https://github.com/slovnicki/beamer/issues/645

stan-at-work avatar Oct 31 '23 11:10 stan-at-work

@stan-at-work yes, if remove the no anim, the error disappear, but, the page change looks strange, it is not good

wenchaosong avatar Nov 07 '23 01:11 wenchaosong

I tried ReverseTransitionDelegate, it has the same ability to make it disappear

wenchaosong avatar Nov 07 '23 01:11 wenchaosong

I tried ReverseTransitionDelegate, it has the same ability to make it disappear

For now its good that there is a fix the thing that needs to be fixed is in beamer. @slovnicki You need to take it from here, you got a startup from my issue 🤙

Sten435 avatar Nov 14 '23 06:11 Sten435

@slovnicki Any update on this ?

stan-at-work avatar Feb 06 '24 07:02 stan-at-work