Files
Remever/lib/screens/dialogs/replace_diaog.dart

236 lines
7.4 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
import 'dart:io';
import 'package:auto_route/auto_route.dart';
import 'package:flutter/material.dart';
import 'package:remever/common/functions.dart';
import 'package:remever/common/resources.dart';
import 'package:remever/common/utils.dart';
import 'package:remever/common/widgets/typography.dart';
import 'package:remever/common/widgets/w_if.dart';
import 'package:remever/common/widgets/wspace.dart';
import 'package:remever/components/extensions/context.dart';
import 'package:remever/components/extensions/state.dart';
import 'package:remever/database/database.dart';
import 'package:remever/gen/assets.gen.dart';
import 'package:remever/inject.dart';
import 'package:remever/router.gr.dart';
import 'package:remever/screens/collections/widgets/collection_progress_bar.dart';
import 'package:remever/screens/dialogs/dialog_header.dart';
import 'package:remever/services/tickets/tickets_interface.dart';
import 'package:remever/widgets/primary_button.dart';
/// Диалог для переноса карточки в другую коллекцию
class ReplaceDialog extends StatefulWidget {
const ReplaceDialog({
super.key,
required this.currentCollection,
required this.ticket,
});
final Collection currentCollection;
final Ticket ticket;
@override
State<ReplaceDialog> createState() => _ReplaceDialogState();
}
class _ReplaceDialogState extends State<ReplaceDialog> {
/// Коллекция, в которую будет перенесена карточка
Collection? _collectionToTransfer;
/// Обработчик выбора коллекции
void _onCollectionTap() {
context.pushRoute(
CollectionSearchRoute(
onCollectionSelect: (collection) {
safeSetState(() => _collectionToTransfer = collection);
},
),
);
}
/// Обработчик кнопки "Перенести"
Future<void> _onTransferTap() async {
// Проверяем, что выбрана коллекция для переноса
if (_collectionToTransfer == null) {
showErrorToast('Необходимо выбрать место для переноса');
return;
}
// Проверяем, что выбранная коллекция не совпадает с текущей
if (_collectionToTransfer!.id == widget.currentCollection.id) {
showErrorToast(
'Карточка уже находится в этой коллекции, выберите другую',
);
return;
}
// Переносим карточку через сервис
await getIt<TicketsInterface>().transferTicket(
widget.ticket.id,
_collectionToTransfer!.id,
);
// Закрываем диалог
Navigator.of(context).pop();
}
@override
Widget build(BuildContext context) {
return Material(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const DialogHeader(title: 'Переместить карточку'),
const HSpace(16),
Padding(
padding: const EdgeInsets.symmetric(horizontal: 28).r,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
AppTypography('из коллекции', type: Medium16px()),
const HSpace(8),
_buildCollection(widget.currentCollection),
const HSpace(16),
_buildArrowIcon(),
const HSpace(16),
AppTypography('в коллекцию', type: Medium16px()),
const HSpace(8),
_buildCollection(_collectionToTransfer, isSelectable: true),
const HSpace(16),
_buildTransferButton(),
],
),
),
],
),
);
}
/// Кнопка "Перенести"
Widget _buildTransferButton() {
return PrimaryButton(
onTap: _onTransferTap,
child: AppTypography(
'Перенести',
type: Regular14px(),
color: AppColors.white,
),
);
}
/// Иконка стрелки между коллекциями
Widget _buildArrowIcon() {
return Center(
child: SizedBox.square(
dimension: 34.r,
child: DecoratedBox(
decoration: const BoxDecoration(
shape: BoxShape.circle,
color: AppColors.gray,
),
child: Center(
child: Assets.icons.typeArrowDown.image(height: 18.h, width: 18.w),
),
),
),
);
}
/// Виджет отображения коллекции
Widget _buildCollection(Collection? collection, {bool isSelectable = false}) {
return GestureDetector(
onTap: isSelectable ? _onCollectionTap : null,
child: Container(
constraints: BoxConstraints(minHeight: 66.h, maxHeight: 84.h),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(12).r,
color: AppColors.white,
),
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8).r,
child:
collection == null
? Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
AppTypography('Выберите коллекцию', type: Bold14px()),
],
)
: Row(
children: [
_buildAvatar(collection),
const WSpace(5),
_buildInfo(collection),
],
),
),
);
}
/// Информация о коллекции
Widget _buildInfo(Collection collection) {
return SizedBox(
width: 230.w,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
_buildTitle(collection),
const HSpace(4),
Row(
children: [
Assets.icons.typeCards.image(
height: 18.h,
width: 18.w,
color: AppColors.disabled,
),
const WSpace(2),
AppTypography(
'${collection.likesCount} ${Utils.declOfNum(collection.likesCount, ['карточек', 'карточки', 'карточек'])}',
type: Regular14px(),
color: AppColors.disabled,
),
],
),
const HSpace(6),
const CollectionProgressBar(),
],
),
);
}
/// Название коллекции
Widget _buildTitle(Collection collection) {
return AppTypography(
collection.title,
type: Medium16px(),
maxLines: 2,
softWrap: true,
);
}
/// Обложка коллекции
Widget _buildAvatar(Collection collection) {
return SizedBox.square(
dimension: 50.r,
child: DecoratedBox(
decoration: BoxDecoration(shape: BoxShape.circle, color: AppColors.bg),
child: Wif(
condition: collection.image != null,
builder:
(context) => ClipOval(
child: Image.file(File(collection.image!), fit: BoxFit.cover),
),
fallback:
(context) => Center(
child: AppTypography(
collection.title.substring(0, 1),
type: Bold34px(),
),
),
),
),
);
}
}