mirror of
https://github.com/smmarty/friflex_flutter_starter.git
synced 2025-12-22 01:20:46 +00:00
refactor(full refactor): Рефакторинг стартера (#8)
This commit is contained in:
@@ -1,31 +1,66 @@
|
||||
import 'package:flutter/widgets.dart';
|
||||
import 'package:friflex_starter/features/debug/debug_screen.dart';
|
||||
import 'package:friflex_starter/features/debug/screens/debug_screen.dart';
|
||||
import 'package:friflex_starter/features/debug/screens/icons_screen.dart';
|
||||
import 'package:friflex_starter/features/debug/screens/lang_screen.dart';
|
||||
import 'package:friflex_starter/features/debug/screens/theme_screen.dart';
|
||||
import 'package:friflex_starter/features/debug/screens/tokens_screen.dart';
|
||||
import 'package:friflex_starter/features/debug/screens/ui_kit_screen.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
/// {@template debug_routes}
|
||||
/// Роуты для отладки приложения
|
||||
/// [buildRoutes] - метод для создания роутов
|
||||
/// {@endtemplate}
|
||||
abstract final class DebugRoutes {
|
||||
/// Название роута страницы профиля пользователя
|
||||
/// Название экранов
|
||||
static const String debugScreenName = 'debug_screen';
|
||||
static const String tokensScreenName = 'tokens_screen';
|
||||
static const String uiKitScreenName = 'ui_kit_screen';
|
||||
static const String iconsScreenName = 'icons_screen';
|
||||
static const String themeScreenName = 'theme_screen';
|
||||
static const String langScreenName = 'lang_screen';
|
||||
|
||||
/// Путь роута страницы профиля пользователя
|
||||
static const String _debugScreenPath = '/debug';
|
||||
/// Пути к экранам
|
||||
static const String debugScreenPath = '/debug';
|
||||
static const String tokensScreenPath = 'debug/tokens';
|
||||
static const String uiKitScreenPath = 'debug/ui_kit';
|
||||
static const String iconsScreenPath = 'debug/icons';
|
||||
static const String themeScreenPath = 'debug/theme';
|
||||
static const String langScreenPath = 'debug/lang';
|
||||
|
||||
/// Метод для построения ветки роутов по фиче профиля пользователя
|
||||
/// Метод для создания роутов для отладки
|
||||
///
|
||||
/// Принимает:
|
||||
/// - [routes] - вложенные роуты
|
||||
static StatefulShellBranch buildShellBranch({
|
||||
List<RouteBase> routes = const [],
|
||||
List<NavigatorObserver>? observers,
|
||||
}) =>
|
||||
StatefulShellBranch(
|
||||
initialLocation: _debugScreenPath,
|
||||
observers: observers,
|
||||
static GoRoute buildRoutes({List<RouteBase> routes = const []}) => GoRoute(
|
||||
path: debugScreenPath,
|
||||
name: debugScreenName,
|
||||
builder: (context, state) => const DebugScreen(),
|
||||
routes: [
|
||||
...routes,
|
||||
GoRoute(
|
||||
path: _debugScreenPath,
|
||||
name: debugScreenName,
|
||||
builder: (context, state) => const DebugScreen(),
|
||||
routes: routes,
|
||||
path: tokensScreenPath,
|
||||
name: tokensScreenName,
|
||||
builder: (context, state) => const TokensScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: uiKitScreenPath,
|
||||
name: uiKitScreenName,
|
||||
builder: (context, state) => const UiKitScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: iconsScreenPath,
|
||||
name: iconsScreenName,
|
||||
builder: (context, state) => const IconsScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: themeScreenPath,
|
||||
name: themeScreenName,
|
||||
builder: (context, state) => const ThemeScreen(),
|
||||
),
|
||||
GoRoute(
|
||||
path: langScreenPath,
|
||||
name: langScreenName,
|
||||
builder: (context, state) => const LangScreen(),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
@@ -1,118 +0,0 @@
|
||||
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/gen/assets.gen.dart';
|
||||
import 'package:friflex_starter/gen/fonts.gen.dart';
|
||||
|
||||
class DebugScreen extends StatelessWidget {
|
||||
const DebugScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Debug Screen')),
|
||||
body: Center(
|
||||
child: ListView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
children: [
|
||||
Text(
|
||||
'Реализация SecureStorage: ${context.di.services.secureStorage.nameImpl}',
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'Окружение: ${context.di.appConfig.env.name}',
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
context.theme.changeTheme();
|
||||
},
|
||||
child: const Text('Сменить тему'),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
ColoredBox(
|
||||
color: context.colors.testColor,
|
||||
child: const SizedBox(height: 100, width: 100),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'Текущая тема: ${context.theme.themeMode}',
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'Текущий репозиторий: ${context.di.repositories.authRepository.name}',
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
context.localization.changeLocal(
|
||||
const Locale('ru', 'RU'),
|
||||
);
|
||||
},
|
||||
child: const Text('Сменить язык на Rусский'),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
context.localization.changeLocal(
|
||||
const Locale('en', 'EN'),
|
||||
);
|
||||
},
|
||||
child: const Text('Сменить язык на Английский'),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'Тестовое слово montserrat bold: ${context.l10n.helloWorld}',
|
||||
style: TextStyle(
|
||||
color: context.colors.testColor,
|
||||
fontFamily: Assets.fonts.montserratBold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'Тестовое слово montserrat medium: ${context.l10n.helloWorld}',
|
||||
style: TextStyle(
|
||||
color: context.colors.testColor,
|
||||
fontFamily: FontFamily.montserrat,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'Текущий язык: ${context.l10n.localeName}',
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
const Text('Тестовая иконка из assets'),
|
||||
const SizedBox(height: 16),
|
||||
Assets.icons.home.svg(),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
throw Exception(
|
||||
'Тестовая ошибка Exception для отладки FlutterError',
|
||||
);
|
||||
},
|
||||
child: const Text('Вызывать ошибку FlutterError'),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
await _callError();
|
||||
},
|
||||
child: const Text('Вызывать ошибку PlatformDispatcher'),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
await context.di.debugService.openDebugScreen(context);
|
||||
},
|
||||
child: const Text('Вызывать Экран отладки'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _callError() async {
|
||||
throw Exception('Тестовая ошибка Exception для отладки PlatformDispatcher');
|
||||
}
|
||||
}
|
||||
@@ -1,19 +1,57 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:friflex_starter/features/debug/i_debug_service.dart';
|
||||
import 'package:talker_bloc_logger/talker_bloc_logger_observer.dart';
|
||||
import 'package:talker_dio_logger/talker_dio_logger_interceptor.dart';
|
||||
import 'package:talker_flutter/talker_flutter.dart';
|
||||
|
||||
/// Класс реализации интерфейса Debug сервиса
|
||||
/// {@template debug_service}
|
||||
/// Реализация сервиса отладки, с помощью Talker
|
||||
/// {@endtemplate}
|
||||
class DebugService implements IDebugService {
|
||||
/// {@macro debug_service}
|
||||
DebugService() {
|
||||
_talker = TalkerFlutter.init();
|
||||
_talkerDioLogger = TalkerDioLogger(talker: _talker);
|
||||
_talkerRouteObserver = TalkerRouteObserver(_talker);
|
||||
_talkerBlocObserver = TalkerBlocObserver(talker: _talker);
|
||||
}
|
||||
|
||||
/// Наименование сервиса
|
||||
static const name = 'DebugService';
|
||||
|
||||
@override
|
||||
void logDebug(Object message, {Object? logLevel, Map<String, dynamic>? args}) {
|
||||
if (kDebugMode) {
|
||||
print('Message: $message');
|
||||
}
|
||||
/// Реализация Talker
|
||||
late final Talker _talker;
|
||||
|
||||
/// Реализация логики
|
||||
/// Реализация TalkerDioLogger
|
||||
late final TalkerDioLogger _talkerDioLogger;
|
||||
|
||||
/// Реализация TalkerRouteObserver
|
||||
late final TalkerRouteObserver _talkerRouteObserver;
|
||||
|
||||
/// Реализация TalkerBlocLoggerObserver
|
||||
late final TalkerBlocObserver _talkerBlocObserver;
|
||||
|
||||
/// Получает TalkerDioLoggerInterceptor
|
||||
@override
|
||||
TalkerDioLogger get dioLogger => _talkerDioLogger;
|
||||
|
||||
/// Получает TalkerRouteObserver\
|
||||
@override
|
||||
TalkerRouteObserver get routeObserver => _talkerRouteObserver;
|
||||
|
||||
/// Получает TalkerBlocObserver
|
||||
@override
|
||||
TalkerBlocObserver get blocObserver => _talkerBlocObserver;
|
||||
|
||||
@override
|
||||
void logDebug(
|
||||
Object message, {
|
||||
Object? logLevel,
|
||||
Map<String, dynamic>? args,
|
||||
}) {
|
||||
_talker.debug(
|
||||
message is Function ? Function.apply(message, []) as Object : message,
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
@@ -24,43 +62,34 @@ class DebugService implements IDebugService {
|
||||
Map<String, dynamic>? args,
|
||||
StackTrace? stackTrace,
|
||||
}) {
|
||||
final logMessage = message is Function ? Function.apply(message, []) as Object : message;
|
||||
if (kDebugMode) {
|
||||
print('Message: $logMessage');
|
||||
print('Error: $error');
|
||||
print('StackTrace: $stackTrace');
|
||||
}
|
||||
|
||||
/// Реализация логики
|
||||
final logMessage =
|
||||
message is Function ? Function.apply(message, []) as Object : message;
|
||||
_talker.error(logMessage, error, stackTrace);
|
||||
}
|
||||
|
||||
@override
|
||||
void log(Object message, {Object? logLevel, Map<String, dynamic>? args}) {
|
||||
final logMessage = message is Function ? Function.apply(message, []) as Object : message;
|
||||
if (kDebugMode) {
|
||||
print('Message: $logMessage');
|
||||
}
|
||||
|
||||
/// Реализация логики
|
||||
final logMessage =
|
||||
message is Function ? Function.apply(message, []) as Object : message;
|
||||
_talker.log(logMessage);
|
||||
}
|
||||
|
||||
@override
|
||||
void logWarning(Object message, {Object? logLevel, Map<String, dynamic>? args}) {
|
||||
final logMessage = message is Function ? Function.apply(message, []) as Object : message;
|
||||
if (kDebugMode) {
|
||||
print('Message: $logMessage');
|
||||
}
|
||||
|
||||
/// Реализация логики
|
||||
void logWarning(
|
||||
Object message, {
|
||||
Object? logLevel,
|
||||
Map<String, dynamic>? args,
|
||||
}) {
|
||||
final logMessage =
|
||||
message is Function ? Function.apply(message, []) as Object : message;
|
||||
_talker.warning(logMessage);
|
||||
}
|
||||
|
||||
@override
|
||||
Future<T?> openDebugScreen<T>(BuildContext context, {bool useRootNavigator = false}) {
|
||||
if (kDebugMode) {
|
||||
print('Переход на страницу отладки');
|
||||
}
|
||||
|
||||
/// Реализация логики
|
||||
return Future.value();
|
||||
Future<void> openDebugScreen(BuildContext context,
|
||||
{bool useRootNavigator = false,}) async {
|
||||
await Navigator.of(context).push(
|
||||
MaterialPageRoute(builder: (context) => TalkerScreen(talker: _talker)),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,15 @@ import 'package:flutter/material.dart';
|
||||
abstract interface class IDebugService {
|
||||
static const name = 'IDebugService';
|
||||
|
||||
/// Наблюдение за dio
|
||||
dynamic get dioLogger;
|
||||
|
||||
/// Наблюдение за роутами
|
||||
dynamic get routeObserver;
|
||||
|
||||
/// Наблюдение за BLoC
|
||||
dynamic get blocObserver;
|
||||
|
||||
/// Метод для логирования сообщений
|
||||
void log(
|
||||
Object message, {
|
||||
@@ -39,7 +48,7 @@ abstract interface class IDebugService {
|
||||
/// Принимает:
|
||||
/// - [context] - для определения навигатора по нему
|
||||
/// - [useRootNavigator] - при true, открывает окно в корневом навигаторе
|
||||
Future<T?> openDebugScreen<T>(
|
||||
Future<void> openDebugScreen(
|
||||
BuildContext context, {
|
||||
bool useRootNavigator = false,
|
||||
});
|
||||
|
||||
96
lib/features/debug/screens/debug_screen.dart
Normal file
96
lib/features/debug/screens/debug_screen.dart
Normal file
@@ -0,0 +1,96 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:friflex_starter/app/app_box.dart';
|
||||
import 'package:friflex_starter/app/app_context_ext.dart';
|
||||
import 'package:friflex_starter/features/debug/debug_routes.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
|
||||
class DebugScreen extends StatelessWidget {
|
||||
const DebugScreen({Key? key}) : super(key: key);
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Debug Screen')),
|
||||
body: Center(
|
||||
child: ListView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
children: [
|
||||
Text(
|
||||
'Окружение: ${context.di.appConfig.env.name}',
|
||||
),
|
||||
const HBox(22),
|
||||
Text(
|
||||
'Реализация AppServices: ${context.di.services.secureStorage.nameImpl}',
|
||||
),
|
||||
const HBox(22),
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
await context.di.debugService.openDebugScreen(context);
|
||||
},
|
||||
child: const Text('Вызывать Экран отладки'),
|
||||
),
|
||||
const HBox(22),
|
||||
const Text('Экраны для отладки:'),
|
||||
const HBox(16),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
context.pushNamed(DebugRoutes.iconsScreenName);
|
||||
},
|
||||
child: const Text('Экран с иконками'),
|
||||
),
|
||||
const HBox(16),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
context.pushNamed(DebugRoutes.themeScreenName);
|
||||
},
|
||||
child: const Text('Экран настроек темы'),
|
||||
),
|
||||
const HBox(16),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
context.pushNamed(DebugRoutes.tokensScreenName);
|
||||
},
|
||||
child: const Text('Экран с токенами'),
|
||||
),
|
||||
const HBox(16),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
context.pushNamed(DebugRoutes.uiKitScreenName);
|
||||
},
|
||||
child: const Text('Экран UI Kit'),
|
||||
),
|
||||
const HBox(16),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
context.pushNamed(DebugRoutes.langScreenName);
|
||||
},
|
||||
child: const Text('Экран локализации'),
|
||||
),
|
||||
const HBox(22),
|
||||
const Text('Имитирование ошибок:'),
|
||||
const HBox(16),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
throw Exception(
|
||||
'Тестовая ошибка Exception для отладки FlutterError',
|
||||
);
|
||||
},
|
||||
child: const Text('Вызывать ошибку FlutterError'),
|
||||
),
|
||||
const HBox(16),
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
await _callError();
|
||||
},
|
||||
child: const Text('Вызывать ошибку PlatformDispatcher'),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> _callError() async {
|
||||
throw Exception('Тестовая ошибка Exception для отладки PlatformDispatcher');
|
||||
}
|
||||
}
|
||||
54
lib/features/debug/screens/icons_screen.dart
Normal file
54
lib/features/debug/screens/icons_screen.dart
Normal file
@@ -0,0 +1,54 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:friflex_starter/app/app_box.dart';
|
||||
import 'package:friflex_starter/gen/assets.gen.dart';
|
||||
|
||||
/// {@template IconsScreen}
|
||||
/// Экран для отрисовки иконок
|
||||
/// {@endtemplate}
|
||||
class IconsScreen extends StatelessWidget {
|
||||
/// {@macro IconsScreen}
|
||||
const IconsScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final iconList = Assets.icons.values
|
||||
.map(
|
||||
(icon) => _ItemIcon(icon: icon.svg(), name: icon.path),
|
||||
)
|
||||
.toList();
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Иконки')),
|
||||
body: Center(
|
||||
child: ListView.separated(
|
||||
padding: const EdgeInsets.all(16),
|
||||
itemBuilder: (context, index) {
|
||||
return iconList[index];
|
||||
},
|
||||
separatorBuilder: (context, index) => const Divider(),
|
||||
itemCount: iconList.length,
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Приватный класс для реализации элемента списка иконок
|
||||
class _ItemIcon extends StatelessWidget {
|
||||
/// Создает экземпляр элемента списка иконок
|
||||
///
|
||||
/// Принимает:
|
||||
/// - [icon] - иконка
|
||||
/// - [name] - название иконки
|
||||
const _ItemIcon({required this.icon, required this.name});
|
||||
|
||||
/// Иконка
|
||||
final Widget icon;
|
||||
|
||||
/// Название иконки
|
||||
final String name;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(children: [icon, const WBox(16), Text(name)]);
|
||||
}
|
||||
}
|
||||
65
lib/features/debug/screens/lang_screen.dart
Normal file
65
lib/features/debug/screens/lang_screen.dart
Normal file
@@ -0,0 +1,65 @@
|
||||
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/gen/assets.gen.dart';
|
||||
import 'package:friflex_starter/gen/fonts.gen.dart';
|
||||
|
||||
/// {@template LangScreen}
|
||||
/// Экран для отладки языков приложения
|
||||
/// {@endtemplate}
|
||||
class LangScreen extends StatelessWidget {
|
||||
/// {@macro LangScreen}
|
||||
const LangScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Lang')),
|
||||
body: Center(
|
||||
child: ListView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
children: [
|
||||
const SizedBox(height: 16),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
context.localization.changeLocal(
|
||||
const Locale('ru', 'RU'),
|
||||
);
|
||||
},
|
||||
child: const Text('Сменить язык на Rусский'),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
context.localization.changeLocal(
|
||||
const Locale('en', 'EN'),
|
||||
);
|
||||
},
|
||||
child: const Text('Сменить язык на Английский'),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'Тестовое слово bold: ${context.l10n.helloWorld}',
|
||||
style: TextStyle(
|
||||
color: context.colors.testColor,
|
||||
fontFamily: Assets.fonts.montserratBold,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'Тестовое слово medium: ${context.l10n.helloWorld}',
|
||||
style: TextStyle(
|
||||
color: context.colors.testColor,
|
||||
fontFamily: FontFamily.montserrat,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'Текущий язык: ${context.l10n.localeName}',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
40
lib/features/debug/screens/theme_screen.dart
Normal file
40
lib/features/debug/screens/theme_screen.dart
Normal file
@@ -0,0 +1,40 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:friflex_starter/app/app_context_ext.dart';
|
||||
import 'package:friflex_starter/app/theme/app_colors_scheme.dart';
|
||||
|
||||
/// {@template ThemeScreen}
|
||||
/// Экран для отладки темы приложения
|
||||
/// {@endtemplate}
|
||||
class ThemeScreen extends StatelessWidget {
|
||||
/// {@macro ThemeScreen}
|
||||
const ThemeScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Theme')),
|
||||
body: Center(
|
||||
child: ListView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
children: [
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
context.theme.changeTheme();
|
||||
},
|
||||
child: const Text('Сменить тему'),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
ColoredBox(
|
||||
color: context.colors.testColor,
|
||||
child: const SizedBox(height: 100, width: 100),
|
||||
),
|
||||
const SizedBox(height: 16),
|
||||
Text(
|
||||
'Текущая тема: ${context.theme.themeMode}',
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
31
lib/features/debug/screens/tokens_screen.dart
Normal file
31
lib/features/debug/screens/tokens_screen.dart
Normal file
@@ -0,0 +1,31 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// {@template TokensScreen}
|
||||
/// Экран для отображения токенов
|
||||
/// {@endtemplate}
|
||||
class TokensScreen extends StatelessWidget {
|
||||
/// {@macro TokensScreen}
|
||||
const TokensScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(title: const Text('Tokens')),
|
||||
body: Center(
|
||||
child: ListView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
children: const [
|
||||
Text(
|
||||
'Access Token: ',
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
Text(
|
||||
'Refresh Token: ',
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
31
lib/features/debug/screens/ui_kit_screen.dart
Normal file
31
lib/features/debug/screens/ui_kit_screen.dart
Normal file
@@ -0,0 +1,31 @@
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
/// {@template UiKitScreen}
|
||||
/// Экран для отрисовки UI Kit
|
||||
/// и тестирования его компонентов.
|
||||
/// {@endtemplate}
|
||||
class UiKitScreen extends StatelessWidget {
|
||||
/// {@macro UiKitScreen}
|
||||
const UiKitScreen({super.key});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
appBar: AppBar(
|
||||
title: const Text('UI Kit Screen'),
|
||||
),
|
||||
body: Center(
|
||||
child: ListView(
|
||||
padding: const EdgeInsets.all(16),
|
||||
children: const [
|
||||
Text(
|
||||
'UI Kit Screen',
|
||||
),
|
||||
SizedBox(height: 16),
|
||||
// Здесь можно добавить другие компоненты UI Kit
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user