This commit is contained in:
Artem Luzin m
2025-06-17 20:05:59 +07:00
parent e12fc35917
commit f7d4c02623
6 changed files with 89 additions and 31 deletions

View File

@@ -1,4 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:friflex_starter/app/theme/app_colors_scheme.dart';
import 'package:friflex_starter/app/theme/theme_notifier.dart'; import 'package:friflex_starter/app/theme/theme_notifier.dart';
import 'package:friflex_starter/di/di_container.dart'; import 'package:friflex_starter/di/di_container.dart';
import 'package:friflex_starter/l10n/gen/app_localizations.dart'; import 'package:friflex_starter/l10n/gen/app_localizations.dart';
@@ -11,7 +12,7 @@ extension AppContextExt on BuildContext {
DiContainer get di => read<DiContainer>(); DiContainer get di => read<DiContainer>();
/// Геттер для получения цветовой схемы /// Геттер для получения цветовой схемы
ColorScheme get colors => Theme.of(this).colorScheme; AppColors get colors => Theme.of(this).extension<AppColors>()!;
/// Геттер для получения темы /// Геттер для получения темы
ThemeNotifier get theme => read<ThemeNotifier>(); ThemeNotifier get theme => read<ThemeNotifier>();

View File

@@ -1,18 +1,83 @@
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
/// {@template app_colors}
/// Класс, реализующий расширение для добавления токенов в цветовую схему /// Класс, реализующий расширение для добавления токенов в цветовую схему
extension AppColorsScheme on ColorScheme { /// {@endtemplate}
bool get _isDark => brightness == Brightness.dark; class AppColors extends ThemeExtension<AppColors> with DiagnosticableTreeMixin {
/// {@macro app_colors}
///
/// Принимает:
///
/// * [testColor] - цвет тестового текста
/// * [errorSnackbarBackground] - цвет фона снекбара ошибки
/// * [successSnackbarBackground] - цвет фона снекбара успеха
/// * [infoSnackbarBackground] - цвет фона снекбара информации
const AppColors({
required this.testColor,
required this.errorSnackbarBackground,
required this.successSnackbarBackground,
required this.infoSnackbarBackground,
});
// Тестовый цвет /// Цвет тестового текста
Color get testColor => _isDark ? Colors.green : Colors.red; final Color testColor;
/// Цвет заднего фона снекбара с ошибкой /// Цвет фона снекбара ошибки
Color get errorSnackbarBackground => const Color(0xFFD24720); final Color errorSnackbarBackground;
/// Цвет заднего фона снекбара с успехом /// Цвет фона снекбара успеха
Color get successSnackbarBackground => const Color(0xFF6FB62C); final Color successSnackbarBackground;
/// Цвет заднего фона снекбара с информацией /// Цвет фона снекбара информации
Color get infoSnackbarBackground => const Color.fromARGB(255, 220, 108, 77); final Color infoSnackbarBackground;
/// Цвета светлой темы
static final AppColors light = AppColors(
testColor: Colors.red,
errorSnackbarBackground: const Color(0xFFD24720),
successSnackbarBackground: const Color(0xFF6FB62C),
infoSnackbarBackground: const Color.fromARGB(255, 220, 108, 77),
);
/// Цвета тёмной темы
static final AppColors dark = AppColors(
testColor: Colors.red,
errorSnackbarBackground: const Color(0xFFD24720),
successSnackbarBackground: const Color(0xFF6FB62C),
infoSnackbarBackground: const Color.fromARGB(255, 220, 108, 77),
);
@override
ThemeExtension<AppColors> copyWith({
Color? testColor,
Color? errorSnackbarBackground,
Color? successSnackbarBackground,
Color? infoSnackbarBackground,
}) => AppColors(
testColor: testColor ?? this.testColor,
errorSnackbarBackground: errorSnackbarBackground ?? this.errorSnackbarBackground,
successSnackbarBackground: successSnackbarBackground ?? this.successSnackbarBackground,
infoSnackbarBackground: infoSnackbarBackground ?? this.infoSnackbarBackground,
);
@override
ThemeExtension<AppColors> lerp(covariant ThemeExtension<AppColors>? other, double t) {
if (other is! AppColors) return this;
return AppColors(
testColor: Color.lerp(testColor, other.testColor, t)!,
errorSnackbarBackground: Color.lerp(
errorSnackbarBackground,
other.errorSnackbarBackground,
t,
)!,
successSnackbarBackground: Color.lerp(
successSnackbarBackground,
other.successSnackbarBackground,
t,
)!,
infoSnackbarBackground: Color.lerp(infoSnackbarBackground, other.infoSnackbarBackground, t)!,
);
}
} }

View File

@@ -1,10 +1,13 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:friflex_starter/app/theme/app_colors_scheme.dart';
/// Класс для конфигурации светлой/темной темы приложения /// Класс для конфигурации светлой/темной темы приложения
abstract class AppTheme { abstract class AppTheme {
/// Геттер для получения светлой темы /// Геттер для получения светлой темы
static ThemeData get light => ThemeData.light(); static ThemeData get light =>
ThemeData.light().copyWith(extensions: <ThemeExtension<Object?>>[AppColors.light]);
/// Геттер для получения темной темы /// Геттер для получения темной темы
static ThemeData get dark => ThemeData.dark(); static ThemeData get dark =>
ThemeData.dark().copyWith(extensions: <ThemeExtension<Object?>>[AppColors.dark]);
} }

View File

@@ -2,7 +2,6 @@ import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:friflex_starter/app/app_context_ext.dart'; import 'package:friflex_starter/app/app_context_ext.dart';
import 'package:friflex_starter/app/theme/app_colors_scheme.dart';
import 'package:friflex_starter/app/ui_kit/app_box.dart'; import 'package:friflex_starter/app/ui_kit/app_box.dart';
/// {@template app_snackbar} /// {@template app_snackbar}
@@ -140,8 +139,7 @@ class AppSnackBar extends StatefulWidget {
} }
} }
class _AppSnackBarState extends State<AppSnackBar> class _AppSnackBarState extends State<AppSnackBar> with SingleTickerProviderStateMixin {
with SingleTickerProviderStateMixin {
late AnimationController _animationController; late AnimationController _animationController;
late Animation<double> _slideAnimation; late Animation<double> _slideAnimation;
Timer? _dismissTimer; Timer? _dismissTimer;
@@ -176,10 +174,10 @@ class _AppSnackBarState extends State<AppSnackBar>
// Конечная позиция снекбара - 15 пикселей ниже верхнего отступа // Конечная позиция снекбара - 15 пикселей ниже верхнего отступа
final endPosition = topPadding + 15; final endPosition = topPadding + 15;
// Создание анимации с использованием Tween // Создание анимации с использованием Tween
_slideAnimation = Tween<double>(begin: startPosition, end: endPosition) _slideAnimation = Tween<double>(
.animate( begin: startPosition,
CurvedAnimation(parent: _animationController, curve: Curves.easeOut), end: endPosition,
); ).animate(CurvedAnimation(parent: _animationController, curve: Curves.easeOut));
_animationController.forward(); _animationController.forward();
} }
@@ -233,10 +231,7 @@ class _AppSnackBarState extends State<AppSnackBar>
color: _getBackgroundColor(widget.type), color: _getBackgroundColor(widget.type),
borderRadius: BorderRadius.circular(16), borderRadius: BorderRadius.circular(16),
), ),
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
vertical: 12,
horizontal: 16,
),
child: Row( child: Row(
children: [ children: [
_Icon(type: widget.type), _Icon(type: widget.type),
@@ -289,11 +284,7 @@ class _Icon extends StatelessWidget {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return switch (type) { return switch (type) {
TypeSnackBar.success => Icon( TypeSnackBar.success => Icon(Icons.check_circle, color: Colors.white, size: 32),
Icons.check_circle,
color: Colors.white,
size: 32,
),
TypeSnackBar.error => Icon(Icons.error, color: Colors.white, size: 32), TypeSnackBar.error => Icon(Icons.error, color: Colors.white, size: 32),
TypeSnackBar.info => Icon(Icons.info, color: Colors.white, size: 32), TypeSnackBar.info => Icon(Icons.info, color: Colors.white, size: 32),
}; };

View File

@@ -1,6 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:friflex_starter/app/app_context_ext.dart'; import 'package:friflex_starter/app/app_context_ext.dart';
import 'package:friflex_starter/app/theme/app_colors_scheme.dart';
import 'package:friflex_starter/gen/assets.gen.dart'; import 'package:friflex_starter/gen/assets.gen.dart';
import 'package:friflex_starter/gen/fonts.gen.dart'; import 'package:friflex_starter/gen/fonts.gen.dart';

View File

@@ -1,6 +1,5 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:friflex_starter/app/app_context_ext.dart'; import 'package:friflex_starter/app/app_context_ext.dart';
import 'package:friflex_starter/app/theme/app_colors_scheme.dart';
/// {@template ThemeScreen} /// {@template ThemeScreen}
/// Экран для отладки темы приложения /// Экран для отладки темы приложения