bugfix(collections): Оптимизация редактирования и создания коллекции

This commit is contained in:
2025-09-08 17:42:09 +03:00
parent cebc46bbb3
commit a376faf0ce
3 changed files with 321 additions and 303 deletions

File diff suppressed because one or more lines are too long

View File

@@ -1,5 +1,5 @@
import 'dart:convert';
import 'dart:io'; import 'dart:io';
import 'dart:typed_data';
import 'package:auto_route/auto_route.dart'; import 'package:auto_route/auto_route.dart';
import 'package:file_picker/file_picker.dart'; import 'package:file_picker/file_picker.dart';
@@ -36,88 +36,85 @@ class CrudCollectionScreen extends StatefulWidget {
} }
class _CrudCollectionScreenState extends State<CrudCollectionScreen> { class _CrudCollectionScreenState extends State<CrudCollectionScreen> {
/// Флаг публичности коллекции late CrudCollectionDto _collection;
bool _isPublic = false; bool _isPublic = false;
CrudCollectionDto? _collection;
/// Смена публичности
void _setPublic(bool public) {
_collection = _collection?.copyWith(isPublic: public);
safeSetState(() => _isPublic = public);
}
@override @override
void initState() { void initState() {
super.initState();
_initializeCollection();
}
void _initializeCollection() {
_collection = CrudCollectionDto( _collection = CrudCollectionDto(
desc: widget.editedCollection?.desc ?? '', desc: widget.editedCollection?.desc ?? '',
title: widget.editedCollection?.title ?? '', title: widget.editedCollection?.title ?? '',
isPublic: widget.editedCollection?.isPublic ?? false, isPublic: widget.editedCollection?.isPublic ?? false,
avatar: widget.editedCollection?.image, avatar: widget.editedCollection?.image,
); );
_isPublic = _collection.isPublic;
super.initState();
} }
void _pickImage() async { Future<void> _pickImage() async {
final result = await FilePicker.platform.pickFiles(); final result = await FilePicker.platform.pickFiles();
if (result == null || result.files.isEmpty) { if (result?.files.single.path case final String? path?) {
try {
final bytes = await File(path!).readAsBytes();
_updateCollection(avatar: bytes);
} catch (e) {
showErrorToast('Не удалось загрузить изображение');
}
} else {
showErrorToast('Файл не выбран'); showErrorToast('Файл не выбран');
return; }
} }
final filePath = result.files.single.path; void _updateCollection({
String? title,
if (filePath == null) { String? desc,
showErrorToast('Не удалось получить путь к файлу'); bool? isPublic,
Uint8List? avatar,
return; }) {
} _collection = _collection.copyWith(
title: title ?? _collection.title,
final file = File(filePath); desc: desc ?? _collection.desc,
final bytes = await file.readAsBytes(); isPublic: isPublic ?? _collection.isPublic,
avatar: avatar ?? _collection.avatar,
// final base64String = base64Encode(bytes); );
_collection = _collection?.copyWith(avatar: bytes);
safeSetState(() {}); safeSetState(() {});
} }
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
logger.logBuild('build create screen');
return Scaffold( return Scaffold(
backgroundColor: AppColors.gray_bg, backgroundColor: AppColors.gray_bg,
appBar: _buildAppBar(context), appBar: _buildAppBar(),
body: _buildMainBody(context), body: _buildMainBody(),
); );
} }
/// Основное тело экрана Widget _buildMainBody() {
Widget _buildMainBody(BuildContext context) {
return Padding( return Padding(
padding: const EdgeInsets.symmetric(horizontal: 16).r, padding: const EdgeInsets.symmetric(horizontal: 16).r,
child: SingleChildScrollView( child: SingleChildScrollView(
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: [
const HSpace(16), const HSpace(16),
_buildPhotoAndTitle(context), _buildPhotoAndTitle(),
const HSpace(16), const HSpace(16),
..._buildDescription(context), ..._buildDescription(),
const HSpace(16), const HSpace(16),
// _buildPublickSwitch(), // _buildPublicSwitch(),
const HSpace(16), const HSpace(16),
AnimatedOpacity( AnimatedOpacity(
// opacity: _isPublic ? 1 : 0, // opacity: _isPublic ? 1 : 0,
opacity: 0, opacity: 0,
duration: const Duration(seconds: 1), duration: const Duration(milliseconds: 300),
child: Column( child: Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[ children: [
..._buildTagButton(), ..._buildTagButton(),
const HSpace(16), const HSpace(16),
_buildTagsList(), _buildTagsList(),
@@ -125,7 +122,7 @@ class _CrudCollectionScreenState extends State<CrudCollectionScreen> {
], ],
), ),
), ),
_buildCreateBtn(context), _buildCreateBtn(),
const BottomSafeSpace(), const BottomSafeSpace(),
], ],
), ),
@@ -133,30 +130,10 @@ class _CrudCollectionScreenState extends State<CrudCollectionScreen> {
); );
} }
///Кнопка создания Widget _buildCreateBtn() {
Widget _buildCreateBtn(BuildContext context) {
return PrimaryButton( return PrimaryButton(
height: 52, height: 52,
onTap: () async { onTap: _handleCreateOrUpdate,
if (_collection!.desc.isEmpty && _collection!.title.isEmpty) {
showErrorToast(
'Для создания публичной коллекции добавьте описание и тэги',
);
return;
}
widget.editedCollection != null
? await getIt<CollectionsInterface>().updateCollection(
_collection!,
widget.editedCollection!.id,
)
: await getIt<CollectionsInterface>().createCollection(
_collection!,
);
context.back();
},
color: AppColors.primary, color: AppColors.primary,
child: AppTypography( child: AppTypography(
widget.editedCollection == null widget.editedCollection == null
@@ -168,24 +145,73 @@ class _CrudCollectionScreenState extends State<CrudCollectionScreen> {
); );
} }
/// Построение списка тегов Future<void> _handleCreateOrUpdate() async {
if (!_isCollectionValid()) return;
if (!_hasChanges()) {
context.back();
}
try {
final collectionService = getIt<CollectionsInterface>();
widget.editedCollection != null
? await collectionService.updateCollection(
_collection,
widget.editedCollection!.id,
)
: await collectionService.createCollection(_collection);
context.back();
} catch (e) {
showErrorToast(
'Ошибка при ${widget.editedCollection != null ? 'обновлении' : 'создании'} коллекции',
);
}
}
bool _isCollectionValid() {
if (_collection.title.isEmpty && _collection.desc.isEmpty) {
showErrorToast('Для создания коллекции добавьте название и описание');
return false;
}
if (_isPublic && _collection.desc.isEmpty) {
showErrorToast(
'Для создания публичной коллекции добавьте описание и тэги',
);
return false;
}
return true;
}
Widget _buildTagsList() { Widget _buildTagsList() {
return SizedBox( return SizedBox(
height: 68.h, height: 68.h,
child: Row( child: Row(
children: <Widget>[ children: [
Expanded( Expanded(
child: Wrap( child: Wrap(
runSpacing: 8.r, runSpacing: 8.r,
spacing: 8.r, spacing: 8.r,
children: List<Widget>.generate(6, (int index) { children: List.generate(6, _buildTagItem),
),
),
const WSpace(9),
_buildAddTagButton(),
],
),
);
}
Widget _buildTagItem(int index) {
return GestureDetector( return GestureDetector(
onTap: () {}, onTap: () {},
child: Container( child: Container(
height: 30, height: 30,
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: borderRadius: const BorderRadius.all(Radius.circular(6)).r,
const BorderRadius.all(Radius.circular(6)).r,
color: const Color(0xFFFFE4E6), color: const Color(0xFFFFE4E6),
), ),
child: Padding( child: Padding(
@@ -193,7 +219,7 @@ class _CrudCollectionScreenState extends State<CrudCollectionScreen> {
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisSize: MainAxisSize.min, mainAxisSize: MainAxisSize.min,
children: <Widget>[ children: [
AppTypography( AppTypography(
'tag $index', 'tag $index',
type: Regular14px(), type: Regular14px(),
@@ -201,61 +227,42 @@ class _CrudCollectionScreenState extends State<CrudCollectionScreen> {
color: AppColors.danger, color: AppColors.danger,
), ),
const WSpace(8), const WSpace(8),
Center( Icon(Icons.close, size: 14.r, color: AppColors.danger),
child: Icon(
Icons.close,
size: 14.r,
color: AppColors.danger,
),
),
], ],
), ),
), ),
), ),
); );
}), }
),
), Widget _buildAddTagButton() {
const WSpace(9), return GestureDetector(
GestureDetector( onTap: _showTagsDialog,
onTap: () { child: AppTypography('+13', type: Medium16px(), color: AppColors.primary),
);
}
void _showTagsDialog() {
showCuperModalBottomSheet( showCuperModalBottomSheet(
context: context, context: context,
height: 270.h, height: 270.h,
builder: (BuildContext context) => const TagsDialog(), builder: (_) => const TagsDialog(),
);
},
child: AppTypography(
'+13',
type: Medium16px(),
color: AppColors.primary,
),
),
],
),
); );
} }
/// Построение кнопки добавления тега
List<Widget> _buildTagButton() { List<Widget> _buildTagButton() {
return <Widget>[ return [
AppTypography('Тэги', type: SemiBold14px()), AppTypography('Тэги', type: SemiBold14px()),
const HSpace(4), const HSpace(4),
CrudCollectionField( CrudCollectionField(height: 42, width: 348, hint: 'Добавить тэг'),
height: 42,
width: 348,
hint: 'Добавить тэг',
// onTap: () => context.pushRoute(const AddTagsRoute()),
),
]; ];
} }
/// Построение свитчера на публичность коллекции Widget _buildPublicSwitch() {
Widget _buildPublickSwitch() {
return GestureDetector( return GestureDetector(
onTap: () => _setPublic(!_isPublic), onTap: _togglePublic,
child: Row( child: Row(
children: <Widget>[ children: [
SizedBox.square( SizedBox.square(
dimension: 20.r, dimension: 20.r,
child: Assets.icons.typePublic.image(color: AppColors.primary), child: Assets.icons.typePublic.image(color: AppColors.primary),
@@ -287,95 +294,116 @@ class _CrudCollectionScreenState extends State<CrudCollectionScreen> {
); );
} }
/// Построение блока с описанием void _togglePublic() => _setPublic(!_isPublic);
List<Widget> _buildDescription(BuildContext context) {
return <Widget>[ void _setPublic(bool isPublic) {
_updateCollection(isPublic: isPublic);
safeSetState(() => _isPublic = isPublic);
}
List<Widget> _buildDescription() {
return [
AppTypography('Описание', type: SemiBold14px()), AppTypography('Описание', type: SemiBold14px()),
const HSpace(4), const HSpace(4),
CrudCollectionField( CrudCollectionField(
height: 110, height: 110,
width: 348, width: 348,
hint: 'Добавить описание', hint: 'Добавить описание',
content: _collection?.desc, content: _collection.desc,
onTap: () { onTap:
context.pushRoute( () => _navigateToFullscreenField(
CrudCollectionFullscreenField(
title: 'Описание', title: 'Описание',
height: 333, height: 333,
content: _collection?.desc, content: _collection.desc,
onEditingComplete: (res) { onResult: (result) => _updateCollection(desc: result ?? ''),
safeSetState(
() => _collection = _collection?.copyWith(desc: res ?? ''),
);
},
), ),
);
},
), ),
]; ];
} }
/// Построение блока фото и заголовка Widget _buildTitle() {
Widget _buildPhotoAndTitle(BuildContext context) {
return Row(
children: <Widget>[_buildPhoto(), const WSpace(8), _buildTitle(context)],
);
}
/// Построение поля для ввода заголовка
Widget _buildTitle(BuildContext context) {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, children: [
children: <Widget>[
AppTypography('Название', type: SemiBold14px()), AppTypography('Название', type: SemiBold14px()),
const HSpace(4), const HSpace(4),
CrudCollectionField( CrudCollectionField(
height: 91, height: 91,
width: 225, width: 225,
hint: 'Добавить название', hint: 'Добавить название',
content: _collection?.title, content: _collection.title,
onTap: () { onTap:
context.pushRoute( () => _navigateToFullscreenField(
CrudCollectionFullscreenField(
title: 'Название', title: 'Название',
hint: 'Максимальное количество символов - 250', hint: 'Максимальное количество символов - 250',
content: _collection?.title, content: _collection.title,
onEditingComplete: (res) { onResult: (result) => _updateCollection(title: result ?? ''),
safeSetState(
() => _collection = _collection?.copyWith(title: res ?? ''),
);
},
), ),
);
},
), ),
], ],
); );
} }
/// Построение обложки void _navigateToFullscreenField({
required String title,
String? hint,
String? content,
required Function(String?) onResult,
double height = 91,
}) {
context.pushRoute(
CrudCollectionFullscreenField(
title: title,
hint: hint,
height: height,
content: content,
onEditingComplete: onResult,
),
);
}
Widget _buildPhotoAndTitle() {
return Row(
children: [
_buildPhoto(),
const WSpace(8),
Expanded(child: _buildTitle()),
],
);
}
Widget _buildPhoto() { Widget _buildPhoto() {
return GestureDetector( return GestureDetector(
onTap: () => _pickImage(), onTap: _pickImage,
child: SizedBox.square( child: SizedBox.square(
dimension: 115.r, dimension: 115.r,
child: DecoratedBox( child: DecoratedBox(
decoration: const BoxDecoration( decoration: const BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
gradient: LinearGradient( gradient: LinearGradient(
colors: <Color>[Color(0xFFB6AAFE), Color(0xFFDBD7F4)], colors: [Color(0xFFB6AAFE), Color(0xFFDBD7F4)],
begin: Alignment.bottomLeft, begin: Alignment.bottomLeft,
end: Alignment.topRight, end: Alignment.topRight,
), ),
), ),
child: Wif( child: Wif(
condition: _collection!.avatar != null, condition: _collection.avatar != null,
builder: builder:
(context) => ClipOval( (_) => ClipOval(
child: Image.memory(_collection!.avatar!, fit: BoxFit.cover), child: Image.memory(
_collection.avatar!,
fit: BoxFit.cover,
errorBuilder: (_, __, ___) => _buildPhotoPlaceholder(),
), ),
fallback: ),
(context) => SizedBox.square( fallback: (_) => _buildPhotoPlaceholder(),
),
),
),
);
}
Widget _buildPhotoPlaceholder() {
return SizedBox.square(
dimension: 32.r, dimension: 32.r,
child: Center( child: Center(
child: Assets.icons.typePhoto.image( child: Assets.icons.typePhoto.image(
@@ -384,38 +412,16 @@ class _CrudCollectionScreenState extends State<CrudCollectionScreen> {
color: AppColors.primary, color: AppColors.primary,
), ),
), ),
),
),
),
),
); );
} }
/// Построение шапки AppBar _buildAppBar() {
AppBar _buildAppBar(BuildContext context) {
return AppBar( return AppBar(
toolbarHeight: 56.h, toolbarHeight: 56.h,
backgroundColor: AppColors.white, backgroundColor: AppColors.white,
shadowColor: Colors.transparent, shadowColor: Colors.transparent,
leading: IconButton( leading: IconButton(
onPressed: () async { onPressed: _handleBackPress,
if (widget.editedCollection != null) {
final bool? res = await showCuperModalBottomSheet(
context: context,
height: 262.h,
builder:
(BuildContext context) => const AlertInfoDialog(
title: 'Вы хотите сбросить все внесенные изменения?',
acceptTitle: 'Да, сбросить',
declineTitle: 'Нет, оставить',
),
);
if (res != null && res) context.back();
} else {
context.back();
}
},
icon: const Icon(CupertinoIcons.left_chevron, color: Colors.black), icon: const Icon(CupertinoIcons.left_chevron, color: Colors.black),
), ),
centerTitle: true, centerTitle: true,
@@ -429,35 +435,66 @@ class _CrudCollectionScreenState extends State<CrudCollectionScreen> {
color: AppColors.body_text, color: AppColors.body_text,
), ),
), ),
actions: <Widget>[ actions: [
Wif( if (widget.editedCollection != null && _hasChanges())
condition: widget.editedCollection != null, Padding(
builder: (BuildContext context) {
return Padding(
padding: const EdgeInsets.only(right: 16).r, padding: const EdgeInsets.only(right: 16).r,
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: _showResetDialog,
showCuperModalBottomSheet( child: Assets.icons.typeTrash.image(
height: 24.h,
width: 24.w,
color: AppColors.danger,
),
),
),
],
);
}
Future<void> _handleBackPress() async {
if (widget.editedCollection != null) {
final shouldExit = await _showExitDialog();
if (shouldExit == true) context.back();
} else {
context.back();
}
}
Future<bool?> _showExitDialog() async {
// Показываем диалог только если есть редактируемая коллекция и есть изменения
if (widget.editedCollection != null && _hasChanges()) {
return showCuperModalBottomSheet<bool>(
context: context, context: context,
height: 262.h, height: 262.h,
builder: builder:
(BuildContext context) => const AlertInfoDialog( (_) => const AlertInfoDialog(
title: 'Вы хотите сбросить все внесенные изменения?', title: 'Вы хотите сбросить все внесенные изменения?',
acceptTitle: 'Да, сбросить', acceptTitle: 'Да, сбросить',
declineTitle: 'Нет, оставить', declineTitle: 'Нет, оставить',
), ),
); );
}, }
child: Assets.icons.typeTrash.image( return true;
height: 24.h, }
width: 24.w,
color: AppColors.primary, bool _hasChanges() {
), // Если нет редактируемой коллекции, значит это создание новой
), if (widget.editedCollection == null) return false;
);
}, // Сравниваем все поля
), return _collection.title != widget.editedCollection!.title ||
], _collection.desc != widget.editedCollection!.desc ||
); _collection.isPublic != widget.editedCollection!.isPublic ||
_collection.avatar != widget.editedCollection!.image;
}
void _showResetDialog() {
_showExitDialog().then((result) {
if (result == true) {
_initializeCollection();
safeSetState(() {});
}
});
} }
} }

View File

@@ -39,10 +39,10 @@ class _CrudCollectionFullscreenFieldState
@override @override
void initState() { void initState() {
super.initState();
if (widget.content != null) { if (widget.content != null) {
_controller.text = widget.content!; _controller.text = widget.content!;
} }
super.initState();
} }
@override @override
@@ -58,15 +58,14 @@ class _CrudCollectionFullscreenFieldState
top: false, top: false,
child: Scaffold( child: Scaffold(
backgroundColor: AppColors.gray_bg, backgroundColor: AppColors.gray_bg,
appBar: _buildAppBar(context), appBar: _buildAppBar(),
body: _buildMainBody(context), body: _buildMainBody(),
), ),
), ),
); );
} }
/// Построение основного тела экрана Widget _buildMainBody() {
Widget _buildMainBody(BuildContext context) {
return Stack( return Stack(
children: [ children: [
Padding( Padding(
@@ -77,7 +76,7 @@ class _CrudCollectionFullscreenFieldState
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
const HSpace(16), const HSpace(16),
_buildField(context), _buildField(),
if (widget.hint != null) ...[ if (widget.hint != null) ...[
const HSpace(16), const HSpace(16),
AppTypography( AppTypography(
@@ -96,12 +95,10 @@ class _CrudCollectionFullscreenFieldState
); );
} }
/// Построение интерактивной плашки меню
Widget _buildMenu() { Widget _buildMenu() {
return Consumer<ScreenHeight>( return Consumer<ScreenHeight>(
builder: (context, screenHeight, _) { builder: (_, screenHeight, __) {
return AnimatedOpacity( return AnimatedOpacity(
// opacity: screenHeight.isOpen ? 1 : 0,
opacity: 1, opacity: 1,
duration: const Duration(milliseconds: 500), duration: const Duration(milliseconds: 500),
child: Container( child: Container(
@@ -126,7 +123,6 @@ class _CrudCollectionFullscreenFieldState
); );
} }
/// Кнопка "Вставить из буфера обмена"
Widget _buildPasteButton() { Widget _buildPasteButton() {
return GestureDetector( return GestureDetector(
onTap: _onPasteTap, onTap: _onPasteTap,
@@ -134,22 +130,20 @@ class _CrudCollectionFullscreenFieldState
); );
} }
/// Обработка нажатия на кнопку "Вставить" Future<void> _onPasteTap() async {
void _onPasteTap() async {
try { try {
final ClipboardData? data = await Clipboard.getData('text/plain'); final data = await Clipboard.getData(Clipboard.kTextPlain);
if (data?.text == null || data!.text!.isEmpty) { if (data?.text?.isEmpty ?? true) {
showErrorToast('Не удалось получить текст из буфера обмена'); showErrorToast('Не удалось получить текст из буфера обмена');
return; return;
} }
_controller.text += ' ${data.text}'; _controller.text += ' ${data!.text}';
showSuccessToast('Текст вставлен из буфера обмена'); showSuccessToast('Текст вставлен из буфера обмена');
} catch (e) { } catch (e) {
showErrorToast('Ошибка при вставке текста: $e'); showErrorToast('Ошибка при вставке текста: $e');
} }
} }
/// Кнопка "Скопировать в буфер обмена"
Widget _buildCopyButton() { Widget _buildCopyButton() {
return GestureDetector( return GestureDetector(
onTap: _onCopyTap, onTap: _onCopyTap,
@@ -157,8 +151,7 @@ class _CrudCollectionFullscreenFieldState
); );
} }
/// Обработка нажатия на кнопку "Копировать" Future<void> _onCopyTap() async {
void _onCopyTap() async {
if (_controller.text.isEmpty) { if (_controller.text.isEmpty) {
showErrorToast('Нет содержимого для отправки в буфер обмена'); showErrorToast('Нет содержимого для отправки в буфер обмена');
return; return;
@@ -171,45 +164,30 @@ class _CrudCollectionFullscreenFieldState
} }
} }
/// Кнопка "Подтвердить"
Widget _buildSubmitButton() { Widget _buildSubmitButton() {
return GestureDetector( return GestureDetector(
onTap: _onSubmitTap, onTap: _onSubmitTap,
child: SizedBox.square( child: SizedBox.square(
dimension: 32.r, dimension: 32.r,
child: DecoratedBox( child: const DecoratedBox(
decoration: const BoxDecoration( decoration: BoxDecoration(
shape: BoxShape.circle, shape: BoxShape.circle,
color: AppColors.primary, color: AppColors.primary,
), ),
child: Center( child: Center(
child: Assets.icons.typeCheck.image( child: Icon(Icons.check, color: AppColors.white, size: 24),
height: 24.h,
width: 24.w,
color: AppColors.white,
),
), ),
), ),
), ),
); );
} }
/// Обработка нажатия на кнопку "Подтвердить"
void _onSubmitTap() { void _onSubmitTap() {
if (_controller.text.isEmpty) {
showErrorToast(
'Для создания публичной коллекции добавьте описание и тэги',
);
return;
}
widget.onEditingComplete(_controller.text); widget.onEditingComplete(_controller.text);
context.back(); context.back();
} }
/// Построение поля ввода Widget _buildField() {
Widget _buildField(BuildContext context) {
return SizedBox( return SizedBox(
height: widget.height.h, height: widget.height.h,
child: DecoratedBox( child: DecoratedBox(
@@ -236,30 +214,26 @@ class _CrudCollectionFullscreenFieldState
); );
} }
/// Построение шапки AppBar _buildAppBar() {
AppBar _buildAppBar(BuildContext context) {
return AppBar( return AppBar(
toolbarHeight: 56.h, toolbarHeight: 56.h,
backgroundColor: AppColors.white, backgroundColor: AppColors.white,
shadowColor: Colors.transparent, shadowColor: Colors.transparent,
leading: IconButton( leading: IconButton(
onPressed: () => _handleBackPress(context), onPressed: () => _handleBackPress(),
icon: const Icon(CupertinoIcons.left_chevron, color: Colors.black), icon: const Icon(CupertinoIcons.left_chevron, color: Colors.black),
), ),
centerTitle: true, centerTitle: true,
title: GestureDetector( title: AppTypography(
// onLongPress: () => _showExitDialog(context),
child: AppTypography(
widget.title, widget.title,
type: SemiBold20px(), type: SemiBold20px(),
color: AppColors.body_text, color: AppColors.body_text,
), ),
),
actions: [ actions: [
Padding( Padding(
padding: const EdgeInsets.only(right: 16).r, padding: const EdgeInsets.only(right: 16).r,
child: GestureDetector( child: GestureDetector(
onTap: () => _showResetDialog(context), onTap: _showResetDialog,
child: Assets.icons.typeTrash.image( child: Assets.icons.typeTrash.image(
height: 24.h, height: 24.h,
width: 24.w, width: 24.w,
@@ -271,39 +245,46 @@ class _CrudCollectionFullscreenFieldState
); );
} }
/// Обработка нажатия на кнопку "Назад" Future<void> _handleBackPress() async {
void _handleBackPress(BuildContext context) async { final shouldExit = await _showExitDialog();
// final bool? shouldExit = await _showExitDialog(context); if (shouldExit ?? false) {
// if (shouldExit ?? false) {
context.back(); context.back();
// } }
} }
/// Показать диалог выхода Future<bool?> _showExitDialog() async {
Future<bool?> _showExitDialog(BuildContext context) async { final res = await showCuperModalBottomSheet<bool>(
return showCuperModalBottomSheet(
context: context, context: context,
height: 262.h, height: 262.h,
builder: builder:
(context) => const AlertInfoDialog( (_) => const AlertInfoDialog(
title: 'Вы хотите выйти из режима создания описания коллекции?', title: 'У вас есть несохраненные изменения',
acceptTitle: 'Выйти, не сохранять', acceptTitle: 'Выйти',
declineTitle: 'Сохранить и выйти', declineTitle: 'Сохранить и выйти',
), ),
); );
if (res == null) return false;
if (res) return true;
widget.onEditingComplete(_controller.text);
return true;
} }
/// Показать диалог сброса Future<void> _showResetDialog() async {
void _showResetDialog(BuildContext context) { final res = await showCuperModalBottomSheet<bool>(
// showCuperModalBottomSheet( context: context,
// context: context, height: 262.h,
// height: 262.h, builder:
// builder: (_) => AlertInfoDialog(
// (context) => const AlertInfoDialog( title: 'Удалить вcе содержимое поля "${widget.title}"?',
// title: 'Вы хотите сбросить все внесенные изменения?', acceptTitle: 'Удалить',
// acceptTitle: 'Да, сбросить', declineTitle: 'Отменить',
// declineTitle: 'Нет, оставить', ),
// ), );
// );
if (res == true) {
_controller.clear();
}
} }
} }