mnemo_cards/lib/admin/add_card.dart
2024-05-29 00:25:51 +03:00

302 lines
14 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:convert';
import 'dart:io';
import 'dart:typed_data';
import 'package:dio/dio.dart';
import 'package:flutter/material.dart';
import 'package:file_picker/file_picker.dart';
import 'package:mnemo_cards/admin/admin_api.dart';
import 'package:mnemo_cards/domain/router/app_router.dart';
import 'package:mnemo_cards/features/packs/images_holder.dart';
import 'package:mnemo_cards/widgets/game_card_widget.dart';
import 'package:mnemo_cards/widgets/header.dart';
import 'package:mnemo_cards_common/mnemo_cards_common.dart';
import '../di/locator.dart';
import '../main.dart';
import '../widgets/image_fade.dart';
class EditCard {
GameCardDto gameCardDto;
AdminApi adminApi;
bool imageChanged = false;
EditCard(GameCardDto? cardDto, this.adminApi)
: gameCardDto = cardDto ??
const GameCardDto(
id: -1,
image: null,
mnemo: null,
original: null,
translation: null,
transcription: null,
transcriptionMnemo: null,
imageBack: null,
back: null,
);
void _saveCard() async {
final dto = imageChanged ? gameCardDto : gameCardDto.copyWith.image(null);
final result = await adminApi.addCard(dto);
if (!result) {
ScaffoldMessenger.of(scaffoldKey.currentContext!).showSnackBar(SnackBar(
content: Text('ERROR'),
));
} else {
ScaffoldMessenger.of(scaffoldKey.currentContext!).showSnackBar(SnackBar(
content: Text('Success!!!'),
));
appRouter.maybePop();
}
}
void _deleteCard() async {
final result = await adminApi.deleteCard(gameCardDto);
if (!result) {
ScaffoldMessenger.of(scaffoldKey.currentContext!).showSnackBar(SnackBar(
content: Text('ERROR'),
));
} else {
ScaffoldMessenger.of(scaffoldKey.currentContext!).showSnackBar(SnackBar(
content: Text('Success!!!'),
));
appRouter.maybePop();
}
}
void addCard(BuildContext context) {
final theme = Theme.of(context).textTheme;
final TextEditingController originalController =
TextEditingController(text: gameCardDto.original);
final TextEditingController translationController =
TextEditingController(text: gameCardDto.translation);
final TextEditingController transcriptionController =
TextEditingController(text: gameCardDto.transcription);
final TextEditingController transcriptionMnemoController =
TextEditingController(text: gameCardDto.transcriptionMnemo);
final TextEditingController mnemoController =
TextEditingController(text: gameCardDto.mnemo);
final TextEditingController backController =
TextEditingController(text: gameCardDto.back);
showDialog(
context: context,
builder: (c) {
return Center(
child: Scaffold(
body: Material(
child: ListView(
children: [
Header(
'${gameCardDto.id}',
hasPopButton: true,
trail: Row(
children: [
IconButton(
onPressed: _saveCard,
icon: Icon(Icons.save),
),
if (gameCardDto.id >= 0)
GestureDetector(
onLongPress: _deleteCard,
child: Icon(Icons.delete),
)
],
),
),
StatefulBuilder(builder: (context, setState) {
return Stack(
alignment: Alignment.center,
children: [
Padding(
padding: EdgeInsets.all(8.0),
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
Column(
children: [
TextField(
controller: originalController,
onChanged: (v) {
gameCardDto =
gameCardDto.copyWith(original: v);
},
decoration: InputDecoration(
hintText: 'Original (cerdo)'),
maxLines: 1,
style: theme.displayMedium?.copyWith(
fontSize:
theme.displayMedium!.fontSize!,
),
),
TextField(
controller: translationController,
onChanged: (v) {
gameCardDto = gameCardDto.copyWith(
translation: v);
},
decoration: InputDecoration(
hintText: 'Translation (свинья)'),
maxLines: 1,
style: theme.headlineSmall?.copyWith(
color: theme.headlineSmall!.color!
.withOpacity(0.5),
fontSize:
theme.headlineSmall!.fontSize!,
),
),
Row(
children: [
Flexible(
child: TextField(
controller: transcriptionController,
onChanged: (v) {
gameCardDto = gameCardDto
.copyWith(transcription: v);
},
decoration: InputDecoration(
hintText: 'Transcription'),
maxLines: 1,
style:
theme.headlineSmall?.copyWith(
color:
theme.headlineSmall!.color!,
fontSize: theme
.headlineSmall!.fontSize!,
),
),
),
SizedBox(
width: 4.0,
),
Flexible(
child: TextField(
controller:
transcriptionMnemoController,
onChanged: (v) {
gameCardDto =
gameCardDto.copyWith(
transcriptionMnemo: v);
},
decoration: InputDecoration(
hintText:
'Transcription mnemo'),
maxLines: 1,
style:
theme.headlineSmall?.copyWith(
color:
theme.headlineSmall!.color!,
fontSize: theme
.headlineSmall!.fontSize!,
),
),
),
],
),
],
),
SizedBox(
width: MediaQuery.of(context).size.width - 20,
height:
MediaQuery.of(context).size.width - 20,
child: GestureDetector(
onTap: () async {
FilePickerResult? result =
await FilePicker.platform.pickFiles();
if (result != null &&
result.files.isNotEmpty) {
imageChanged = true;
final file = result.files.first;
final encoded = base64.normalize(
base64.encode(
File(file.path!).readAsBytesSync(),
),
);
gameCardDto = gameCardDto.copyWith(
image: encoded,
);
}
setState(() {});
},
child: gameCardDto.image == null
? Container(
alignment: Alignment.center,
color: Colors.white,
child: Icon(
Icons.image,
color: Colors.grey,
),
)
: Stack(
children: [
ImageFade(
key: ValueKey(gameCardDto.id),
image: MemoryImage(
base64.decode(
gameCardDto.image!)),
fit: BoxFit.contain,
syncDuration: Duration.zero,
),
Positioned(
top: 8.0,
right: 8.0,
child: IconButton(
onPressed: () {
gameCardDto =
gameCardDto.copyWith(
image: null,
);
setState(() {});
},
icon: Icon(Icons.delete)),
),
],
),
),
),
TextField(
controller: mnemoController,
onChanged: (v) {
gameCardDto =
gameCardDto.copyWith(mnemo: v);
},
decoration: InputDecoration(
hintText: 'Mnemo ([свинья] с сердечком)',
),
maxLines: 1,
style: theme.headlineSmall?.copyWith(
fontSize: theme.headlineSmall!.fontSize!,
),
),
TextField(
controller: backController,
onChanged: (v) {
gameCardDto = gameCardDto.copyWith(
back: v,
);
},
decoration: InputDecoration(
hintText: 'Задняя сторона',
),
maxLines: 1,
style: theme.headlineSmall?.copyWith(
fontSize: theme.headlineSmall!.fontSize!,
),
),
],
),
),
],
);
}),
],
),
),
),
);
});
}
}