You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

723 lines
29KB

  1. import 'dart:convert';
  2. import 'package:farm_tpf/custom_model/Media.dart';
  3. import 'package:farm_tpf/custom_model/Nursery.dart';
  4. import 'package:farm_tpf/custom_model/NurseryDetail.dart';
  5. import 'package:farm_tpf/data/api/app_exception.dart';
  6. import 'package:farm_tpf/data/repository/repository.dart';
  7. import 'package:farm_tpf/models/index.dart';
  8. import 'package:farm_tpf/presentation/custom_widgets/bloc/media_helper_bloc.dart';
  9. import 'package:farm_tpf/presentation/custom_widgets/widget_loading.dart';
  10. import 'package:farm_tpf/presentation/custom_widgets/widget_media_picker.dart';
  11. import 'package:farm_tpf/presentation/screens/actions/bloc/action_detail_bloc.dart';
  12. import 'package:farm_tpf/presentation/screens/actions/nursery/bloc/expansion_list_bloc.dart';
  13. import 'package:farm_tpf/presentation/screens/resources/sc_resource_helper.dart';
  14. import 'package:farm_tpf/utils/bloc/bloc/status_add_form_bloc.dart';
  15. import 'package:farm_tpf/utils/const_color.dart';
  16. import 'package:farm_tpf/utils/const_common.dart';
  17. import 'package:farm_tpf/utils/const_string.dart';
  18. import 'package:farm_tpf/utils/const_style.dart';
  19. import 'package:farm_tpf/utils/pref.dart';
  20. import 'package:farm_tpf/utils/validators.dart';
  21. import 'package:flutter/material.dart';
  22. import 'package:flutter_bloc/flutter_bloc.dart';
  23. import 'package:flutter_cache_manager/flutter_cache_manager.dart';
  24. import 'package:flutter_datetime_picker/flutter_datetime_picker.dart';
  25. import 'package:fluttertoast/fluttertoast.dart';
  26. import 'package:get/get.dart';
  27. import 'package:get/state_manager.dart';
  28. import 'package:intl/intl.dart';
  29. import 'package:keyboard_dismisser/keyboard_dismisser.dart';
  30. import 'package:mime/mime.dart';
  31. import 'package:pattern_formatter/pattern_formatter.dart';
  32. import 'package:farm_tpf/utils/formatter.dart';
  33. class EditActionNurseryScreen extends StatefulWidget {
  34. final int cropId;
  35. final bool isEdit;
  36. final int activityId;
  37. EditActionNurseryScreen(
  38. {@required this.cropId, this.isEdit = false, this.activityId});
  39. @override
  40. _EditActionNurseryState createState() => _EditActionNurseryState();
  41. }
  42. class _EditActionNurseryState extends State<EditActionNurseryScreen> {
  43. final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
  44. final _repository = Repository();
  45. GlobalKey<FormState> _formKey = GlobalKey();
  46. bool _autoValidate = false;
  47. Nursery _nursery = Nursery();
  48. var pref = LocalPref();
  49. FlutterToast flutterToast;
  50. TextEditingController _substrateController = TextEditingController();
  51. TextEditingController _seedLengthController = TextEditingController();
  52. TextEditingController _quantityController = TextEditingController();
  53. TextEditingController _seedIncubationTimeController = TextEditingController();
  54. TextEditingController _descriptionController = TextEditingController();
  55. TextEditingController _workerNameController = TextEditingController();
  56. TextEditingController _trayNumberController = TextEditingController();
  57. String executeTimeView;
  58. DateTime executeTime = DateTime.now();
  59. List<NurseryDetail> currentNurseryDetail = List<NurseryDetail>();
  60. ExpansionListBloc _bloc;
  61. int currentIndexUpdate = -1;
  62. bool isResetForm = true;
  63. final changeSupply = Get.put(ChangeSupply());
  64. int selectedSupplyId = -1;
  65. List<String> filePaths = List<String>();
  66. var changeFileController = Get.put(ChangeFileController());
  67. @override
  68. void initState() {
  69. super.initState();
  70. changeSupply.initValue();
  71. changeFileController.initValue();
  72. _nursery.nurseryDetail = new List<NurseryDetail>();
  73. flutterToast = FlutterToast(context);
  74. //UPDATE
  75. if (_nursery.id != null) {
  76. try {
  77. executeTime =
  78. DateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").parse(_nursery.executeDate);
  79. } catch (_) {}
  80. } else {
  81. //ADD NEW
  82. var parsedExecuteDate =
  83. DateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(executeTime);
  84. _nursery.executeDate = "$parsedExecuteDate";
  85. }
  86. executeTimeView = DateFormat("dd/MM/yyyy HH:mm").format(executeTime);
  87. _nursery.cropId = widget.cropId;
  88. }
  89. _validateInputs() async {
  90. if (_formKey.currentState.validate()) {
  91. _formKey.currentState.save();
  92. LoadingDialog.showLoadingDialog(context);
  93. _nursery.nurseryDetail = currentNurseryDetail;
  94. filePaths = Get.find<ChangeFileController>().files;
  95. var activityNursery = jsonEncode(_nursery.toJson()).toString();
  96. //ADD NEW
  97. if (_nursery.activityId == null) {
  98. _repository.createNursery((value) {
  99. LoadingDialog.hideLoadingDialog(context);
  100. Get.back();
  101. Get.snackbar(label_add_success, "Hoạt động ươm",
  102. snackPosition: SnackPosition.BOTTOM);
  103. }, (error) {
  104. LoadingDialog.hideLoadingDialog(context);
  105. _scaffoldKey.currentState.showSnackBar(SnackBar(
  106. content: Row(
  107. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  108. children: <Widget>[
  109. Flexible(child: Text(AppException.handleError(error))),
  110. Icon(Icons.error),
  111. ],
  112. ),
  113. backgroundColor: Colors.red,
  114. duration: Duration(seconds: 3),
  115. ));
  116. }, activityNursery, filePaths: filePaths);
  117. } else {
  118. //UPDATE
  119. _repository.updateNursery((value) {
  120. LoadingDialog.hideLoadingDialog(context);
  121. Get.back();
  122. Get.snackbar(label_add_success, "Hoạt động ươm",
  123. snackPosition: SnackPosition.BOTTOM);
  124. }, (error) {
  125. LoadingDialog.hideLoadingDialog(context);
  126. _scaffoldKey.currentState.showSnackBar(SnackBar(
  127. content: Row(
  128. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  129. children: <Widget>[
  130. Flexible(child: Text(AppException.handleError(error))),
  131. Icon(Icons.error),
  132. ],
  133. ),
  134. backgroundColor: Colors.red,
  135. duration: Duration(seconds: 3),
  136. ));
  137. }, activityNursery, filePaths: filePaths);
  138. }
  139. } else {
  140. _autoValidate = true;
  141. }
  142. }
  143. Widget _btnExecuteTimePicker() {
  144. return FlatButton(
  145. padding: EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
  146. onPressed: () {
  147. DatePicker.showDateTimePicker(context,
  148. showTitleActions: true, onChanged: (date) {}, onConfirm: (date) {
  149. setState(() {
  150. var parsedDate =
  151. DateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'").format(date);
  152. _nursery.executeDate = "$parsedDate";
  153. executeTimeView = DateFormat("dd/MM/yyyy HH:mm").format(date);
  154. });
  155. }, currentTime: executeTime, locale: LocaleType.vi);
  156. },
  157. child: Container(
  158. padding:
  159. EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
  160. decoration: BoxDecoration(
  161. border: kBorderTextField,
  162. ),
  163. child: Row(
  164. children: [
  165. Expanded(
  166. child: Text(
  167. //TODO: check condition
  168. executeTimeView == null ? "$executeTime" : executeTimeView,
  169. style: TextStyle(fontSize: 14.0, color: Colors.black87),
  170. )),
  171. Icon(
  172. Icons.date_range,
  173. color: Colors.blue,
  174. ),
  175. ],
  176. )));
  177. }
  178. Widget _btnSelectSeed() {
  179. return FlatButton(
  180. padding: EdgeInsets.only(top: 0.0, right: 0.0, bottom: 0.0, left: 0.0),
  181. onPressed: () {
  182. Navigator.of(context)
  183. .push(MaterialPageRoute(
  184. builder: (_) => ResourceHelperScreen(
  185. titleName: "Gía thể",
  186. type: ConstCommon.supplyTypeSubStrate,
  187. selectedId: Get.find<ChangeSupply>().selectedSupplyId),
  188. fullscreenDialog: false))
  189. .then((value) {
  190. if (value != null) {
  191. var result = value as Supply;
  192. _nursery.substratesId = result.id;
  193. changeSupply.change(result);
  194. print("Home: $value");
  195. }
  196. });
  197. },
  198. child: Container(
  199. padding:
  200. EdgeInsets.only(top: 0.0, right: 0.0, bottom: 10.5, left: 0.0),
  201. decoration: BoxDecoration(
  202. border: kBorderTextField,
  203. ),
  204. child: Row(
  205. children: [
  206. GetBuilder<ChangeSupply>(
  207. builder: (_) => Expanded(
  208. child: Text(
  209. changeSupply.currentSupply.name == null
  210. ? "Loại giá thể"
  211. : changeSupply.currentSupply.name.toString(),
  212. style: TextStyle(
  213. fontSize: 14.0, color: Colors.black87)))),
  214. Icon(
  215. Icons.arrow_drop_down,
  216. color: Colors.grey,
  217. ),
  218. ],
  219. )));
  220. }
  221. Widget _seedLengthField() {
  222. return TextFormField(
  223. keyboardType: TextInputType.numberWithOptions(decimal: true),
  224. inputFormatters: [
  225. ThousandsFormatter(
  226. formatter: NumberFormat("#,###.##", "es"), allowFraction: true)
  227. ],
  228. decoration: InputDecoration(labelText: "Chiều dài mần"),
  229. controller: _seedLengthController,
  230. validator: (String value) {
  231. return Validators.validNumber(value, "Chiều dài mần");
  232. },
  233. onSaved: (newValue) {
  234. _nursery.seedLength = newValue.parseDoubleThousand();
  235. },
  236. );
  237. }
  238. Widget _quantityField() {
  239. return TextFormField(
  240. keyboardType: TextInputType.numberWithOptions(decimal: true),
  241. inputFormatters: [
  242. ThousandsFormatter(
  243. formatter: NumberFormat("#,###.##", "es"), allowFraction: true)
  244. ],
  245. decoration: InputDecoration(labelText: "Số lượng hạt gieo"),
  246. controller: _quantityController,
  247. validator: (String value) {
  248. return Validators.validNumber(value, "Số lượng hạt gieo");
  249. },
  250. onSaved: (newValue) {
  251. _nursery.quantity = newValue.parseDoubleThousand();
  252. },
  253. );
  254. }
  255. Widget _seedIncubationTimeField() {
  256. return TextFormField(
  257. keyboardType: TextInputType.numberWithOptions(decimal: true),
  258. inputFormatters: [
  259. ThousandsFormatter(
  260. formatter: NumberFormat("#,###.##", "es"), allowFraction: true)
  261. ],
  262. decoration: InputDecoration(labelText: "Thời gian ngâm hạt"),
  263. controller: _seedIncubationTimeController,
  264. validator: (String value) {
  265. return Validators.validNumber(value, "Thời gian ngâm hạt");
  266. },
  267. onSaved: (newValue) {
  268. _nursery.seedIncubationTime = newValue.parseDoubleThousand();
  269. },
  270. );
  271. }
  272. Widget _desciptionField() {
  273. return TextFormField(
  274. keyboardType: TextInputType.text,
  275. decoration: InputDecoration(labelText: "Ghi chú"),
  276. controller: _descriptionController,
  277. onSaved: (newValue) {
  278. _nursery.description = newValue;
  279. },
  280. );
  281. }
  282. Widget _btnAddWorker() {
  283. //TODO :check flow error sua item -> xoa list -> bam nut them
  284. return Builder(builder: (context) {
  285. return BlocConsumer<StatusAddFormBloc, StatusAddFormState>(
  286. listener: (context, state) {
  287. if (state is Edit) {
  288. isResetForm = false;
  289. _workerNameController.text = state.nurseryDetail.workerName;
  290. _trayNumberController.text = state.nurseryDetail.trayNumber;
  291. } else if (state is Delete) {
  292. if (currentIndexUpdate == state.index) {
  293. isResetForm = true;
  294. _workerNameController.text = "";
  295. _trayNumberController.text = "";
  296. }
  297. } else {
  298. isResetForm = true;
  299. _workerNameController.text = "";
  300. _trayNumberController.text = "";
  301. }
  302. }, builder: (context, state) {
  303. return Container(
  304. padding: EdgeInsets.all(8.0),
  305. decoration: BoxDecoration(
  306. shape: BoxShape.rectangle,
  307. borderRadius: BorderRadius.circular(10),
  308. color: Colors.white,
  309. border: Border.all(color: COLOR_CONST.DEFAULT)),
  310. child: Column(
  311. children: [
  312. TextFormField(
  313. keyboardType: TextInputType.text,
  314. controller: _workerNameController,
  315. decoration: InputDecoration(labelText: "Tên công nhân"),
  316. onSaved: (newValue) {},
  317. ),
  318. TextFormField(
  319. keyboardType: TextInputType.text,
  320. controller: _trayNumberController,
  321. decoration: InputDecoration(labelText: "Ươm khây số"),
  322. onSaved: (newValue) {},
  323. ),
  324. Align(
  325. alignment: Alignment.centerRight,
  326. child: Row(
  327. mainAxisAlignment: MainAxisAlignment.spaceBetween,
  328. children: [
  329. isResetForm
  330. ? Container()
  331. : OutlineButton(
  332. shape: RoundedRectangleBorder(
  333. borderRadius: new BorderRadius.circular(8.0)),
  334. child: Text("Huỷ"),
  335. onPressed: () {
  336. context.bloc<StatusAddFormBloc>().add(Reset());
  337. }),
  338. FlatButton(
  339. color: COLOR_CONST.DEFAULT,
  340. shape: RoundedRectangleBorder(
  341. borderRadius: new BorderRadius.circular(8.0)),
  342. onPressed: () {
  343. if (_workerNameController.text.isEmpty ||
  344. _trayNumberController.text.isEmpty) {
  345. return;
  346. }
  347. NurseryDetail _nurseryDetail = NurseryDetail()
  348. ..workerName = _workerNameController.text
  349. ..trayNumber = _trayNumberController.text;
  350. if (state is Edit) {
  351. context.bloc<ExpansionListBloc>().add(Update(
  352. index: state.index,
  353. item: _nurseryDetail,
  354. items: state.items));
  355. } else {
  356. currentNurseryDetail.insert(0, _nurseryDetail);
  357. BlocProvider.of<ExpansionListBloc>(context)
  358. .add(AddNew(items: currentNurseryDetail));
  359. }
  360. context.bloc<StatusAddFormBloc>().add(Reset());
  361. },
  362. child: Text(
  363. (state is Edit) ? "Sửa" : "Thêm",
  364. style: TextStyle(color: Colors.white),
  365. ))
  366. ],
  367. ),
  368. ),
  369. ],
  370. ));
  371. });
  372. });
  373. }
  374. Widget _buildListAddWorker() {
  375. return Builder(builder: (context) {
  376. return BlocBuilder<ExpansionListBloc, ExpansionListState>(
  377. builder: (context, state) {
  378. if (state is ExpansionListSuccess) {
  379. currentNurseryDetail = state.items;
  380. if (currentNurseryDetail.isEmpty) {
  381. return Container();
  382. }
  383. return Container(
  384. height: 70,
  385. child: ListView.builder(
  386. physics: ClampingScrollPhysics(),
  387. scrollDirection: Axis.horizontal,
  388. shrinkWrap: true,
  389. itemCount: currentNurseryDetail.length,
  390. itemBuilder: (context, index) {
  391. return GestureDetector(
  392. onTap: () {
  393. print("Show preview image or video");
  394. currentIndexUpdate = index;
  395. context.bloc<StatusAddFormBloc>().add(Changed(
  396. status: CRUDStatus.edit,
  397. index: index,
  398. nurseryDetail: currentNurseryDetail[index],
  399. items: currentNurseryDetail));
  400. },
  401. child: Card(
  402. child: Stack(
  403. alignment: Alignment.bottomCenter,
  404. overflow: Overflow.visible,
  405. children: <Widget>[
  406. Positioned(
  407. child: ClipRRect(
  408. borderRadius: BorderRadius.circular(8),
  409. child: Container(
  410. padding: EdgeInsets.all(4),
  411. width: 120,
  412. child: Column(
  413. children: [
  414. SizedBox(
  415. height: 12.0,
  416. ),
  417. Flexible(
  418. child: Text(
  419. currentNurseryDetail[index]
  420. .workerName ??
  421. "",
  422. overflow: TextOverflow.ellipsis,
  423. maxLines: 1),
  424. ),
  425. Flexible(
  426. child: Text(currentNurseryDetail[index]
  427. .trayNumber ??
  428. ""))
  429. ],
  430. ),
  431. ),
  432. )),
  433. Positioned(
  434. top: -10,
  435. right: -10,
  436. child: IconButton(
  437. icon: Icon(
  438. Icons.cancel,
  439. color: Colors.redAccent,
  440. ),
  441. onPressed: () {
  442. print("On tap delete media");
  443. context.bloc<ExpansionListBloc>().add(
  444. DeleteItem(
  445. index: index,
  446. items: currentNurseryDetail));
  447. context.bloc<StatusAddFormBloc>().add(
  448. Changed(
  449. status: CRUDStatus.delete,
  450. index: index,
  451. nurseryDetail:
  452. currentNurseryDetail[index],
  453. items: currentNurseryDetail));
  454. }),
  455. )
  456. ],
  457. )));
  458. }));
  459. } else if (state is ExpansionListFailure) {
  460. return Container();
  461. } else {
  462. return Container();
  463. }
  464. });
  465. });
  466. }
  467. _actionAppBar() {
  468. IconButton iconButton;
  469. if (1 == 1) {
  470. iconButton = IconButton(
  471. icon: Icon(
  472. Icons.done,
  473. color: Colors.black,
  474. ),
  475. onPressed: () {
  476. FocusScopeNode currentFocus = FocusScope.of(context);
  477. if (!currentFocus.hasPrimaryFocus) {
  478. currentFocus.unfocus();
  479. }
  480. _validateInputs();
  481. },
  482. );
  483. return <Widget>[iconButton];
  484. }
  485. return <Widget>[Container()];
  486. }
  487. @override
  488. Widget build(BuildContext context) => KeyboardDismisser(
  489. gestures: [
  490. GestureType.onTap,
  491. GestureType.onPanUpdateDownDirection,
  492. ],
  493. child: Scaffold(
  494. key: _scaffoldKey,
  495. appBar: AppBar(
  496. centerTitle: true,
  497. title: Text(plot_action_nursery),
  498. actions: _actionAppBar()),
  499. body: KeyboardDismisser(
  500. child: MultiBlocProvider(
  501. providers: [
  502. BlocProvider<ExpansionListBloc>(
  503. create: (context) => ExpansionListBloc(),
  504. ),
  505. BlocProvider<StatusAddFormBloc>(
  506. create: (context) => StatusAddFormBloc(),
  507. ),
  508. BlocProvider<ActionDetailBloc>(
  509. create: (context) =>
  510. ActionDetailBloc(repository: Repository())
  511. ..add(FetchData(
  512. isNeedFetchData: widget.isEdit,
  513. activityId: widget.activityId))),
  514. BlocProvider<MediaHelperBloc>(
  515. create: (context) =>
  516. MediaHelperBloc()..add(ChangeListMedia(items: [])),
  517. )
  518. ],
  519. child: Form(
  520. key: _formKey,
  521. autovalidate: _autoValidate,
  522. child: SingleChildScrollView(
  523. padding: EdgeInsets.all(8.0),
  524. child: BlocConsumer<ActionDetailBloc,
  525. ActionDetailState>(
  526. listener: (context, state) async {
  527. if (state is ActionDetailFailure) {
  528. print("fail");
  529. LoadingDialog.hideLoadingDialog(context);
  530. } else if (state is ActionDetailSuccess) {
  531. LoadingDialog.hideLoadingDialog(context);
  532. print("success");
  533. print(state.item);
  534. _nursery = Nursery.fromJson(state.item);
  535. _seedLengthController.text =
  536. _nursery.seedLength.toString();
  537. //Show media
  538. if (_nursery.media.isNotEmpty) {
  539. await cacheFiles(_nursery.media)
  540. .then((value) {
  541. print("then: ${value.length}");
  542. BlocProvider.of<MediaHelperBloc>(context)
  543. .add(ChangeListMedia(items: value));
  544. }).whenComplete(() {
  545. print("completed");
  546. });
  547. }
  548. //Show worker
  549. if (_nursery.nurseryDetail.length > 0) {
  550. BlocProvider.of<ExpansionListBloc>(context)
  551. .add(AddNew(
  552. items: _nursery.nurseryDetail));
  553. }
  554. } else if (state is ActionDetailInitial) {
  555. print("init");
  556. } else if (state is ActionDetailLoading) {
  557. print("loading");
  558. LoadingDialog.showLoadingDialog(context);
  559. }
  560. },
  561. builder: (context, state) {
  562. return Column(
  563. children: <Widget>[
  564. Container(
  565. width: double.infinity,
  566. child: Text(
  567. "Ngày thực hiện",
  568. style: TextStyle(
  569. color: Colors.black54,
  570. fontSize: 13.0),
  571. ),
  572. ),
  573. _btnExecuteTimePicker(),
  574. SizedBox(
  575. height: 8.0,
  576. ),
  577. Container(
  578. width: double.infinity,
  579. child: Text(
  580. "Tên giống",
  581. style: TextStyle(
  582. color: Colors.black54,
  583. fontSize: 13.0),
  584. ),
  585. ),
  586. _btnSelectSeed(),
  587. SizedBox(
  588. height: 8.0,
  589. ),
  590. _seedLengthField(),
  591. SizedBox(
  592. height: 8.0,
  593. ),
  594. _quantityField(),
  595. SizedBox(
  596. height: 8.0,
  597. ),
  598. _seedIncubationTimeField(),
  599. SizedBox(
  600. height: 8.0,
  601. ),
  602. _desciptionField(),
  603. SizedBox(
  604. height: 8.0,
  605. ),
  606. _btnAddWorker(),
  607. SizedBox(
  608. height: 8.0,
  609. ),
  610. _buildListAddWorker(),
  611. SizedBox(
  612. height: 8.0,
  613. ),
  614. BlocBuilder<MediaHelperBloc,
  615. MediaHelperState>(
  616. builder: (context, state) {
  617. if (state is MediaHelperSuccess) {
  618. print("length: " +
  619. state.items.length.toString());
  620. return WidgetMediaPicker(
  621. currentItems: state.items,
  622. onChangeFiles: (filePaths) async {
  623. Get.find<ChangeFileController>()
  624. .addAllFile(filePaths);
  625. });
  626. } else {
  627. return Center(
  628. child: CircularProgressIndicator());
  629. }
  630. }),
  631. ],
  632. );
  633. },
  634. ),
  635. ))))));
  636. @override
  637. void dispose() {
  638. _substrateController.dispose();
  639. _seedLengthController.dispose();
  640. _quantityController.dispose();
  641. _seedIncubationTimeController.dispose();
  642. _descriptionController.dispose();
  643. super.dispose();
  644. }
  645. Future<List<Media>> cacheFiles(String existedMedias) async {
  646. var medias = List<Media>();
  647. var mediaPathsLocal = List<String>();
  648. var mediaPaths = existedMedias.split(";");
  649. for (int i = 0; i < mediaPaths.length; i++) {
  650. var tempFile = await DefaultCacheManager()
  651. .getSingleFile(ConstCommon.baseImageUrl + mediaPaths[i]);
  652. print(tempFile.path);
  653. var isVideo = lookupMimeType(tempFile.path) == "video/mp4";
  654. print("file type: " + lookupMimeType(tempFile.path));
  655. Media media = Media()
  656. ..pathFile = tempFile.path
  657. ..isVideo = isVideo;
  658. medias.add(media);
  659. mediaPathsLocal.add(tempFile.path);
  660. }
  661. Get.find<ChangeFileController>().addAllFile(filePaths);
  662. return medias;
  663. }
  664. }
  665. class ChangeSupply extends GetxController {
  666. Supply currentSupply;
  667. int selectedSupplyId;
  668. void initValue() {
  669. currentSupply = Supply();
  670. selectedSupplyId = -1;
  671. update();
  672. }
  673. void change(Supply supply) {
  674. currentSupply = supply;
  675. selectedSupplyId = supply.id;
  676. update();
  677. }
  678. }
  679. class ChangeFileController extends GetxController {
  680. List<String> files;
  681. void initValue() {
  682. files = [];
  683. update();
  684. }
  685. void addAllFile(List<String> filePaths) {
  686. files = [];
  687. files = filePaths;
  688. update();
  689. }
  690. void addFile(String filePath) {
  691. files.add(filePath);
  692. update();
  693. }
  694. void deleteFile(String filePath) {
  695. files.remove(filePath);
  696. update();
  697. }
  698. }