import 'package:auto_route/auto_route.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_keyboard_size/flutter_keyboard_size.dart'; import 'package:remever/common/functions.dart'; import 'package:remever/common/resources.dart'; import 'package:remever/common/widgets/typography.dart'; import 'package:remever/common/widgets/wspace.dart'; import 'package:remever/components/extensions/context.dart'; import 'package:remever/gen/assets.gen.dart'; import 'package:remever/screens/dialogs/alert_dialog.dart'; @RoutePage() class CrudCollectionFullscreenField extends StatefulWidget { const CrudCollectionFullscreenField({ super.key, this.title = '', this.hint, this.content, this.height = 92, required this.onEditingComplete, }); final String title; final double height; final String? hint; final String? content; final void Function(String?) onEditingComplete; @override State createState() => _CrudCollectionFullscreenFieldState(); } class _CrudCollectionFullscreenFieldState extends State { final TextEditingController _controller = TextEditingController(); @override void initState() { if (widget.content != null) { _controller.text = widget.content!; } super.initState(); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return KeyboardSizeProvider( child: SafeArea( top: false, child: Scaffold( backgroundColor: AppColors.gray_bg, appBar: _buildAppBar(context), body: _buildMainBody(context), ), ), ); } /// Построение основного тела экрана Widget _buildMainBody(BuildContext context) { return Stack( children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 16).r, child: SingleChildScrollView( physics: const BouncingScrollPhysics(), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const HSpace(16), _buildField(context), if (widget.hint != null) ...[ const HSpace(16), AppTypography( widget.hint!, type: Regular14px(), color: AppColors.disabled, ), ], const HSpace(50), ], ), ), ), Align(alignment: Alignment.bottomCenter, child: _buildMenu()), ], ); } /// Построение интерактивной плашки меню Widget _buildMenu() { return Consumer( builder: (context, screenHeight, _) { return AnimatedOpacity( // opacity: screenHeight.isOpen ? 1 : 0, opacity: 1, duration: const Duration(milliseconds: 500), child: Container( height: 64.h, decoration: BoxDecoration( color: AppColors.white, border: Border( top: BorderSide(color: AppColors.gray, width: 1.w), ), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ _buildPasteButton(), _buildCopyButton(), _buildSubmitButton(), ], ), ), ); }, ); } /// Кнопка "Вставить из буфера обмена" Widget _buildPasteButton() { return GestureDetector( onTap: _onPasteTap, child: Assets.icons.typePaste.image(height: 24.h, width: 24.w), ); } /// Обработка нажатия на кнопку "Вставить" void _onPasteTap() async { try { final ClipboardData? data = await Clipboard.getData('text/plain'); if (data?.text == null || data!.text!.isEmpty) { showErrorToast('Не удалось получить текст из буфера обмена'); return; } _controller.text += ' ${data.text}'; showSuccessToast('Текст вставлен из буфера обмена'); } catch (e) { showErrorToast('Ошибка при вставке текста: $e'); } } /// Кнопка "Скопировать в буфер обмена" Widget _buildCopyButton() { return GestureDetector( onTap: _onCopyTap, child: Assets.icons.typeCopy.image(height: 24.h, width: 24.w), ); } /// Обработка нажатия на кнопку "Копировать" void _onCopyTap() async { if (_controller.text.isEmpty) { showErrorToast('Нет содержимого для отправки в буфер обмена'); return; } try { await Clipboard.setData(ClipboardData(text: _controller.text)); showSuccessToast('Текст скопирован в буфер обмена'); } catch (e) { showErrorToast('Ошибка при копировании текста: $e'); } } /// Кнопка "Подтвердить" Widget _buildSubmitButton() { return GestureDetector( onTap: _onSubmitTap, child: SizedBox.square( dimension: 32.r, child: DecoratedBox( decoration: const BoxDecoration( shape: BoxShape.circle, color: AppColors.primary, ), child: Center( child: Assets.icons.typeCheck.image( height: 24.h, width: 24.w, color: AppColors.white, ), ), ), ), ); } /// Обработка нажатия на кнопку "Подтвердить" void _onSubmitTap() { if (_controller.text.isEmpty) { showErrorToast( 'Для создания публичной коллекции добавьте описание и тэги', ); return; } widget.onEditingComplete(_controller.text); context.back(); } /// Построение поля ввода Widget _buildField(BuildContext context) { return SizedBox( height: widget.height.h, child: DecoratedBox( decoration: BoxDecoration( color: AppColors.white, borderRadius: BorderRadius.circular(12).r, ), child: Padding( padding: const EdgeInsets.all(12).r, child: TextField( autofocus: true, controller: _controller, textCapitalization: TextCapitalization.sentences, maxLines: 99, maxLength: 250, cursorColor: AppColors.danger, decoration: const InputDecoration.collapsed( hintText: 'Введите содержимое', hintStyle: TextStyle(color: AppColors.gray), ), ), ), ), ); } /// Построение шапки AppBar _buildAppBar(BuildContext context) { return AppBar( toolbarHeight: 56.h, backgroundColor: AppColors.white, shadowColor: Colors.transparent, leading: IconButton( onPressed: () => _handleBackPress(context), icon: const Icon(CupertinoIcons.left_chevron, color: Colors.black), ), centerTitle: true, title: GestureDetector( // onLongPress: () => _showExitDialog(context), child: AppTypography( widget.title, type: SemiBold20px(), color: AppColors.body_text, ), ), actions: [ Padding( padding: const EdgeInsets.only(right: 16).r, child: GestureDetector( onTap: () => _showResetDialog(context), child: Assets.icons.typeTrash.image( height: 24.h, width: 24.w, color: AppColors.danger, ), ), ), ], ); } /// Обработка нажатия на кнопку "Назад" void _handleBackPress(BuildContext context) async { // final bool? shouldExit = await _showExitDialog(context); // if (shouldExit ?? false) { context.back(); // } } /// Показать диалог выхода Future _showExitDialog(BuildContext context) async { return showCuperModalBottomSheet( context: context, height: 262.h, builder: (context) => const AlertInfoDialog( title: 'Вы хотите выйти из режима создания описания коллекции?', acceptTitle: 'Выйти, не сохранять', declineTitle: 'Сохранить и выйти', ), ); } /// Показать диалог сброса void _showResetDialog(BuildContext context) { // showCuperModalBottomSheet( // context: context, // height: 262.h, // builder: // (context) => const AlertInfoDialog( // title: 'Вы хотите сбросить все внесенные изменения?', // acceptTitle: 'Да, сбросить', // declineTitle: 'Нет, оставить', // ), // ); } }