juice 1.0.4 copy "juice: ^1.0.4" to clipboard
juice: ^1.0.4 copied to clipboard

Juice is a lightweight, modular reactive state management library for Flutter, combining clean design with BLoC, Stream-Based State Management

example/lib/main.dart

import 'package:juice/juice.dart';

import 'blocs/file_upload/src/ui/file_upload_page.dart';
import 'blocs/chat/ui/chat_page.dart';
import 'blocs/counter/ui/counter_page.dart';
import 'blocs/form/ui/form_page.dart';
import 'blocs/todo/ui/todo_page.dart';
import 'blocs/weather/ui/weather_page.dart';
import 'blocs/blocs.dart';
import 'config/bloc_registration.dart';

// Example routes definition
final exampleRoutes = {
  '/counter': (context) => const CounterPage(),
  '/todo': (context) => const TodoPage(),
  '/chat': (context) => const ChatPage(),
  '/form': (context) => const FormPage(),
  '/weather': (context) => const WeatherPage(),
  '/upload': (context) => const FileUploadPage(),
};

void main() {
  GlobalBlocResolver().resolver = BlocResolver();
  BlocRegistry.initialize(ExampleDeepLinkConfig.config);

  // Get initial deep link if any
  final args = Uri.base.queryParameters;
  final initialExample = args['example'];

  runApp(MyApp(initialExample: initialExample));
}

class MyApp extends StatefulWidget {
  final String? initialExample;

  const MyApp({super.key, this.initialExample});

  @override
  State<MyApp> createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> {
  @override
  void initState() {
    super.initState();

    // Handle initial deep link after first frame
    WidgetsBinding.instance.addPostFrameCallback((_) {
      if (widget.initialExample != null) {
        final appBloc = GlobalBlocResolver().resolver.resolve<AppBloc>();
        appBloc.send(UpdateEvent(
          aviatorName: 'deepLink',
          aviatorArgs: {'deepLink': widget.initialExample},
        ));
      }
    });
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      navigatorKey:
          GlobalBlocResolver().resolver.resolve<AppBloc>().navigatorKey,
      title: 'Juice Examples',
      theme: ThemeData(
        colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
        useMaterial3: true,
      ),
      // Handle both initial route and deep links
      initialRoute: '/',
      onGenerateRoute: (settings) {
        if (settings.name == '/') {
          return MaterialPageRoute(
            builder: (context) => const MyHomePage(title: 'Juice Examples'),
          );
        }

        // Find matching example route
        final builder = exampleRoutes[settings.name];
        if (builder != null) {
          return MaterialPageRoute(
            builder: (context) => PopScope(
              onPopInvokedWithResult: (b, r) =>
                  GlobalBlocResolver().resolver.disposeAll(),
              child: builder(context),
            ),
          );
        }

        // Handle unknown routes
        return MaterialPageRoute(
          builder: (context) => const MyHomePage(title: 'Juice Examples'),
        );
      },
    );
  }
}

class MyHomePage extends StatelessWidget {
  const MyHomePage({super.key, required this.title});
  final String title;

  @override
  Widget build(BuildContext context) {
    final examples = [
      {'title': 'Counter Example', 'route': '/counter'},
      {'title': 'Todo Example', 'route': '/todo'},
      {'title': 'Chat Example', 'route': '/chat'},
      {'title': 'Form Example', 'route': '/form'},
      {'title': 'Weather Example', 'route': '/weather'},
      {'title': 'File Upload', 'route': '/upload'},
    ];

    return Scaffold(
      appBar: AppBar(
        title: Text(title),
        backgroundColor: Theme.of(context).colorScheme.inversePrimary,
      ),
      body: ListView.builder(
        itemCount: examples.length,
        itemBuilder: (context, index) {
          final example = examples[index];
          return ListTile(
            title: Text(example['title'] as String),
            trailing: const Icon(Icons.arrow_forward),
            onTap: () {
              Navigator.pushNamed(context, example['route'] as String);
            },
          );
        },
      ),
    );
  }
}

// Add DeepLinkAviator configuration
class ExampleDeepLinkConfig {
  static final config = DeepLinkConfig(
    authRoute: '/', // No auth needed for examples
    routes: {
      'counter': DeepLinkRoute(path: ['/counter']),
      'todo': DeepLinkRoute(path: ['/todo']),
      'chat': DeepLinkRoute(path: ['/chat']),
      'form': DeepLinkRoute(path: ['/form']),
      'weather': DeepLinkRoute(path: ['/weather']),
      'upload': DeepLinkRoute(path: ['/upload']),
    },
  );
}
6
likes
140
points
34
downloads

Publisher

verified publishernuovea.com

Weekly Downloads

Juice is a lightweight, modular reactive state management library for Flutter, combining clean design with BLoC, Stream-Based State Management

Homepage
Repository (GitHub)
View/report issues
Contributing

Topics

#bloc #reactive #clean-architecture #state-management

Documentation

Documentation
API reference

License

MIT (license)

Dependencies

cupertino_icons, flutter, flutter_test, logger, rxdart

More

Packages that depend on juice