Skip to content

Commit

Permalink
feat: add word search to dictionary
Browse files Browse the repository at this point in the history
  • Loading branch information
jeroen-meijer committed Jul 20, 2020
1 parent 696b3b6 commit c4fc6e3
Show file tree
Hide file tree
Showing 8 changed files with 139 additions and 82 deletions.
10 changes: 9 additions & 1 deletion .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
{
"dart.lineLength": 80
"dart.lineLength": 80,
"search.exclude": {
"**/node_modules": true,
"**/bower_components": true,
"**/*.code-search": true,
"app/assets/dicts/**/*": true,
"dict_parser/*.json": true,
"dict_parser/*.xml": true,
}
}
2 changes: 1 addition & 1 deletion app/assets/dicts/dict_ja.json

Large diffs are not rendered by default.

12 changes: 6 additions & 6 deletions app/lib/assets/dictionaries.dart
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import 'package:meta/meta.dart';
import 'package:provider/provider.dart';
import 'package:shared_models/shared_models.dart';

export 'package:shared_models/shared_models.dart';

@immutable
class Dictionaries {
const Dictionaries({
Expand All @@ -20,6 +22,10 @@ class Dictionaries {
return all.map((dict) => dict.language).toList();
}

static Dictionaries of(BuildContext context) {
return Provider.of<Dictionaries>(context, listen: false);
}

static Future<Dictionary> _loadDictionaryFromDisk(Language language) async {
final dictText =
await rootBundle.loadString('assets/dicts/dict_${language.code}.json');
Expand All @@ -39,12 +45,6 @@ class Dictionaries {
}
}

extension DictionariesX on Dictionaries {
static Dictionaries of(BuildContext context) {
return Provider.of<Dictionaries>(context, listen: false);
}
}

extension DictionaryX on Dictionary {
static Dictionary of(BuildContext context) {
return Provider.of<Dictionary>(context, listen: false);
Expand Down
66 changes: 50 additions & 16 deletions app/lib/ui/screens/game/game_screen.dart
Original file line number Diff line number Diff line change
@@ -1,31 +1,65 @@
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shiritori/assets/assets.dart';
import 'package:shiritori/intl/intl.dart';
import 'package:shiritori/theme/theme.dart';
import 'package:shiritori/ui/widgets/widgets.dart';

class GameScreen extends StatelessWidget {
class GameScreen extends StatefulWidget {
GameScreen({
Key key,
@required this.dictionary,
}) : assert(dictionary != null),
super(key: key);

final Dictionary dictionary;

@override
_GameScreenState createState() => _GameScreenState();
}

class _GameScreenState extends State<GameScreen> {
static const _query = 'しお';

List<WordEntry> _searchResults;

@override
void initState() {
super.initState();
_searchResults = widget.dictionary.searchWord(_query);
}

@override
Widget build(BuildContext context) {
final intl = ShiritoriLocalizations.of(context).game;
final uiIntl = ShiritoriLocalizations.of(context).ui;

return DefaultStylingColor(
color: AppTheme.colorSingleplayer,
child: Scaffold(
body: CustomScrollView(
slivers: [
AppSliverNavigationBar(
title: Text(intl.singleplayerTitle),
leading: TextButton(
onTap: Navigator.of(context).pop,
child: Text(uiIntl.back),
return Provider<Dictionary>.value(
value: widget.dictionary,
child: DefaultStylingColor(
color: AppTheme.colorSingleplayer,
child: Scaffold(
body: CustomScrollView(
slivers: [
AppSliverNavigationBar(
title: Text(intl.singleplayerTitle),
leading: TextButton(
onTap: Navigator.of(context).pop,
child: Text(uiIntl.back),
),
),
SliverFillRemaining(
child: Center(
child: Text(
'Selected dictionary: ${widget.dictionary}\n'
'Information for the word $_query:\n'
'$_searchResults',
),
),
),
),
const SliverFillRemaining(
child: ColoredBox(color: Colors.red),
),
],
],
),
),
),
);
Expand Down
5 changes: 4 additions & 1 deletion app/lib/ui/screens/home/home_screen.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:ui' as ui;
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:provider/provider.dart';
import 'package:shiritori/assets/assets.dart';
import 'package:shiritori/intl/intl.dart';
import 'package:shiritori/theme/theme.dart';
import 'package:shiritori/ui/screens/game/game.dart';
Expand Down Expand Up @@ -51,7 +52,9 @@ class HomeScreen extends StatelessWidget {
),
ExpandingRouteButton(
routeBuilder: (context) {
return GameScreen();
return GameScreen(
dictionary: Dictionaries.of(context).japanese,
);
},
child: Text(intl.quickPlayButtonTitle),
),
Expand Down
107 changes: 52 additions & 55 deletions app/lib/ui/screens/home/widgets/home_menu.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import 'dart:developer';
import 'package:animations/animations.dart';
import 'package:flutter/material.dart';
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
import 'package:shiritori/assets/assets.dart';
import 'package:shiritori/intl/intl.dart';
import 'package:shiritori/theme/theme.dart';
import 'package:shiritori/ui/screens/game/game.dart';
Expand Down Expand Up @@ -30,7 +31,9 @@ class HomeMenu extends StatelessWidget {
color: AppTheme.colorSingleplayer,
icon: const Text('遊ぶ'),
expandedChildBuilder: (context) {
return GameScreen();
return GameScreen(
dictionary: Dictionaries.of(context).japanese,
);
},
),
_PlayCard(
Expand Down Expand Up @@ -98,63 +101,57 @@ class _PlayCard extends StatelessWidget {
aspectRatio: 1,
child: Opacity(
opacity: expandedChildBuilder != null ? 1.0 : 0.5,
child: LayoutBuilder(
builder: (context, constraints) {
log('$constraints');

return OpenContainer(
tappable: false,
transitionDuration: AppTheme.durationAnimationDefault,
openBuilder: (context, close) {
return expandedChildBuilder?.call(context);
},
closedColor: cardTheme.color,
closedShape: cardTheme.shape,
closedElevation: cardTheme.elevation,
closedBuilder: (context, open) {
return ScaleButton(
onTap: !enabled ? null : open,
child: Material(
type: MaterialType.transparency,
child: DefaultStylingColor(
color: color,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
DefaultTextStyle.merge(
style: textTheme.subtitle2,
child: subtitle,
),
const SubtitleLine(),
verticalMargin4,
DefaultTextStyle.merge(
maxLines: 1,
softWrap: false,
overflow: TextOverflow.fade,
style: textTheme.headline5,
child: title,
),
const Spacer(),
DefaultTextStyle.merge(
style: TextStyle(
fontWeight: textTheme.headline4.fontWeight,
),
child: AbsoluteTextIconTheme(
size: 56.0,
color: color,
child: icon,
),
),
],
child: OpenContainer(
tappable: false,
transitionDuration: AppTheme.durationAnimationDefault,
openBuilder: (context, close) {
return expandedChildBuilder?.call(context);
},
closedColor: cardTheme.color,
closedShape: cardTheme.shape,
closedElevation: cardTheme.elevation,
closedBuilder: (context, open) {
return ScaleButton(
onTap: !enabled ? null : open,
child: Material(
type: MaterialType.transparency,
child: DefaultStylingColor(
color: color,
child: Padding(
padding: const EdgeInsets.all(16.0),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
DefaultTextStyle.merge(
style: textTheme.subtitle2,
child: subtitle,
),
),
const SubtitleLine(),
verticalMargin4,
DefaultTextStyle.merge(
maxLines: 1,
softWrap: false,
overflow: TextOverflow.fade,
style: textTheme.headline5,
child: title,
),
const Spacer(),
DefaultTextStyle.merge(
style: TextStyle(
fontWeight: textTheme.headline4.fontWeight,
),
child: AbsoluteTextIconTheme(
size: 56.0,
color: color,
child: icon,
),
),
],
),
),
);
},
),
),
);
},
),
Expand Down
2 changes: 1 addition & 1 deletion dict_parser/lib/main.dart
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import 'package:dict_parser/utils.dart';
import 'package:shared_models/shared_models.dart';
import 'package:xml/xml.dart';

const _wordCountLimit = 20000;
const _wordCountLimit = 50000;

// TODO: Move to config wrapper class for better compatibilty with other dicts.
const _nounTag = '&n;';
Expand Down
17 changes: 16 additions & 1 deletion shared_models/lib/src/dictionary.dart
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
import 'dart:developer';

import 'package:equatable/equatable.dart';
import 'package:json_annotation/json_annotation.dart';
import 'package:meta/meta.dart';
Expand Down Expand Up @@ -49,12 +51,25 @@ class Dictionary extends Equatable {
final Map<String, Set<int>> indicies;
final List<WordEntry> entries;

List<WordEntry> searchWord(String query) {
log('SEARCH');
final queryIndicies = indicies[query];
if (queryIndicies == null) {
return null;
}

return queryIndicies.map((index) => entries[index]).toList(growable: false);
}

factory Dictionary.fromJson(Map<String, dynamic> json) =>
_$DictionaryFromJson(json);
Map<String, dynamic> toJson() => _$DictionaryToJson(this);

@override
bool get stringify => true;
String toString() {
return 'Dictionary for language ${language.code} '
'(${indicies.length} indicies, ${entries.length} entries)';
}

@override
List<Object> get props => [indicies, entries];
Expand Down

0 comments on commit c4fc6e3

Please sign in to comment.