302 lines
14 KiB
Dart
302 lines
14 KiB
Dart
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!,
|
||
),
|
||
),
|
||
],
|
||
),
|
||
),
|
||
],
|
||
);
|
||
}),
|
||
],
|
||
),
|
||
),
|
||
),
|
||
);
|
||
});
|
||
}
|
||
}
|