From f9d61ed9b78af4da197c1a07b98574d3d068fb32 Mon Sep 17 00:00:00 2001 From: th8m0z Date: Mon, 5 Feb 2024 13:17:12 +0100 Subject: [PATCH 1/4] filtering tags --- lib/ui/add_book_screen/add_book_screen.dart | 507 +++++++++--------- .../widgets/tags_text_field.dart | 42 +- 2 files changed, 288 insertions(+), 261 deletions(-) diff --git a/lib/ui/add_book_screen/add_book_screen.dart b/lib/ui/add_book_screen/add_book_screen.dart index 3e6b24eb..36d66f9b 100644 --- a/lib/ui/add_book_screen/add_book_screen.dart +++ b/lib/ui/add_book_screen/add_book_screen.dart @@ -20,6 +20,7 @@ import 'package:openreads/main.dart'; import 'package:openreads/model/book.dart'; import 'package:openreads/ui/add_book_screen/widgets/cover_view_edit.dart'; import 'package:openreads/ui/add_book_screen/widgets/widgets.dart'; +import 'package:openreads/ui/common/keyboard_dismissable.dart'; class AddBookScreen extends StatefulWidget { const AddBookScreen({ @@ -321,256 +322,262 @@ class _AddBookScreenState extends State { @override Widget build(BuildContext context) { - return Scaffold( - appBar: AppBar( - title: Text( - widget.editingExistingBook - ? LocaleKeys.edit_book.tr() - : LocaleKeys.add_new_book.tr(), - style: const TextStyle(fontSize: 18), + return KeyboardDismissible( + child: Scaffold( + appBar: AppBar( + title: Text( + widget.editingExistingBook + ? LocaleKeys.edit_book.tr() + : LocaleKeys.add_new_book.tr(), + style: const TextStyle(fontSize: 18), + ), + actions: [ + BlocBuilder( + builder: (context, state) { + return TextButton( + onPressed: (state.id != null) + ? () => _updateBook(state) + : () => _saveBook(state), + child: Text( + LocaleKeys.save.tr(), + style: const TextStyle(fontSize: 16), + ), + ); + }, + ) + ], ), - actions: [ - BlocBuilder( - builder: (context, state) { - return TextButton( - onPressed: (state.id != null) - ? () => _updateBook(state) - : () => _saveBook(state), - child: Text( - LocaleKeys.save.tr(), - style: const TextStyle(fontSize: 16), + body: SafeArea( + child: SingleChildScrollView( + child: Column( + children: [ + _buildCover(), + const Padding( + padding: EdgeInsets.all(10), + child: Divider(), ), - ); - }, - ) - ], - ), - body: SafeArea( - child: SingleChildScrollView( - child: Column( - children: [ - _buildCover(), - const Padding( - padding: EdgeInsets.all(10), - child: Divider(), - ), - BookTextField( - controller: _titleCtrl, - hint: LocaleKeys.enter_title.tr(), - icon: Icons.book, - keyboardType: TextInputType.name, - autofocus: - (widget.fromOpenLibrary || widget.editingExistingBook) - ? false - : true, - maxLines: 5, - maxLength: 255, - textCapitalization: TextCapitalization.sentences, - ), - const SizedBox(height: 10), - BookTextField( - controller: _subtitleCtrl, - hint: LocaleKeys.enter_subtitle.tr(), - icon: Icons.book, - keyboardType: TextInputType.name, - maxLines: 5, - maxLength: 255, - textCapitalization: TextCapitalization.sentences, - ), - const SizedBox(height: 10), - BookTextField( - controller: _authorCtrl, - hint: LocaleKeys.enter_author.tr(), - icon: Icons.person, - keyboardType: TextInputType.name, - maxLines: 5, - maxLength: 255, - textCapitalization: TextCapitalization.words, - ), - const Padding( - padding: EdgeInsets.all(10), - child: Divider(), - ), - BookStatusRow( - animDuration: _animDuration, - defaultHeight: defaultFormHeight, - ), - const SizedBox(height: 10), - BookRatingBar(animDuration: _animDuration), - BlocBuilder( - builder: (context, state) { - return Column( - children: [ - ...state.readings.asMap().entries.map( - (entry) { - return ReadingRow( - index: entry.key, - reading: entry.value, - ); - }, - ), - ], - ); - }, - ), - _buildAddNewReadingButton(context), - const Padding( - padding: EdgeInsets.all(10), - child: Divider(), - ), - BookTypeDropdown( - bookTypes: bookTypes, - changeBookType: _changeBookType, - ), - const SizedBox(height: 10), - Row( - children: [ - Expanded( - child: BookTextField( - controller: _pagesCtrl, - hint: LocaleKeys.enter_pages.tr(), - icon: FontAwesomeIcons.solidFileLines, - keyboardType: TextInputType.number, - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly - ], - maxLength: 10, - padding: const EdgeInsets.fromLTRB(10, 0, 5, 0), - ), - ), - Expanded( - child: BookTextField( - controller: _pubYearCtrl, - hint: LocaleKeys.enter_publication_year.tr(), - icon: FontAwesomeIcons.solidCalendar, - keyboardType: TextInputType.number, - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly + BookTextField( + controller: _titleCtrl, + hint: LocaleKeys.enter_title.tr(), + icon: Icons.book, + keyboardType: TextInputType.name, + autofocus: + (widget.fromOpenLibrary || widget.editingExistingBook) + ? false + : true, + maxLines: 5, + maxLength: 255, + textCapitalization: TextCapitalization.sentences, + ), + const SizedBox(height: 10), + BookTextField( + controller: _subtitleCtrl, + hint: LocaleKeys.enter_subtitle.tr(), + icon: Icons.book, + keyboardType: TextInputType.name, + maxLines: 5, + maxLength: 255, + textCapitalization: TextCapitalization.sentences, + ), + const SizedBox(height: 10), + BookTextField( + controller: _authorCtrl, + hint: LocaleKeys.enter_author.tr(), + icon: Icons.person, + keyboardType: TextInputType.name, + maxLines: 5, + maxLength: 255, + textCapitalization: TextCapitalization.words, + ), + const Padding( + padding: EdgeInsets.all(10), + child: Divider(), + ), + BookStatusRow( + animDuration: _animDuration, + defaultHeight: defaultFormHeight, + ), + const SizedBox(height: 10), + BookRatingBar(animDuration: _animDuration), + BlocBuilder( + builder: (context, state) { + return Column( + children: [ + ...state.readings.asMap().entries.map( + (entry) { + return ReadingRow( + index: entry.key, + reading: entry.value, + ); + }, + ), ], - maxLength: 4, - padding: const EdgeInsets.fromLTRB(5, 0, 10, 0), + ); + }, + ), + _buildAddNewReadingButton(context), + const Padding( + padding: EdgeInsets.all(10), + child: Divider(), + ), + BookTypeDropdown( + bookTypes: bookTypes, + changeBookType: _changeBookType, + ), + const SizedBox(height: 10), + Row( + children: [ + Expanded( + child: BookTextField( + controller: _pagesCtrl, + hint: LocaleKeys.enter_pages.tr(), + icon: FontAwesomeIcons.solidFileLines, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly + ], + maxLength: 10, + padding: const EdgeInsets.fromLTRB(10, 0, 5, 0), + ), ), - ), - ], - ), - const SizedBox(height: 10), - BookTextField( - controller: _descriptionCtrl, - hint: LocaleKeys.enter_description.tr(), - icon: FontAwesomeIcons.solidKeyboard, - keyboardType: TextInputType.multiline, - maxLength: 5000, - hideCounter: false, - maxLines: 15, - textCapitalization: TextCapitalization.sentences, - ), - const SizedBox(height: 10), - BookTextField( - controller: _isbnCtrl, - hint: LocaleKeys.isbn.tr(), - icon: FontAwesomeIcons.i, - keyboardType: TextInputType.number, - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly - ], - maxLength: 20, - ), - const SizedBox(height: 10), - BookTextField( - controller: _olidCtrl, - hint: LocaleKeys.open_library_ID.tr(), - icon: FontAwesomeIcons.o, - keyboardType: TextInputType.text, - maxLength: 20, - textCapitalization: TextCapitalization.characters, - ), - const SizedBox(height: 10), - StreamBuilder>( - stream: bookCubit.tags, - builder: (context, AsyncSnapshot?> snapshot) { - return TagsField( - controller: _tagsCtrl, - hint: LocaleKeys.enter_tags.tr(), - icon: FontAwesomeIcons.tags, - keyboardType: TextInputType.text, - maxLength: 20, - onSubmitted: (_) => _addNewTag(), - onEditingComplete: () {}, - unselectTag: (tag) => _unselectTag(tag), - allTags: snapshot.data, - ); - }, - ), - const Padding( - padding: EdgeInsets.all(10), - child: Divider(), - ), - BookTextField( - controller: _myReviewCtrl, - hint: LocaleKeys.my_review.tr(), - icon: FontAwesomeIcons.solidKeyboard, - keyboardType: TextInputType.multiline, - maxLength: 5000, - hideCounter: false, - maxLines: 15, - textCapitalization: TextCapitalization.sentences, - ), - const SizedBox(height: 10), - BookTextField( - controller: _notesCtrl, - hint: LocaleKeys.notes.tr(), - icon: FontAwesomeIcons.noteSticky, - keyboardType: TextInputType.multiline, - maxLength: 5000, - hideCounter: false, - maxLines: 15, - textCapitalization: TextCapitalization.sentences, - ), - const SizedBox(height: 30), - Row( - children: [ - const SizedBox(width: 10), - Expanded( - flex: 10, - child: FilledButton.tonal( - onPressed: () => Navigator.pop(context), - style: ButtonStyle( - shape: MaterialStateProperty.all(RoundedRectangleBorder( - borderRadius: BorderRadius.circular(cornerRadius), - )), + Expanded( + child: BookTextField( + controller: _pubYearCtrl, + hint: LocaleKeys.enter_publication_year.tr(), + icon: FontAwesomeIcons.solidCalendar, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly + ], + maxLength: 4, + padding: const EdgeInsets.fromLTRB(5, 0, 10, 0), ), - child: const Center( - child: Text("Cancel"), + ), + ], + ), + const SizedBox(height: 10), + BookTextField( + controller: _descriptionCtrl, + hint: LocaleKeys.enter_description.tr(), + icon: FontAwesomeIcons.solidKeyboard, + keyboardType: TextInputType.multiline, + maxLength: 5000, + hideCounter: false, + maxLines: 15, + textCapitalization: TextCapitalization.sentences, + ), + const SizedBox(height: 10), + BookTextField( + controller: _isbnCtrl, + hint: LocaleKeys.isbn.tr(), + icon: FontAwesomeIcons.i, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly + ], + maxLength: 20, + ), + const SizedBox(height: 10), + BookTextField( + controller: _olidCtrl, + hint: LocaleKeys.open_library_ID.tr(), + icon: FontAwesomeIcons.o, + keyboardType: TextInputType.text, + maxLength: 20, + textCapitalization: TextCapitalization.characters, + ), + const SizedBox(height: 10), + StreamBuilder>( + stream: bookCubit.tags, + builder: (context, AsyncSnapshot?> snapshot) { + final book = context.read().state; + return TagsField( + existingTags: _parseBookTags(book.tags), + controller: _tagsCtrl, + hint: LocaleKeys.enter_tags.tr(), + icon: FontAwesomeIcons.tags, + keyboardType: TextInputType.text, + maxLength: 20, + onSubmitted: (_) => _addNewTag(), + onEditingComplete: () {}, + unselectTag: (tag) => _unselectTag(tag), + allTags: snapshot.data, + ); + }, + ), + const Padding( + padding: EdgeInsets.all(10), + child: Divider(), + ), + BookTextField( + controller: _myReviewCtrl, + hint: LocaleKeys.my_review.tr(), + icon: FontAwesomeIcons.solidKeyboard, + keyboardType: TextInputType.multiline, + maxLength: 5000, + hideCounter: false, + maxLines: 15, + textCapitalization: TextCapitalization.sentences, + ), + const SizedBox(height: 10), + BookTextField( + controller: _notesCtrl, + hint: LocaleKeys.notes.tr(), + icon: FontAwesomeIcons.noteSticky, + keyboardType: TextInputType.multiline, + maxLength: 5000, + hideCounter: false, + maxLines: 15, + textCapitalization: TextCapitalization.sentences, + ), + const SizedBox(height: 30), + Row( + children: [ + const SizedBox(width: 10), + Expanded( + flex: 10, + child: FilledButton.tonal( + onPressed: () => Navigator.pop(context), + style: ButtonStyle( + shape: + MaterialStateProperty.all(RoundedRectangleBorder( + borderRadius: BorderRadius.circular(cornerRadius), + )), + ), + child: const Center( + child: Text("Cancel"), + ), ), ), - ), - const SizedBox(width: 10), - Expanded( - flex: 19, - child: BlocBuilder( - builder: (context, state) { - return FilledButton( - onPressed: (state.id != null) - ? () => _updateBook(state) - : () => _saveBook(state), - style: ButtonStyle( - shape: MaterialStateProperty.all( - RoundedRectangleBorder( - borderRadius: BorderRadius.circular(cornerRadius), - )), - ), - child: const Center( - child: Text("Save"), - ), - ); - }, + const SizedBox(width: 10), + Expanded( + flex: 19, + child: BlocBuilder( + builder: (context, state) { + return FilledButton( + onPressed: (state.id != null) + ? () => _updateBook(state) + : () => _saveBook(state), + style: ButtonStyle( + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: + BorderRadius.circular(cornerRadius), + )), + ), + child: const Center( + child: Text("Save"), + ), + ); + }, + ), ), - ), - const SizedBox(width: 10), - ], - ), - const SizedBox(height: 50.0), - ], + const SizedBox(width: 10), + ], + ), + const SizedBox(height: 50.0), + ], + ), ), ), ), @@ -600,4 +607,20 @@ class _AddBookScreenState extends State { ), ); } + + List _parseBookTags(String? tags) { + if (tags == null) { + return []; + } + final List parsedTags = List.empty(growable: true); + + for (String tag in tags.split('|||||')) { + if (!parsedTags.contains(tag)) { + parsedTags.add(tag); + } + } + parsedTags.sort((a, b) => a.compareTo(b)); + + return parsedTags; + } } diff --git a/lib/ui/add_book_screen/widgets/tags_text_field.dart b/lib/ui/add_book_screen/widgets/tags_text_field.dart index 7893367f..315ed781 100644 --- a/lib/ui/add_book_screen/widgets/tags_text_field.dart +++ b/lib/ui/add_book_screen/widgets/tags_text_field.dart @@ -7,24 +7,24 @@ import 'package:openreads/logic/cubit/edit_book_cubit.dart'; import 'package:openreads/model/book.dart'; class TagsField extends StatelessWidget { - const TagsField({ - super.key, - this.controller, - this.hint, - this.icon, - required this.keyboardType, - required this.maxLength, - this.inputFormatters, - this.autofocus = false, - this.maxLines = 1, - this.hideCounter = true, - this.textInputAction, - this.textCapitalization = TextCapitalization.none, - this.onSubmitted, - this.onEditingComplete, - this.unselectTag, - this.allTags, - }); + const TagsField( + {super.key, + this.controller, + this.hint, + this.icon, + required this.keyboardType, + required this.maxLength, + this.inputFormatters, + this.autofocus = false, + this.maxLines = 1, + this.hideCounter = true, + this.textInputAction, + this.textCapitalization = TextCapitalization.none, + this.onSubmitted, + this.onEditingComplete, + this.unselectTag, + this.allTags, + required this.existingTags}); final TextEditingController? controller; final String? hint; @@ -39,7 +39,7 @@ class TagsField extends StatelessWidget { final TextCapitalization textCapitalization; final Function(String)? onSubmitted; final Function()? onEditingComplete; - + final List existingTags; final Function(String)? unselectTag; final List? allTags; @@ -100,6 +100,10 @@ class TagsField extends StatelessWidget { Scrollbar( child: TypeAheadField( itemBuilder: (context, suggestion) { + if (existingTags.contains(suggestion)) { + return const SizedBox.shrink(); + } + return Container( color: Theme.of(context).colorScheme.surfaceVariant, child: ListTile( From 6b2914c0f638dea58e829ef18913fb13fc525a38 Mon Sep 17 00:00:00 2001 From: th8m0z Date: Mon, 5 Feb 2024 17:00:04 +0100 Subject: [PATCH 2/4] removed accidental adding of keyboarddismissible here --- lib/ui/add_book_screen/add_book_screen.dart | 493 ++++++++++---------- 1 file changed, 244 insertions(+), 249 deletions(-) diff --git a/lib/ui/add_book_screen/add_book_screen.dart b/lib/ui/add_book_screen/add_book_screen.dart index 36d66f9b..946310e1 100644 --- a/lib/ui/add_book_screen/add_book_screen.dart +++ b/lib/ui/add_book_screen/add_book_screen.dart @@ -20,7 +20,6 @@ import 'package:openreads/main.dart'; import 'package:openreads/model/book.dart'; import 'package:openreads/ui/add_book_screen/widgets/cover_view_edit.dart'; import 'package:openreads/ui/add_book_screen/widgets/widgets.dart'; -import 'package:openreads/ui/common/keyboard_dismissable.dart'; class AddBookScreen extends StatefulWidget { const AddBookScreen({ @@ -322,262 +321,258 @@ class _AddBookScreenState extends State { @override Widget build(BuildContext context) { - return KeyboardDismissible( - child: Scaffold( - appBar: AppBar( - title: Text( - widget.editingExistingBook - ? LocaleKeys.edit_book.tr() - : LocaleKeys.add_new_book.tr(), - style: const TextStyle(fontSize: 18), - ), - actions: [ - BlocBuilder( - builder: (context, state) { - return TextButton( - onPressed: (state.id != null) - ? () => _updateBook(state) - : () => _saveBook(state), - child: Text( - LocaleKeys.save.tr(), - style: const TextStyle(fontSize: 16), - ), - ); - }, - ) - ], + return Scaffold( + appBar: AppBar( + title: Text( + widget.editingExistingBook + ? LocaleKeys.edit_book.tr() + : LocaleKeys.add_new_book.tr(), + style: const TextStyle(fontSize: 18), ), - body: SafeArea( - child: SingleChildScrollView( - child: Column( - children: [ - _buildCover(), - const Padding( - padding: EdgeInsets.all(10), - child: Divider(), - ), - BookTextField( - controller: _titleCtrl, - hint: LocaleKeys.enter_title.tr(), - icon: Icons.book, - keyboardType: TextInputType.name, - autofocus: - (widget.fromOpenLibrary || widget.editingExistingBook) - ? false - : true, - maxLines: 5, - maxLength: 255, - textCapitalization: TextCapitalization.sentences, - ), - const SizedBox(height: 10), - BookTextField( - controller: _subtitleCtrl, - hint: LocaleKeys.enter_subtitle.tr(), - icon: Icons.book, - keyboardType: TextInputType.name, - maxLines: 5, - maxLength: 255, - textCapitalization: TextCapitalization.sentences, - ), - const SizedBox(height: 10), - BookTextField( - controller: _authorCtrl, - hint: LocaleKeys.enter_author.tr(), - icon: Icons.person, - keyboardType: TextInputType.name, - maxLines: 5, - maxLength: 255, - textCapitalization: TextCapitalization.words, - ), - const Padding( - padding: EdgeInsets.all(10), - child: Divider(), - ), - BookStatusRow( - animDuration: _animDuration, - defaultHeight: defaultFormHeight, - ), - const SizedBox(height: 10), - BookRatingBar(animDuration: _animDuration), - BlocBuilder( - builder: (context, state) { - return Column( - children: [ - ...state.readings.asMap().entries.map( - (entry) { - return ReadingRow( - index: entry.key, - reading: entry.value, - ); - }, - ), - ], - ); - }, - ), - _buildAddNewReadingButton(context), - const Padding( - padding: EdgeInsets.all(10), - child: Divider(), - ), - BookTypeDropdown( - bookTypes: bookTypes, - changeBookType: _changeBookType, + actions: [ + BlocBuilder( + builder: (context, state) { + return TextButton( + onPressed: (state.id != null) + ? () => _updateBook(state) + : () => _saveBook(state), + child: Text( + LocaleKeys.save.tr(), + style: const TextStyle(fontSize: 16), ), - const SizedBox(height: 10), - Row( - children: [ - Expanded( - child: BookTextField( - controller: _pagesCtrl, - hint: LocaleKeys.enter_pages.tr(), - icon: FontAwesomeIcons.solidFileLines, - keyboardType: TextInputType.number, - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly - ], - maxLength: 10, - padding: const EdgeInsets.fromLTRB(10, 0, 5, 0), + ); + }, + ) + ], + ), + body: SafeArea( + child: SingleChildScrollView( + child: Column( + children: [ + _buildCover(), + const Padding( + padding: EdgeInsets.all(10), + child: Divider(), + ), + BookTextField( + controller: _titleCtrl, + hint: LocaleKeys.enter_title.tr(), + icon: Icons.book, + keyboardType: TextInputType.name, + autofocus: + (widget.fromOpenLibrary || widget.editingExistingBook) + ? false + : true, + maxLines: 5, + maxLength: 255, + textCapitalization: TextCapitalization.sentences, + ), + const SizedBox(height: 10), + BookTextField( + controller: _subtitleCtrl, + hint: LocaleKeys.enter_subtitle.tr(), + icon: Icons.book, + keyboardType: TextInputType.name, + maxLines: 5, + maxLength: 255, + textCapitalization: TextCapitalization.sentences, + ), + const SizedBox(height: 10), + BookTextField( + controller: _authorCtrl, + hint: LocaleKeys.enter_author.tr(), + icon: Icons.person, + keyboardType: TextInputType.name, + maxLines: 5, + maxLength: 255, + textCapitalization: TextCapitalization.words, + ), + const Padding( + padding: EdgeInsets.all(10), + child: Divider(), + ), + BookStatusRow( + animDuration: _animDuration, + defaultHeight: defaultFormHeight, + ), + const SizedBox(height: 10), + BookRatingBar(animDuration: _animDuration), + BlocBuilder( + builder: (context, state) { + return Column( + children: [ + ...state.readings.asMap().entries.map( + (entry) { + return ReadingRow( + index: entry.key, + reading: entry.value, + ); + }, ), + ], + ); + }, + ), + _buildAddNewReadingButton(context), + const Padding( + padding: EdgeInsets.all(10), + child: Divider(), + ), + BookTypeDropdown( + bookTypes: bookTypes, + changeBookType: _changeBookType, + ), + const SizedBox(height: 10), + Row( + children: [ + Expanded( + child: BookTextField( + controller: _pagesCtrl, + hint: LocaleKeys.enter_pages.tr(), + icon: FontAwesomeIcons.solidFileLines, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly + ], + maxLength: 10, + padding: const EdgeInsets.fromLTRB(10, 0, 5, 0), ), - Expanded( - child: BookTextField( - controller: _pubYearCtrl, - hint: LocaleKeys.enter_publication_year.tr(), - icon: FontAwesomeIcons.solidCalendar, - keyboardType: TextInputType.number, - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly - ], - maxLength: 4, - padding: const EdgeInsets.fromLTRB(5, 0, 10, 0), - ), + ), + Expanded( + child: BookTextField( + controller: _pubYearCtrl, + hint: LocaleKeys.enter_publication_year.tr(), + icon: FontAwesomeIcons.solidCalendar, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly + ], + maxLength: 4, + padding: const EdgeInsets.fromLTRB(5, 0, 10, 0), ), - ], - ), - const SizedBox(height: 10), - BookTextField( - controller: _descriptionCtrl, - hint: LocaleKeys.enter_description.tr(), - icon: FontAwesomeIcons.solidKeyboard, - keyboardType: TextInputType.multiline, - maxLength: 5000, - hideCounter: false, - maxLines: 15, - textCapitalization: TextCapitalization.sentences, - ), - const SizedBox(height: 10), - BookTextField( - controller: _isbnCtrl, - hint: LocaleKeys.isbn.tr(), - icon: FontAwesomeIcons.i, - keyboardType: TextInputType.number, - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly - ], - maxLength: 20, - ), - const SizedBox(height: 10), - BookTextField( - controller: _olidCtrl, - hint: LocaleKeys.open_library_ID.tr(), - icon: FontAwesomeIcons.o, - keyboardType: TextInputType.text, - maxLength: 20, - textCapitalization: TextCapitalization.characters, - ), - const SizedBox(height: 10), - StreamBuilder>( - stream: bookCubit.tags, - builder: (context, AsyncSnapshot?> snapshot) { - final book = context.read().state; - return TagsField( - existingTags: _parseBookTags(book.tags), - controller: _tagsCtrl, - hint: LocaleKeys.enter_tags.tr(), - icon: FontAwesomeIcons.tags, - keyboardType: TextInputType.text, - maxLength: 20, - onSubmitted: (_) => _addNewTag(), - onEditingComplete: () {}, - unselectTag: (tag) => _unselectTag(tag), - allTags: snapshot.data, - ); - }, - ), - const Padding( - padding: EdgeInsets.all(10), - child: Divider(), - ), - BookTextField( - controller: _myReviewCtrl, - hint: LocaleKeys.my_review.tr(), - icon: FontAwesomeIcons.solidKeyboard, - keyboardType: TextInputType.multiline, - maxLength: 5000, - hideCounter: false, - maxLines: 15, - textCapitalization: TextCapitalization.sentences, - ), - const SizedBox(height: 10), - BookTextField( - controller: _notesCtrl, - hint: LocaleKeys.notes.tr(), - icon: FontAwesomeIcons.noteSticky, - keyboardType: TextInputType.multiline, - maxLength: 5000, - hideCounter: false, - maxLines: 15, - textCapitalization: TextCapitalization.sentences, - ), - const SizedBox(height: 30), - Row( - children: [ - const SizedBox(width: 10), - Expanded( - flex: 10, - child: FilledButton.tonal( - onPressed: () => Navigator.pop(context), - style: ButtonStyle( - shape: - MaterialStateProperty.all(RoundedRectangleBorder( - borderRadius: BorderRadius.circular(cornerRadius), - )), - ), - child: const Center( - child: Text("Cancel"), - ), + ), + ], + ), + const SizedBox(height: 10), + BookTextField( + controller: _descriptionCtrl, + hint: LocaleKeys.enter_description.tr(), + icon: FontAwesomeIcons.solidKeyboard, + keyboardType: TextInputType.multiline, + maxLength: 5000, + hideCounter: false, + maxLines: 15, + textCapitalization: TextCapitalization.sentences, + ), + const SizedBox(height: 10), + BookTextField( + controller: _isbnCtrl, + hint: LocaleKeys.isbn.tr(), + icon: FontAwesomeIcons.i, + keyboardType: TextInputType.number, + inputFormatters: [ + FilteringTextInputFormatter.digitsOnly + ], + maxLength: 20, + ), + const SizedBox(height: 10), + BookTextField( + controller: _olidCtrl, + hint: LocaleKeys.open_library_ID.tr(), + icon: FontAwesomeIcons.o, + keyboardType: TextInputType.text, + maxLength: 20, + textCapitalization: TextCapitalization.characters, + ), + const SizedBox(height: 10), + StreamBuilder>( + stream: bookCubit.tags, + builder: (context, AsyncSnapshot?> snapshot) { + final book = context.read().state; + return TagsField( + existingTags: _parseBookTags(book.tags), + controller: _tagsCtrl, + hint: LocaleKeys.enter_tags.tr(), + icon: FontAwesomeIcons.tags, + keyboardType: TextInputType.text, + maxLength: 20, + onSubmitted: (_) => _addNewTag(), + onEditingComplete: () {}, + unselectTag: (tag) => _unselectTag(tag), + allTags: snapshot.data, + ); + }, + ), + const Padding( + padding: EdgeInsets.all(10), + child: Divider(), + ), + BookTextField( + controller: _myReviewCtrl, + hint: LocaleKeys.my_review.tr(), + icon: FontAwesomeIcons.solidKeyboard, + keyboardType: TextInputType.multiline, + maxLength: 5000, + hideCounter: false, + maxLines: 15, + textCapitalization: TextCapitalization.sentences, + ), + const SizedBox(height: 10), + BookTextField( + controller: _notesCtrl, + hint: LocaleKeys.notes.tr(), + icon: FontAwesomeIcons.noteSticky, + keyboardType: TextInputType.multiline, + maxLength: 5000, + hideCounter: false, + maxLines: 15, + textCapitalization: TextCapitalization.sentences, + ), + const SizedBox(height: 30), + Row( + children: [ + const SizedBox(width: 10), + Expanded( + flex: 10, + child: FilledButton.tonal( + onPressed: () => Navigator.pop(context), + style: ButtonStyle( + shape: MaterialStateProperty.all(RoundedRectangleBorder( + borderRadius: BorderRadius.circular(cornerRadius), + )), ), - ), - const SizedBox(width: 10), - Expanded( - flex: 19, - child: BlocBuilder( - builder: (context, state) { - return FilledButton( - onPressed: (state.id != null) - ? () => _updateBook(state) - : () => _saveBook(state), - style: ButtonStyle( - shape: MaterialStateProperty.all( - RoundedRectangleBorder( - borderRadius: - BorderRadius.circular(cornerRadius), - )), - ), - child: const Center( - child: Text("Save"), - ), - ); - }, + child: const Center( + child: Text("Cancel"), ), ), - const SizedBox(width: 10), - ], - ), - const SizedBox(height: 50.0), - ], - ), + ), + const SizedBox(width: 10), + Expanded( + flex: 19, + child: BlocBuilder( + builder: (context, state) { + return FilledButton( + onPressed: (state.id != null) + ? () => _updateBook(state) + : () => _saveBook(state), + style: ButtonStyle( + shape: MaterialStateProperty.all( + RoundedRectangleBorder( + borderRadius: BorderRadius.circular(cornerRadius), + )), + ), + child: const Center( + child: Text("Save"), + ), + ); + }, + ), + ), + const SizedBox(width: 10), + ], + ), + const SizedBox(height: 50.0), + ], ), ), ), From dbc4c81b5df7f85b4508ad88499d9736fd39e761 Mon Sep 17 00:00:00 2001 From: th8m0z Date: Tue, 27 Feb 2024 18:19:58 +0100 Subject: [PATCH 3/4] tags filtering even when book is not saved --- lib/ui/add_book_screen/add_book_screen.dart | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/ui/add_book_screen/add_book_screen.dart b/lib/ui/add_book_screen/add_book_screen.dart index 946310e1..a09fae6f 100644 --- a/lib/ui/add_book_screen/add_book_screen.dart +++ b/lib/ui/add_book_screen/add_book_screen.dart @@ -230,6 +230,13 @@ class _AddBookScreenState extends State { } void _addNewTag() { + final tag = _tagsCtrl.text; + + if (tag.isEmpty) { + FocusManager.instance.primaryFocus?.unfocus(); + return; + } + context.read().addNewTag(_tagsCtrl.text); _tagsCtrl.clear(); @@ -496,7 +503,11 @@ class _AddBookScreenState extends State { icon: FontAwesomeIcons.tags, keyboardType: TextInputType.text, maxLength: 20, - onSubmitted: (_) => _addNewTag(), + onSubmitted: (_) { + _addNewTag(); + // Adding setState causes reload which is needed so that tag suggestions update + setState(() {}); + }, onEditingComplete: () {}, unselectTag: (tag) => _unselectTag(tag), allTags: snapshot.data, From 3e169cef23a9eb5b405ed57664a6e134c5dd27e2 Mon Sep 17 00:00:00 2001 From: th8m0z Date: Thu, 29 Feb 2024 23:09:19 +0100 Subject: [PATCH 4/4] fix merge conflict with origin --- lib/ui/add_book_screen/add_book_screen.dart | 105 ++------------------ 1 file changed, 8 insertions(+), 97 deletions(-) diff --git a/lib/ui/add_book_screen/add_book_screen.dart b/lib/ui/add_book_screen/add_book_screen.dart index daca8962..ddc275bb 100644 --- a/lib/ui/add_book_screen/add_book_screen.dart +++ b/lib/ui/add_book_screen/add_book_screen.dart @@ -446,100 +446,6 @@ class _AddBookScreenState extends State { padding: const EdgeInsets.fromLTRB(10, 0, 5, 0), ), ), - ), - ], - ), - const SizedBox(height: 10), - BookTextField( - controller: _descriptionCtrl, - hint: LocaleKeys.enter_description.tr(), - icon: FontAwesomeIcons.solidKeyboard, - keyboardType: TextInputType.multiline, - maxLength: 5000, - hideCounter: false, - maxLines: 15, - textCapitalization: TextCapitalization.sentences, - ), - const SizedBox(height: 10), - BookTextField( - controller: _isbnCtrl, - hint: LocaleKeys.isbn.tr(), - icon: FontAwesomeIcons.i, - keyboardType: TextInputType.number, - inputFormatters: [ - FilteringTextInputFormatter.digitsOnly - ], - maxLength: 20, - ), - const SizedBox(height: 10), - BookTextField( - controller: _olidCtrl, - hint: LocaleKeys.open_library_ID.tr(), - icon: FontAwesomeIcons.o, - keyboardType: TextInputType.text, - maxLength: 20, - textCapitalization: TextCapitalization.characters, - ), - const SizedBox(height: 10), - StreamBuilder>( - stream: bookCubit.tags, - builder: (context, AsyncSnapshot?> snapshot) { - final book = context.read().state; - return TagsField( - existingTags: _parseBookTags(book.tags), - controller: _tagsCtrl, - hint: LocaleKeys.enter_tags.tr(), - icon: FontAwesomeIcons.tags, - keyboardType: TextInputType.text, - maxLength: 20, - onSubmitted: (_) { - _addNewTag(); - // Adding setState causes reload which is needed so that tag suggestions update - setState(() {}); - }, - onEditingComplete: () {}, - unselectTag: (tag) => _unselectTag(tag), - allTags: snapshot.data, - ); - }, - ), - const Padding( - padding: EdgeInsets.all(10), - child: Divider(), - ), - BookTextField( - controller: _myReviewCtrl, - hint: LocaleKeys.my_review.tr(), - icon: FontAwesomeIcons.solidKeyboard, - keyboardType: TextInputType.multiline, - maxLength: 5000, - hideCounter: false, - maxLines: 15, - textCapitalization: TextCapitalization.sentences, - ), - const SizedBox(height: 10), - BookTextField( - controller: _notesCtrl, - hint: LocaleKeys.notes.tr(), - icon: FontAwesomeIcons.noteSticky, - keyboardType: TextInputType.multiline, - maxLength: 5000, - hideCounter: false, - maxLines: 15, - textCapitalization: TextCapitalization.sentences, - ), - const SizedBox(height: 30), - Row( - children: [ - const SizedBox(width: 10), - Expanded( - flex: 10, - child: FilledButton.tonal( - onPressed: () => Navigator.pop(context), - style: ButtonStyle( - shape: MaterialStateProperty.all(RoundedRectangleBorder( - borderRadius: BorderRadius.circular(cornerRadius), - )), Expanded( child: BookTextField( controller: _pubYearCtrl, @@ -551,7 +457,6 @@ class _AddBookScreenState extends State { ], maxLength: 4, padding: const EdgeInsets.fromLTRB(5, 0, 10, 0), - ), ), ], @@ -591,13 +496,19 @@ class _AddBookScreenState extends State { StreamBuilder>( stream: bookCubit.tags, builder: (context, AsyncSnapshot?> snapshot) { + final book = context.read().state; return TagsField( + existingTags: _parseBookTags(book.tags), controller: _tagsCtrl, hint: LocaleKeys.enter_tags.tr(), icon: FontAwesomeIcons.tags, keyboardType: TextInputType.text, - maxLength: Constants.maxTagLength, - onSubmitted: (_) => _addNewTag(), + maxLength: 20, + onSubmitted: (_) { + _addNewTag(); + // Adding setState causes reload which is needed so that tag suggestions update + setState(() {}); + }, onEditingComplete: () {}, unselectTag: (tag) => _unselectTag(tag), allTags: snapshot.data,