Создание карточки в коллекции + экран поиска коллекции
This commit is contained in:
@@ -1,22 +1,91 @@
|
||||
import 'dart:io';
|
||||
import 'dart:math';
|
||||
|
||||
import 'package:auto_route/auto_route.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/cupertino.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/gen/assets.gen.dart';
|
||||
import 'package:remever/inject.dart';
|
||||
import 'package:remever/models/create_ticket_dto.dart';
|
||||
import 'package:remever/router.gr.dart';
|
||||
import 'package:remever/screens/collections/widgets/collection_progress_bar.dart';
|
||||
import 'package:remever/screens/collections/widgets/learning_card.dart';
|
||||
import 'package:remever/screens/create_card/widgets/crud_ticket.dart';
|
||||
import 'package:remever/services/tickets/tickets_interface.dart';
|
||||
import 'package:remever/widgets/debug/app_debug.dart';
|
||||
import 'package:remever/widgets/primary_button.dart';
|
||||
|
||||
@RoutePage()
|
||||
class CreateScreen extends StatelessWidget {
|
||||
class CreateScreen extends StatefulWidget {
|
||||
const CreateScreen({super.key});
|
||||
|
||||
@override
|
||||
State<CreateScreen> createState() => _CreateScreenState();
|
||||
}
|
||||
|
||||
class _CreateScreenState extends State<CreateScreen> {
|
||||
CreateTicketDto _dto = CreateTicketDto();
|
||||
|
||||
void _pickImage(bool isQuestion) async {
|
||||
final result = await FilePicker.platform.pickFiles();
|
||||
|
||||
if (result == null || result.files.isEmpty) {
|
||||
showErrorToast('Файл не выбран');
|
||||
return;
|
||||
}
|
||||
|
||||
final filePath = result.files.single.path;
|
||||
|
||||
if (filePath == null) {
|
||||
showErrorToast('Не удалось получить путь к файлу');
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
final file = File(filePath);
|
||||
final bytes = await file.readAsBytes();
|
||||
|
||||
_dto =
|
||||
isQuestion
|
||||
? _dto.copyWith(questionImage: bytes)
|
||||
: _dto.copyWith(answerImage: bytes);
|
||||
|
||||
safeSetState(() {});
|
||||
}
|
||||
|
||||
void _onCollectionTap() {
|
||||
{
|
||||
context.pushRoute(
|
||||
CollectionSearchRoute(
|
||||
onCollectionSelect: (collection) {
|
||||
safeSetState(() => _dto = _dto.copyWith(collection: collection));
|
||||
},
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void _onCreateTap() async {
|
||||
if (_dto.collection == null ||
|
||||
_dto.answer == null ||
|
||||
_dto.question == null) {
|
||||
showErrorToast('Необходимо заполнить все поля');
|
||||
return;
|
||||
}
|
||||
|
||||
await getIt<TicketsInterface>().createTicket(_dto);
|
||||
|
||||
context.pushRoute(CollectionRoute());
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Scaffold(
|
||||
@@ -59,42 +128,55 @@ class CreateScreen extends StatelessWidget {
|
||||
const HSpace(16),
|
||||
AppTypography('Вопрос', type: Medium16px()),
|
||||
const HSpace(4),
|
||||
LearningCard(
|
||||
index: 0,
|
||||
type: CardType.CREATE,
|
||||
CrudTicket(
|
||||
onTextTap: () {
|
||||
context.pushRoute(
|
||||
CrudCollectionFullscreenField(
|
||||
title: 'Вопрос',
|
||||
hint: '',
|
||||
height: 313,
|
||||
onEditingComplete: (p0) {},
|
||||
content: _dto.question,
|
||||
onEditingComplete: (res) {
|
||||
safeSetState(() {
|
||||
_dto = _dto.copyWith(question: res);
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onImageTap: () => _pickImage(true),
|
||||
isQuestion: true,
|
||||
dto: _dto,
|
||||
),
|
||||
const HSpace(16),
|
||||
AppTypography('Ответ', type: Medium16px()),
|
||||
LearningCard(
|
||||
index: 1,
|
||||
type: CardType.CREATE,
|
||||
const HSpace(4),
|
||||
CrudTicket(
|
||||
onTextTap: () {
|
||||
context.pushRoute(
|
||||
CrudCollectionFullscreenField(
|
||||
title: 'Ответ',
|
||||
hint: '',
|
||||
height: 313,
|
||||
onEditingComplete: (p0) {},
|
||||
content: _dto.answer,
|
||||
onEditingComplete: (res) {
|
||||
safeSetState(() {
|
||||
_dto = _dto.copyWith(answer: res);
|
||||
});
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
onImageTap: () => _pickImage(false),
|
||||
isQuestion: false,
|
||||
dto: _dto,
|
||||
),
|
||||
revertCard(),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
_createBtn(),
|
||||
_buildCreateButton(),
|
||||
const HSpace(31),
|
||||
],
|
||||
),
|
||||
@@ -124,8 +206,12 @@ class CreateScreen extends StatelessWidget {
|
||||
fit: BoxFit.contain,
|
||||
child: CupertinoSwitch(
|
||||
activeTrackColor: AppColors.primary,
|
||||
value: false,
|
||||
onChanged: (bool value) {},
|
||||
value: _dto.needRevert ?? false,
|
||||
onChanged: (bool value) {
|
||||
safeSetState(() {
|
||||
_dto = _dto.copyWith(needRevert: value);
|
||||
});
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
@@ -134,17 +220,22 @@ class CreateScreen extends StatelessWidget {
|
||||
);
|
||||
}
|
||||
|
||||
Row _filters() {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
_buildFilterButton(AppColors.gray_bg, 'Запомнить', () {}),
|
||||
_buildFilterButton(AppColors.white, 'Держать в фокусе', () {}),
|
||||
],
|
||||
Widget _filters() {
|
||||
return AppDebug(
|
||||
builder: (context, isDebug) {
|
||||
if (!isDebug) return SizedBox();
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: <Widget>[
|
||||
_buildFilterButton(AppColors.gray_bg, 'Запомнить', () {}),
|
||||
_buildFilterButton(AppColors.white, 'Держать в фокусе', () {}),
|
||||
],
|
||||
);
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Widget _createBtn() {
|
||||
Widget _buildCreateButton() {
|
||||
return PrimaryButton(
|
||||
color: AppColors.primary,
|
||||
child: AppTypography(
|
||||
@@ -152,7 +243,7 @@ class CreateScreen extends StatelessWidget {
|
||||
type: Medium14px(),
|
||||
color: AppColors.white,
|
||||
),
|
||||
onTap: () {},
|
||||
onTap: () => _onCreateTap(),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -176,7 +267,7 @@ class CreateScreen extends StatelessWidget {
|
||||
|
||||
Widget _buildCollection(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () {},
|
||||
onTap: () => _onCollectionTap(),
|
||||
child: Container(
|
||||
constraints: BoxConstraints(minHeight: 66.h, maxHeight: 84.h),
|
||||
decoration: BoxDecoration(
|
||||
@@ -184,8 +275,21 @@ class CreateScreen extends StatelessWidget {
|
||||
color: AppColors.white,
|
||||
),
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8).r,
|
||||
child: Row(
|
||||
children: <Widget>[_buildAvatar(), const WSpace(5), _buildInfo()],
|
||||
child: Wif(
|
||||
condition: _dto.collection != null,
|
||||
builder: (context) {
|
||||
return Row(
|
||||
children: <Widget>[_buildAvatar(), const WSpace(5), _buildInfo()],
|
||||
);
|
||||
},
|
||||
fallback: (context) {
|
||||
return Row(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: [
|
||||
AppTypography('Выберите коллекцию ', type: Bold14px()),
|
||||
],
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -212,7 +316,7 @@ class CreateScreen extends StatelessWidget {
|
||||
),
|
||||
const WSpace(2),
|
||||
AppTypography(
|
||||
Random().nextInt(654).toString(),
|
||||
'${_dto.collection!.likesCount.toString()} ${Utils.declOfNum(_dto.collection!.likesCount, ['карточек', 'карточки', 'карточек'])}',
|
||||
type: Regular14px(),
|
||||
color: AppColors.disabled,
|
||||
),
|
||||
@@ -230,7 +334,7 @@ class CreateScreen extends StatelessWidget {
|
||||
///
|
||||
Widget _buildTitle() {
|
||||
return AppTypography(
|
||||
'Астрономия',
|
||||
_dto.collection!.title,
|
||||
type: Medium16px(),
|
||||
maxLines: 2,
|
||||
softWrap: true,
|
||||
@@ -244,9 +348,21 @@ class CreateScreen extends StatelessWidget {
|
||||
return SizedBox.square(
|
||||
dimension: 50.r,
|
||||
child: DecoratedBox(
|
||||
decoration: BoxDecoration(
|
||||
shape: BoxShape.circle,
|
||||
image: DecorationImage(image: Assets.images.img.provider()),
|
||||
decoration: BoxDecoration(shape: BoxShape.circle, color: AppColors.bg),
|
||||
|
||||
child: Wif(
|
||||
condition: _dto.collection?.image != null,
|
||||
builder:
|
||||
(context) => ClipOval(
|
||||
child: Image.memory(_dto.collection!.image!, fit: BoxFit.cover),
|
||||
),
|
||||
fallback:
|
||||
(context) => Center(
|
||||
child: AppTypography(
|
||||
_dto.collection!.title.substring(0, 1),
|
||||
type: Bold34px(),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user