JST 4 - Add kanji search suggestions (#3)

* Add division package

* Add base logic and widget

* Finish layout

* Fix kanji regex

* Add bloc logic
JST-11
Oystein Kristoffer Tveit 2020-07-21 23:29:02 +02:00 committed by GitHub
parent 2f63c202fc
commit 76d2b090f3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 111 additions and 56 deletions

View File

@ -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<KanjiEvent, KanjiState> {
} 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();

View File

@ -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();
}

View File

@ -5,18 +5,23 @@ abstract class KanjiState {
}
class KanjiSearchInitial extends KanjiState {
KanjiSearchInitial();
const KanjiSearchInitial();
}
class KanjiSearchInput extends KanjiState {
final List<String> 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);
}

View File

@ -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<String> _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<KanjiBloc>(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),
),
),
),
),
);
}
}

View File

@ -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<KanjiBloc>(context).add(GetKanjiSuggestions(text)),
onSubmitted: (text) =>
BlocProvider.of<KanjiBloc>(context).add(GetKanji(text)),
decoration: new InputDecoration(

View File

@ -0,0 +1,5 @@
final kanjiPattern = RegExp(r'[\u3400-\u4DB5\u4E00-\u9FCB\uF900-\uFA6A]');
List<String> kanjiSuggestions(String string) {
return kanjiPattern.allMatches(string).map((match) => match.group(0)).toList();
}

View File

@ -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"

View File

@ -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