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:friflex_starter/app/theme/app_colors_scheme.dart';
import 'package:friflex_starter/app/theme/theme_notifier.dart';
import 'package:friflex_starter/di/di_container.dart';
import 'package:friflex_starter/l10n/gen/app_localizations.dart';
@@ -11,7 +12,7 @@ extension AppContextExt on BuildContext {
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>();

View File

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