laams_push 1.1.0 copy "laams_push: ^1.1.0" to clipboard
laams_push: ^1.1.0 copied to clipboard

A declarative URI-based router for advanced navigation in Flutter, tailored for deep linking, user auth-based navigation, custom transition animations, ease of use, and many more.

example/lib/main.dart

import 'package:flutter/material.dart';
import 'package:laams_push/laams_push.dart';
import 'package:provider/provider.dart';

/// A Bloc for keeping the state of the user
/// You can use a package of of your choice
/// For this app, ChangeNotifier with Provider has been chosen.
class UserBloc with ChangeNotifier {
  bool _isSignedIn = true;
  bool get isSignedIn => _isSignedIn;
  void signIn() {
    _isSignedIn = true;
    notifyListeners();
  }

  void signOut() {
    _isSignedIn = false;
    notifyListeners();
  }
}

// Product Enttiy
class Product {
  final int id;
  final String name;
  const Product({required this.id, required this.name});

  Product copyWith({int? id, String? name}) {
    return Product(id: id ?? this.id, name: name ?? this.name);
  }

  factory Product.fromJson(Map<String, dynamic> json) {
    return Product(id: json['id'], name: json['name']);
  }

  Map<String, dynamic> toJson() {
    return <String, dynamic>{'id': id, 'name': name};
  }
}

/// You can use any state management solution.
class ProductBloc with ChangeNotifier {
  List<Product> _products = [];
  List<Product> get products => List<Product>.unmodifiable(_products);
  ProductBloc() {
    _products = productsFakeRepo;
  }

  void getProducts() {
    _products = productsFakeRepo;
    notifyListeners();
  }

  List<Product> productsFakeRepo = List<Product>.generate(100, (index) {
    return Product(id: index, name: 'My Product $index');
  });
}

void main() {
  runApp(MultiProvider(
    providers: [
      ChangeNotifierProvider(create: (_) => UserBloc()),
      ChangeNotifierProvider(create: (_) => ProductBloc()),
    ],
    child: const MyApp(),
  ));
}

class MyApp extends StatelessWidget {
  const MyApp({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final userBloc = context.watch<UserBloc>();
    return LaamsPushApp.router(
      isUserSignedIn: userBloc.isSignedIn,
      theme: ThemeData.light(),
      title: 'Laams Router Application',
      publicRoutes: const [SignInScreen.name],
      onGeneratePages: (LaamsRoute route) {
        switch (route.name) {
          case HomeScreen.name:
            return LaamsPage.fromRoute(route, const HomeScreen());
          case SignInScreen.name:
            return LaamsPage.fromRoute(route, const SignInScreen());
          case ProductsScreen.name:
            return LaamsPage.fromRoute(route, const ProductsScreen());
          case ProductDetail.name:
            final product = Product.fromJson(route.query!);
            return LaamsPage.fromRoute(route, ProductDetail(product));
          default:
            return LaamsPage.fromRoute(route, NotFoundScreen(route));
        }
      },
    );
  }
}

/// It `must` be called as the default in [LaamsPushApp.onGeneratePages],
class NotFoundScreen extends StatelessWidget {
  final LaamsRoute route;
  static const String name = '/notfound';
  const NotFoundScreen(this.route, {Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('Cound Not Find ${route.name.toUpperCase()}')),
      body: Center(
        child: TextButton(
          onPressed: () => LaamsPush.replace(context, HomeScreen.name),
          child: const Text('Could Find the page, go back home?'),
        ),
      ),
    );
  }
}

/// If the user is not signed in, this page is displayed to the user.
/// It `must` be passed as public route.
class SignInScreen extends StatelessWidget {
  static const String name = '/signin';
  const SignInScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('Signin Screen')),
      body: Center(
        child: TextButton(
          onPressed: context.read<UserBloc>().signIn,
          child: const Text('Sign In'),
        ),
      ),
    );
  }
}

/// The first page automatically displayed after signinin
/// it must the first route to be decalared.
class HomeScreen extends StatelessWidget {
  static const String name = '/';
  const HomeScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final signout = TextButton(
      onPressed: () => context.read<UserBloc>().signOut(),
      child: const Text("Signout", style: TextStyle(color: Colors.white)),
    );
    return Scaffold(
      appBar: AppBar(title: const Text('Home Screen'), actions: [signout]),
      body: Center(
        child: TextButton(
          onPressed: () => LaamsPush.push(context, ProductsScreen.name),
          child: const Text('Go to Products Screen'),
        ),
      ),
    );
  }
}

class ProductsScreen extends StatelessWidget {
  static const String name = '/products';
  const ProductsScreen({Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    final productsList = Consumer<ProductBloc>(
      builder: (context, bloc, _) => ListView.builder(
        itemBuilder: (context, index) => ListTile(
          onTap: () => LaamsPush.push(
            context,
            ProductDetail.name,
            query: bloc.products[index].toJson(),
          ),
          title: Text(bloc.products[index].name),
          subtitle: Text('${bloc.products[index].id}'),
        ),
      ),
    );
    return Scaffold(
      appBar: AppBar(title: const Text('Products Screen')),
      body: productsList,
    );
  }
}

class ProductDetail extends StatelessWidget {
  static const String name = '/product';
  final Product product;
  const ProductDetail(this.product, {Key? key}) : super(key: key);

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text('About ${product.name}')),
      body: ListTile(
        onTap: () => LaamsPush.pop(context),
        title: Text(product.name),
        subtitle: Text('${product.id}'),
        trailing: const Icon(Icons.close),
      ),
    );
  }
}
4
likes
120
pub points
0%
popularity

Publisher

verified publisherlaams.io

A declarative URI-based router for advanced navigation in Flutter, tailored for deep linking, user auth-based navigation, custom transition animations, ease of use, and many more.

Homepage
Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (LICENSE)

Dependencies

flutter

More

Packages that depend on laams_push