Skip to content

kekland/ispect

 
 

Repository files navigation

A package combining Inspector, Talker, and more from pub.dev for efficient project implementation. 🚀

This package is not meant to be a groundbreaking innovation but rather a curated collection of high-quality tools from pub.dev, tailored for my future projects. I've decided to share it with the community in hopes it might be of use to others. It combines time-tested utilities and my personal enhancements aimed at improving project efficiency and adaptability.

As the underlying packages evolve, I plan to update and enhance this package, possibly adding new features based on community feedback and emerging needs. This package is meant to be a dynamic toolset that grows and improves over time, facilitating smoother development processes for Flutter developers.

Your feedback is highly valued as it will help shape future updates and ensure the package remains relevant and useful. 😊


Show some ❤️ and star the repo to support the project!

Pub License: MIT Repository views Pub

Pub likes Pub popularity Pub points


📌 Features

  • ✅ Draggable button for route to ISpect page, manage Inspector tools
  • ✅ Localizations: ru, en, kk. (I will add more translations in the future.)
  • ✅ Talker logger implementation: BLoC, Dio, Routing, Provider
  • ✅ You can customize more options during initialization of ISpectTalker like BLoC, Dispatcher error and etc.
  • ✅ Updated ISpectTalker page: added more options.
    • Detailed HTTP logs: request, response, error
    • Debug tools
    • Cache manager
    • Device and app info
  • ✅ Feedback
  • ✅ Performance tracker

📌 Getting Started

Follow these steps to use this package

Add dependency

dependencies:
  ispect: ^1.6.4

Add import package

import 'package:ispect/ispect.dart';
import 'package:talker_flutter/talker_flutter.dart';

Easy to use

Simple example of use ISpect
You can manage ISpect using ISpect.read(context). Put this code in your project at an screen and learn how it works. 😊

ISpect's example

 

Code:

Note: For handle Dio: see
The simplest realization:

final navigatorKey = GlobalKey<NavigatorState>();

final themeProvider = StateNotifierProvider<ThemeManager, ThemeMode>((ref) => ThemeManager());

final dio = Dio(
  BaseOptions(
    baseUrl: 'https://jsonplaceholder.typicode.com',
  ),
);

class ThemeManager extends StateNotifier<ThemeMode> {
  ThemeManager() : super(ThemeMode.dark);

  void toggleTheme() {
    state = state == ThemeMode.dark ? ThemeMode.light : ThemeMode.dark;
  }

  void setTheme(ThemeMode themeMode) {
    state = themeMode;
  }

  ThemeMode get themeMode => state;
}

void main() {
  final talker = TalkerFlutter.init();

  ISpect.run(
    () => runApp(
      ProviderScope(
        observers: [
          TalkerRiverpodObserver(
            talker: talker,
            settings: const TalkerRiverpodLoggerSettings(),
          ),
        ],
        child: App(talker: talker),
      ),
    ),
    talker: talker,
    onInitialized: () {
      dio.interceptors.add(TalkerDioLogger(
        talker: ISpectTalker.talker,
      ));
    },
  );
}

class App extends ConsumerWidget {
  final Talker talker;
  const App({super.key, required this.talker});

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    final themeMode = ref.watch(themeProvider);
    const locale = Locale('ru');

    return ISpectScopeWrapper(
      options: ISpectOptions(
        locale: locale,
        actionItems: [
          TalkerActionItem(
            title: 'Test',
            icon: Icons.account_tree_rounded,
            onTap: (ispectContext) {
              Navigator.of(ispectContext).push(
                MaterialPageRoute(
                  builder: (context) => const Scaffold(
                    body: Center(
                      child: Text('Test'),
                    ),
                  ),
                ),
              );
            },
          ),
        ],
      ),
      isISpectEnabled: true,
      child: MaterialApp(
        navigatorKey: navigatorKey,
        navigatorObservers: [
          TalkerRouteObserver(talker),
        ],
        locale: locale,
        supportedLocales: AppGeneratedLocalization.delegate.supportedLocales,
        localizationsDelegates: ISpectLocalizations.localizationDelegates([
          AppGeneratedLocalization.delegate,
        ]),
        theme: ThemeData.from(
          colorScheme: ColorScheme.fromSeed(
            seedColor: Colors.blue,
            brightness: Brightness.light,
          ),
        ),
        darkTheme: ThemeData.from(
          colorScheme: ColorScheme.fromSeed(
            seedColor: Colors.blue,
            brightness: Brightness.dark,
          ),
        ),
        themeMode: themeMode,
        builder: (context, child) {
          child = ISpectBuilder(
            navigatorKey: navigatorKey,
            initialPosition: (0, 300),
            onPositionChanged: (x, y) {
              debugPrint('x: $x, y: $y');
            },
            child: child,
          );
          return child;
        },
        home: const _Home(),
      ),
    );
  }
}

class _Home extends ConsumerWidget {
  const _Home();

  @override
  Widget build(BuildContext context, WidgetRef ref) {
    ref.watch(themeProvider.notifier);
    final iSpect = ISpect.read(context);
    return Scaffold(
      body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: [
            Text(AppGeneratedLocalization.of(context).app_title),
            ElevatedButton(
              onPressed: () {
                ref.read(themeProvider.notifier).toggleTheme();
                // iSpect.setThemeMode(themeNotifier.themeMode);
              },
              child: const Text('Toggle theme'),
            ),
            ElevatedButton(
              onPressed: () {
                iSpect.toggleISpect();
              },
              child: const Text('Toggle ISpect'),
            ),
            ElevatedButton(
              onPressed: () {
                dio.get('/posts/1');
              },
              child: const Text('Send HTTP request'),
            ),
            ElevatedButton(
              onPressed: () {
                dio.get('/post3s/1');
              },
              child: const Text('Send HTTP request with error'),
            ),
            ElevatedButton(
              onPressed: () {
                dio.options.headers.addAll({
                  'Authorization': 'Bearer token',
                });
                dio.get('/posts/1');
                dio.options.headers.remove('Authorization');
              },
              child: const Text('Send HTTP request with Token'),
            ),
            ElevatedButton(
              onPressed: () {
                throw Exception('Test exception');
              },
              child: const Text('Throw exception'),
            ),
            ElevatedButton(
                onPressed: () {
                  debugPrint('Send print message');
                },
                child: const Text('Send print message')),
          ],
        ),
      ),
    );
  }
}

For change ISpect theme:

ISpect.read(context).setThemeMode(value ? ThemeMode.dark : ThemeMode.light);

For handle routing (GoRouter)

You can use NavigatorObserver, but in practice it does not always work correctly.
Alternatively, you can use a listener:

    _router.routerDelegate.addListener(() {
      final String location =
          _router.routerDelegate.currentConfiguration.last.matchedLocation;
      talkerWrapper.route(location);
    });

Thanks to all contributors of this package


About

Wrapper around Inspector, Talker and etc

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • Dart 99.4%
  • Other 0.6%