import 'dart:convert'; import 'dart:io'; import 'package:dio/dio.dart'; import 'package:flutter/material.dart'; import 'package:flutter_colorpicker/flutter_colorpicker.dart'; import 'package:mnemo_cards/admin/admin_api.dart'; import 'package:mnemo_cards/di/injector.dart'; import 'package:mnemo_cards/managers/repository/api.dart'; import 'package:mnemo_cards/managers/repository/dio_provider.dart'; import 'package:mnemo_cards/utils/iterable_helper.dart'; import 'package:mnemo_cards/utils/string_helper.dart'; import 'package:mnemo_cards/widgets/header.dart'; import 'package:mnemo_cards_common/mnemo_cards_common.dart'; import 'package:file_picker/file_picker.dart'; import '../main.dart'; import '../widgets/image_fade.dart'; class AddPackage with Api { EditCardPackDto cardPackDto; AdminApi adminApi; bool palleteVisible = false; AddPackage(EditCardPackDto? cardPackDto, this.adminApi) : cardPackDto = cardPackDto ?? EditCardPackDto.fromJson({}); void _deletePack() async { final delete = await showDialog( context: scaffoldKey.currentContext!, builder: (c) => Center( child: Container( color: Colors.white, width: 200, child: IconButton( icon: Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text('Удалить '), Icon(Icons.delete), ], ), onPressed: () { Navigator.of(c).pop(true); }, ), ), )); if (!delete) return; final result = await adminApi.deletePack(cardPackDto); if (!result) { ScaffoldMessenger.of(scaffoldKey.currentContext!).showSnackBar(SnackBar( content: Text('ERROR'), )); } else { ScaffoldMessenger.of(scaffoldKey.currentContext!).showSnackBar(SnackBar( content: Text('Success!!!'), )); appRouter.maybePop(); } } void _savePack() async { final result = await adminApi.editPack(cardPackDto); if (!result) { ScaffoldMessenger.of(scaffoldKey.currentContext!).showSnackBar(SnackBar( content: Text('ERROR'), )); } else { ScaffoldMessenger.of(scaffoldKey.currentContext!).showSnackBar(SnackBar( content: Text('Success!!!'), )); appRouter.maybePop(); } } void addPack(BuildContext context) { showDialog( context: context, builder: (c) { return Center( child: Card( child: Padding( padding: const EdgeInsets.all(8.0), child: ListView( children: [ Header( '${cardPackDto.id}', hasPopButton: true, trail: Row( children: [ IconButton( onPressed: _savePack, icon: Icon(Icons.save), ), if (cardPackDto.id != null) GestureDetector( onLongPress: _deletePack, child: Icon(Icons.delete), ) ], ), ), _TextParam( 'Title', cardPackDto.title, (v) { cardPackDto = cardPackDto.copyWith.title(v); }, ), _TextParam( 'Subtitle', cardPackDto.subtitle, (v) { cardPackDto = cardPackDto.copyWith.subtitle(v); }, ), _TextParam( 'Description', cardPackDto.description, (v) => cardPackDto = cardPackDto.copyWith.description(v), ), _TextParam( 'Size', cardPackDto.size?.toString(), (v) { cardPackDto = cardPackDto.copyWith.size( int.tryParse(v), ); }, ), _TextParam( 'Google play id', cardPackDto.googlePlayId, (v) { cardPackDto = cardPackDto.copyWith.googlePlayId(v); }, ), _TextParam( 'Appstore id', cardPackDto.appStoreId, (v) { cardPackDto = cardPackDto.copyWith.appStoreId(v); }, ), _TextParam( 'Price', cardPackDto.price, (v) { cardPackDto = cardPackDto.copyWith.price(v); }, ), Row( children: [ Expanded(child: Text('Enabled ')), StatefulBuilder(builder: (context, setState) { return Switch( value: cardPackDto.enabled ?? false, onChanged: (v) { setState(() { cardPackDto = cardPackDto.copyWith.enabled(v); }); }); }), ], ), StatefulBuilder(builder: (context, setState) { return Column( children: [ Row( children: [ Expanded(child: Text('Поменять цвет ')), Switch( value: palleteVisible, onChanged: (v) => setState(() { palleteVisible = !palleteVisible; }), ), ], ), if (palleteVisible) ColorPicker( pickerAreaHeightPercent: 0.5, paletteType: PaletteType.hsvWithHue, pickerColor: cardPackDto.color?.asColor ?? Colors.transparent, onColorChanged: (color) { String? colorString; if (color.alpha != 0) { colorString = '#${color.toHexString()}'; } cardPackDto = cardPackDto.copyWith.color(colorString); }, ), ], ); }), StatefulBuilder(builder: (context, setState) { return 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) { final file = result.files.first; final encoded = base64.normalize( base64.encode( File(file.path!).readAsBytesSync(), ), ); cardPackDto = cardPackDto.copyWith.cover( encoded, ); } setState(() {}); }, child: cardPackDto.cover == null ? Container( alignment: Alignment.center, color: Colors.white, child: Icon( Icons.image, color: Colors.grey, ), ) : Stack( children: [ ImageFade( key: ValueKey(cardPackDto.id), image: MemoryImage( base64.decode(cardPackDto.cover!)), fit: BoxFit.contain, syncDuration: Duration.zero, ), Positioned( top: 8.0, right: 8.0, child: IconButton( onPressed: () { cardPackDto = cardPackDto.copyWith( cover: null, ); setState(() {}); }, icon: Icon(Icons.delete)), ), ], ), ), ); }), _TextParam( 'Preview cards', cardPackDto.previewCards?.toString(), (v) { final cards = (jsonDecode(v) as List).cast(); cardPackDto = cardPackDto.copyWith.previewCards(cards); }, ), _TextParam( 'Order (lower is higher)', cardPackDto.order?.toString(), (v) { cardPackDto = cardPackDto.copyWith.order( int.tryParse(v), ); }, ), _TextParam( 'Cards order (ids)', cardPackDto.cardsOrder?.join(','), (v) { final ids = v .split(',') .map((s) => int.tryParse(s.trim())) .whereNotNull() .toList(); cardPackDto = cardPackDto.copyWith(cardsOrder: ids); }, ), ], ), ), ), ); }); } } class _TextParam extends StatelessWidget { final String title; final String? initial; final Function(String v) onChanged; _TextParam(this.title, this.initial, this.onChanged); @override Widget build(BuildContext context) { return Padding( padding: const EdgeInsets.all(8.0), child: Row( children: [ Text(title), Expanded( child: TextField( controller: TextEditingController(text: initial), onChanged: onChanged, ), ), ], ), ); } }