From d282f4bb380ce9c445d6bd3a4c9f001bb6b5f501 Mon Sep 17 00:00:00 2001 From: davidpkj Date: Sun, 17 Jul 2022 19:25:26 +0200 Subject: Initial Commit --- lib/views/shoplist_view.dart | 167 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 167 insertions(+) create mode 100644 lib/views/shoplist_view.dart (limited to 'lib/views/shoplist_view.dart') diff --git a/lib/views/shoplist_view.dart b/lib/views/shoplist_view.dart new file mode 100644 index 0000000..a9caed8 --- /dev/null +++ b/lib/views/shoplist_view.dart @@ -0,0 +1,167 @@ +import 'dart:convert'; + +import 'package:flutter/material.dart'; + +import 'package:kulinar_app/constants.dart'; +import 'package:kulinar_app/widgets/error_widgets.dart'; +import 'package:kulinar_app/widgets/toastbar_widget.dart'; +import 'package:kulinar_app/widgets/custom_drawer_widget.dart'; +import 'package:kulinar_app/models/data/shoplist_data_class.dart'; + +import 'package:flutter_gen/gen_l10n/app_localizations.dart'; + +class ShoplistView extends StatefulWidget { + const ShoplistView({Key? key}) : super(key: key); + + @override + _ShoplistView createState() => _ShoplistView(); +} + +class _ShoplistView extends State { + final FocusNode _focusNode = FocusNode(); + final TextEditingController _controller = TextEditingController(); + final GlobalKey _scaffoldKey = GlobalKey(); + final GlobalKey _listKey = GlobalKey(); + PersistentBottomSheetController? _bottomSheetController; + bool _open = false; + + @override + Widget build(BuildContext context) { + return Scaffold( + key: _scaffoldKey, + appBar: AppBar(title: Text(AppLocalizations.of(context)!.category7)), + drawer: CustomDrawer(initalIndex: 4), + floatingActionButton: _buildFloatingActionButton(), + body: _buildAnimatedList(), + ); + } + + Widget _buildFloatingActionButton() { + return FloatingActionButton( + child: Icon(_open ? Icons.remove_rounded : Icons.add_rounded, color: cIconColor), + onPressed: () { + if (_open) { + _closeInput(); + } else { + _bottomSheetController = _scaffoldKey.currentState!.showBottomSheet((context) => _buildBottomSheetInput()); + _open = !_open; + + setState(() {}); + } + }, + ); + } + + // TODO: FIXME: Sometimes exception "cant call insertItem of null" is thrown when first item is added or last is removed + Widget _buildAnimatedList() { + if (ShoplistData.shoplist.length == 0) return NoContentError(); + + return AnimatedList( + key: _listKey, + initialItemCount: ShoplistData.shoplist.length, + itemBuilder: (BuildContext context, int index, Animation animation) { + return SlideTransition( + position: animation.drive(Tween(begin: Offset(1.0, 0.0), end: Offset(0.0, 0.0))), + child: Dismissible( + key: Key(_getUniqueKeyString(ShoplistData.shoplist[index])), + background: _buildDimissibleBackground(true), + secondaryBackground: _buildDimissibleBackground(false), + child: ListTile( + title: Text(ShoplistData.shoplist[index]), + ), + onDismissed: (_) { + String _content = AppLocalizations.of(context)!.removed; + String _actionLabel = AppLocalizations.of(context)!.undo; + + _removeItem(index); + ToastBar.showToastBar(context, _content, actionLabel: _actionLabel, actionCallback: () => _addItem(ShoplistData.removed.removeLast())); + }, + ), + ); + }, + ); + } + + Widget _buildDimissibleBackground(bool left) { + return Container( + color: cPrimaryColor, + /* + child: Row( + mainAxisAlignment: left ? MainAxisAlignment.start : MainAxisAlignment.end, + children: [ + Padding( + padding: const EdgeInsets.all(8.0), + child: Icon( + Icons.delete_rounded, + color: cIconColor, + ), + ), + ], + ), + */ + ); + } + + Widget _buildBottomSheetInput() { + _focusNode.requestFocus(); + + return WillPopScope( + child: Container( + height: 75.0, + color: cPrimaryColor, + child: Padding( + padding: const EdgeInsets.all(15.0), + child: TextFormField( + controller: _controller, + style: cRecipeTextStyle.copyWith(color: cIconColor), + cursorColor: cIconColor, + focusNode: _focusNode, + textInputAction: TextInputAction.done, + onEditingComplete: () { + String _text = _controller.text.trim(); + + _closeInput(); + _controller.clear(); + + if (_text != "") _addItem(_text); + }, + ), + ), + ), + onWillPop: () async { + return false; + }, + ); + } + + String _getUniqueKeyString(String item) { + return base64Encode(utf8.encode(item)); + } + + void _removeItem(int index) { + _listKey.currentState!.removeItem(index, (_, __) => Container()); + ShoplistData.removed.add(ShoplistData.shoplist.removeAt(index)); + + ShoplistData.save(); + + setState(() {}); + } + + void _addItem(String string) { + ShoplistData.shoplist.add(string); + if (ShoplistData.shoplist.length > 1) _listKey.currentState!.insertItem(ShoplistData.shoplist.indexOf(string)); + + ShoplistData.save(); + + setState(() {}); + } + + void _closeInput() { + _bottomSheetController!.close(); + _focusNode.unfocus(); + + _open = !_open; + + setState(() {}); + } +} -- cgit v1.2.3