From a3b9cc0ebc1436e3b7b1824ad8e2f7645d6228c4 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Beno=C3=AEt=20Harrault?= <benoit@harrault.fr>
Date: Sun, 20 Oct 2024 23:14:45 +0200
Subject: [PATCH] Use flutter custom toolbox lib

---
 lib/config/menu.dart                    |   3 +-
 lib/config/theme.dart                   | 192 ----------------------
 lib/cubit/api_cubit.dart                |   4 +-
 lib/cubit/bottom_nav_cubit.dart         |   2 +-
 lib/cubit/data_cubit.dart               |   3 +-
 lib/cubit/game_cubit.dart               |   3 +-
 lib/cubit/settings_cubit.dart           |   3 +-
 lib/cubit/theme_cubit.dart              |   3 +-
 lib/main.dart                           |   7 +-
 lib/models/game/game.dart               |   3 +-
 lib/models/game/game_board.dart         |   3 +-
 lib/models/interface_type.dart          |   2 +-
 lib/network/api.dart                    |   2 +-
 lib/repository/api.dart                 |   3 +-
 lib/ui/helpers/app_titles.dart          |  32 ----
 lib/ui/helpers/styled_button.dart       | 210 ------------------------
 lib/ui/helpers/styled_container.dart    |  66 --------
 lib/ui/painters/cell_painter.dart       |   2 +-
 lib/ui/screens/about_page.dart          |   5 +-
 lib/ui/screens/api_page.dart            |   4 +-
 lib/ui/screens/camera_page.dart         |   2 +-
 lib/ui/screens/demo_page.dart           |  11 +-
 lib/ui/screens/game_page.dart           |   3 +-
 lib/ui/screens/graph_page.dart          |   2 +-
 lib/ui/screens/settings_page.dart       |   2 +-
 lib/ui/skeleton.dart                    |   2 +-
 lib/ui/widgets/api_data.dart            |   3 +-
 lib/ui/widgets/app_bar.dart             |   2 +-
 lib/ui/widgets/debug_bloc.dart          |  28 ----
 lib/ui/widgets/error.dart               |  17 --
 lib/ui/widgets/game/game_board.dart     |   3 +-
 lib/ui/widgets/header_app.dart          |   7 +-
 lib/ui/widgets/settings_form.dart       |   5 +-
 lib/ui/widgets/take_picture_widget.dart |   3 +-
 lib/ui/widgets/theme_card.dart          |   2 +-
 lib/utils/color_extensions.dart         |  33 ----
 lib/utils/picture_storage.dart          |   4 +-
 lib/utils/tools.dart                    |   7 -
 pubspec.lock                            |  49 +++---
 pubspec.yaml                            |  15 +-
 40 files changed, 74 insertions(+), 678 deletions(-)
 delete mode 100644 lib/config/theme.dart
 delete mode 100644 lib/ui/helpers/app_titles.dart
 delete mode 100644 lib/ui/helpers/styled_button.dart
 delete mode 100644 lib/ui/helpers/styled_container.dart
 delete mode 100644 lib/ui/widgets/debug_bloc.dart
 delete mode 100644 lib/ui/widgets/error.dart
 delete mode 100644 lib/utils/color_extensions.dart
 delete mode 100644 lib/utils/tools.dart

diff --git a/lib/config/menu.dart b/lib/config/menu.dart
index 99f8668..69a2ac1 100644
--- a/lib/config/menu.dart
+++ b/lib/config/menu.dart
@@ -1,6 +1,5 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
-import 'package:unicons/unicons.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:random/ui/screens/about_page.dart';
 import 'package:random/ui/screens/api_page.dart';
diff --git a/lib/config/theme.dart b/lib/config/theme.dart
deleted file mode 100644
index 138460e..0000000
--- a/lib/config/theme.dart
+++ /dev/null
@@ -1,192 +0,0 @@
-import 'package:flutter/material.dart';
-
-/// Colors from Tailwind CSS (v3.0) - June 2022
-///
-/// https://tailwindcss.com/docs/customizing-colors
-
-const int _primaryColor = 0xFF6366F1;
-const MaterialColor primarySwatch = MaterialColor(_primaryColor, <int, Color>{
-  50: Color(0xFFEEF2FF), // indigo-50
-  100: Color(0xFFE0E7FF), // indigo-100
-  200: Color(0xFFC7D2FE), // indigo-200
-  300: Color(0xFFA5B4FC), // indigo-300
-  400: Color(0xFF818CF8), // indigo-400
-  500: Color(_primaryColor), // indigo-500
-  600: Color(0xFF4F46E5), // indigo-600
-  700: Color(0xFF4338CA), // indigo-700
-  800: Color(0xFF3730A3), // indigo-800
-  900: Color(0xFF312E81), // indigo-900
-});
-
-const int _textColor = 0xFF64748B;
-const MaterialColor textSwatch = MaterialColor(_textColor, <int, Color>{
-  50: Color(0xFFF8FAFC), // slate-50
-  100: Color(0xFFF1F5F9), // slate-100
-  200: Color(0xFFE2E8F0), // slate-200
-  300: Color(0xFFCBD5E1), // slate-300
-  400: Color(0xFF94A3B8), // slate-400
-  500: Color(_textColor), // slate-500
-  600: Color(0xFF475569), // slate-600
-  700: Color(0xFF334155), // slate-700
-  800: Color(0xFF1E293B), // slate-800
-  900: Color(0xFF0F172A), // slate-900
-});
-
-const Color errorColor = Color(0xFFDC2626); // red-600
-
-final ColorScheme lightColorScheme = ColorScheme.light(
-  primary: primarySwatch.shade500,
-  secondary: primarySwatch.shade500,
-  onSecondary: Colors.white,
-  error: errorColor,
-  onSurface: textSwatch.shade500,
-  surface: textSwatch.shade50,
-  surfaceContainerHighest: Colors.white,
-  shadow: textSwatch.shade900.withOpacity(.1),
-);
-
-final ColorScheme darkColorScheme = ColorScheme.dark(
-  primary: primarySwatch.shade500,
-  secondary: primarySwatch.shade500,
-  onSecondary: Colors.white,
-  error: errorColor,
-  onSurface: textSwatch.shade300,
-  surface: const Color(0xFF262630),
-  surfaceContainerHighest: const Color(0xFF282832),
-  shadow: textSwatch.shade900.withOpacity(.2),
-);
-
-final ThemeData lightTheme = ThemeData(
-  colorScheme: lightColorScheme,
-  fontFamily: 'Nunito',
-  textTheme: TextTheme(
-    displayLarge: TextStyle(
-      color: textSwatch.shade700,
-      fontFamily: 'Nunito',
-    ),
-    displayMedium: TextStyle(
-      color: textSwatch.shade600,
-      fontFamily: 'Nunito',
-    ),
-    displaySmall: TextStyle(
-      color: textSwatch.shade500,
-      fontFamily: 'Nunito',
-    ),
-    headlineLarge: TextStyle(
-      color: textSwatch.shade700,
-      fontFamily: 'Nunito',
-    ),
-    headlineMedium: TextStyle(
-      color: textSwatch.shade600,
-      fontFamily: 'Nunito',
-    ),
-    headlineSmall: TextStyle(
-      color: textSwatch.shade500,
-      fontFamily: 'Nunito',
-    ),
-    titleLarge: TextStyle(
-      color: textSwatch.shade700,
-      fontFamily: 'Nunito',
-    ),
-    titleMedium: TextStyle(
-      color: textSwatch.shade600,
-      fontFamily: 'Nunito',
-    ),
-    titleSmall: TextStyle(
-      color: textSwatch.shade500,
-      fontFamily: 'Nunito',
-    ),
-    bodyLarge: TextStyle(
-      color: textSwatch.shade700,
-      fontFamily: 'Nunito',
-    ),
-    bodyMedium: TextStyle(
-      color: textSwatch.shade600,
-      fontFamily: 'Nunito',
-    ),
-    bodySmall: TextStyle(
-      color: textSwatch.shade500,
-      fontFamily: 'Nunito',
-    ),
-    labelLarge: TextStyle(
-      color: textSwatch.shade700,
-      fontFamily: 'Nunito',
-    ),
-    labelMedium: TextStyle(
-      color: textSwatch.shade600,
-      fontFamily: 'Nunito',
-    ),
-    labelSmall: TextStyle(
-      color: textSwatch.shade500,
-      fontFamily: 'Nunito',
-    ),
-  ),
-);
-
-final ThemeData darkTheme = lightTheme.copyWith(
-  colorScheme: darkColorScheme,
-  textTheme: TextTheme(
-    displayLarge: TextStyle(
-      color: textSwatch.shade200,
-      fontFamily: 'Nunito',
-    ),
-    displayMedium: TextStyle(
-      color: textSwatch.shade300,
-      fontFamily: 'Nunito',
-    ),
-    displaySmall: TextStyle(
-      color: textSwatch.shade400,
-      fontFamily: 'Nunito',
-    ),
-    headlineLarge: TextStyle(
-      color: textSwatch.shade200,
-      fontFamily: 'Nunito',
-    ),
-    headlineMedium: TextStyle(
-      color: textSwatch.shade300,
-      fontFamily: 'Nunito',
-    ),
-    headlineSmall: TextStyle(
-      color: textSwatch.shade400,
-      fontFamily: 'Nunito',
-    ),
-    titleLarge: TextStyle(
-      color: textSwatch.shade200,
-      fontFamily: 'Nunito',
-    ),
-    titleMedium: TextStyle(
-      color: textSwatch.shade300,
-      fontFamily: 'Nunito',
-    ),
-    titleSmall: TextStyle(
-      color: textSwatch.shade400,
-      fontFamily: 'Nunito',
-    ),
-    bodyLarge: TextStyle(
-      color: textSwatch.shade200,
-      fontFamily: 'Nunito',
-    ),
-    bodyMedium: TextStyle(
-      color: textSwatch.shade300,
-      fontFamily: 'Nunito',
-    ),
-    bodySmall: TextStyle(
-      color: textSwatch.shade400,
-      fontFamily: 'Nunito',
-    ),
-    labelLarge: TextStyle(
-      color: textSwatch.shade200,
-      fontFamily: 'Nunito',
-    ),
-    labelMedium: TextStyle(
-      color: textSwatch.shade300,
-      fontFamily: 'Nunito',
-    ),
-    labelSmall: TextStyle(
-      color: textSwatch.shade400,
-      fontFamily: 'Nunito',
-    ),
-  ),
-);
-
-final ThemeData appTheme = darkTheme;
diff --git a/lib/cubit/api_cubit.dart b/lib/cubit/api_cubit.dart
index 1835d78..d53bd16 100644
--- a/lib/cubit/api_cubit.dart
+++ b/lib/cubit/api_cubit.dart
@@ -1,10 +1,8 @@
-import 'package:equatable/equatable.dart';
-import 'package:hydrated_bloc/hydrated_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:random/models/api_failure.dart';
 import 'package:random/models/api_data.dart';
 import 'package:random/repository/api.dart';
-import 'package:random/utils/tools.dart';
 
 part 'api_state.dart';
 
diff --git a/lib/cubit/bottom_nav_cubit.dart b/lib/cubit/bottom_nav_cubit.dart
index 76d5c37..f27411d 100644
--- a/lib/cubit/bottom_nav_cubit.dart
+++ b/lib/cubit/bottom_nav_cubit.dart
@@ -1,4 +1,4 @@
-import 'package:hydrated_bloc/hydrated_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:random/config/menu.dart';
 
diff --git a/lib/cubit/data_cubit.dart b/lib/cubit/data_cubit.dart
index 262453a..d735047 100644
--- a/lib/cubit/data_cubit.dart
+++ b/lib/cubit/data_cubit.dart
@@ -1,6 +1,5 @@
-import 'package:equatable/equatable.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 import 'package:flutter/material.dart';
-import 'package:hydrated_bloc/hydrated_bloc.dart';
 
 part 'data_state.dart';
 
diff --git a/lib/cubit/game_cubit.dart b/lib/cubit/game_cubit.dart
index 336c70f..1f39160 100644
--- a/lib/cubit/game_cubit.dart
+++ b/lib/cubit/game_cubit.dart
@@ -1,6 +1,5 @@
-import 'package:equatable/equatable.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 import 'package:flutter/material.dart';
-import 'package:hydrated_bloc/hydrated_bloc.dart';
 
 import 'package:random/models/game/game.dart';
 
diff --git a/lib/cubit/settings_cubit.dart b/lib/cubit/settings_cubit.dart
index 35d6c2d..9f8f3b2 100644
--- a/lib/cubit/settings_cubit.dart
+++ b/lib/cubit/settings_cubit.dart
@@ -1,6 +1,5 @@
-import 'package:equatable/equatable.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 import 'package:flutter/material.dart';
-import 'package:hydrated_bloc/hydrated_bloc.dart';
 
 import 'package:random/models/interface_type.dart';
 
diff --git a/lib/cubit/theme_cubit.dart b/lib/cubit/theme_cubit.dart
index b793e89..f6c84b0 100644
--- a/lib/cubit/theme_cubit.dart
+++ b/lib/cubit/theme_cubit.dart
@@ -1,6 +1,5 @@
-import 'package:equatable/equatable.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 import 'package:flutter/material.dart';
-import 'package:hydrated_bloc/hydrated_bloc.dart';
 
 part 'theme_state.dart';
 
diff --git a/lib/main.dart b/lib/main.dart
index b4a2c31..b774645 100644
--- a/lib/main.dart
+++ b/lib/main.dart
@@ -1,13 +1,8 @@
 import 'dart:io';
 
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:hive/hive.dart';
-import 'package:hydrated_bloc/hydrated_bloc.dart';
-import 'package:path_provider/path_provider.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:random/config/theme.dart';
 import 'package:random/cubit/api_cubit.dart';
 import 'package:random/cubit/bottom_nav_cubit.dart';
 import 'package:random/cubit/data_cubit.dart';
diff --git a/lib/models/game/game.dart b/lib/models/game/game.dart
index 56cde71..966b251 100644
--- a/lib/models/game/game.dart
+++ b/lib/models/game/game.dart
@@ -1,9 +1,10 @@
 import 'dart:math';
 
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
 import 'package:random/models/game/game_board.dart';
 import 'package:random/models/game/game_cell.dart';
 import 'package:random/models/game/game_settings.dart';
-import 'package:random/utils/tools.dart';
 
 class Game {
   GameBoard board;
diff --git a/lib/models/game/game_board.dart b/lib/models/game/game_board.dart
index 03e0611..8f0135e 100644
--- a/lib/models/game/game_board.dart
+++ b/lib/models/game/game_board.dart
@@ -1,8 +1,9 @@
 import 'dart:math';
 
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
 import 'package:random/models/game/game_cell.dart';
 import 'package:random/models/game/game_settings.dart';
-import 'package:random/utils/tools.dart';
 
 class GameBoard {
   final List<List<GameCell>> cells;
diff --git a/lib/models/interface_type.dart b/lib/models/interface_type.dart
index 2976321..1ea9b3a 100644
--- a/lib/models/interface_type.dart
+++ b/lib/models/interface_type.dart
@@ -1,5 +1,5 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 enum InterfaceType {
   basic,
diff --git a/lib/network/api.dart b/lib/network/api.dart
index 92a90e0..3496021 100644
--- a/lib/network/api.dart
+++ b/lib/network/api.dart
@@ -1,9 +1,9 @@
 import 'dart:io';
 
 import 'package:dio/dio.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:random/models/api_failure.dart';
-import 'package:random/utils/tools.dart';
 
 class ApiService {
   final Dio _dio = Dio();
diff --git a/lib/repository/api.dart b/lib/repository/api.dart
index 7530d1f..14dba65 100644
--- a/lib/repository/api.dart
+++ b/lib/repository/api.dart
@@ -1,6 +1,7 @@
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
+
 import 'package:random/models/api_data.dart';
 import 'package:random/network/api.dart';
-import 'package:random/utils/tools.dart';
 
 class ApiRepository {
   const ApiRepository({required this.apiService});
diff --git a/lib/ui/helpers/app_titles.dart b/lib/ui/helpers/app_titles.dart
deleted file mode 100644
index b98107b..0000000
--- a/lib/ui/helpers/app_titles.dart
+++ /dev/null
@@ -1,32 +0,0 @@
-import 'package:easy_localization/easy_localization.dart';
-import 'package:flutter/material.dart';
-
-class AppHeader extends StatelessWidget {
-  const AppHeader({super.key, required this.text});
-
-  final String text;
-
-  @override
-  Widget build(BuildContext context) {
-    return Text(
-      tr(text),
-      textAlign: TextAlign.start,
-      style: Theme.of(context).textTheme.headlineMedium!.apply(fontWeightDelta: 2),
-    );
-  }
-}
-
-class AppTitle extends StatelessWidget {
-  const AppTitle({super.key, required this.text});
-
-  final String text;
-
-  @override
-  Widget build(BuildContext context) {
-    return Text(
-      tr(text),
-      textAlign: TextAlign.start,
-      style: Theme.of(context).textTheme.titleLarge!.apply(fontWeightDelta: 2),
-    );
-  }
-}
diff --git a/lib/ui/helpers/styled_button.dart b/lib/ui/helpers/styled_button.dart
deleted file mode 100644
index 7f2807f..0000000
--- a/lib/ui/helpers/styled_button.dart
+++ /dev/null
@@ -1,210 +0,0 @@
-import 'package:auto_size_text/auto_size_text.dart';
-import 'package:flutter/material.dart';
-
-import 'package:random/utils/color_extensions.dart';
-
-class StyledButton extends StatelessWidget {
-  const StyledButton({
-    super.key,
-    required this.color,
-    required this.onPressed,
-    this.onLongPress,
-    required this.child,
-  });
-
-  final Color color;
-  final VoidCallback? onPressed;
-  final VoidCallback? onLongPress;
-  final Widget child;
-
-  factory StyledButton.text({
-    Key? key,
-    required VoidCallback? onPressed,
-    VoidCallback? onLongPress,
-    required String caption,
-    required Color color,
-  }) {
-    final Widget captionWidget = AutoSizeText(
-      caption,
-      maxLines: 1,
-      style: TextStyle(
-        inherit: true,
-        fontWeight: FontWeight.w900,
-        color: color.darken(60),
-        shadows: [
-          Shadow(
-            blurRadius: 5.0,
-            color: color.lighten(60),
-            offset: const Offset(2, 2),
-          ),
-          Shadow(
-            blurRadius: 5.0,
-            color: color.lighten(60),
-            offset: const Offset(2, -2),
-          ),
-          Shadow(
-            blurRadius: 5.0,
-            color: color.lighten(60),
-            offset: const Offset(-2, 2),
-          ),
-          Shadow(
-            blurRadius: 5.0,
-            color: color.lighten(60),
-            offset: const Offset(-2, -2),
-          ),
-        ],
-      ),
-    );
-
-    return StyledButton(
-      color: color,
-      onPressed: onPressed,
-      onLongPress: onLongPress,
-      child: captionWidget,
-    );
-  }
-
-  factory StyledButton.icon({
-    Key? key,
-    required VoidCallback? onPressed,
-    VoidCallback? onLongPress,
-    required Icon icon,
-    required Color color,
-    required double iconSize,
-  }) {
-    return StyledButton(
-      color: color,
-      onPressed: onPressed,
-      onLongPress: onLongPress,
-      child: Icon(
-        icon.icon,
-        color: icon.color ?? color.darken(60),
-        size: iconSize,
-        shadows: [
-          Shadow(
-            blurRadius: 5.0,
-            color: color.lighten(60),
-            offset: const Offset(2, 2),
-          ),
-          Shadow(
-            blurRadius: 5.0,
-            color: color.lighten(60),
-            offset: const Offset(2, -2),
-          ),
-          Shadow(
-            blurRadius: 5.0,
-            color: color.lighten(60),
-            offset: const Offset(-2, 2),
-          ),
-          Shadow(
-            blurRadius: 5.0,
-            color: color.lighten(60),
-            offset: const Offset(-2, -2),
-          ),
-        ],
-      ),
-    );
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    const double borderWidth = 4;
-    final Color borderColor = color.darken(40);
-    const double borderRadius = 10;
-
-    return Container(
-      margin: const EdgeInsets.all(2),
-      padding: const EdgeInsets.all(2),
-      decoration: BoxDecoration(
-        color: color,
-        border: Border.all(
-          color: borderColor,
-          width: borderWidth,
-        ),
-        borderRadius: BorderRadius.circular(borderRadius),
-      ),
-      child: CustomPaint(
-        painter: StyledButtonPainter(
-          baseColor: color,
-        ),
-        child: MaterialButton(
-          onPressed: onPressed,
-          onLongPress: onLongPress,
-          padding: const EdgeInsets.all(8),
-          materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
-          minWidth: 40,
-          child: child,
-        ),
-      ),
-    );
-  }
-}
-
-class StyledButtonPainter extends CustomPainter {
-  StyledButtonPainter({
-    required this.baseColor,
-  });
-
-  final Color baseColor;
-
-  @override
-  void paint(Canvas canvas, Size size) {
-    final Color lightColor = baseColor.lighten(20);
-    final Color darkColor = baseColor.darken(20);
-
-    final Paint paint = Paint()..style = PaintingStyle.fill;
-
-    const double cornerRadius = 6;
-
-    Path topPath = Path()
-      ..moveTo(cornerRadius, 0)
-      ..lineTo(size.width - cornerRadius, 0)
-      ..arcToPoint(
-        Offset(size.width, cornerRadius),
-        radius: const Radius.circular(cornerRadius),
-      )
-      ..lineTo(size.width, size.height * .35)
-      ..quadraticBezierTo(
-        size.width * .4,
-        size.height * .1,
-        0,
-        size.height * .3,
-      )
-      ..lineTo(0, cornerRadius)
-      ..arcToPoint(
-        const Offset(cornerRadius, 0),
-        radius: const Radius.circular(cornerRadius),
-      );
-
-    Path bottomPath = Path()
-      ..moveTo(cornerRadius, size.height)
-      ..lineTo(size.width - cornerRadius, size.height)
-      ..arcToPoint(
-        Offset(size.width, size.height - cornerRadius),
-        radius: const Radius.circular(cornerRadius),
-        clockwise: false,
-      )
-      ..lineTo(size.width, size.height * .7)
-      ..quadraticBezierTo(
-        size.width * .6,
-        size.height * .9,
-        0,
-        size.height * .7,
-      )
-      ..lineTo(0, size.height - cornerRadius)
-      ..arcToPoint(
-        Offset(cornerRadius, size.height),
-        radius: const Radius.circular(cornerRadius),
-        clockwise: false,
-      );
-
-    paint.color = lightColor;
-    canvas.drawPath(topPath, paint);
-
-    paint.color = darkColor;
-    canvas.drawPath(bottomPath, paint);
-  }
-
-  @override
-  bool shouldRepaint(CustomPainter oldDelegate) => false;
-}
diff --git a/lib/ui/helpers/styled_container.dart b/lib/ui/helpers/styled_container.dart
deleted file mode 100644
index a68c78c..0000000
--- a/lib/ui/helpers/styled_container.dart
+++ /dev/null
@@ -1,66 +0,0 @@
-import 'package:flutter/material.dart';
-
-class StyledContainer extends StatelessWidget {
-  const StyledContainer({
-    super.key,
-    required this.child,
-    this.borderWidth = 20,
-    this.borderRadius = 6,
-    this.depth = 7,
-    this.lowerColor,
-    this.upperColor,
-  });
-
-  final Widget child;
-  final double borderWidth;
-  final double borderRadius;
-  final int depth;
-  final Color? lowerColor;
-  final Color? upperColor;
-
-  Widget nestedContainers({
-    required Widget child,
-    required int containerDepth,
-    required Color lowerColor,
-    required Color upperColor,
-  }) {
-    final double singleBorderWidth = borderWidth / depth;
-    final Color borderColor =
-        Color.lerp(upperColor, lowerColor, (containerDepth / depth - 0.5).abs() * 2) ??
-            Colors.white;
-
-    final double radius = borderRadius + borderRadius * (containerDepth / depth);
-
-    return Container(
-      decoration: BoxDecoration(
-        color: borderColor,
-        border: Border.all(
-          color: borderColor,
-          width: singleBorderWidth,
-        ),
-        borderRadius: BorderRadius.circular(radius),
-      ),
-      child: containerDepth == 0
-          ? Padding(
-              padding: const EdgeInsets.all(8),
-              child: child,
-            )
-          : nestedContainers(
-              child: child,
-              containerDepth: containerDepth - 1,
-              lowerColor: lowerColor,
-              upperColor: upperColor,
-            ),
-    );
-  }
-
-  @override
-  Widget build(BuildContext context) {
-    return nestedContainers(
-      child: child,
-      containerDepth: depth,
-      lowerColor: lowerColor ?? Theme.of(context).colorScheme.surface,
-      upperColor: upperColor ?? Theme.of(context).colorScheme.onSurface,
-    );
-  }
-}
diff --git a/lib/ui/painters/cell_painter.dart b/lib/ui/painters/cell_painter.dart
index cd5aed7..ef3538f 100644
--- a/lib/ui/painters/cell_painter.dart
+++ b/lib/ui/painters/cell_painter.dart
@@ -1,9 +1,9 @@
 import 'dart:ui' as ui;
 
 import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:random/config/app_colors.dart';
-import 'package:random/utils/color_extensions.dart';
 
 class CellPainter extends CustomPainter {
   const CellPainter({required this.value});
diff --git a/lib/ui/screens/about_page.dart b/lib/ui/screens/about_page.dart
index f183a4a..7903553 100644
--- a/lib/ui/screens/about_page.dart
+++ b/lib/ui/screens/about_page.dart
@@ -1,6 +1,5 @@
-import 'package:easy_localization/easy_localization.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 import 'package:flutter/material.dart';
-import 'package:package_info_plus/package_info_plus.dart';
 
 import 'package:random/ui/widgets/header_app.dart';
 
@@ -15,7 +14,7 @@ class AboutPage extends StatelessWidget {
       mainAxisSize: MainAxisSize.max,
       children: <Widget>[
         const SizedBox(height: 8),
-        const AppHeader(text: 'about_title'),
+        const AppHeaderCustom(text: 'about_title'),
         const Text('about_content').tr(),
         FutureBuilder<PackageInfo>(
           future: PackageInfo.fromPlatform(),
diff --git a/lib/ui/screens/api_page.dart b/lib/ui/screens/api_page.dart
index 1441fac..b9a2b22 100644
--- a/lib/ui/screens/api_page.dart
+++ b/lib/ui/screens/api_page.dart
@@ -1,5 +1,5 @@
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:random/cubit/api_cubit.dart';
 import 'package:random/models/api_status.dart';
@@ -18,7 +18,7 @@ class ApiPage extends StatelessWidget {
         physics: const BouncingScrollPhysics(),
         children: <Widget>[
           const SizedBox(height: 8),
-          const AppHeader(text: 'api_page_title'),
+          const AppHeaderCustom(text: 'api_page_title'),
           const SizedBox(height: 20),
           BlocBuilder<ApiDataCubit, ApiDataState>(
             builder: (BuildContext context, ApiDataState apiDataState) {
diff --git a/lib/ui/screens/camera_page.dart b/lib/ui/screens/camera_page.dart
index 668b889..ca4df4c 100644
--- a/lib/ui/screens/camera_page.dart
+++ b/lib/ui/screens/camera_page.dart
@@ -1,5 +1,5 @@
 import 'package:flutter/material.dart';
-import 'package:unicons/unicons.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:random/ui/widgets/take_picture_widget.dart';
 
diff --git a/lib/ui/screens/demo_page.dart b/lib/ui/screens/demo_page.dart
index 4b5018c..a7b4e83 100644
--- a/lib/ui/screens/demo_page.dart
+++ b/lib/ui/screens/demo_page.dart
@@ -1,14 +1,9 @@
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:unicons/unicons.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
-import 'package:random/config/theme.dart';
 import 'package:random/cubit/data_cubit.dart';
 import 'package:random/cubit/settings_cubit.dart';
 import 'package:random/ui/widgets/header_app.dart';
-import 'package:random/ui/helpers/styled_button.dart';
-import 'package:random/ui/helpers/styled_container.dart';
-import 'package:random/utils/tools.dart';
 
 class DemoPage extends StatelessWidget {
   const DemoPage({super.key});
@@ -22,7 +17,7 @@ class DemoPage extends StatelessWidget {
         physics: const BouncingScrollPhysics(),
         children: <Widget>[
           const SizedBox(height: 8),
-          const AppHeader(text: 'TOP'),
+          const AppHeaderCustom(text: 'TOP'),
           const SizedBox(height: 20),
           StyledContainer(
             child: persistedCounterBlock(BlocProvider.of<DataCubit>(context)),
@@ -48,7 +43,7 @@ class DemoPage extends StatelessWidget {
           const SizedBox(height: 8),
           fakeApiCall(),
           const SizedBox(height: 8),
-          const AppHeader(text: 'BOTTOM'),
+          const AppHeaderCustom(text: 'BOTTOM'),
           const SizedBox(height: 8),
           Row(
             mainAxisAlignment: MainAxisAlignment.spaceBetween,
diff --git a/lib/ui/screens/game_page.dart b/lib/ui/screens/game_page.dart
index a0db19d..a8ee1a9 100644
--- a/lib/ui/screens/game_page.dart
+++ b/lib/ui/screens/game_page.dart
@@ -1,6 +1,5 @@
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:unicons/unicons.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:random/cubit/game_cubit.dart';
 import 'package:random/models/game/game.dart';
diff --git a/lib/ui/screens/graph_page.dart b/lib/ui/screens/graph_page.dart
index e26f8a2..3b6d770 100644
--- a/lib/ui/screens/graph_page.dart
+++ b/lib/ui/screens/graph_page.dart
@@ -1,7 +1,7 @@
 import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:random/ui/painters/graph_painter.dart';
-import 'package:random/utils/tools.dart';
 
 class GraphPage extends StatefulWidget {
   const GraphPage({super.key});
diff --git a/lib/ui/screens/settings_page.dart b/lib/ui/screens/settings_page.dart
index 195d012..6995b42 100644
--- a/lib/ui/screens/settings_page.dart
+++ b/lib/ui/screens/settings_page.dart
@@ -14,7 +14,7 @@ class SettingsPage extends StatelessWidget {
       mainAxisSize: MainAxisSize.max,
       children: <Widget>[
         SizedBox(height: 8),
-        AppHeader(text: 'settings_title'),
+        AppHeaderCustom(text: 'settings_title'),
         SizedBox(height: 8),
         SettingsForm(),
       ],
diff --git a/lib/ui/skeleton.dart b/lib/ui/skeleton.dart
index d22acea..3d71d26 100644
--- a/lib/ui/skeleton.dart
+++ b/lib/ui/skeleton.dart
@@ -1,6 +1,6 @@
 import 'package:curved_navigation_bar/curved_navigation_bar.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:random/config/menu.dart';
 import 'package:random/cubit/bottom_nav_cubit.dart';
diff --git a/lib/ui/widgets/api_data.dart b/lib/ui/widgets/api_data.dart
index 669de42..763fe8a 100644
--- a/lib/ui/widgets/api_data.dart
+++ b/lib/ui/widgets/api_data.dart
@@ -1,7 +1,8 @@
 import 'package:flutter/material.dart';
+import 'package:flutter_custom_toolbox/widgets/show_error.dart';
+
 import 'package:random/models/api_data.dart';
 import 'package:random/models/api_status.dart';
-import 'package:random/ui/widgets/error.dart';
 
 class ApiDataWidget extends StatelessWidget {
   const ApiDataWidget({
diff --git a/lib/ui/widgets/app_bar.dart b/lib/ui/widgets/app_bar.dart
index 0d60da6..7343f6f 100644
--- a/lib/ui/widgets/app_bar.dart
+++ b/lib/ui/widgets/app_bar.dart
@@ -8,7 +8,7 @@ class StandardAppBar extends StatelessWidget implements PreferredSizeWidget {
   @override
   Widget build(BuildContext context) {
     return AppBar(
-      title: const AppHeader(text: 'app_name'),
+      title: const AppHeaderCustom(text: 'app_name'),
       actions: const [
         //
       ],
diff --git a/lib/ui/widgets/debug_bloc.dart b/lib/ui/widgets/debug_bloc.dart
deleted file mode 100644
index cbc6dfe..0000000
--- a/lib/ui/widgets/debug_bloc.dart
+++ /dev/null
@@ -1,28 +0,0 @@
-import 'package:flutter/material.dart';
-
-class DebugBloc extends StatelessWidget {
-  const DebugBloc({super.key, required this.content});
-
-  final String content;
-
-  @override
-  Widget build(BuildContext context) {
-    return Container(
-      decoration: BoxDecoration(
-        color: Colors.red,
-        border: Border.all(
-          color: Colors.grey,
-          width: 2,
-        ),
-      ),
-      child: Padding(
-        padding: const EdgeInsets.all(5),
-        child: Text(
-          content,
-          textAlign: TextAlign.start,
-          style: const TextStyle(fontSize: 13),
-        ),
-      ),
-    );
-  }
-}
diff --git a/lib/ui/widgets/error.dart b/lib/ui/widgets/error.dart
deleted file mode 100644
index 9aacdcb..0000000
--- a/lib/ui/widgets/error.dart
+++ /dev/null
@@ -1,17 +0,0 @@
-import 'package:easy_localization/easy_localization.dart';
-import 'package:flutter/material.dart';
-
-class ShowErrorWidget extends StatelessWidget {
-  const ShowErrorWidget({super.key, required this.message});
-
-  final String message;
-
-  @override
-  Widget build(BuildContext context) {
-    return Text(
-      '⚠️ ${tr(message)}',
-      textAlign: TextAlign.start,
-      style: const TextStyle(color: Colors.red),
-    );
-  }
-}
diff --git a/lib/ui/widgets/game/game_board.dart b/lib/ui/widgets/game/game_board.dart
index 3a092b3..21bd65e 100644
--- a/lib/ui/widgets/game/game_board.dart
+++ b/lib/ui/widgets/game/game_board.dart
@@ -1,12 +1,11 @@
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:random/cubit/game_cubit.dart';
 import 'package:random/models/game/game.dart';
 import 'package:random/models/game/game_settings.dart';
 import 'package:random/ui/painters/cell_painter.dart';
 import 'package:random/ui/widgets/game/game_score.dart';
-import 'package:random/utils/tools.dart';
 
 class GameBoardWidget extends StatefulWidget {
   const GameBoardWidget({
diff --git a/lib/ui/widgets/header_app.dart b/lib/ui/widgets/header_app.dart
index 39bfa86..8670546 100644
--- a/lib/ui/widgets/header_app.dart
+++ b/lib/ui/widgets/header_app.dart
@@ -1,14 +1,13 @@
-import 'package:easy_localization/easy_localization.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
 
 import 'package:random/cubit/data_cubit.dart';
 import 'package:random/cubit/api_cubit.dart';
 import 'package:random/cubit/settings_cubit.dart';
 import 'package:random/models/interface_type.dart';
 
-class AppHeader extends StatelessWidget {
-  const AppHeader({super.key, required this.text});
+class AppHeaderCustom extends StatelessWidget {
+  const AppHeaderCustom({super.key, required this.text});
 
   final String text;
 
diff --git a/lib/ui/widgets/settings_form.dart b/lib/ui/widgets/settings_form.dart
index facc79d..8273e66 100644
--- a/lib/ui/widgets/settings_form.dart
+++ b/lib/ui/widgets/settings_form.dart
@@ -1,10 +1,7 @@
-import 'package:easy_localization/easy_localization.dart';
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
-import 'package:unicons/unicons.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:random/cubit/settings_cubit.dart';
-import 'package:random/config/theme.dart';
 import 'package:random/models/interface_type.dart';
 import 'package:random/ui/widgets/theme_card.dart';
 
diff --git a/lib/ui/widgets/take_picture_widget.dart b/lib/ui/widgets/take_picture_widget.dart
index 1bcc14e..290d1e4 100644
--- a/lib/ui/widgets/take_picture_widget.dart
+++ b/lib/ui/widgets/take_picture_widget.dart
@@ -2,10 +2,9 @@ import 'dart:io';
 
 import 'package:camera/camera.dart';
 import 'package:flutter/material.dart';
-import 'package:unicons/unicons.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:random/utils/picture_storage.dart';
-import 'package:random/utils/tools.dart';
 
 class TakePictureWidget extends StatefulWidget {
   const TakePictureWidget({super.key});
diff --git a/lib/ui/widgets/theme_card.dart b/lib/ui/widgets/theme_card.dart
index e68441c..fefb525 100644
--- a/lib/ui/widgets/theme_card.dart
+++ b/lib/ui/widgets/theme_card.dart
@@ -1,5 +1,5 @@
 import 'package:flutter/material.dart';
-import 'package:flutter_bloc/flutter_bloc.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 import 'package:random/cubit/theme_cubit.dart';
 
diff --git a/lib/utils/color_extensions.dart b/lib/utils/color_extensions.dart
deleted file mode 100644
index 4e55e33..0000000
--- a/lib/utils/color_extensions.dart
+++ /dev/null
@@ -1,33 +0,0 @@
-import 'dart:ui';
-
-extension ColorExtension on Color {
-  Color darken([int percent = 40]) {
-    assert(1 <= percent && percent <= 100);
-    final value = 1 - percent / 100;
-    return Color.fromARGB(
-      alpha,
-      (red * value).round(),
-      (green * value).round(),
-      (blue * value).round(),
-    );
-  }
-
-  Color lighten([int percent = 40]) {
-    assert(1 <= percent && percent <= 100);
-    final value = percent / 100;
-    return Color.fromARGB(
-      alpha,
-      (red + ((255 - red) * value)).round(),
-      (green + ((255 - green) * value)).round(),
-      (blue + ((255 - blue) * value)).round(),
-    );
-  }
-
-  Color avg(Color other) {
-    final red = (this.red + other.red) ~/ 2;
-    final green = (this.green + other.green) ~/ 2;
-    final blue = (this.blue + other.blue) ~/ 2;
-    final alpha = (this.alpha + other.alpha) ~/ 2;
-    return Color.fromARGB(alpha, red, green, blue);
-  }
-}
diff --git a/lib/utils/picture_storage.dart b/lib/utils/picture_storage.dart
index 9914680..6f1e0ac 100644
--- a/lib/utils/picture_storage.dart
+++ b/lib/utils/picture_storage.dart
@@ -1,9 +1,7 @@
 import 'dart:io';
 
 import 'package:path/path.dart';
-import 'package:path_provider/path_provider.dart';
-
-import 'package:random/utils/tools.dart';
+import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
 
 class PictureStorage {
   Future<String> get _localPath async {
diff --git a/lib/utils/tools.dart b/lib/utils/tools.dart
deleted file mode 100644
index fd48b2b..0000000
--- a/lib/utils/tools.dart
+++ /dev/null
@@ -1,7 +0,0 @@
-import 'package:flutter/foundation.dart';
-
-void printlog(String message) {
-  if (!kReleaseMode) {
-    debugPrint(message);
-  }
-}
diff --git a/pubspec.lock b/pubspec.lock
index b5faee9..99fc0e7 100644
--- a/pubspec.lock
+++ b/pubspec.lock
@@ -5,10 +5,10 @@ packages:
     dependency: transitive
     description:
       name: args
-      sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a"
+      sha256: bf9f5caeea8d8fe6721a9c358dd8a5c1947b27f1cfaa18b39c301273594919e6
       url: "https://pub.dev"
     source: hosted
-    version: "2.5.0"
+    version: "2.6.0"
   async:
     dependency: transitive
     description:
@@ -18,7 +18,7 @@ packages:
     source: hosted
     version: "2.11.0"
   auto_size_text:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: auto_size_text
       sha256: "3f5261cd3fb5f2a9ab4e2fc3fba84fd9fcaac8821f20a1d4e71f557521b22599"
@@ -109,10 +109,10 @@ packages:
     dependency: transitive
     description:
       name: crypto
-      sha256: ec30d999af904f33454ba22ed9a86162b35e52b44ac4807d1d93c288041d7d27
+      sha256: "1e445881f28f22d6140f181e07737b22f1e099a5e1ff94b0af2f9e4a463f4855"
       url: "https://pub.dev"
     source: hosted
-    version: "3.0.5"
+    version: "3.0.6"
   curved_navigation_bar:
     dependency: "direct main"
     description:
@@ -138,7 +138,7 @@ packages:
     source: hosted
     version: "2.0.0"
   easy_localization:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: easy_localization
       sha256: fa59bcdbbb911a764aa6acf96bbb6fa7a5cf8234354fc45ec1a43a0349ef0201
@@ -154,7 +154,7 @@ packages:
     source: hosted
     version: "0.0.2"
   equatable:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: equatable
       sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2
@@ -183,13 +183,22 @@ packages:
     source: sdk
     version: "0.0.0"
   flutter_bloc:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: flutter_bloc
       sha256: b594505eac31a0518bdcb4b5b79573b8d9117b193cc80cc12e17d639b10aa27a
       url: "https://pub.dev"
     source: hosted
     version: "8.1.6"
+  flutter_custom_toolbox:
+    dependency: "direct main"
+    description:
+      path: "."
+      ref: "0.1.0"
+      resolved-ref: ff755f2ce78457881908d5a3afce728a47315469
+      url: "https://git.harrault.fr/android/flutter-toolbox.git"
+    source: git
+    version: "0.1.0"
   flutter_lints:
     dependency: "direct dev"
     description:
@@ -217,7 +226,7 @@ packages:
     source: sdk
     version: "0.0.0"
   hive:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: hive
       sha256: "8dcf6db979d7933da8217edcec84e9df1bdb4e4edc7fc77dbd5aa74356d6d941"
@@ -241,7 +250,7 @@ packages:
     source: hosted
     version: "4.0.2"
   hydrated_bloc:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: hydrated_bloc
       sha256: af35b357739fe41728df10bec03aad422cdc725a1e702e03af9d2a41ea05160c
@@ -289,13 +298,13 @@ packages:
     source: hosted
     version: "1.0.0"
   package_info_plus:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: package_info_plus
-      sha256: "894f37107424311bdae3e476552229476777b8752c5a2a2369c0cb9a2d5442ef"
+      sha256: df3eb3e0aed5c1107bb0fdb80a8e82e778114958b1c5ac5644fb1ac9cae8a998
       url: "https://pub.dev"
     source: hosted
-    version: "8.0.3"
+    version: "8.1.0"
   package_info_plus_platform_interface:
     dependency: transitive
     description:
@@ -313,7 +322,7 @@ packages:
     source: hosted
     version: "1.9.0"
   path_provider:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: path_provider
       sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
@@ -364,10 +373,10 @@ packages:
     dependency: transitive
     description:
       name: platform
-      sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
+      sha256: "5d6b1b0036a5f331ebc77c850ebc8506cbc1e9416c27e59b439f917a902a4984"
       url: "https://pub.dev"
     source: hosted
-    version: "3.1.5"
+    version: "3.1.6"
   plugin_platform_interface:
     dependency: transitive
     description:
@@ -494,7 +503,7 @@ packages:
     source: hosted
     version: "1.3.2"
   unicons:
-    dependency: "direct main"
+    dependency: transitive
     description:
       name: unicons
       sha256: f3eab9d87c226415ef857cfd2167e1d12ad81ea1f5783b46cf644224fea4eab7
@@ -521,10 +530,10 @@ packages:
     dependency: transitive
     description:
       name: win32
-      sha256: "4d45dc9069dba4619dc0ebd93c7cec5e66d8482cb625a370ac806dcc8165f2ec"
+      sha256: "2735daae5150e8b1dfeb3eb0544b4d3af0061e9e82cef063adcd583bdae4306a"
       url: "https://pub.dev"
     source: hosted
-    version: "5.5.5"
+    version: "5.7.0"
   xdg_directories:
     dependency: transitive
     description:
@@ -534,5 +543,5 @@ packages:
     source: hosted
     version: "1.1.0"
 sdks:
-  dart: ">=3.5.0 <4.0.0"
+  dart: ">=3.5.3 <4.0.0"
   flutter: ">=3.24.0"
diff --git a/pubspec.yaml b/pubspec.yaml
index 5e3fcb2..5e0f249 100644
--- a/pubspec.yaml
+++ b/pubspec.yaml
@@ -3,7 +3,7 @@ description: A random application, for testing purpose only.
 
 publish_to: "none"
 
-version: 1.1.2+67
+version: 1.1.3+68
 
 environment:
   sdk: "^3.0.0"
@@ -13,15 +13,10 @@ dependencies:
     sdk: flutter
 
   # base
-  auto_size_text: ^3.0.0
-  easy_localization: ^3.0.1
-  equatable: ^2.0.5
-  flutter_bloc: ^8.1.1
-  hive: ^2.2.3
-  hydrated_bloc: ^9.0.0
-  package_info_plus: ^8.0.0
-  path_provider: ^2.0.11
-  unicons: ^3.0.0
+  flutter_custom_toolbox:
+    git:
+      url: https://git.harrault.fr/android/flutter-toolbox.git
+      ref: 0.1.0
 
   # specific
   camera: ^0.11.0+2
-- 
GitLab