Skip to content
Snippets Groups Projects
Commit a3b9cc0e authored by Benoît Harrault's avatar Benoît Harrault
Browse files

Use flutter custom toolbox lib

parent 9f0982fb
No related branches found
No related tags found
1 merge request!84Resolve "Use flutter_toolbox lib"
Pipeline #6427 passed
Showing
with 21 additions and 531 deletions
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.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/about_page.dart';
import 'package:random/ui/screens/api_page.dart'; import 'package:random/ui/screens/api_page.dart';
......
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;
import 'package:equatable/equatable.dart'; import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:random/models/api_failure.dart'; import 'package:random/models/api_failure.dart';
import 'package:random/models/api_data.dart'; import 'package:random/models/api_data.dart';
import 'package:random/repository/api.dart'; import 'package:random/repository/api.dart';
import 'package:random/utils/tools.dart';
part 'api_state.dart'; part 'api_state.dart';
......
import 'package:hydrated_bloc/hydrated_bloc.dart'; import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:random/config/menu.dart'; import 'package:random/config/menu.dart';
......
import 'package:equatable/equatable.dart'; import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
part 'data_state.dart'; part 'data_state.dart';
......
import 'package:equatable/equatable.dart'; import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:random/models/game/game.dart'; import 'package:random/models/game/game.dart';
......
import 'package:equatable/equatable.dart'; import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:random/models/interface_type.dart'; import 'package:random/models/interface_type.dart';
......
import 'package:equatable/equatable.dart'; import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
part 'theme_state.dart'; part 'theme_state.dart';
......
import 'dart:io'; import 'dart:io';
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:hive/hive.dart';
import 'package:hydrated_bloc/hydrated_bloc.dart';
import 'package:path_provider/path_provider.dart';
import 'package:random/config/theme.dart';
import 'package:random/cubit/api_cubit.dart'; import 'package:random/cubit/api_cubit.dart';
import 'package:random/cubit/bottom_nav_cubit.dart'; import 'package:random/cubit/bottom_nav_cubit.dart';
import 'package:random/cubit/data_cubit.dart'; import 'package:random/cubit/data_cubit.dart';
......
import 'dart:math'; 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_board.dart';
import 'package:random/models/game/game_cell.dart'; import 'package:random/models/game/game_cell.dart';
import 'package:random/models/game/game_settings.dart'; import 'package:random/models/game/game_settings.dart';
import 'package:random/utils/tools.dart';
class Game { class Game {
GameBoard board; GameBoard board;
......
import 'dart:math'; 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_cell.dart';
import 'package:random/models/game/game_settings.dart'; import 'package:random/models/game/game_settings.dart';
import 'package:random/utils/tools.dart';
class GameBoard { class GameBoard {
final List<List<GameCell>> cells; final List<List<GameCell>> cells;
......
import 'package:easy_localization/easy_localization.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
enum InterfaceType { enum InterfaceType {
basic, basic,
......
import 'dart:io'; import 'dart:io';
import 'package:dio/dio.dart'; import 'package:dio/dio.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:random/models/api_failure.dart'; import 'package:random/models/api_failure.dart';
import 'package:random/utils/tools.dart';
class ApiService { class ApiService {
final Dio _dio = Dio(); final Dio _dio = Dio();
......
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:random/models/api_data.dart'; import 'package:random/models/api_data.dart';
import 'package:random/network/api.dart'; import 'package:random/network/api.dart';
import 'package:random/utils/tools.dart';
class ApiRepository { class ApiRepository {
const ApiRepository({required this.apiService}); const ApiRepository({required this.apiService});
......
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),
);
}
}
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;
}
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,
);
}
}
import 'dart:ui' as ui; import 'dart:ui' as ui;
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:random/config/app_colors.dart'; import 'package:random/config/app_colors.dart';
import 'package:random/utils/color_extensions.dart';
class CellPainter extends CustomPainter { class CellPainter extends CustomPainter {
const CellPainter({required this.value}); const CellPainter({required this.value});
......
import 'package:easy_localization/easy_localization.dart'; import 'package:flutter_custom_toolbox/flutter_toolbox.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:random/ui/widgets/header_app.dart'; import 'package:random/ui/widgets/header_app.dart';
...@@ -15,7 +14,7 @@ class AboutPage extends StatelessWidget { ...@@ -15,7 +14,7 @@ class AboutPage extends StatelessWidget {
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
children: <Widget>[ children: <Widget>[
const SizedBox(height: 8), const SizedBox(height: 8),
const AppHeader(text: 'about_title'), const AppHeaderCustom(text: 'about_title'),
const Text('about_content').tr(), const Text('about_content').tr(),
FutureBuilder<PackageInfo>( FutureBuilder<PackageInfo>(
future: PackageInfo.fromPlatform(), future: PackageInfo.fromPlatform(),
......
import 'package:flutter/material.dart'; 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/cubit/api_cubit.dart';
import 'package:random/models/api_status.dart'; import 'package:random/models/api_status.dart';
...@@ -18,7 +18,7 @@ class ApiPage extends StatelessWidget { ...@@ -18,7 +18,7 @@ class ApiPage extends StatelessWidget {
physics: const BouncingScrollPhysics(), physics: const BouncingScrollPhysics(),
children: <Widget>[ children: <Widget>[
const SizedBox(height: 8), const SizedBox(height: 8),
const AppHeader(text: 'api_page_title'), const AppHeaderCustom(text: 'api_page_title'),
const SizedBox(height: 20), const SizedBox(height: 20),
BlocBuilder<ApiDataCubit, ApiDataState>( BlocBuilder<ApiDataCubit, ApiDataState>(
builder: (BuildContext context, ApiDataState apiDataState) { builder: (BuildContext context, ApiDataState apiDataState) {
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment