Skip to content

Commit bcac80b

Browse files
committed
Add Google Search Service to search by alphabetic string
1 parent f19cdea commit bcac80b

22 files changed

+200
-69
lines changed

assets/secrets.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
"api_key": "AIzaSyBq9FRGxSAtGSZ9j4iU1Tyf5YeZ35Z73Kg",
3+
"search_engine_id": "017828047618730186096:qr6tqqq1y57"
4+
}

lib/helpers/left_pad.dart

Lines changed: 0 additions & 7 deletions
This file was deleted.

lib/main.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
22
import 'package:provider/provider.dart';
33

44
import 'package:infobootleg/screens/redirection_screen.dart';
5-
import 'helpers/theme_data.dart';
5+
import 'utils/theme_data.dart';
66
import 'services/auth_service.dart';
77

88
void main() => runApp(Infobootleg());

lib/models/search_state_model.dart

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import 'package:flutter/widgets.dart';
2-
import 'package:infobootleg/helpers/retriever.dart';
2+
3+
import 'package:infobootleg/services/infoleg_retrieval_service.dart';
34
import 'package:infobootleg/models/law_model.dart';
45

56
enum Screen { search, summary, text, favorites, comment }
@@ -78,7 +79,7 @@ class SearchStateModel extends ChangeNotifier {
7879

7980
Future<void> updateLawContents() async {
8081
Map<String, String> retrievedlawContents =
81-
await Retriever.retrieveLawText(url: activeLaw.link);
82+
await InfolegRetrievalService.retrieveLawText(url: activeLaw.link);
8283
_lawContents = retrievedlawContents;
8384

8485
notifyListeners();

lib/models/secret_model.dart

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import 'package:meta/meta.dart';
2+
3+
class Secret {
4+
final String apiKey;
5+
final String searchEngineId;
6+
7+
Secret({
8+
@required this.apiKey,
9+
@required this.searchEngineId,
10+
});
11+
12+
factory Secret.fromJson(Map<String, dynamic> jsonMap) {
13+
return Secret(
14+
apiKey: jsonMap['api_key'],
15+
searchEngineId: jsonMap['search_engine_id'],
16+
);
17+
}
18+
}

lib/screens/comment_screen.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import 'package:material_design_icons_flutter/material_design_icons_flutter.dart
44

55
import 'package:infobootleg/models/search_state_model.dart';
66
import 'package:infobootleg/models/favorite_model.dart';
7-
import 'package:infobootleg/services/database_service.dart';
7+
import 'package:infobootleg/services/firestore_database_service.dart';
88
import 'package:infobootleg/widgets/basic_card.dart';
99
import 'package:infobootleg/widgets/article_card_with_comment_box.dart';
1010
import 'package:infobootleg/widgets/short_title_card.dart';
@@ -18,7 +18,7 @@ class CommentScreen extends StatelessWidget {
1818
);
1919

2020
final SearchStateModel searchState;
21-
final DatabaseService dbService;
21+
final FirestoreDatabaseService dbService;
2222
final Favorite favorite;
2323
final TextEditingController _textEditingController = TextEditingController();
2424

lib/screens/favorites_screen.dart

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import 'package:flutter/material.dart';
22
import 'package:flutter_widgets/flutter_widgets.dart';
33
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
44

5-
import 'package:infobootleg/services/database_service.dart';
5+
import 'package:infobootleg/services/firestore_database_service.dart';
66
import 'package:infobootleg/models/search_state_model.dart';
77
import 'package:infobootleg/widgets/short_title_card.dart';
88
import 'package:infobootleg/models/favorite_model.dart';
@@ -15,7 +15,7 @@ class FavoritesScreen extends StatefulWidget {
1515
FavoritesScreen(this.searchState, this.dbService);
1616

1717
final SearchStateModel searchState;
18-
final DatabaseService dbService;
18+
final FirestoreDatabaseService dbService;
1919

2020
@override
2121
_FavoritesScreenState createState() => _FavoritesScreenState();

lib/screens/law_search_screen.dart

Lines changed: 51 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,19 @@
1+
import 'package:cloud_firestore/cloud_firestore.dart';
12
import 'package:flutter/material.dart';
23
import 'package:provider/provider.dart';
34

5+
import 'package:infobootleg/utils/exceptions.dart';
6+
import 'package:infobootleg/services/google_search_service.dart';
47
import 'package:infobootleg/models/law_model.dart';
58
import 'package:infobootleg/models/search_state_model.dart';
6-
import 'package:infobootleg/helpers/left_pad.dart';
79
import 'package:infobootleg/services/auth_service.dart';
8-
import 'package:infobootleg/services/database_service.dart';
10+
import 'package:infobootleg/services/firestore_database_service.dart';
911
import 'package:infobootleg/widgets/alert_box.dart';
1012

1113
class LawSearchScreen extends StatelessWidget {
1214
LawSearchScreen(this.searchState, this.dbService);
1315
final SearchStateModel searchState;
14-
final DatabaseService dbService;
16+
final FirestoreDatabaseService dbService;
1517
final TextEditingController _textController = TextEditingController();
1618

1719
@override
@@ -34,7 +36,11 @@ class LawSearchScreen extends StatelessWidget {
3436
],
3537
),
3638
backgroundColor: Theme.of(context).canvasColor,
37-
body: Center(child: _buildSearchCard(context)),
39+
body: FractionallySizedBox(
40+
heightFactor: 0.9,
41+
child: Center(
42+
child: _buildSearchCard(context),
43+
)),
3844
);
3945
}
4046

@@ -90,7 +96,8 @@ class LawSearchScreen extends StatelessWidget {
9096
child: Column(
9197
mainAxisSize: MainAxisSize.min,
9298
children: [
93-
// TODO: Search by title using Bing
99+
Text("Infobootleg", style: Theme.of(context).textTheme.title),
100+
SizedBox(height: 20),
94101
Text("Buscar ley por número o título",
95102
style: Theme.of(context).textTheme.subtitle),
96103
SizedBox(height: 20),
@@ -107,7 +114,7 @@ class LawSearchScreen extends StatelessWidget {
107114
alignment: Alignment.center,
108115
child: TextField(
109116
controller: _textController,
110-
onSubmitted: (userInput) => _onSubmitted(context, userInput),
117+
onSubmitted: (userInput) => _onSubmitted(userInput, context),
111118
style: TextStyle(fontSize: 25.0),
112119
keyboardType: TextInputType.number,
113120
decoration: InputDecoration(
@@ -122,10 +129,45 @@ class LawSearchScreen extends StatelessWidget {
122129
);
123130
}
124131

125-
_onSubmitted(BuildContext context, String userInput) async {
126-
final dbService = Provider.of<DatabaseService>(context);
132+
_onSubmitted(String userInput, BuildContext context) async {
133+
bool isAlphabeticInput = RegExp(r'[a-zA-Z]+').hasMatch(userInput);
134+
bool isNumericInput = RegExp(r'[0-9]+').hasMatch(userInput);
135+
136+
if (isAlphabeticInput) {
137+
_processAlphabeticInput(userInput, context);
138+
} else if (isNumericInput) {
139+
_processNumericInput(userInput, context);
140+
}
141+
}
142+
143+
_processAlphabeticInput(String userInput, BuildContext context) async {
144+
try {
145+
String lawId = await GoogleSearchService.fetchLawId(userInput);
146+
DocumentSnapshot snapshot =
147+
await dbService.retrieveLawDocumentById(lawId);
148+
searchState.updateActiveLaw(Law(snapshot.data));
149+
searchState.transitionVerticallyTo(Screen.summary);
150+
} on NoResultsFromGoogleSearchAPIException {
151+
AlertBox(
152+
title: "Sin datos",
153+
content: "No hay una ley referida a «$userInput» en la base de datos.",
154+
confirmActionText: "Buscar otra ley",
155+
).show(context);
156+
}
157+
}
158+
159+
_processNumericInput(String userInput, BuildContext context) async {
160+
String _leftPad(userInput) {
161+
while (userInput.length < 5) {
162+
userInput = "0" + userInput;
163+
}
164+
return userInput;
165+
}
166+
167+
String lawNumber = _leftPad(userInput);
168+
127169
try {
128-
final snapshot = await dbService.readLaw(id: leftPad(userInput));
170+
final snapshot = await dbService.retrieveLawDocumentByNumber(lawNumber);
129171
searchState.updateActiveLaw(Law(snapshot.data));
130172
searchState.transitionVerticallyTo(Screen.summary);
131173
} catch (e) {

lib/screens/law_summary_screen.dart

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,21 +2,18 @@ import 'package:flutter/material.dart';
22
import 'package:url_launcher/url_launcher.dart';
33
import 'package:material_design_icons_flutter/material_design_icons_flutter.dart';
44

5-
import 'package:infobootleg/helpers/retriever.dart';
5+
import 'package:infobootleg/services/infoleg_retrieval_service.dart';
66
import 'package:infobootleg/widgets/basic_card.dart';
77
import 'package:infobootleg/widgets/law_title_card.dart';
88
import 'package:infobootleg/widgets/modif_relations_box.dart';
99
import 'package:infobootleg/models/search_state_model.dart';
10-
import 'package:infobootleg/helpers/hex_color.dart';
10+
import 'package:infobootleg/utils/hex_color.dart';
1111
import 'package:infobootleg/models/law_model.dart';
1212
import 'package:infobootleg/widgets/alert_box.dart';
13+
import 'package:infobootleg/utils/exceptions.dart';
1314

1415
enum ModificationType { modifies, isModifiedBy }
1516

16-
class NoPatternMatchException implements Exception {
17-
NoPatternMatchException();
18-
}
19-
2017
class LawSummaryScreen extends StatelessWidget {
2118
LawSummaryScreen(this.searchState);
2219

@@ -111,7 +108,7 @@ class LawSummaryScreen extends StatelessWidget {
111108
if (await canLaunch(url)) {
112109
await launch(url);
113110
} else {
114-
throw 'Could not launch $url';
111+
throw Exception('Could not launch $url');
115112
}
116113
}
117114

@@ -120,7 +117,7 @@ class LawSummaryScreen extends StatelessWidget {
120117
try {
121118
await searchState.updateLawContents();
122119
searchState.transitionVerticallyTo(Screen.text);
123-
} on NoPatternMatchException {
120+
} on NoLawTextPatternMatchException {
124121
final bool answer = await AlertBox(
125122
title: "Formato desconocido",
126123
content:
@@ -313,7 +310,7 @@ class LawSummaryScreen extends StatelessWidget {
313310
void _onModificationRelationsButtonPressed(
314311
BuildContext context, ModificationType modificationType) async {
315312
Map<int, Map<String, String>> allRows =
316-
await Retriever.retrieveModificationRelations(
313+
await InfolegRetrievalService.retrieveModificationRelations(
317314
fullTextUrl: searchState.activeLaw.link,
318315
modificationType: modificationType,
319316
);

lib/screens/law_text_screen.dart

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import 'package:material_design_icons_flutter/material_design_icons_flutter.dart
44

55
import 'package:infobootleg/models/favorite_model.dart';
66
import 'package:infobootleg/models/search_state_model.dart';
7-
import 'package:infobootleg/services/database_service.dart';
7+
import 'package:infobootleg/services/firestore_database_service.dart';
88
import 'package:infobootleg/widgets/article_card_with_corner_icons.dart';
99
import 'package:infobootleg/widgets/law_title_card.dart';
1010
import 'package:infobootleg/widgets/table_of_contents.dart';
@@ -13,7 +13,7 @@ class LawTextScreen extends StatelessWidget {
1313
LawTextScreen(this.searchState, this.dbService);
1414

1515
final SearchStateModel searchState;
16-
final DatabaseService dbService;
16+
final FirestoreDatabaseService dbService;
1717
final ItemScrollController _scrollController = ItemScrollController();
1818

1919
@override
@@ -80,22 +80,16 @@ class LawTextScreen extends StatelessWidget {
8080

8181
String articleNumber = searchState.lawContents.keys.toList()[articleIndex];
8282

83-
return Padding(
84-
padding: EdgeInsets.symmetric(
85-
vertical: 7.5,
86-
horizontal: 10.0,
87-
),
88-
child: ArticleCardWithCornerIcons(
89-
position: articleIndex,
90-
lawNumber: searchState.activeLaw.number,
91-
articleNumber: articleNumber,
92-
articleText: searchState.lawContents[articleNumber],
93-
isStarred: _getStarredStatus(articleNumber, userFavorites),
94-
onArticleSelected: scrollToListItem,
95-
onSave: (favorite) => dbService.saveFavorite(favorite),
96-
onDelete: (favorite) => dbService.deleteFavorite(favorite),
97-
onSaveOrDeleteCompleted: _showSnackBar,
98-
),
83+
return ArticleCardWithCornerIcons(
84+
position: articleIndex,
85+
lawNumber: searchState.activeLaw.number,
86+
articleNumber: articleNumber,
87+
articleText: searchState.lawContents[articleNumber],
88+
isStarred: _getStarredStatus(articleNumber, userFavorites),
89+
onArticleSelected: scrollToListItem,
90+
onSave: (favorite) => dbService.saveFavorite(favorite),
91+
onDelete: (favorite) => dbService.deleteFavorite(favorite),
92+
onSaveOrDeleteCompleted: _showSnackBar,
9993
);
10094
}
10195

0 commit comments

Comments
 (0)