From 2f63c202fc1c48a79692fe8aaaa01daf713e7f02 Mon Sep 17 00:00:00 2001 From: h7x4abk3g Date: Mon, 20 Jul 2020 15:41:48 +0200 Subject: [PATCH 1/6] Squashed commit of the following: commit 17db40663d761fc989803469620e3af5ae62f674 Author: h7x4 Date: Sun Jul 19 23:27:31 2020 +0200 Style examples commit 298add43b7d00961de7524560cd37c704c26b885 Author: h7x4abk3g Date: Sat Jul 18 18:49:40 2020 +0200 Add examples --- .../kanji/kanji__search_page/examples.dart | 126 ++++++++++++++++++ .../kanji__search_page/kanji_search_page.dart | 2 + 2 files changed, 128 insertions(+) create mode 100644 lib/components/kanji/kanji__search_page/examples.dart diff --git a/lib/components/kanji/kanji__search_page/examples.dart b/lib/components/kanji/kanji__search_page/examples.dart new file mode 100644 index 0000000..f90911a --- /dev/null +++ b/lib/components/kanji/kanji__search_page/examples.dart @@ -0,0 +1,126 @@ +import 'package:flutter/material.dart'; +import 'package:unofficial_jisho_api/api.dart'; + +class Examples extends StatelessWidget { + final List _onyomiExamples; + final List _kunyomiExamples; + + const Examples( + this._onyomiExamples, + this._kunyomiExamples, + ); + + @override + Widget build(BuildContext context) { + return ExpansionTile( + title: Center( + child: Container( + padding: EdgeInsets.symmetric(vertical: 10.0, horizontal: 10.0), + decoration: BoxDecoration( + color: Colors.blue, + borderRadius: BorderRadius.circular(10.0), + ), + child: Text( + 'Examples', + style: TextStyle( + color: Colors.white, + fontSize: 20.0, + ), + ), + ), + ), + children: [ + _onyomiExamples + .map((onyomiExample) => _Example(onyomiExample, _KanaType.onyomi)) + .toList(), + _kunyomiExamples + .map((kunyomiExample) => + _Example(kunyomiExample, _KanaType.kunyomi)) + .toList(), + ].expand((list) => list).toList()); + } +} + +enum _KanaType { kunyomi, onyomi } + +class _Example extends StatelessWidget { + final _KanaType _kanaType; + final YomiExample _yomiExample; + + const _Example(this._yomiExample, this._kanaType); + + @override + Widget build(BuildContext context) { + return Container( + margin: EdgeInsets.symmetric( + vertical: 10.0, + horizontal: 10.0, + ), + decoration: BoxDecoration( + color: Colors.grey, borderRadius: BorderRadius.circular(10.0)), + child: IntrinsicHeight( + child: Row( + children: [ + Container( + padding: EdgeInsets.symmetric( + vertical: 10.0, + horizontal: 10.0, + ), + decoration: BoxDecoration( + color: (_kanaType == _KanaType.kunyomi) + ? Colors.lightBlue + : Colors.orange, + borderRadius: BorderRadius.only( + topLeft: Radius.circular(10.0), + bottomLeft: Radius.circular(10.0), + ), + ), + child: Column( + children: [ + Container( + child: Text( + _yomiExample.reading, + style: TextStyle( + color: Colors.white, + fontSize: 15.0, + ), + ), + ), + SizedBox( + height: 5.0, + ), + Container( + child: Text( + _yomiExample.example, + style: TextStyle( + color: Colors.white, + fontSize: 20.0, + ), + ), + ), + ], + ), + ), + SizedBox( + width: 15.0, + ), + Expanded( + child: Wrap( + children: [ + Container( + child: Text( + _yomiExample.meaning, + style: TextStyle( + color: Colors.white, + ), + ), + ) + ], + ), + ), + ], + ), + ), + ); + } +} diff --git a/lib/components/kanji/kanji__search_page/kanji_search_page.dart b/lib/components/kanji/kanji__search_page/kanji_search_page.dart index 2e7cead..3c054ed 100644 --- a/lib/components/kanji/kanji__search_page/kanji_search_page.dart +++ b/lib/components/kanji/kanji__search_page/kanji_search_page.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:jisho_study_tool/components/kanji/kanji__search_page/examples.dart'; import 'package:unofficial_jisho_api/api.dart' as jisho; @@ -81,6 +82,7 @@ class KanjiResultCard extends StatelessWidget { ], ), ), + Examples(_result.onyomiExamples, _result.kunyomiExamples), ], ); } From 76d2b090f3e9f88d32644a07a83527db565f62e1 Mon Sep 17 00:00:00 2001 From: h7x4 Date: Tue, 21 Jul 2020 23:29:02 +0200 Subject: [PATCH 2/6] JST 4 - Add kanji search suggestions (#3) * Add division package * Add base logic and widget * Finish layout * Fix kanji regex * Add bloc logic --- lib/bloc/kanji/kanji_bloc.dart | 5 ++ lib/bloc/kanji/kanji_event.dart | 10 ++-- lib/bloc/kanji/kanji_state.dart | 17 ++++--- lib/components/kanji/kanji_suggestions.dart | 55 +++++++++++++++++++++ lib/screens/kanji_search.dart | 4 ++ lib/services/kanji_suggestions.dart | 5 ++ pubspec.lock | 32 ++++++++---- pubspec.yaml | 39 +-------------- 8 files changed, 111 insertions(+), 56 deletions(-) create mode 100644 lib/components/kanji/kanji_suggestions.dart create mode 100644 lib/services/kanji_suggestions.dart diff --git a/lib/bloc/kanji/kanji_bloc.dart b/lib/bloc/kanji/kanji_bloc.dart index 593baf2..a8cfe7d 100644 --- a/lib/bloc/kanji/kanji_bloc.dart +++ b/lib/bloc/kanji/kanji_bloc.dart @@ -5,6 +5,7 @@ import './kanji_state.dart'; import 'package:bloc/bloc.dart'; import 'package:jisho_study_tool/services/kanji_search.dart'; +import 'package:jisho_study_tool/services/kanji_suggestions.dart'; export './kanji_event.dart'; export './kanji_state.dart'; @@ -28,6 +29,10 @@ class KanjiBloc extends Bloc { } on Exception { yield KanjiSearchError('Something went wrong'); } + } else if (event is GetKanjiSuggestions) { + + final suggestions = kanjiSuggestions(event.searchString); + yield KanjiSearchInput(suggestions); } else if (event is ReturnToInitialState) { yield KanjiSearchInitial(); diff --git a/lib/bloc/kanji/kanji_event.dart b/lib/bloc/kanji/kanji_event.dart index 6bbe8e5..7bb79b8 100644 --- a/lib/bloc/kanji/kanji_event.dart +++ b/lib/bloc/kanji/kanji_event.dart @@ -2,12 +2,16 @@ abstract class KanjiEvent { const KanjiEvent(); } +class GetKanjiSuggestions extends KanjiEvent { + final String searchString; + const GetKanjiSuggestions(this.searchString); +} + class GetKanji extends KanjiEvent { final String kanjiSearchString; - - GetKanji(this.kanjiSearchString); + const GetKanji(this.kanjiSearchString); } class ReturnToInitialState extends KanjiEvent { - ReturnToInitialState(); + const ReturnToInitialState(); } \ No newline at end of file diff --git a/lib/bloc/kanji/kanji_state.dart b/lib/bloc/kanji/kanji_state.dart index 7e5aff2..ad835db 100644 --- a/lib/bloc/kanji/kanji_state.dart +++ b/lib/bloc/kanji/kanji_state.dart @@ -5,18 +5,23 @@ abstract class KanjiState { } class KanjiSearchInitial extends KanjiState { - KanjiSearchInitial(); + const KanjiSearchInitial(); +} + +class KanjiSearchInput extends KanjiState { + final List kanjiSuggestions; + const KanjiSearchInput(this.kanjiSuggestions); } class KanjiSearchLoading extends KanjiState { - KanjiSearchLoading(); + const KanjiSearchLoading(); } class KanjiSearchFinished extends KanjiState { final KanjiResult kanji; final bool starred; - KanjiSearchFinished({ + const KanjiSearchFinished({ this.kanji, this.starred = false, }); @@ -25,7 +30,5 @@ class KanjiSearchFinished extends KanjiState { class KanjiSearchError extends KanjiState { final String message; - KanjiSearchError(this.message); -} - -class ReKanjiSearch extends KanjiState {} + const KanjiSearchError(this.message); +} \ No newline at end of file diff --git a/lib/components/kanji/kanji_suggestions.dart b/lib/components/kanji/kanji_suggestions.dart new file mode 100644 index 0000000..3c0a044 --- /dev/null +++ b/lib/components/kanji/kanji_suggestions.dart @@ -0,0 +1,55 @@ +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:jisho_study_tool/bloc/kanji/kanji_bloc.dart'; + +class KanjiSuggestions extends StatelessWidget { + final List _suggestions; + const KanjiSuggestions(this._suggestions); + + @override + Widget build(BuildContext context) { + return Container( + color: Colors.grey[300], + padding: EdgeInsets.symmetric( + vertical: 20.0, + horizontal: 40.0, + ), + child: GridView.count( + crossAxisCount: 3, + mainAxisSpacing: 20.0, + crossAxisSpacing: 40.0, + children: _suggestions.map((kanji) => _Suggestion(kanji)).toList(), + ), + ); + } +} + +class _Suggestion extends StatelessWidget { + final String _kanji; + const _Suggestion(this._kanji); + + @override + Widget build(BuildContext context) { + return InkWell( + onTap: () { + FocusScope.of(context).unfocus(); //Puts away the keyboard + BlocProvider.of(context).add(GetKanji(_kanji)); + }, + child: Container( + decoration: BoxDecoration( + color: Colors.grey, + borderRadius: BorderRadius.circular(10.0), + ), + child: Container( + margin: EdgeInsets.all(10.0), + child: FittedBox( + child: Text( + _kanji, + style: TextStyle(color: Colors.white), + ), + ), + ), + ), + ); + } +} diff --git a/lib/screens/kanji_search.dart b/lib/screens/kanji_search.dart index 03f9100..2a0fc7d 100644 --- a/lib/screens/kanji_search.dart +++ b/lib/screens/kanji_search.dart @@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:jisho_study_tool/bloc/kanji/kanji_bloc.dart'; import 'package:jisho_study_tool/components/kanji/kanji__search_page/kanji_search_page.dart'; +import 'package:jisho_study_tool/components/kanji/kanji_suggestions.dart'; import 'package:jisho_study_tool/components/loading.dart'; class KanjiView extends StatelessWidget { @@ -12,6 +13,8 @@ class KanjiView extends StatelessWidget { builder: (context, state) { if (state is KanjiSearchInitial) return Container(); + else if (state is KanjiSearchInput) + return KanjiSuggestions(state.kanjiSuggestions); else if (state is KanjiSearchLoading) return LoadingScreen(); else if (state is KanjiSearchFinished) @@ -42,6 +45,7 @@ class KanjiViewBar extends StatelessWidget { child: Container( padding: EdgeInsets.symmetric(vertical: 10.0), child: TextField( + onChanged: (text) => BlocProvider.of(context).add(GetKanjiSuggestions(text)), onSubmitted: (text) => BlocProvider.of(context).add(GetKanji(text)), decoration: new InputDecoration( diff --git a/lib/services/kanji_suggestions.dart b/lib/services/kanji_suggestions.dart new file mode 100644 index 0000000..a2adfc2 --- /dev/null +++ b/lib/services/kanji_suggestions.dart @@ -0,0 +1,5 @@ +final kanjiPattern = RegExp(r'[\u3400-\u4DB5\u4E00-\u9FCB\uF900-\uFA6A]'); + +List kanjiSuggestions(String string) { + return kanjiPattern.allMatches(string).map((match) => match.group(0)).toList(); +} \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index 84e8413..c88cf25 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -7,7 +7,7 @@ packages: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.4.1" + version: "2.4.2" bloc: dependency: transitive description: @@ -22,6 +22,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.0.0" + characters: + dependency: transitive + description: + name: characters + url: "https://pub.dartlang.org" + source: hosted + version: "1.1.0-nullsafety" charcode: dependency: transitive description: @@ -42,7 +49,7 @@ packages: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.14.12" + version: "1.15.0-nullsafety" csslib: dependency: transitive description: @@ -57,6 +64,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.1.2" + division: + dependency: "direct main" + description: + name: division + url: "https://pub.dartlang.org" + source: hosted + version: "0.8.8" fake_async: dependency: transitive description: @@ -127,14 +141,14 @@ packages: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.6" + version: "0.12.9" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.1.8" + version: "1.3.0-nullsafety" nested: dependency: transitive description: @@ -202,7 +216,7 @@ packages: name: stack_trace url: "https://pub.dartlang.org" source: hosted - version: "1.9.3" + version: "1.9.5" stream_channel: dependency: transitive description: @@ -230,14 +244,14 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.2.16" + version: "0.2.18" typed_data: dependency: transitive description: name: typed_data url: "https://pub.dartlang.org" source: hosted - version: "1.1.6" + version: "1.3.0-nullsafety" unofficial_jisho_api: dependency: "direct main" description: @@ -286,7 +300,7 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.0.8" + version: "2.1.0-nullsafety" sdks: - dart: ">=2.7.0 <3.0.0" + dart: ">=2.9.0-18.0 <2.9.0" flutter: ">=1.16.0 <2.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index 7b108ef..7129eb3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,16 +1,5 @@ name: jisho_study_tool description: A new Flutter project. - -# The following defines the version and build number for your application. -# A version number is three numbers separated by dots, like 1.2.43 -# followed by an optional build number separated by a +. -# Both the version and the builder number may be overridden in flutter -# build by specifying --build-name and --build-number, respectively. -# In Android, build-name is used as versionName while build-number used as versionCode. -# Read more about Android versioning at https://developer.android.com/studio/publish/versioning -# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. -# Read more about iOS versioning at -# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html version: 1.0.0+1 environment: @@ -20,45 +9,24 @@ dependencies: flutter: sdk: flutter - # The following adds the Cupertino Icons font to your application. - # Use with the CupertinoIcons class for iOS style icons. # cupertino_icons: ^0.1.2 unofficial_jisho_api: ^1.1.0 flutter_bloc: ^5.0.1 url_launcher: ^5.5.0 + division: ^0.8.8 dev_dependencies: flutter_test: sdk: flutter - -# For information on the generic Dart part of this file, see the -# following page: https://dart.dev/tools/pub/pubspec - -# The following section is specific to Flutter. flutter: - - # The following line ensures that the Material Icons font is - # included with your application, so that you can use the icons in - # the material Icons class. uses-material-design: true - - # To add assets to your application, add an assets section, like this: + # assets: # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg - # An image asset can refer to one or more resolution-specific "variants", see - # https://flutter.dev/assets-and-images/#resolution-aware. - # For details regarding adding assets from package dependencies, see - # https://flutter.dev/assets-and-images/#from-packages - - # To add custom fonts to your application, add a fonts section here, - # in this "flutter" section. Each entry in this list should have a - # "family" key with the font family name, and a "fonts" key with a - # list giving the asset and other descriptors for the font. For - # example: # fonts: # - family: Schyler # fonts: @@ -70,6 +38,3 @@ flutter: # - asset: fonts/TrajanPro.ttf # - asset: fonts/TrajanPro_Bold.ttf # weight: 700 - # - # For details regarding fonts from package dependencies, - # see https://flutter.dev/custom-fonts/#from-packages From 689983b84826a27d89d56b850c839aade469a060 Mon Sep 17 00:00:00 2001 From: h7x4abk3g Date: Wed, 22 Jul 2020 14:13:53 +0200 Subject: [PATCH 3/6] Placed keyboard logic inside bloc listener --- lib/components/kanji/kanji_suggestions.dart | 1 - lib/screens/kanji_search.dart | 67 +++++++++++++-------- 2 files changed, 41 insertions(+), 27 deletions(-) diff --git a/lib/components/kanji/kanji_suggestions.dart b/lib/components/kanji/kanji_suggestions.dart index 3c0a044..ade96cb 100644 --- a/lib/components/kanji/kanji_suggestions.dart +++ b/lib/components/kanji/kanji_suggestions.dart @@ -32,7 +32,6 @@ class _Suggestion extends StatelessWidget { Widget build(BuildContext context) { return InkWell( onTap: () { - FocusScope.of(context).unfocus(); //Puts away the keyboard BlocProvider.of(context).add(GetKanji(_kanji)); }, child: Container( diff --git a/lib/screens/kanji_search.dart b/lib/screens/kanji_search.dart index 2a0fc7d..557d071 100644 --- a/lib/screens/kanji_search.dart +++ b/lib/screens/kanji_search.dart @@ -9,23 +9,33 @@ import 'package:jisho_study_tool/components/loading.dart'; class KanjiView extends StatelessWidget { @override Widget build(BuildContext context) { - return BlocBuilder( - builder: (context, state) { - if (state is KanjiSearchInitial) - return Container(); - else if (state is KanjiSearchInput) - return KanjiSuggestions(state.kanjiSuggestions); - else if (state is KanjiSearchLoading) - return LoadingScreen(); - else if (state is KanjiSearchFinished) - return WillPopScope( - child: KanjiResultCard(state.kanji), - onWillPop: () async { - BlocProvider.of(context).add(ReturnToInitialState()); - return false; - }); - throw 'No such event found'; + return BlocListener( + listener: (context, state) { + if (state is KanjiSearchInitial) { + FocusScope.of(context).unfocus(); + } else if (state is KanjiSearchLoading) { + FocusScope.of(context).unfocus(); + } }, + child: BlocBuilder( + builder: (context, state) { + if (state is KanjiSearchInitial) { + return Container(); + } else if (state is KanjiSearchInput) + return KanjiSuggestions(state.kanjiSuggestions); + else if (state is KanjiSearchLoading) + return LoadingScreen(); + else if (state is KanjiSearchFinished) + return WillPopScope( + child: KanjiResultCard(state.kanji), + onWillPop: () async { + BlocProvider.of(context) + .add(ReturnToInitialState()); + return false; + }); + throw 'No such event found'; + }, + ), ); } } @@ -38,23 +48,28 @@ class KanjiViewBar extends StatelessWidget { children: [ IconButton( icon: Icon(Icons.arrow_back), - onPressed: () => BlocProvider.of(context) - .add(ReturnToInitialState()), + onPressed: () => + BlocProvider.of(context).add(ReturnToInitialState()), ), Expanded( child: Container( - padding: EdgeInsets.symmetric(vertical: 10.0), child: TextField( - onChanged: (text) => BlocProvider.of(context).add(GetKanjiSuggestions(text)), + onChanged: (text) => BlocProvider.of(context) + .add(GetKanjiSuggestions(text)), onSubmitted: (text) => BlocProvider.of(context).add(GetKanji(text)), decoration: new InputDecoration( - prefixIcon: Icon(Icons.search), - hintText: 'Search for kanji', - fillColor: Colors.white, - filled: true, - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(100.0)), + prefixIcon: Icon(Icons.search), + hintText: 'Search for kanji', + fillColor: Colors.white, + filled: true, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(100.0), + ), + contentPadding: EdgeInsets.symmetric(vertical: 10.0), + isDense: false), + style: TextStyle( + fontSize: 14.0, ), ), ), From ccd38eac2ab09627db60670a850178a45fbc4bb7 Mon Sep 17 00:00:00 2001 From: h7x4abk3g Date: Wed, 22 Jul 2020 15:22:21 +0200 Subject: [PATCH 4/6] Separate text field logic --- lib/screens/kanji_search.dart | 79 ++++++++++++++++++++++++++--------- 1 file changed, 60 insertions(+), 19 deletions(-) diff --git a/lib/screens/kanji_search.dart b/lib/screens/kanji_search.dart index 557d071..250b128 100644 --- a/lib/screens/kanji_search.dart +++ b/lib/screens/kanji_search.dart @@ -53,25 +53,7 @@ class KanjiViewBar extends StatelessWidget { ), Expanded( child: Container( - child: TextField( - onChanged: (text) => BlocProvider.of(context) - .add(GetKanjiSuggestions(text)), - onSubmitted: (text) => - BlocProvider.of(context).add(GetKanji(text)), - decoration: new InputDecoration( - prefixIcon: Icon(Icons.search), - hintText: 'Search for kanji', - fillColor: Colors.white, - filled: true, - border: OutlineInputBorder( - borderRadius: BorderRadius.circular(100.0), - ), - contentPadding: EdgeInsets.symmetric(vertical: 10.0), - isDense: false), - style: TextStyle( - fontSize: 14.0, - ), - ), + child: _KanjiTextField(), ), ), IconButton( @@ -87,3 +69,62 @@ class KanjiViewBar extends StatelessWidget { ); } } + +class _KanjiTextField extends StatefulWidget { + @override + _KanjiTextFieldState createState() => new _KanjiTextFieldState(); +} + +class _KanjiTextFieldState extends State<_KanjiTextField> { + FocusNode _focus = new FocusNode(); + TextEditingController _textController = new TextEditingController(); + + @override + void initState() { + super.initState(); + _focus.addListener(_onFocusChange); + } + + void _onFocusChange() { + debugPrint('TextField Focus Changed: ${_focus.hasFocus.toString()}'); + if (_focus.hasFocus) _getKanjiSuggestions(_textController.text); + else FocusScope.of(context).unfocus(); + } + + void _getKanjiSuggestions(String text) => + BlocProvider.of(context).add(GetKanjiSuggestions(text)); + + void _clearText() { + _textController.text = ''; + _getKanjiSuggestions(_textController.text); + } + + @override + Widget build(BuildContext context) { + return TextField( + focusNode: _focus, + controller: _textController, + onChanged: (text) => _getKanjiSuggestions(text), + onSubmitted: (text) => + BlocProvider.of(context).add(GetKanji(text)), + decoration: new InputDecoration( + prefixIcon: Icon(Icons.search), + hintText: 'Search for kanji', + fillColor: Colors.white, + filled: true, + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(100.0), + ), + contentPadding: EdgeInsets.symmetric(vertical: 10.0), + isDense: false, + suffixIcon: IconButton( + icon: Icon(Icons.clear), + onPressed: () => _clearText(), + ) + ), + style: TextStyle( + fontSize: 14.0, + ), + ); + } +} From 50812c93ab76ffede54c7e060b2bf99c652675e1 Mon Sep 17 00:00:00 2001 From: h7x4abk3g Date: Wed, 22 Jul 2020 16:24:00 +0200 Subject: [PATCH 5/6] Add paste button --- lib/screens/kanji_search.dart | 48 +++++++++++++++++++++++++++-------- 1 file changed, 37 insertions(+), 11 deletions(-) diff --git a/lib/screens/kanji_search.dart b/lib/screens/kanji_search.dart index 250b128..9ed202f 100644 --- a/lib/screens/kanji_search.dart +++ b/lib/screens/kanji_search.dart @@ -1,4 +1,5 @@ import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:jisho_study_tool/bloc/kanji/kanji_bloc.dart'; @@ -75,9 +76,12 @@ class _KanjiTextField extends StatefulWidget { _KanjiTextFieldState createState() => new _KanjiTextFieldState(); } +enum TextFieldButton {clear, paste} + class _KanjiTextFieldState extends State<_KanjiTextField> { FocusNode _focus = new FocusNode(); TextEditingController _textController = new TextEditingController(); + TextFieldButton _button = TextFieldButton.paste; @override void initState() { @@ -85,22 +89,47 @@ class _KanjiTextFieldState extends State<_KanjiTextField> { _focus.addListener(_onFocusChange); } - void _onFocusChange() { - debugPrint('TextField Focus Changed: ${_focus.hasFocus.toString()}'); - if (_focus.hasFocus) _getKanjiSuggestions(_textController.text); - else FocusScope.of(context).unfocus(); - } - void _getKanjiSuggestions(String text) => BlocProvider.of(context).add(GetKanjiSuggestions(text)); + void updateSuggestions() => _getKanjiSuggestions(_textController.text); + + void _onFocusChange() { + debugPrint('TextField Focus Changed: ${_focus.hasFocus.toString()}'); + + setState(() { + _button = _focus.hasFocus ? TextFieldButton.clear : TextFieldButton.paste; + }); + + if (_focus.hasFocus) + updateSuggestions(); + else + FocusScope.of(context).unfocus(); + } + void _clearText() { _textController.text = ''; - _getKanjiSuggestions(_textController.text); + updateSuggestions(); + } + + void _pasteText() async { + ClipboardData clipboardData = await Clipboard.getData('text/plain'); + _textController.text = clipboardData.text; + updateSuggestions(); } @override Widget build(BuildContext context) { + IconButton _clearButton = IconButton( + icon: Icon(Icons.clear), + onPressed: () => _clearText(), + ); + + IconButton _pasteButton = IconButton( + icon: Icon(Icons.content_paste), + onPressed: () => _pasteText(), + ); + return TextField( focusNode: _focus, controller: _textController, @@ -117,10 +146,7 @@ class _KanjiTextFieldState extends State<_KanjiTextField> { ), contentPadding: EdgeInsets.symmetric(vertical: 10.0), isDense: false, - suffixIcon: IconButton( - icon: Icon(Icons.clear), - onPressed: () => _clearText(), - ) + suffixIcon: (_button == TextFieldButton.clear) ? _clearButton : _pasteButton, ), style: TextStyle( fontSize: 14.0, From 3d0cef86ca1c5c0f843019f80a1b5ed488c78dad Mon Sep 17 00:00:00 2001 From: h7x4abk3g Date: Mon, 17 Aug 2020 11:15:32 +0200 Subject: [PATCH 6/6] Misc --- lib/bloc/search/search_bloc.dart | 2 ++ lib/bloc/search/search_state.dart | 4 +--- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/bloc/search/search_bloc.dart b/lib/bloc/search/search_bloc.dart index 1cd2b14..966d290 100644 --- a/lib/bloc/search/search_bloc.dart +++ b/lib/bloc/search/search_bloc.dart @@ -1,6 +1,8 @@ import 'dart:async'; import 'package:bloc/bloc.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; import 'package:meta/meta.dart'; part 'search_event.dart'; diff --git a/lib/bloc/search/search_state.dart b/lib/bloc/search/search_state.dart index 87f3d6a..8e79f14 100644 --- a/lib/bloc/search/search_state.dart +++ b/lib/bloc/search/search_state.dart @@ -9,6 +9,4 @@ class SearchLoading extends SearchState {} class SearchFinished extends SearchState {} -class SearchError extends SearchState {} - -class ReSearch extends SearchState {} \ No newline at end of file +class SearchError extends SearchState {} \ No newline at end of file