slovnicki / beamer

A routing package built on top of Router and Navigator's pages API, supporting arbitrary nested navigation, guards and more.
MIT License
591 stars 129 forks source link

[Question] How to change Not Found page ? bottom_navigation_multiple_beamers #602

Closed dleurs closed 1 year ago

dleurs commented 1 year ago

Hello :)

I try to change not found page, unsuccessfully. Can you help me plz ?

I am using bottom_navigation_multiple_beamers example in my app

final routerDelegate = BeamerDelegate(
    initialPath: NavConfig.INITIAL_PATH,
    locationBuilder: RoutesLocationBuilder(
      routes: {
        '*': (context, state, data) => AppNavBar(),
      },
    ),
  );
return MaterialApp.router(
        routerDelegate: routerDelegate,
        routeInformationParser: BeamerParser(),
        backButtonDispatcher: BeamerBackButtonDispatcher(
          delegate: routerDelegate as BeamerDelegate,
        ),

Initially I got this in every BeamerDelegate

routerDelegates = [
    BeamerDelegate(
      initialPath: NavConfig.FANFARES_URI.path,
      locationBuilder: (routeInformation, _) {
        if (routeInformation.location!.contains(NavConfig.FANFARES_URI.path)) {
          return FanfaresLocation(routeInformation);
        }
        return NotFound(path: routeInformation.location!);
      },
    ),

/// beamer 1.5.3 files : 

class NotFound extends BeamLocation<BeamState> {
  /// Creates a [NotFound] [BeamLocation] with
  /// `RouteInformation(location: path)` as its state.
  NotFound({String path = '/'}) : super(RouteInformation(location: path));

  @override
  List<BeamPage> buildPages(BuildContext context, BeamState state) => [];

  @override
  List<String> get pathPatterns => [];
}

But it is impossible for the user to go back to the root of the BeamerDelegate

I changed to

    BeamerDelegate(
      initialPath: NavConfig.FANFARES_URI.path,
      locationBuilder: (routeInformation, _) {
        if (routeInformation.location!.contains(NavConfig.FANFARES_URI.path)) {
          return FanfaresLocation(routeInformation);
        }
        return NotFoundLocation(routeInformation, NavConfig.FANFARES_URI.path);
        //return NotFound(path: routeInformation.location!);
      },
    ),
class NotFoundLocation extends BeamLocation<BeamState> {
  final String pathToGo;
  NotFoundLocation(RouteInformation routeInformation, String this.pathToGo) : super(routeInformation);

  @override
  List<String> get pathPatterns => [];

  @override
  List<BeamPage> buildPages(BuildContext context, BeamState state) => [
        BeamPage(
          key: ValueKey(NotFoundScreen.name + pathToGo),
          title: Config.APP_NAME + ' ' + NotFoundScreen.name,
          //type: BeamPageType.noTransition,
          child: NotFoundScreen(
            pathToGo: pathToGo,
          ),
        ),
      ];
}

class NotFoundScreen extends StatelessWidget {
  static String get name => 'Page inconnue';
  final String pathToGo;
  const NotFoundScreen({required this.pathToGo, super.key});

  @override
  Widget build(BuildContext context) {
    return Column(
      children: [
        Expanded(child: SizedBox.shrink()),
        Text(
          S.of(context).page_inconnue,
          style: Theme.of(context).textTheme.titleSmall,
        ),
        SizedBox(
          height: 100,
        ),
        ElevatedButton(
          style: AppDimensions.defaultElevatedButtonTheme(context),
          onPressed: () {
            Beamer.of(context).beamToReplacementNamed(pathToGo);
          },
          child: Text(S.of(context).page_inconnue_get_back),
        ),
        Expanded(child: SizedBox.shrink()),
      ],
    );
  }
}

In order to go back to root of every beamerdelegate, which is working fine but now every indexes (except the initial one) start with this NotFoundScreen

https://user-images.githubusercontent.com/58068925/227663439-ac88d6b7-b68e-4522-86f7-b6a15bd9ff15.mp4

Thank you very much for your help !

dleurs commented 1 year ago

Same issue with

class NotFoundLocation extends BeamLocation<BeamState> {
  final String pathToGo;
  NotFoundLocation({String path = '/', required String this.pathToGo}) : super(RouteInformation(location: path));

  @override
  List<String> get pathPatterns => [];

  @override
  List<BeamPage> buildPages(BuildContext context, BeamState state) => [
        BeamPage(
          key: ValueKey(NotFoundScreen.name + pathToGo),
          title: Config.APP_NAME + ' ' + NotFoundScreen.name,
          //type: BeamPageType.noTransition,
          child: NotFoundScreen(
            pathToGo: pathToGo,
          ),
        ),
      ];
}
dleurs commented 1 year ago

Found solution

BeamerDelegate(
      initialPath: NavConfig.FANFARES_URI.path,
      notFoundPage: AppNotFound.beamPage(pathToRoot: NavConfig.FANFARES_URI.path),
      locationBuilder: (routeInformation, _) {
        if (routeInformation.location!.contains(NavConfig.FANFARES_URI.path)) {
          return FanfaresLocation(routeInformation);
        }
        return NotFound(path: routeInformation.location!);
      },
    ),
class AppNotFound {
  static BeamPage beamPage({required String pathToRoot}) => BeamPage(
        key: ValueKey(NotFoundScreen.name + pathToRoot),
        title: Config.APP_NAME + ' ' + NotFoundScreen.name,
        //type: BeamPageType.noTransition,
        child: NotFoundScreen(pathToGo: pathToRoot),
      );
}