From 3feb6f60265c7da7e4f74300329cfa43cabac547 Mon Sep 17 00:00:00 2001 From: Nolence Date: Fri, 29 Apr 2022 11:59:37 -0600 Subject: [PATCH 01/12] moved everything to json serializable --- build.yaml | 20 ++ example/pubspec.lock | 16 +- lib/google_place.dart | 50 ++- lib/src/autocomplete/autocomplete.dart | 102 ++---- .../autocomplete_prediction.dart | 39 +-- .../autocomplete_prediction.g.dart | 43 +++ .../autocomplete/autocomplete_response.dart | 28 -- .../autocomplete_response.dart | 19 ++ .../autocomplete_response.g.dart | 24 ++ lib/src/details/details.dart | 61 ++-- lib/src/details/details_response.dart | 33 -- .../details_response/details_response.dart | 25 ++ .../details_response/details_response.g.dart | 25 ++ .../{ => details_result}/details_result.dart | 69 +--- .../details_result/details_result.g.dart | 81 +++++ .../address_component.dart | 20 +- .../address_component.g.dart | 22 ++ lib/src/models/bounds.dart | 20 -- lib/src/models/bounds/bounds.dart | 17 + lib/src/models/bounds/bounds.g.dart | 21 ++ lib/src/models/close.dart | 17 - lib/src/models/component.dart | 3 +- lib/src/models/debug_log.dart | 13 - lib/src/models/debug_log/debug_log.dart | 15 + lib/src/models/debug_log/debug_log.g.dart | 15 + lib/src/models/geometry.dart | 26 -- lib/src/models/geometry/geometry.dart | 24 ++ lib/src/models/geometry/geometry.g.dart | 25 ++ lib/src/models/input_type.dart | 5 +- lib/src/models/lat_lon.dart | 8 - lib/src/models/location.dart | 13 - lib/src/models/location/location.dart | 25 ++ lib/src/models/location/location.g.dart | 17 + .../models/main_text_matched_substring.dart | 13 - lib/src/models/matched_substring.dart | 13 - .../matched_substring/matched_substring.dart | 17 + .../matched_substring.g.dart | 19 ++ lib/src/models/northeast.dart | 13 - .../{ => opening_hours}/opening_hours.dart | 25 +- .../models/opening_hours/opening_hours.g.dart | 24 ++ lib/src/models/{ => period}/period.dart | 22 +- lib/src/models/period/period.g.dart | 19 ++ lib/src/models/{ => photo}/photo.dart | 27 +- lib/src/models/photo/photo.g.dart | 23 ++ lib/src/models/plus_code.dart | 16 - lib/src/models/plus_code/plus_code.dart | 19 ++ lib/src/models/plus_code/plus_code.g.dart | 17 + lib/src/models/rank-by.dart | 4 - lib/src/models/rank_by.dart | 1 + lib/src/models/{ => review}/review.dart | 22 +- lib/src/models/review/review.g.dart | 29 ++ lib/src/models/southwest.dart | 13 - lib/src/models/structured_formatting.dart | 28 -- .../structured_formatting.dart | 29 ++ .../structured_formatting.g.dart | 26 ++ lib/src/models/term.dart | 16 - lib/src/models/term/term.dart | 18 + lib/src/models/term/term.g.dart | 17 + .../time_and_day.dart} | 19 +- .../models/time_and_day/time_and_day.g.dart | 18 + lib/src/models/viewport.dart | 20 -- .../query_autocomplete.dart | 74 ++--- lib/src/search/find_place_response.dart | 44 --- .../find_place_response.dart | 32 ++ .../find_place_response.g.dart | 31 ++ lib/src/search/near_by_search_response.dart | 44 --- .../nearby_search_response.dart | 32 ++ .../nearby_search_response.g.dart | 33 ++ lib/src/search/search.dart | 46 ++- lib/src/search/search_candidate.dart | 136 -------- .../{ => search_result}/search_result.dart | 51 +-- .../search/search_result/search_result.g.dart | 59 ++++ lib/src/search/text_search_response.dart | 40 +-- lib/src/search/text_search_response.g.dart | 31 ++ lib/src/utils/network_utility.dart | 11 +- pubspec.lock | 310 +++++++++++++++++- pubspec.yaml | 7 +- 77 files changed, 1508 insertions(+), 941 deletions(-) create mode 100644 build.yaml rename lib/src/autocomplete/{ => autocomplete_prediction}/autocomplete_prediction.dart (63%) create mode 100644 lib/src/autocomplete/autocomplete_prediction/autocomplete_prediction.g.dart delete mode 100644 lib/src/autocomplete/autocomplete_response.dart create mode 100644 lib/src/autocomplete/autocomplete_response/autocomplete_response.dart create mode 100644 lib/src/autocomplete/autocomplete_response/autocomplete_response.g.dart delete mode 100644 lib/src/details/details_response.dart create mode 100644 lib/src/details/details_response/details_response.dart create mode 100644 lib/src/details/details_response/details_response.g.dart rename lib/src/details/{ => details_result}/details_result.dart (72%) create mode 100644 lib/src/details/details_result/details_result.g.dart rename lib/src/models/{ => address_component}/address_component.dart (66%) create mode 100644 lib/src/models/address_component/address_component.g.dart delete mode 100644 lib/src/models/bounds.dart create mode 100644 lib/src/models/bounds/bounds.dart create mode 100644 lib/src/models/bounds/bounds.g.dart delete mode 100644 lib/src/models/close.dart delete mode 100644 lib/src/models/debug_log.dart create mode 100644 lib/src/models/debug_log/debug_log.dart create mode 100644 lib/src/models/debug_log/debug_log.g.dart delete mode 100644 lib/src/models/geometry.dart create mode 100644 lib/src/models/geometry/geometry.dart create mode 100644 lib/src/models/geometry/geometry.g.dart delete mode 100644 lib/src/models/location.dart create mode 100644 lib/src/models/location/location.dart create mode 100644 lib/src/models/location/location.g.dart delete mode 100644 lib/src/models/main_text_matched_substring.dart delete mode 100644 lib/src/models/matched_substring.dart create mode 100644 lib/src/models/matched_substring/matched_substring.dart create mode 100644 lib/src/models/matched_substring/matched_substring.g.dart delete mode 100644 lib/src/models/northeast.dart rename lib/src/models/{ => opening_hours}/opening_hours.dart (62%) create mode 100644 lib/src/models/opening_hours/opening_hours.g.dart rename lib/src/models/{ => period}/period.dart (51%) create mode 100644 lib/src/models/period/period.g.dart rename lib/src/models/{ => photo}/photo.dart (51%) create mode 100644 lib/src/models/photo/photo.g.dart delete mode 100644 lib/src/models/plus_code.dart create mode 100644 lib/src/models/plus_code/plus_code.dart create mode 100644 lib/src/models/plus_code/plus_code.g.dart delete mode 100644 lib/src/models/rank-by.dart create mode 100644 lib/src/models/rank_by.dart rename lib/src/models/{ => review}/review.dart (80%) create mode 100644 lib/src/models/review/review.g.dart delete mode 100644 lib/src/models/southwest.dart delete mode 100644 lib/src/models/structured_formatting.dart create mode 100644 lib/src/models/structured_formatting/structured_formatting.dart create mode 100644 lib/src/models/structured_formatting/structured_formatting.g.dart delete mode 100644 lib/src/models/term.dart create mode 100644 lib/src/models/term/term.dart create mode 100644 lib/src/models/term/term.g.dart rename lib/src/models/{open.dart => time_and_day/time_and_day.dart} (50%) create mode 100644 lib/src/models/time_and_day/time_and_day.g.dart delete mode 100644 lib/src/models/viewport.dart delete mode 100644 lib/src/search/find_place_response.dart create mode 100644 lib/src/search/find_place_response/find_place_response.dart create mode 100644 lib/src/search/find_place_response/find_place_response.g.dart delete mode 100644 lib/src/search/near_by_search_response.dart create mode 100644 lib/src/search/nearby_search_response/nearby_search_response.dart create mode 100644 lib/src/search/nearby_search_response/nearby_search_response.g.dart delete mode 100644 lib/src/search/search_candidate.dart rename lib/src/search/{ => search_result}/search_result.dart (72%) create mode 100644 lib/src/search/search_result/search_result.g.dart create mode 100644 lib/src/search/text_search_response.g.dart diff --git a/build.yaml b/build.yaml new file mode 100644 index 0000000..0c0dd01 --- /dev/null +++ b/build.yaml @@ -0,0 +1,20 @@ +targets: + $default: + builders: + json_serializable: + options: + # Options configure how source code is generated for every + # `@JsonSerializable`-annotated class in the package. + # + # The default value for each is listed. + any_map: false + checked: false + constructor: "" + create_factory: true + create_to_json: true + disallow_unrecognized_keys: false + explicit_to_json: false + field_rename: snake + generic_argument_factories: false + ignore_unannotated: false + include_if_null: true diff --git a/example/pubspec.lock b/example/pubspec.lock index 2215551..f22c74f 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -95,6 +95,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.0.0" + json_annotation: + dependency: transitive + description: + name: json_annotation + url: "https://pub.dartlang.org" + source: hosted + version: "4.5.0" matcher: dependency: transitive description: @@ -102,6 +109,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.12.11" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" meta: dependency: transitive description: @@ -169,7 +183,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.3" + version: "0.4.8" typed_data: dependency: transitive description: diff --git a/lib/google_place.dart b/lib/google_place.dart index d26814d..85f60ca 100644 --- a/lib/google_place.dart +++ b/lib/google_place.dart @@ -6,38 +6,32 @@ import 'package:google_place/src/photos/photos.dart'; import 'package:google_place/src/query_autocomplete/query_autocomplete.dart'; import 'package:google_place/src/search/search.dart'; -export 'package:google_place/src/autocomplete/autocomplete_prediction.dart'; -export 'package:google_place/src/autocomplete/autocomplete_response.dart'; -export 'package:google_place/src/details/details_response.dart'; -export 'package:google_place/src/details/details_result.dart'; -export 'package:google_place/src/models/address_component.dart'; -export 'package:google_place/src/models/bounds.dart'; -export 'package:google_place/src/models/close.dart'; +export 'package:google_place/src/autocomplete/autocomplete_prediction/autocomplete_prediction.dart'; +export 'package:google_place/src/autocomplete/autocomplete_response/autocomplete_response.dart'; +export 'package:google_place/src/details/details_response/details_response.dart'; +export 'package:google_place/src/details/details_result/details_result.dart'; +export 'package:google_place/src/models/address_component/address_component.dart'; +export 'package:google_place/src/models/bounds/bounds.dart'; export 'package:google_place/src/models/component.dart'; -export 'package:google_place/src/models/debug_log.dart'; -export 'package:google_place/src/models/geometry.dart'; +export 'package:google_place/src/models/debug_log/debug_log.dart'; +export 'package:google_place/src/models/geometry/geometry.dart'; export 'package:google_place/src/models/input_type.dart'; export 'package:google_place/src/models/lat_lon.dart'; -export 'package:google_place/src/models/location.dart'; +export 'package:google_place/src/models/location/location.dart'; export 'package:google_place/src/models/locationbias.dart'; -export 'package:google_place/src/models/main_text_matched_substring.dart'; -export 'package:google_place/src/models/matched_substring.dart'; -export 'package:google_place/src/models/northeast.dart'; -export 'package:google_place/src/models/open.dart'; -export 'package:google_place/src/models/opening_hours.dart'; -export 'package:google_place/src/models/period.dart'; -export 'package:google_place/src/models/photo.dart'; -export 'package:google_place/src/models/plus_code.dart'; -export 'package:google_place/src/models/rank-by.dart'; -export 'package:google_place/src/models/review.dart'; -export 'package:google_place/src/models/southwest.dart'; -export 'package:google_place/src/models/structured_formatting.dart'; -export 'package:google_place/src/models/term.dart'; -export 'package:google_place/src/models/viewport.dart'; -export 'package:google_place/src/search/find_place_response.dart'; -export 'package:google_place/src/search/near_by_search_response.dart'; -export 'package:google_place/src/search/search_candidate.dart'; -export 'package:google_place/src/search/search_result.dart'; +export 'package:google_place/src/models/matched_substring/matched_substring.dart'; +export 'package:google_place/src/models/opening_hours/opening_hours.dart'; +export 'package:google_place/src/models/period/period.dart'; +export 'package:google_place/src/models/photo/photo.dart'; +export 'package:google_place/src/models/plus_code/plus_code.dart'; +export 'package:google_place/src/models/rank_by.dart'; +export 'package:google_place/src/models/review/review.dart'; +export 'package:google_place/src/models/structured_formatting/structured_formatting.dart'; +export 'package:google_place/src/models/term/term.dart'; +export 'package:google_place/src/models/time_and_day/time_and_day.dart'; +export 'package:google_place/src/search/find_place_response/find_place_response.dart'; +export 'package:google_place/src/search/nearby_search_response/nearby_search_response.dart'; +export 'package:google_place/src/search/search_result/search_result.dart'; export 'package:google_place/src/search/text_search_response.dart'; /// The Places API is a service that returns information about places. diff --git a/lib/src/autocomplete/autocomplete.dart b/lib/src/autocomplete/autocomplete.dart index f4d63ae..f4701d3 100644 --- a/lib/src/autocomplete/autocomplete.dart +++ b/lib/src/autocomplete/autocomplete.dart @@ -1,14 +1,25 @@ +import 'dart:convert'; + import 'package:google_place/google_place.dart'; +import 'package:google_place/src/autocomplete/autocomplete_response/autocomplete_response.dart'; import 'package:google_place/src/utils/network_utility.dart'; class Autocomplete { static final _authority = 'maps.googleapis.com'; + static final _unencodedPath = 'maps/api/place/autocomplete/json'; + final String apiKEY; + final Map headers; + final String? proxyUrl; - Autocomplete(this.apiKEY, this.headers, this.proxyUrl); + const Autocomplete( + this.apiKEY, + this.headers, + this.proxyUrl, + ); /// The Place Autocomplete service is a web service that returns place predictions in response /// to an HTTP request. The request specifies a textual search string and optional geographic @@ -105,10 +116,13 @@ class Autocomplete { _unencodedPath, queryParameters, ); - var response = await NetworkUtility.fetchUrl(uri, headers: headers); + + final response = await NetworkUtility.fetchUrl(uri, headers: headers); + if (response != null) { - return AutocompleteResponse.parseAutocompleteResult(response); + return AutocompleteResponse.fromJson(jsonDecode(response)); } + return null; } @@ -225,13 +239,24 @@ class Autocomplete { List? components, bool strictbounds, ) { - String result = input.trimRight(); - result = result.trimLeft(); - Map queryParameters = { - 'input': result, + final cleanedInput = input.trimRight().trimLeft(); + final queryParameters = { + 'input': cleanedInput, 'key': apiKEY, + if (origin != null) 'origin': '${origin.latitude},${origin.longitude}', + if (location != null) + 'location': '${location.latitude},${location.longitude}', + if (offset != null) 'offset': offset.toString(), + if (radius != null) 'radius': radius.toString(), + if (sessionToken != null && sessionToken != '') + 'sessiontoken': sessionToken, + if (region != null && region != '') 'region': region, + if (language != null && language != '') 'language': language, + if (types != null && types != '') 'types': types, + if (strictbounds) 'strictbounds': 'true', }; + // TODO: What is this doing? if (components != null && components.length > 0) { String result = ''; for (int i = 0; i < components.length; i++) { @@ -246,69 +271,6 @@ class Autocomplete { queryParameters.addAll(item); } - if (origin != null) { - var item = { - 'origin': '${origin.latitude},${origin.longitude}', - }; - queryParameters.addAll(item); - } - - if (location != null) { - var item = { - 'location': '${location.latitude},${location.longitude}', - }; - queryParameters.addAll(item); - } - - if (offset != null) { - var item = { - 'offset': offset.toString(), - }; - queryParameters.addAll(item); - } - - if (radius != null) { - var item = { - 'radius': radius.toString(), - }; - queryParameters.addAll(item); - } - - if (sessionToken != null && sessionToken != '') { - var item = { - 'sessionToken': sessionToken, - }; - queryParameters.addAll(item); - } - - if (region != null && region != '') { - var item = { - 'region': region, - }; - queryParameters.addAll(item); - } - - if (language != null && language != '') { - var item = { - 'language': language, - }; - queryParameters.addAll(item); - } - - if (types != null && types != '') { - var item = { - 'types': types, - }; - queryParameters.addAll(item); - } - - if (strictbounds) { - var item = { - 'strictbounds': strictbounds.toString(), - }; - queryParameters.addAll(item); - } - return queryParameters; } } diff --git a/lib/src/autocomplete/autocomplete_prediction.dart b/lib/src/autocomplete/autocomplete_prediction/autocomplete_prediction.dart similarity index 63% rename from lib/src/autocomplete/autocomplete_prediction.dart rename to lib/src/autocomplete/autocomplete_prediction/autocomplete_prediction.dart index d4828f9..d2f97e4 100644 --- a/lib/src/autocomplete/autocomplete_prediction.dart +++ b/lib/src/autocomplete/autocomplete_prediction/autocomplete_prediction.dart @@ -1,7 +1,11 @@ -import 'package:google_place/src/models/matched_substring.dart'; -import 'package:google_place/src/models/structured_formatting.dart'; -import 'package:google_place/src/models/term.dart'; +import 'package:google_place/src/models/matched_substring/matched_substring.dart'; +import 'package:google_place/src/models/structured_formatting/structured_formatting.dart'; +import 'package:google_place/src/models/term/term.dart'; +import 'package:json_annotation/json_annotation.dart'; +part 'autocomplete_prediction.g.dart'; + +@JsonSerializable() class AutocompletePrediction { /// [description] contains the human-readable name for the returned result. For establishment results, this is usually /// the business name. @@ -29,7 +33,7 @@ class AutocompletePrediction { /// [structuredFormatting] provides pre-formatted text that can be shown in your autocomplete results final StructuredFormatting? structuredFormatting; - /// contains an array of terms identifying each section of the returned description + /// Contains an array of terms identifying each section of the returned description /// (a section of the description is generally terminated with a comma). final List? terms; @@ -49,27 +53,8 @@ class AutocompletePrediction { this.types, }); - factory AutocompletePrediction.fromJson(Map json) { - return AutocompletePrediction( - description: json['description'] as String?, - distanceMeters: json['distance_meters'] as int?, - id: json['id'] as String?, - matchedSubstrings: json['matched_substrings'] != null - ? json['matched_substrings'] - .map((json) => MatchedSubstring.fromJson(json)) - .toList() - : null, - placeId: json['place_id'] as String?, - reference: json['reference'] as String?, - structuredFormatting: json['structured_formatting'] != null - ? StructuredFormatting.fromJson(json['structured_formatting']) - : null, - terms: json['terms'] != null - ? json['terms'].map((json) => Term.fromJson(json)).toList() - : null, - types: json['types'] != null - ? (json['types'] as List).cast() - : null, - ); - } + factory AutocompletePrediction.fromJson(Map json) => + _$AutocompletePredictionFromJson(json); + + Map toJson() => _$AutocompletePredictionToJson(this); } diff --git a/lib/src/autocomplete/autocomplete_prediction/autocomplete_prediction.g.dart b/lib/src/autocomplete/autocomplete_prediction/autocomplete_prediction.g.dart new file mode 100644 index 0000000..9e3e70f --- /dev/null +++ b/lib/src/autocomplete/autocomplete_prediction/autocomplete_prediction.g.dart @@ -0,0 +1,43 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'autocomplete_prediction.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +AutocompletePrediction _$AutocompletePredictionFromJson( + Map json) => + AutocompletePrediction( + description: json['description'] as String?, + distanceMeters: json['distance_meters'] as int?, + id: json['id'] as String?, + matchedSubstrings: (json['matched_substrings'] as List?) + ?.map((e) => MatchedSubstring.fromJson(e as Map)) + .toList(), + placeId: json['place_id'] as String?, + reference: json['reference'] as String?, + structuredFormatting: json['structured_formatting'] == null + ? null + : StructuredFormatting.fromJson( + json['structured_formatting'] as Map), + terms: (json['terms'] as List?) + ?.map((e) => Term.fromJson(e as Map)) + .toList(), + types: + (json['types'] as List?)?.map((e) => e as String).toList(), + ); + +Map _$AutocompletePredictionToJson( + AutocompletePrediction instance) => + { + 'description': instance.description, + 'distance_meters': instance.distanceMeters, + 'id': instance.id, + 'matched_substrings': instance.matchedSubstrings, + 'place_id': instance.placeId, + 'reference': instance.reference, + 'structured_formatting': instance.structuredFormatting, + 'terms': instance.terms, + 'types': instance.types, + }; diff --git a/lib/src/autocomplete/autocomplete_response.dart b/lib/src/autocomplete/autocomplete_response.dart deleted file mode 100644 index 7490aba..0000000 --- a/lib/src/autocomplete/autocomplete_response.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'dart:convert'; - -import 'package:google_place/src/autocomplete/autocomplete_prediction.dart'; - -/// The Autocomplete response contains place predictions and status -class AutocompleteResponse { - final String? status; - final List? predictions; - - AutocompleteResponse({this.status, this.predictions}); - - factory AutocompleteResponse.fromJson(Map json) { - return AutocompleteResponse( - status: json['status'] as String?, - predictions: json['predictions'] != null - ? json['predictions'] - .map( - (json) => AutocompletePrediction.fromJson(json)) - .toList() - : null, - ); - } - - static AutocompleteResponse parseAutocompleteResult(String responseBody) { - final parsed = json.decode(responseBody).cast(); - return AutocompleteResponse.fromJson(parsed); - } -} diff --git a/lib/src/autocomplete/autocomplete_response/autocomplete_response.dart b/lib/src/autocomplete/autocomplete_response/autocomplete_response.dart new file mode 100644 index 0000000..41c8c8f --- /dev/null +++ b/lib/src/autocomplete/autocomplete_response/autocomplete_response.dart @@ -0,0 +1,19 @@ +import 'package:google_place/src/autocomplete/autocomplete_prediction/autocomplete_prediction.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'autocomplete_response.g.dart'; + +/// The Autocomplete response contains place predictions and status +@JsonSerializable() +class AutocompleteResponse { + final String? status; + + final List? predictions; + + const AutocompleteResponse({this.status, this.predictions}); + + factory AutocompleteResponse.fromJson(Map json) => + _$AutocompleteResponseFromJson(json); + + Map toJson() => _$AutocompleteResponseToJson(this); +} diff --git a/lib/src/autocomplete/autocomplete_response/autocomplete_response.g.dart b/lib/src/autocomplete/autocomplete_response/autocomplete_response.g.dart new file mode 100644 index 0000000..06f7b0c --- /dev/null +++ b/lib/src/autocomplete/autocomplete_response/autocomplete_response.g.dart @@ -0,0 +1,24 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'autocomplete_response.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +AutocompleteResponse _$AutocompleteResponseFromJson( + Map json) => + AutocompleteResponse( + status: json['status'] as String?, + predictions: (json['predictions'] as List?) + ?.map( + (e) => AutocompletePrediction.fromJson(e as Map)) + .toList(), + ); + +Map _$AutocompleteResponseToJson( + AutocompleteResponse instance) => + { + 'status': instance.status, + 'predictions': instance.predictions, + }; diff --git a/lib/src/details/details.dart b/lib/src/details/details.dart index 23d395f..f2c4d39 100644 --- a/lib/src/details/details.dart +++ b/lib/src/details/details.dart @@ -1,15 +1,20 @@ -import 'package:google_place/google_place.dart'; -import 'package:google_place/src/details/details_response.dart'; +import 'dart:convert'; + +import 'package:google_place/src/details/details_response/details_response.dart'; import 'package:google_place/src/utils/network_utility.dart'; class Details { static final _authority = 'maps.googleapis.com'; + static final _unencodedPath = 'maps/api/place/details/json'; + final String apiKEY; + final Map headers; + final String? proxyUrl; - Details(this.apiKEY, this.headers, this.proxyUrl); + const Details(this.apiKEY, this.headers, this.proxyUrl); /// Once you have a place_id from a Place Search, you can request more details about a /// particular establishment or point of interest by initiating a Place Details request. @@ -44,7 +49,7 @@ class Details { String? fields, }) async { assert(placeId != ""); - var queryParameters = _createParameters( + final queryParameters = _createParameters( apiKEY, placeId, language, @@ -52,16 +57,18 @@ class Details { sessionToken, fields, ); - var uri = NetworkUtility.createUri( + final uri = NetworkUtility.createUri( proxyUrl, _authority, _unencodedPath, queryParameters, ); - var response = await NetworkUtility.fetchUrl(uri, headers: headers); + final response = await NetworkUtility.fetchUrl(uri, headers: headers); + if (response != null) { - return DetailsResponse.parseDetailsResult(response); + return DetailsResponse.fromJson(jsonDecode(response)); } + return null; } @@ -98,7 +105,7 @@ class Details { String? fields, }) async { assert(placeId != ""); - var queryParameters = _createParameters( + final queryParameters = _createParameters( apiKEY, placeId, language, @@ -106,14 +113,14 @@ class Details { sessionToken, fields, ); - - var uri = Uri.https( + final uri = Uri.https( proxyUrl != null && proxyUrl != '' ? proxyUrl! : _authority, proxyUrl != null && proxyUrl != '' ? 'https://$_authority/$_unencodedPath' : _unencodedPath, queryParameters, ); + return await NetworkUtility.fetchUrl(uri, headers: headers); } @@ -126,38 +133,16 @@ class Details { String? sessionToken, String? fields, ) { - Map queryParameters = { + final queryParameters = { 'key': apiKEY, 'place_id': placeId, - }; - - if (language != null && language != '') { - var item = { - 'language': language, - }; - queryParameters.addAll(item); - } - - if (region != null && region != '') { - var item = { - 'region': region, - }; - queryParameters.addAll(item); - } - - if (sessionToken != null && sessionToken != '') { - var item = { + if (language != null && language != '') 'language': language, + if (region != null && region != '') 'region': region, + if (sessionToken != null && sessionToken != '') 'sessiontoken': sessionToken, - }; - queryParameters.addAll(item); - } + if (fields != null && fields != '') 'fields': fields, + }; - if (fields != null && fields != '') { - var item = { - 'fields': fields, - }; - queryParameters.addAll(item); - } return queryParameters; } } diff --git a/lib/src/details/details_response.dart b/lib/src/details/details_response.dart deleted file mode 100644 index 0781cc7..0000000 --- a/lib/src/details/details_response.dart +++ /dev/null @@ -1,33 +0,0 @@ -import 'dart:convert'; - -import 'package:google_place/src/details/details_result.dart'; - -/// The Details response contains html Attributions and details and status -class DetailsResponse { - final String? status; - final List? htmlAttributions; - final DetailsResult? result; - - DetailsResponse({ - this.status, - this.htmlAttributions, - this.result, - }); - - factory DetailsResponse.fromJson(Map json) { - return DetailsResponse( - status: json['status'], - htmlAttributions: json['html_attributions'] != null - ? (json['html_attributions'] as List).cast() - : null, - result: json['result'] != null - ? DetailsResult.fromJson(json['result']) - : null, - ); - } - - static DetailsResponse parseDetailsResult(String responseBody) { - final parsed = json.decode(responseBody).cast(); - return DetailsResponse.fromJson(parsed); - } -} diff --git a/lib/src/details/details_response/details_response.dart b/lib/src/details/details_response/details_response.dart new file mode 100644 index 0000000..9d50769 --- /dev/null +++ b/lib/src/details/details_response/details_response.dart @@ -0,0 +1,25 @@ +import 'package:google_place/src/details/details_result/details_result.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'details_response.g.dart'; + +/// The Details response contains html Attributions and details and status +@JsonSerializable() +class DetailsResponse { + final String? status; + + final List? htmlAttributions; + + final DetailsResult? result; + + const DetailsResponse({ + this.status, + this.htmlAttributions, + this.result, + }); + + factory DetailsResponse.fromJson(Map json) => + _$DetailsResponseFromJson(json); + + Map toJson() => _$DetailsResponseToJson(this); +} diff --git a/lib/src/details/details_response/details_response.g.dart b/lib/src/details/details_response/details_response.g.dart new file mode 100644 index 0000000..7c9b98d --- /dev/null +++ b/lib/src/details/details_response/details_response.g.dart @@ -0,0 +1,25 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'details_response.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +DetailsResponse _$DetailsResponseFromJson(Map json) => + DetailsResponse( + status: json['status'] as String?, + htmlAttributions: (json['html_attributions'] as List?) + ?.map((e) => e as String) + .toList(), + result: json['result'] == null + ? null + : DetailsResult.fromJson(json['result'] as Map), + ); + +Map _$DetailsResponseToJson(DetailsResponse instance) => + { + 'status': instance.status, + 'html_attributions': instance.htmlAttributions, + 'result': instance.result, + }; diff --git a/lib/src/details/details_result.dart b/lib/src/details/details_result/details_result.dart similarity index 72% rename from lib/src/details/details_result.dart rename to lib/src/details/details_result/details_result.dart index 5f157c8..0fe4c88 100644 --- a/lib/src/details/details_result.dart +++ b/lib/src/details/details_result/details_result.dart @@ -1,10 +1,14 @@ -import 'package:google_place/src/models/address_component.dart'; -import 'package:google_place/src/models/geometry.dart'; -import 'package:google_place/src/models/opening_hours.dart'; -import 'package:google_place/src/models/photo.dart'; -import 'package:google_place/src/models/plus_code.dart'; -import 'package:google_place/src/models/review.dart'; +import 'package:google_place/src/models/address_component/address_component.dart'; +import 'package:google_place/src/models/geometry/geometry.dart'; +import 'package:google_place/src/models/opening_hours/opening_hours.dart'; +import 'package:google_place/src/models/photo/photo.dart'; +import 'package:google_place/src/models/plus_code/plus_code.dart'; +import 'package:google_place/src/models/review/review.dart'; +import 'package:json_annotation/json_annotation.dart'; +part 'details_result.g.dart'; + +@JsonSerializable() class DetailsResult { /// [addressComponents] is an array containing the separate components applicable to this address. final List? addressComponents; @@ -113,7 +117,7 @@ class DetailsResult { 'permanently_closed is now deprecated. Instead, use business_status to get the operational status of businesses.') final bool? permanentlyClosed; - DetailsResult({ + const DetailsResult({ this.addressComponents, this.businessStatus, this.adrAddress, @@ -142,51 +146,8 @@ class DetailsResult { this.permanentlyClosed, }); - factory DetailsResult.fromJson(Map json) { - return DetailsResult( - addressComponents: json['address_components'] != null - ? json['address_components'] - .map((json) => AddressComponent.fromJson(json)) - .toList() - : null, - businessStatus: json['business_status'], - adrAddress: json['adr_address'], - formattedAddress: json['formatted_address'], - formattedPhoneNumber: json['formatted_phone_number'], - geometry: - json['geometry'] != null ? Geometry.fromJson(json['geometry']) : null, - icon: json['icon'], - id: json['id'], - internationalPhoneNumber: json['international_phone_number'], - name: json['name'], - openingHours: json['opening_hours'] != null - ? OpeningHours.fromJson(json['opening_hours']) - : null, - photos: json['photos'] != null - ? json['photos'].map((json) => Photo.fromJson(json)).toList() - : null, - placeId: json['place_id'], - plusCode: json['plus_code'] != null - ? PlusCode.fromJson(json['plus_code']) - : null, - rating: json['rating'] != null ? json['rating'].toDouble() : null, - reference: json['reference'], - reviews: json['reviews'] != null - ? json['reviews'] - .map((json) => Review.fromJson(json)) - .toList() - : null, - scope: json['scope'], - types: json['types'] != null - ? (json['types'] as List).cast() - : null, - url: json['url'], - userRatingsTotal: json['user_ratings_total'], - utcOffset: json['utc_offset'], - vicinity: json['vicinity'], - website: json['website'], - priceLevel: json['price_level'], - permanentlyClosed: json['permanently_closed'], - ); - } + factory DetailsResult.fromJson(Map json) => + _$DetailsResultFromJson(json); + + Map toJson() => _$DetailsResultToJson(this); } diff --git a/lib/src/details/details_result/details_result.g.dart b/lib/src/details/details_result/details_result.g.dart new file mode 100644 index 0000000..4025eca --- /dev/null +++ b/lib/src/details/details_result/details_result.g.dart @@ -0,0 +1,81 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'details_result.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +DetailsResult _$DetailsResultFromJson(Map json) => + DetailsResult( + addressComponents: (json['address_components'] as List?) + ?.map((e) => AddressComponent.fromJson(e as Map)) + .toList(), + businessStatus: json['business_status'] as String?, + adrAddress: json['adr_address'] as String?, + formattedAddress: json['formatted_address'] as String?, + formattedPhoneNumber: json['formatted_phone_number'] as String?, + geometry: json['geometry'] == null + ? null + : Geometry.fromJson(json['geometry'] as Map), + icon: json['icon'] as String?, + id: json['id'] as String?, + internationalPhoneNumber: json['international_phone_number'] as String?, + name: json['name'] as String?, + openingHours: json['opening_hours'] == null + ? null + : OpeningHours.fromJson( + json['opening_hours'] as Map), + photos: (json['photos'] as List?) + ?.map((e) => Photo.fromJson(e as Map)) + .toList(), + placeId: json['place_id'] as String?, + plusCode: json['plus_code'] == null + ? null + : PlusCode.fromJson(json['plus_code'] as Map), + rating: (json['rating'] as num?)?.toDouble(), + reference: json['reference'] as String?, + reviews: (json['reviews'] as List?) + ?.map((e) => Review.fromJson(e as Map)) + .toList(), + scope: json['scope'] as String?, + types: + (json['types'] as List?)?.map((e) => e as String).toList(), + url: json['url'] as String?, + userRatingsTotal: json['user_ratings_total'] as int?, + utcOffset: json['utc_offset'] as int?, + vicinity: json['vicinity'] as String?, + website: json['website'] as String?, + priceLevel: json['price_level'] as int?, + permanentlyClosed: json['permanently_closed'] as bool?, + ); + +Map _$DetailsResultToJson(DetailsResult instance) => + { + 'address_components': instance.addressComponents, + 'business_status': instance.businessStatus, + 'adr_address': instance.adrAddress, + 'formatted_address': instance.formattedAddress, + 'formatted_phone_number': instance.formattedPhoneNumber, + 'geometry': instance.geometry, + 'icon': instance.icon, + 'id': instance.id, + 'international_phone_number': instance.internationalPhoneNumber, + 'name': instance.name, + 'opening_hours': instance.openingHours, + 'photos': instance.photos, + 'place_id': instance.placeId, + 'plus_code': instance.plusCode, + 'rating': instance.rating, + 'reference': instance.reference, + 'reviews': instance.reviews, + 'scope': instance.scope, + 'types': instance.types, + 'url': instance.url, + 'user_ratings_total': instance.userRatingsTotal, + 'utc_offset': instance.utcOffset, + 'vicinity': instance.vicinity, + 'website': instance.website, + 'price_level': instance.priceLevel, + 'permanently_closed': instance.permanentlyClosed, + }; diff --git a/lib/src/models/address_component.dart b/lib/src/models/address_component/address_component.dart similarity index 66% rename from lib/src/models/address_component.dart rename to lib/src/models/address_component/address_component.dart index 1e8abe4..1c4419d 100644 --- a/lib/src/models/address_component.dart +++ b/lib/src/models/address_component/address_component.dart @@ -1,3 +1,8 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'address_component.g.dart'; + +@JsonSerializable() class AddressComponent { /// [longName] is the full text description or name of the address component as returned by the Geocoder. final String? longName; @@ -10,19 +15,14 @@ class AddressComponent { /// [types] is an array indicating the type of the address component. final List? types; - AddressComponent({ + const AddressComponent({ this.longName, this.shortName, this.types, }); - factory AddressComponent.fromJson(Map json) { - return AddressComponent( - longName: json['long_name'], - shortName: json['short_name'], - types: json['types'] != null - ? (json['types'] as List).cast() - : null, - ); - } + factory AddressComponent.fromJson(Map json) => + _$AddressComponentFromJson(json); + + Map toJson() => _$AddressComponentToJson(this); } diff --git a/lib/src/models/address_component/address_component.g.dart b/lib/src/models/address_component/address_component.g.dart new file mode 100644 index 0000000..82ec465 --- /dev/null +++ b/lib/src/models/address_component/address_component.g.dart @@ -0,0 +1,22 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'address_component.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +AddressComponent _$AddressComponentFromJson(Map json) => + AddressComponent( + longName: json['long_name'] as String?, + shortName: json['short_name'] as String?, + types: + (json['types'] as List?)?.map((e) => e as String).toList(), + ); + +Map _$AddressComponentToJson(AddressComponent instance) => + { + 'long_name': instance.longName, + 'short_name': instance.shortName, + 'types': instance.types, + }; diff --git a/lib/src/models/bounds.dart b/lib/src/models/bounds.dart deleted file mode 100644 index b4df793..0000000 --- a/lib/src/models/bounds.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:google_place/src/models/northeast.dart'; -import 'package:google_place/src/models/southwest.dart'; - -class Bounds { - final Northeast? northeast; - final Southwest? southwest; - - Bounds({this.northeast, this.southwest}); - - factory Bounds.fromJson(Map json) { - return Bounds( - northeast: json['northeast'] != null - ? Northeast.fromJson(json['northeast']) - : null, - southwest: json['southwest'] != null - ? Southwest.fromJson(json['southwest']) - : null, - ); - } -} diff --git a/lib/src/models/bounds/bounds.dart b/lib/src/models/bounds/bounds.dart new file mode 100644 index 0000000..cc01b07 --- /dev/null +++ b/lib/src/models/bounds/bounds.dart @@ -0,0 +1,17 @@ +import 'package:google_place/src/models/location/location.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'bounds.g.dart'; + +@JsonSerializable() +class Bounds { + final Location? northeast; + + final Location? southwest; + + const Bounds({this.northeast, this.southwest}); + + factory Bounds.fromJson(Map json) => _$BoundsFromJson(json); + + Map toJson() => _$BoundsToJson(this); +} diff --git a/lib/src/models/bounds/bounds.g.dart b/lib/src/models/bounds/bounds.g.dart new file mode 100644 index 0000000..c5946cd --- /dev/null +++ b/lib/src/models/bounds/bounds.g.dart @@ -0,0 +1,21 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'bounds.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Bounds _$BoundsFromJson(Map json) => Bounds( + northeast: json['northeast'] == null + ? null + : Location.fromJson(json['northeast'] as Map), + southwest: json['southwest'] == null + ? null + : Location.fromJson(json['southwest'] as Map), + ); + +Map _$BoundsToJson(Bounds instance) => { + 'northeast': instance.northeast, + 'southwest': instance.southwest, + }; diff --git a/lib/src/models/close.dart b/lib/src/models/close.dart deleted file mode 100644 index 17b8c8e..0000000 --- a/lib/src/models/close.dart +++ /dev/null @@ -1,17 +0,0 @@ -class Close { - /// [day] a number from 0–6, corresponding to the days of the week, starting on Sunday. For example, 2 means Tuesday. - final int? day; - - /// [time] may contain a time of day in 24-hour hhmm format. Values are in the range 0000–2359. - /// The time will be reported in the place’s time zone. - final String? time; - - Close({this.day, this.time}); - - factory Close.fromJson(Map json) { - return Close( - day: json['day'], - time: json['time'], - ); - } -} diff --git a/lib/src/models/component.dart b/lib/src/models/component.dart index 488daa4..f052938 100644 --- a/lib/src/models/component.dart +++ b/lib/src/models/component.dart @@ -1,6 +1,7 @@ class Component { final String component; + final String value; - Component(this.component, this.value); + const Component(this.component, this.value); } diff --git a/lib/src/models/debug_log.dart b/lib/src/models/debug_log.dart deleted file mode 100644 index b3084ec..0000000 --- a/lib/src/models/debug_log.dart +++ /dev/null @@ -1,13 +0,0 @@ -class DebugLog { - final List? line; - - DebugLog({this.line}); - - factory DebugLog.fromJson(Map json) { - return DebugLog( - line: json['line'] != null - ? (json['line'] as List).cast() - : null, - ); - } -} diff --git a/lib/src/models/debug_log/debug_log.dart b/lib/src/models/debug_log/debug_log.dart new file mode 100644 index 0000000..c4e5951 --- /dev/null +++ b/lib/src/models/debug_log/debug_log.dart @@ -0,0 +1,15 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'debug_log.g.dart'; + +@JsonSerializable() +class DebugLog { + final List? line; + + const DebugLog({this.line}); + + factory DebugLog.fromJson(Map json) => + _$DebugLogFromJson(json); + + Map toJson() => _$DebugLogToJson(this); +} diff --git a/lib/src/models/debug_log/debug_log.g.dart b/lib/src/models/debug_log/debug_log.g.dart new file mode 100644 index 0000000..8fc52c4 --- /dev/null +++ b/lib/src/models/debug_log/debug_log.g.dart @@ -0,0 +1,15 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'debug_log.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +DebugLog _$DebugLogFromJson(Map json) => DebugLog( + line: (json['line'] as List?)?.map((e) => e as String).toList(), + ); + +Map _$DebugLogToJson(DebugLog instance) => { + 'line': instance.line, + }; diff --git a/lib/src/models/geometry.dart b/lib/src/models/geometry.dart deleted file mode 100644 index 0c1f64e..0000000 --- a/lib/src/models/geometry.dart +++ /dev/null @@ -1,26 +0,0 @@ -import 'package:google_place/src/models/bounds.dart'; -import 'package:google_place/src/models/location.dart'; -import 'package:google_place/src/models/viewport.dart'; - -class Geometry { - /// [location] contains the geocoded latitude,longitude value for this place. - final Location? location; - - /// [viewport] contains the preferred viewport when displaying this place on a map as a LatLngBounds if it is known. - final Viewport? viewport; - - /// [bounds] contains bounds object - final Bounds? bounds; - - Geometry({this.location, this.viewport, this.bounds}); - - factory Geometry.fromJson(Map json) { - return Geometry( - location: - json['location'] != null ? Location.fromJson(json['location']) : null, - viewport: - json['viewport'] != null ? Viewport.fromJson(json['viewport']) : null, - bounds: json['bounds'] != null ? Bounds.fromJson(json['bounds']) : null, - ); - } -} diff --git a/lib/src/models/geometry/geometry.dart b/lib/src/models/geometry/geometry.dart new file mode 100644 index 0000000..fb1252f --- /dev/null +++ b/lib/src/models/geometry/geometry.dart @@ -0,0 +1,24 @@ +import 'package:google_place/src/models/bounds/bounds.dart'; +import 'package:google_place/src/models/location/location.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'geometry.g.dart'; + +@JsonSerializable() +class Geometry { + /// [location] contains the geocoded latitude,longitude value for this place. + final Location? location; + + /// [viewport] contains the preferred viewport when displaying this place on a map as a LatLngBounds if it is known. + final Bounds? viewport; + + /// [bounds] contains bounds object + final Bounds? bounds; + + const Geometry({this.location, this.viewport, this.bounds}); + + factory Geometry.fromJson(Map json) => + _$GeometryFromJson(json); + + Map toJson() => _$GeometryToJson(this); +} diff --git a/lib/src/models/geometry/geometry.g.dart b/lib/src/models/geometry/geometry.g.dart new file mode 100644 index 0000000..e59abcf --- /dev/null +++ b/lib/src/models/geometry/geometry.g.dart @@ -0,0 +1,25 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'geometry.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Geometry _$GeometryFromJson(Map json) => Geometry( + location: json['location'] == null + ? null + : Location.fromJson(json['location'] as Map), + viewport: json['viewport'] == null + ? null + : Bounds.fromJson(json['viewport'] as Map), + bounds: json['bounds'] == null + ? null + : Bounds.fromJson(json['bounds'] as Map), + ); + +Map _$GeometryToJson(Geometry instance) => { + 'location': instance.location, + 'viewport': instance.viewport, + 'bounds': instance.bounds, + }; diff --git a/lib/src/models/input_type.dart b/lib/src/models/input_type.dart index 03fbd91..a99c132 100644 --- a/lib/src/models/input_type.dart +++ b/lib/src/models/input_type.dart @@ -1,7 +1,4 @@ /// [InputType] - The type of input. This can be one of either textquery or phonenumber. /// Phone numbers must be in international format (prefixed by a plus sign ("+"), /// followed by the country code, then the phone number itself). -enum InputType { - TextQuery, - PhoneNumber, -} +enum InputType { TextQuery, PhoneNumber } diff --git a/lib/src/models/lat_lon.dart b/lib/src/models/lat_lon.dart index 6343dd3..75a86d5 100644 --- a/lib/src/models/lat_lon.dart +++ b/lib/src/models/lat_lon.dart @@ -1,12 +1,4 @@ -/// A pair of latitude and longitude coordinates, stored as degrees. class LatLon { - /// Creates a geographical location specified in degrees [latitude] and - /// [longitude]. - /// - /// The latitude is clamped to the inclusive interval from -90.0 to +90.0. - /// - /// The longitude is normalized to the half-open interval from -180.0 - /// (inclusive) to +180.0 (exclusive) const LatLon(double latitude, double longitude) : latitude = (latitude < -90.0 ? -90.0 : (90.0 < latitude ? 90.0 : latitude)), diff --git a/lib/src/models/location.dart b/lib/src/models/location.dart deleted file mode 100644 index 76ad6f2..0000000 --- a/lib/src/models/location.dart +++ /dev/null @@ -1,13 +0,0 @@ -class Location { - final double? lat; - final double? lng; - - Location({this.lat, this.lng}); - - factory Location.fromJson(Map json) { - return Location( - lat: json['lat'] != null ? json['lat'].toDouble() : null, - lng: json['lng'] != null ? json['lng'].toDouble() : null, - ); - } -} diff --git a/lib/src/models/location/location.dart b/lib/src/models/location/location.dart new file mode 100644 index 0000000..e11e2b7 --- /dev/null +++ b/lib/src/models/location/location.dart @@ -0,0 +1,25 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'location.g.dart'; + +/// A pair of latitude and longitude coordinates, stored as degrees. +@JsonSerializable() +class Location { + final double lat; + + final double lng; + + /// Creates a geographical location specified in degrees [latitude] and + /// [longitude]. + /// + /// The latitude is clamped to the inclusive interval from -90.0 to +90.0. + /// + /// The longitude is normalized to the half-open interval from -180.0 + /// (inclusive) to +180.0 (exclusive) + const Location({required this.lat, required this.lng}); + + factory Location.fromJson(Map json) => + _$LocationFromJson(json); + + Map toJson() => _$LocationToJson(this); +} diff --git a/lib/src/models/location/location.g.dart b/lib/src/models/location/location.g.dart new file mode 100644 index 0000000..aca57f1 --- /dev/null +++ b/lib/src/models/location/location.g.dart @@ -0,0 +1,17 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'location.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Location _$LocationFromJson(Map json) => Location( + lat: (json['lat'] as num).toDouble(), + lng: (json['lng'] as num).toDouble(), + ); + +Map _$LocationToJson(Location instance) => { + 'lat': instance.lat, + 'lng': instance.lng, + }; diff --git a/lib/src/models/main_text_matched_substring.dart b/lib/src/models/main_text_matched_substring.dart deleted file mode 100644 index f9013f9..0000000 --- a/lib/src/models/main_text_matched_substring.dart +++ /dev/null @@ -1,13 +0,0 @@ -class MainTextMatchedSubstring { - final int? length; - final int? offset; - - MainTextMatchedSubstring({this.length, this.offset}); - - factory MainTextMatchedSubstring.fromJson(Map json) { - return MainTextMatchedSubstring( - length: json['length'] as int?, - offset: json['offset'] as int?, - ); - } -} diff --git a/lib/src/models/matched_substring.dart b/lib/src/models/matched_substring.dart deleted file mode 100644 index 825dcce..0000000 --- a/lib/src/models/matched_substring.dart +++ /dev/null @@ -1,13 +0,0 @@ -class MatchedSubstring { - final int? length; - final int? offset; - - MatchedSubstring({this.length, this.offset}); - - factory MatchedSubstring.fromJson(Map json) { - return MatchedSubstring( - length: json['length'] as int?, - offset: json['offset'] as int?, - ); - } -} diff --git a/lib/src/models/matched_substring/matched_substring.dart b/lib/src/models/matched_substring/matched_substring.dart new file mode 100644 index 0000000..72a7ad1 --- /dev/null +++ b/lib/src/models/matched_substring/matched_substring.dart @@ -0,0 +1,17 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'matched_substring.g.dart'; + +@JsonSerializable() +class MatchedSubstring { + final int? length; + + final int? offset; + + const MatchedSubstring({this.length, this.offset}); + + factory MatchedSubstring.fromJson(Map json) => + _$MatchedSubstringFromJson(json); + + Map toJson() => _$MatchedSubstringToJson(this); +} diff --git a/lib/src/models/matched_substring/matched_substring.g.dart b/lib/src/models/matched_substring/matched_substring.g.dart new file mode 100644 index 0000000..e6be9b6 --- /dev/null +++ b/lib/src/models/matched_substring/matched_substring.g.dart @@ -0,0 +1,19 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'matched_substring.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +MatchedSubstring _$MatchedSubstringFromJson(Map json) => + MatchedSubstring( + length: json['length'] as int?, + offset: json['offset'] as int?, + ); + +Map _$MatchedSubstringToJson(MatchedSubstring instance) => + { + 'length': instance.length, + 'offset': instance.offset, + }; diff --git a/lib/src/models/northeast.dart b/lib/src/models/northeast.dart deleted file mode 100644 index 04d20f3..0000000 --- a/lib/src/models/northeast.dart +++ /dev/null @@ -1,13 +0,0 @@ -class Northeast { - final double? lat; - final double? lng; - - Northeast({this.lat, this.lng}); - - factory Northeast.fromJson(Map json) { - return Northeast( - lat: json['lat'] != null ? json['lat'].toDouble() : null, - lng: json['lng'] != null ? json['lng'].toDouble() : null, - ); - } -} diff --git a/lib/src/models/opening_hours.dart b/lib/src/models/opening_hours/opening_hours.dart similarity index 62% rename from lib/src/models/opening_hours.dart rename to lib/src/models/opening_hours/opening_hours.dart index 4bf01d1..3b6084e 100644 --- a/lib/src/models/opening_hours.dart +++ b/lib/src/models/opening_hours/opening_hours.dart @@ -1,5 +1,9 @@ -import 'package:google_place/src/models/period.dart'; +import 'package:google_place/src/models/period/period.dart'; +import 'package:json_annotation/json_annotation.dart'; +part 'opening_hours.g.dart'; + +@JsonSerializable() class OpeningHours { /// [openNow] is a boolean value indicating if the place is open at the current time. final bool? openNow; @@ -14,23 +18,14 @@ class OpeningHours { /// [periods] is an array of opening periods covering seven days, starting from Sunday, in chronological order. final List? periods; - OpeningHours({ + const OpeningHours({ this.openNow, this.weekdayText, this.periods, }); - factory OpeningHours.fromJson(Map json) { - return OpeningHours( - openNow: json['open_now'], - weekdayText: json['weekday_text'] != null - ? (json['weekday_text'] as List).cast() - : null, - periods: json['periods'] != null - ? json['periods'] - .map((json) => Period.fromJson(json)) - .toList() - : null, - ); - } + factory OpeningHours.fromJson(Map json) => + _$OpeningHoursFromJson(json); + + Map toJson() => _$OpeningHoursToJson(this); } diff --git a/lib/src/models/opening_hours/opening_hours.g.dart b/lib/src/models/opening_hours/opening_hours.g.dart new file mode 100644 index 0000000..7a8df9f --- /dev/null +++ b/lib/src/models/opening_hours/opening_hours.g.dart @@ -0,0 +1,24 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'opening_hours.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +OpeningHours _$OpeningHoursFromJson(Map json) => OpeningHours( + openNow: json['open_now'] as bool?, + weekdayText: (json['weekday_text'] as List?) + ?.map((e) => e as String) + .toList(), + periods: (json['periods'] as List?) + ?.map((e) => Period.fromJson(e as Map)) + .toList(), + ); + +Map _$OpeningHoursToJson(OpeningHours instance) => + { + 'open_now': instance.openNow, + 'weekday_text': instance.weekdayText, + 'periods': instance.periods, + }; diff --git a/lib/src/models/period.dart b/lib/src/models/period/period.dart similarity index 51% rename from lib/src/models/period.dart rename to lib/src/models/period/period.dart index 75cef25..bb5ab75 100644 --- a/lib/src/models/period.dart +++ b/lib/src/models/period/period.dart @@ -1,22 +1,22 @@ -import 'package:google_place/src/models/close.dart'; -import 'package:google_place/src/models/open.dart'; +import 'package:google_place/src/models/time_and_day/time_and_day.dart'; +import 'package:json_annotation/json_annotation.dart'; +part 'period.g.dart'; + +@JsonSerializable() class Period { /// [close] may contain a pair of day and time objects describing when the place closes. /// Note: If a place is always open, the close section will be missing from the response. /// Clients can rely on always-open being represented as an open period containing day with /// value 0 and time with value 0000, and no close. - final Close? close; + final TimeAndDay? close; /// [open] contains a pair of day and time objects describing when the place opens. - final Open? open; + final TimeAndDay open; + + const Period({required this.open, this.close}); - Period({this.close, this.open}); + factory Period.fromJson(Map json) => _$PeriodFromJson(json); - factory Period.fromJson(Map json) { - return Period( - close: json['close'] != null ? Close.fromJson(json['close']) : null, - open: json['open'] != null ? Open.fromJson(json['open']) : null, - ); - } + Map toJson() => _$PeriodToJson(this); } diff --git a/lib/src/models/period/period.g.dart b/lib/src/models/period/period.g.dart new file mode 100644 index 0000000..cfb8bbf --- /dev/null +++ b/lib/src/models/period/period.g.dart @@ -0,0 +1,19 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'period.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Period _$PeriodFromJson(Map json) => Period( + open: TimeAndDay.fromJson(json['open'] as Map), + close: json['close'] == null + ? null + : TimeAndDay.fromJson(json['close'] as Map), + ); + +Map _$PeriodToJson(Period instance) => { + 'close': instance.close, + 'open': instance.open, + }; diff --git a/lib/src/models/photo.dart b/lib/src/models/photo/photo.dart similarity index 51% rename from lib/src/models/photo.dart rename to lib/src/models/photo/photo.dart index 23a1e58..d1f027a 100644 --- a/lib/src/models/photo.dart +++ b/lib/src/models/photo/photo.dart @@ -1,3 +1,8 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'photo.g.dart'; + +@JsonSerializable() class Photo { /// [photoReference] a string used to identify the photo when you perform a Photo request. final String? photoReference; @@ -11,16 +16,14 @@ class Photo { /// [htmlAttributions] contains any required attributions. This field will always be present, but may be empty. final List? htmlAttributions; - Photo({this.photoReference, this.height, this.width, this.htmlAttributions}); - - factory Photo.fromJson(Map json) { - return Photo( - photoReference: json['photo_reference'], - height: json['height'], - width: json['width'], - htmlAttributions: json['html_attributions'] != null - ? (json['html_attributions'] as List).cast() - : null, - ); - } + const Photo({ + this.photoReference, + this.height, + this.width, + this.htmlAttributions, + }); + + factory Photo.fromJson(Map json) => _$PhotoFromJson(json); + + Map toJson() => _$PhotoToJson(this); } diff --git a/lib/src/models/photo/photo.g.dart b/lib/src/models/photo/photo.g.dart new file mode 100644 index 0000000..d0193e4 --- /dev/null +++ b/lib/src/models/photo/photo.g.dart @@ -0,0 +1,23 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'photo.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Photo _$PhotoFromJson(Map json) => Photo( + photoReference: json['photo_reference'] as String?, + height: json['height'] as int?, + width: json['width'] as int?, + htmlAttributions: (json['html_attributions'] as List?) + ?.map((e) => e as String) + .toList(), + ); + +Map _$PhotoToJson(Photo instance) => { + 'photo_reference': instance.photoReference, + 'height': instance.height, + 'width': instance.width, + 'html_attributions': instance.htmlAttributions, + }; diff --git a/lib/src/models/plus_code.dart b/lib/src/models/plus_code.dart deleted file mode 100644 index 852cd5b..0000000 --- a/lib/src/models/plus_code.dart +++ /dev/null @@ -1,16 +0,0 @@ -class PlusCode { - /// [globalCode] is a 4 character area code and 6 character or longer local code (849VCWC8+R9). - final String? globalCode; - - /// [compoundCode] is a 6 character or longer local code with an explicit location (CWC8+R9, Mountain View, CA, USA). - final String? compoundCode; - - PlusCode({this.globalCode, this.compoundCode}); - - factory PlusCode.fromJson(Map json) { - return PlusCode( - globalCode: json['global_code'], - compoundCode: json['compound_code'], - ); - } -} diff --git a/lib/src/models/plus_code/plus_code.dart b/lib/src/models/plus_code/plus_code.dart new file mode 100644 index 0000000..89de481 --- /dev/null +++ b/lib/src/models/plus_code/plus_code.dart @@ -0,0 +1,19 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'plus_code.g.dart'; + +@JsonSerializable() +class PlusCode { + /// [globalCode] is a 4 character area code and 6 character or longer local code (849VCWC8+R9). + final String? globalCode; + + /// [compoundCode] is a 6 character or longer local code with an explicit location (CWC8+R9, Mountain View, CA, USA). + final String? compoundCode; + + const PlusCode({this.globalCode, this.compoundCode}); + + factory PlusCode.fromJson(Map json) => + _$PlusCodeFromJson(json); + + Map toJson() => _$PlusCodeToJson(this); +} diff --git a/lib/src/models/plus_code/plus_code.g.dart b/lib/src/models/plus_code/plus_code.g.dart new file mode 100644 index 0000000..d18ecdc --- /dev/null +++ b/lib/src/models/plus_code/plus_code.g.dart @@ -0,0 +1,17 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'plus_code.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +PlusCode _$PlusCodeFromJson(Map json) => PlusCode( + globalCode: json['global_code'] as String?, + compoundCode: json['compound_code'] as String?, + ); + +Map _$PlusCodeToJson(PlusCode instance) => { + 'global_code': instance.globalCode, + 'compound_code': instance.compoundCode, + }; diff --git a/lib/src/models/rank-by.dart b/lib/src/models/rank-by.dart deleted file mode 100644 index 8c040b1..0000000 --- a/lib/src/models/rank-by.dart +++ /dev/null @@ -1,4 +0,0 @@ -enum RankBy { - Prominence, - Distance, -} diff --git a/lib/src/models/rank_by.dart b/lib/src/models/rank_by.dart new file mode 100644 index 0000000..bfc3cb4 --- /dev/null +++ b/lib/src/models/rank_by.dart @@ -0,0 +1 @@ +enum RankBy { Prominence, Distance } diff --git a/lib/src/models/review.dart b/lib/src/models/review/review.dart similarity index 80% rename from lib/src/models/review.dart rename to lib/src/models/review/review.dart index 224cb27..e23a8ea 100644 --- a/lib/src/models/review.dart +++ b/lib/src/models/review/review.dart @@ -1,3 +1,8 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'review.g.dart'; + +@JsonSerializable() class Review { /// [authorName] the name of the user who submitted the review. Anonymous reviews are attributed to "A Google user". final String? authorName; @@ -27,7 +32,7 @@ class Review { /// [time] the time that the review was submitted, measured in the number of seconds since since midnight, January 1, 1970 UTC. final int? time; - Review({ + const Review({ this.authorName, this.authorUrl, this.language, @@ -38,16 +43,7 @@ class Review { this.time, }); - factory Review.fromJson(Map json) { - return Review( - authorName: json['author_name'], - authorUrl: json['author_url'], - language: json['language'], - profilePhotoUrl: json['profile_photo_url'], - rating: json['rating'], - relativeTimeDescription: json['relative_time_description'], - text: json['text'], - time: json['time'], - ); - } + factory Review.fromJson(Map json) => _$ReviewFromJson(json); + + Map toJson() => _$ReviewToJson(this); } diff --git a/lib/src/models/review/review.g.dart b/lib/src/models/review/review.g.dart new file mode 100644 index 0000000..3986fe8 --- /dev/null +++ b/lib/src/models/review/review.g.dart @@ -0,0 +1,29 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'review.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Review _$ReviewFromJson(Map json) => Review( + authorName: json['author_name'] as String?, + authorUrl: json['author_url'] as String?, + language: json['language'] as String?, + profilePhotoUrl: json['profile_photo_url'] as String?, + rating: json['rating'] as int?, + relativeTimeDescription: json['relative_time_description'] as String?, + text: json['text'] as String?, + time: json['time'] as int?, + ); + +Map _$ReviewToJson(Review instance) => { + 'author_name': instance.authorName, + 'author_url': instance.authorUrl, + 'language': instance.language, + 'profile_photo_url': instance.profilePhotoUrl, + 'rating': instance.rating, + 'relative_time_description': instance.relativeTimeDescription, + 'text': instance.text, + 'time': instance.time, + }; diff --git a/lib/src/models/southwest.dart b/lib/src/models/southwest.dart deleted file mode 100644 index 36b08c3..0000000 --- a/lib/src/models/southwest.dart +++ /dev/null @@ -1,13 +0,0 @@ -class Southwest { - final double? lat; - final double? lng; - - Southwest({this.lat, this.lng}); - - factory Southwest.fromJson(Map json) { - return Southwest( - lat: json['lat'] != null ? json['lat'].toDouble() : null, - lng: json['lng'] != null ? json['lng'].toDouble() : null, - ); - } -} diff --git a/lib/src/models/structured_formatting.dart b/lib/src/models/structured_formatting.dart deleted file mode 100644 index e4e00db..0000000 --- a/lib/src/models/structured_formatting.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:google_place/src/models/main_text_matched_substring.dart'; - -class StructuredFormatting { - /// [mainText] contains the main text of a prediction, usually the name of the place. - final String? mainText; - - /// [mainTextMatchedSubstrings] contains an array with offset value and length. - /// These describe the location of the entered term in the prediction result text, - /// so that the term can be highlighted if desired. - final List? mainTextMatchedSubstrings; - - /// [secondaryText] contains the secondary text of a prediction, usually the location of the place. - final String? secondaryText; - - StructuredFormatting( - {this.mainText, this.mainTextMatchedSubstrings, this.secondaryText}); - - factory StructuredFormatting.fromJson(Map json) { - return StructuredFormatting( - mainText: json['main_text'] as String?, - mainTextMatchedSubstrings: json['main_text_matched_substrings'] - .map( - (json) => MainTextMatchedSubstring.fromJson(json)) - .toList(), - secondaryText: json['secondary_text'] as String?, - ); - } -} diff --git a/lib/src/models/structured_formatting/structured_formatting.dart b/lib/src/models/structured_formatting/structured_formatting.dart new file mode 100644 index 0000000..58e357f --- /dev/null +++ b/lib/src/models/structured_formatting/structured_formatting.dart @@ -0,0 +1,29 @@ +import 'package:google_place/src/models/matched_substring/matched_substring.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'structured_formatting.g.dart'; + +@JsonSerializable() +class StructuredFormatting { + /// [mainText] contains the main text of a prediction, usually the name of the place. + final String? mainText; + + /// [mainTextMatchedSubstrings] contains an array with offset value and length. + /// These describe the location of the entered term in the prediction result text, + /// so that the term can be highlighted if desired. + final List? mainTextMatchedSubstrings; + + /// [secondaryText] contains the secondary text of a prediction, usually the location of the place. + final String? secondaryText; + + const StructuredFormatting({ + this.mainText, + this.mainTextMatchedSubstrings, + this.secondaryText, + }); + + factory StructuredFormatting.fromJson(Map json) => + _$StructuredFormattingFromJson(json); + + Map toJson() => _$StructuredFormattingToJson(this); +} diff --git a/lib/src/models/structured_formatting/structured_formatting.g.dart b/lib/src/models/structured_formatting/structured_formatting.g.dart new file mode 100644 index 0000000..ef3c9a6 --- /dev/null +++ b/lib/src/models/structured_formatting/structured_formatting.g.dart @@ -0,0 +1,26 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'structured_formatting.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +StructuredFormatting _$StructuredFormattingFromJson( + Map json) => + StructuredFormatting( + mainText: json['main_text'] as String?, + mainTextMatchedSubstrings: + (json['main_text_matched_substrings'] as List?) + ?.map((e) => MatchedSubstring.fromJson(e as Map)) + .toList(), + secondaryText: json['secondary_text'] as String?, + ); + +Map _$StructuredFormattingToJson( + StructuredFormatting instance) => + { + 'main_text': instance.mainText, + 'main_text_matched_substrings': instance.mainTextMatchedSubstrings, + 'secondary_text': instance.secondaryText, + }; diff --git a/lib/src/models/term.dart b/lib/src/models/term.dart deleted file mode 100644 index 93d8b2a..0000000 --- a/lib/src/models/term.dart +++ /dev/null @@ -1,16 +0,0 @@ -class Term { - /// [offset] defining the start position of this term in the description - final int? offset; - - /// [value] containing the text of the term - final String? value; - - Term({this.offset, this.value}); - - factory Term.fromJson(Map json) { - return Term( - offset: json['offset'] as int?, - value: json['value'] as String?, - ); - } -} diff --git a/lib/src/models/term/term.dart b/lib/src/models/term/term.dart new file mode 100644 index 0000000..c1dcee7 --- /dev/null +++ b/lib/src/models/term/term.dart @@ -0,0 +1,18 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'term.g.dart'; + +@JsonSerializable() +class Term { + /// [offset] defining the start position of this term in the description + final int? offset; + + /// [value] containing the text of the term + final String? value; + + const Term({this.offset, this.value}); + + factory Term.fromJson(Map json) => _$TermFromJson(json); + + Map toJson() => _$TermToJson(this); +} diff --git a/lib/src/models/term/term.g.dart b/lib/src/models/term/term.g.dart new file mode 100644 index 0000000..28736ac --- /dev/null +++ b/lib/src/models/term/term.g.dart @@ -0,0 +1,17 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'term.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +Term _$TermFromJson(Map json) => Term( + offset: json['offset'] as int?, + value: json['value'] as String?, + ); + +Map _$TermToJson(Term instance) => { + 'offset': instance.offset, + 'value': instance.value, + }; diff --git a/lib/src/models/open.dart b/lib/src/models/time_and_day/time_and_day.dart similarity index 50% rename from lib/src/models/open.dart rename to lib/src/models/time_and_day/time_and_day.dart index 4469d2c..07545be 100644 --- a/lib/src/models/open.dart +++ b/lib/src/models/time_and_day/time_and_day.dart @@ -1,4 +1,9 @@ -class Open { +import 'package:json_annotation/json_annotation.dart'; + +part 'time_and_day.g.dart'; + +@JsonSerializable() +class TimeAndDay { /// [day] a number from 0–6, corresponding to the days of the week, starting on Sunday. For example, 2 means Tuesday. final int? day; @@ -6,12 +11,10 @@ class Open { /// The time will be reported in the place’s time zone. final String? time; - Open({this.day, this.time}); + const TimeAndDay({this.day, this.time}); + + factory TimeAndDay.fromJson(Map json) => + _$TimeAndDayFromJson(json); - factory Open.fromJson(Map json) { - return Open( - day: json['day'], - time: json['time'], - ); - } + Map toJson() => _$TimeAndDayToJson(this); } diff --git a/lib/src/models/time_and_day/time_and_day.g.dart b/lib/src/models/time_and_day/time_and_day.g.dart new file mode 100644 index 0000000..0ad0aad --- /dev/null +++ b/lib/src/models/time_and_day/time_and_day.g.dart @@ -0,0 +1,18 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'time_and_day.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +TimeAndDay _$TimeAndDayFromJson(Map json) => TimeAndDay( + day: json['day'] as int?, + time: json['time'] as String?, + ); + +Map _$TimeAndDayToJson(TimeAndDay instance) => + { + 'day': instance.day, + 'time': instance.time, + }; diff --git a/lib/src/models/viewport.dart b/lib/src/models/viewport.dart deleted file mode 100644 index 41650d5..0000000 --- a/lib/src/models/viewport.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:google_place/src/models/northeast.dart'; -import 'package:google_place/src/models/southwest.dart'; - -class Viewport { - final Northeast? northeast; - final Southwest? southwest; - - Viewport({this.northeast, this.southwest}); - - factory Viewport.fromJson(Map json) { - return Viewport( - northeast: json['northeast'] != null - ? Northeast.fromJson(json['northeast']) - : null, - southwest: json['southwest'] != null - ? Southwest.fromJson(json['southwest']) - : null, - ); - } -} diff --git a/lib/src/query_autocomplete/query_autocomplete.dart b/lib/src/query_autocomplete/query_autocomplete.dart index 6a3db75..e460036 100644 --- a/lib/src/query_autocomplete/query_autocomplete.dart +++ b/lib/src/query_autocomplete/query_autocomplete.dart @@ -1,14 +1,21 @@ +import 'dart:convert'; + import 'package:google_place/google_place.dart'; +import 'package:google_place/src/autocomplete/autocomplete_response/autocomplete_response.dart'; import 'package:google_place/src/utils/network_utility.dart'; class QueryAutocomplete { static final _authority = 'maps.googleapis.com'; + static final _unencodedPath = 'maps/api/place/queryautocomplete/json'; + final String apiKEY; + final Map headers; + final String? proxyUrl; - QueryAutocomplete(this.apiKEY, this.headers, this.proxyUrl); + const QueryAutocomplete(this.apiKEY, this.headers, this.proxyUrl); /// The Query Autocomplete service can be used to provide a query prediction for text-based /// geographic searches, by returning suggested queries as you type. @@ -40,7 +47,7 @@ class QueryAutocomplete { String? language, }) async { assert(input != ""); - var queryParameters = _createParameters( + final queryParameters = _createParameters( apiKEY, input, offset, @@ -48,12 +55,18 @@ class QueryAutocomplete { radius, language, ); - var uri = NetworkUtility.createUri( - proxyUrl, _authority, _unencodedPath, queryParameters); - var response = await NetworkUtility.fetchUrl(uri, headers: headers); + final uri = NetworkUtility.createUri( + proxyUrl, + _authority, + _unencodedPath, + queryParameters, + ); + final response = await NetworkUtility.fetchUrl(uri, headers: headers); + if (response != null) { - return AutocompleteResponse.parseAutocompleteResult(response); + return AutocompleteResponse.fromJson(jsonDecode(response)); } + return null; } @@ -87,7 +100,7 @@ class QueryAutocomplete { String? language, }) async { assert(input != ""); - var queryParameters = _createParameters( + final queryParameters = _createParameters( apiKEY, input, offset, @@ -95,9 +108,13 @@ class QueryAutocomplete { radius, language, ); + final uri = NetworkUtility.createUri( + proxyUrl, + _authority, + _unencodedPath, + queryParameters, + ); - var uri = NetworkUtility.createUri( - proxyUrl, _authority, _unencodedPath, queryParameters); return await NetworkUtility.fetchUrl(uri, headers: headers); } @@ -110,40 +127,17 @@ class QueryAutocomplete { int? radius, String? language, ) { - String result = input.trimRight(); - result = result.trimLeft(); - Map queryParameters = { - 'input': result, + final cleanedInput = input.trimRight().trimLeft(); + final queryParameters = { + 'input': cleanedInput, 'key': apiKEY, - }; - - if (location != null) { - var item = { + if (location != null) 'location': '${location.latitude},${location.longitude}', - }; - queryParameters.addAll(item); - } - - if (offset != null) { - var item = { - 'offset': offset.toString(), - }; - queryParameters.addAll(item); - } - - if (radius != null) { - var item = { - 'radius': radius.toString(), - }; - queryParameters.addAll(item); - } + if (offset != null) 'offset': offset.toString(), + if (radius != null) 'radius': radius.toString(), + if (language != null && language != '') 'language': language, + }; - if (language != null && language != '') { - var item = { - 'language': language, - }; - queryParameters.addAll(item); - } return queryParameters; } } diff --git a/lib/src/search/find_place_response.dart b/lib/src/search/find_place_response.dart deleted file mode 100644 index 675d5e1..0000000 --- a/lib/src/search/find_place_response.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'dart:convert'; - -import 'package:google_place/src/models/debug_log.dart'; -import 'package:google_place/src/search/search_candidate.dart'; - -/// The Find Place Search response contains html Attributions and search results and status -class FindPlaceResponse { - final String? status; - final List? htmlAttributions; - final String? nextPageToken; - final DebugLog? debugLog; - final List? candidates; - - FindPlaceResponse({ - this.status, - this.htmlAttributions, - this.nextPageToken, - this.debugLog, - this.candidates, - }); - - factory FindPlaceResponse.fromJson(Map json) { - return FindPlaceResponse( - status: json['status'], - htmlAttributions: json['html_attributions'] != null - ? (json['html_attributions'] as List).cast() - : null, - nextPageToken: json['next_page_token'], - debugLog: json['debug_log'] != null - ? DebugLog.fromJson(json['debug_log']) - : null, - candidates: json['candidates'] != null - ? json['candidates'] - .map((json) => SearchCandidate.fromJson(json)) - .toList() - : null, - ); - } - - static FindPlaceResponse parseFindPlaceResult(String responseBody) { - final parsed = json.decode(responseBody).cast(); - return FindPlaceResponse.fromJson(parsed); - } -} diff --git a/lib/src/search/find_place_response/find_place_response.dart b/lib/src/search/find_place_response/find_place_response.dart new file mode 100644 index 0000000..7e51401 --- /dev/null +++ b/lib/src/search/find_place_response/find_place_response.dart @@ -0,0 +1,32 @@ +import 'package:google_place/src/models/debug_log/debug_log.dart'; +import 'package:google_place/src/search/search_result/search_result.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'find_place_response.g.dart'; + +/// The Find Place Search response contains html Attributions and search results and status +@JsonSerializable() +class FindPlaceResponse { + final String? status; + + final List? htmlAttributions; + + final String? nextPageToken; + + final DebugLog? debugLog; + + final List? candidates; + + const FindPlaceResponse({ + this.status, + this.htmlAttributions, + this.nextPageToken, + this.debugLog, + this.candidates, + }); + + factory FindPlaceResponse.fromJson(Map json) => + _$FindPlaceResponseFromJson(json); + + Map toJson() => _$FindPlaceResponseToJson(this); +} diff --git a/lib/src/search/find_place_response/find_place_response.g.dart b/lib/src/search/find_place_response/find_place_response.g.dart new file mode 100644 index 0000000..975c53f --- /dev/null +++ b/lib/src/search/find_place_response/find_place_response.g.dart @@ -0,0 +1,31 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'find_place_response.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +FindPlaceResponse _$FindPlaceResponseFromJson(Map json) => + FindPlaceResponse( + status: json['status'] as String?, + htmlAttributions: (json['html_attributions'] as List?) + ?.map((e) => e as String) + .toList(), + nextPageToken: json['next_page_token'] as String?, + debugLog: json['debug_log'] == null + ? null + : DebugLog.fromJson(json['debug_log'] as Map), + candidates: (json['candidates'] as List?) + ?.map((e) => SearchResult.fromJson(e as Map)) + .toList(), + ); + +Map _$FindPlaceResponseToJson(FindPlaceResponse instance) => + { + 'status': instance.status, + 'html_attributions': instance.htmlAttributions, + 'next_page_token': instance.nextPageToken, + 'debug_log': instance.debugLog, + 'candidates': instance.candidates, + }; diff --git a/lib/src/search/near_by_search_response.dart b/lib/src/search/near_by_search_response.dart deleted file mode 100644 index 068d636..0000000 --- a/lib/src/search/near_by_search_response.dart +++ /dev/null @@ -1,44 +0,0 @@ -import 'dart:convert'; - -import 'package:google_place/src/models/debug_log.dart'; -import 'package:google_place/src/search/search_result.dart'; - -/// The Near By Search response contains html Attributions and search results and status -class NearBySearchResponse { - final String? status; - final List? htmlAttributions; - final String? nextPageToken; - final DebugLog? debugLog; - final List? results; - - NearBySearchResponse({ - this.status, - this.htmlAttributions, - this.nextPageToken, - this.debugLog, - this.results, - }); - - factory NearBySearchResponse.fromJson(Map json) { - return NearBySearchResponse( - status: json['status'], - htmlAttributions: json['html_attributions'] != null - ? (json['html_attributions'] as List).cast() - : null, - nextPageToken: json['next_page_token'], - debugLog: json['debug_log'] != null - ? DebugLog.fromJson(json['debug_log']) - : null, - results: json['results'] != null - ? json['results'] - .map((json) => SearchResult.fromJson(json)) - .toList() - : null, - ); - } - - static NearBySearchResponse parseNearBySearchResult(String responseBody) { - final parsed = json.decode(responseBody).cast(); - return NearBySearchResponse.fromJson(parsed); - } -} diff --git a/lib/src/search/nearby_search_response/nearby_search_response.dart b/lib/src/search/nearby_search_response/nearby_search_response.dart new file mode 100644 index 0000000..3e4389c --- /dev/null +++ b/lib/src/search/nearby_search_response/nearby_search_response.dart @@ -0,0 +1,32 @@ +import 'package:google_place/src/models/debug_log/debug_log.dart'; +import 'package:google_place/src/search/search_result/search_result.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'nearby_search_response.g.dart'; + +/// The Near By Search response contains html Attributions and search results and status +@JsonSerializable() +class NearbySearchResponse { + final String? status; + + final List? htmlAttributions; + + final String? nextPageToken; + + final DebugLog? debugLog; + + final List? results; + + const NearbySearchResponse({ + this.status, + this.htmlAttributions, + this.nextPageToken, + this.debugLog, + this.results, + }); + + factory NearbySearchResponse.fromJson(Map json) => + _$NearbySearchResponseFromJson(json); + + Map toJson() => _$NearbySearchResponseToJson(this); +} diff --git a/lib/src/search/nearby_search_response/nearby_search_response.g.dart b/lib/src/search/nearby_search_response/nearby_search_response.g.dart new file mode 100644 index 0000000..f2e65d4 --- /dev/null +++ b/lib/src/search/nearby_search_response/nearby_search_response.g.dart @@ -0,0 +1,33 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'nearby_search_response.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +NearbySearchResponse _$NearbySearchResponseFromJson( + Map json) => + NearbySearchResponse( + status: json['status'] as String?, + htmlAttributions: (json['html_attributions'] as List?) + ?.map((e) => e as String) + .toList(), + nextPageToken: json['next_page_token'] as String?, + debugLog: json['debug_log'] == null + ? null + : DebugLog.fromJson(json['debug_log'] as Map), + results: (json['results'] as List?) + ?.map((e) => SearchResult.fromJson(e as Map)) + .toList(), + ); + +Map _$NearbySearchResponseToJson( + NearbySearchResponse instance) => + { + 'status': instance.status, + 'html_attributions': instance.htmlAttributions, + 'next_page_token': instance.nextPageToken, + 'debug_log': instance.debugLog, + 'results': instance.results, + }; diff --git a/lib/src/search/search.dart b/lib/src/search/search.dart index 8055826..00b8b26 100644 --- a/lib/src/search/search.dart +++ b/lib/src/search/search.dart @@ -1,17 +1,27 @@ +import 'dart:convert'; + import 'package:google_place/google_place.dart'; +import 'package:google_place/src/search/find_place_response/find_place_response.dart'; +import 'package:google_place/src/search/nearby_search_response/nearby_search_response.dart'; import 'package:google_place/src/utils/network_utility.dart'; class Search { static final _authority = 'maps.googleapis.com'; + static final _unencodedPathFindPlace = 'maps/api/place/findplacefromtext/json'; + static final _unencodedPathNearBySearch = 'maps/api/place/nearbysearch/json'; + static final _unencodedPathTextSearch = 'maps/api/place/textsearch/json'; + final String apiKEY; + final Map headers; + final String? proxyUrl; - Search(this.apiKEY, this.headers, this.proxyUrl); + const Search(this.apiKEY, this.headers, this.proxyUrl); /// A Find Place request takes a text input and returns a place. /// The input can be any kind of Places text data, such as a name, address, or phone number. @@ -41,7 +51,7 @@ class Search { Locationbias? locationbias, }) async { assert(input != ""); - var queryParameters = _createFindPlaceParameters( + final queryParameters = _createFindPlaceParameters( apiKEY, input, inputType, @@ -49,13 +59,14 @@ class Search { fields, locationbias, ); - - var uri = NetworkUtility.createUri( + final uri = NetworkUtility.createUri( proxyUrl, _authority, _unencodedPathFindPlace, queryParameters); - var response = await NetworkUtility.fetchUrl(uri, headers: headers); + final response = await NetworkUtility.fetchUrl(uri, headers: headers); + if (response != null) { - return FindPlaceResponse.parseFindPlaceResult(response); + return FindPlaceResponse.fromJson(jsonDecode(response)); } + return null; } @@ -98,7 +109,7 @@ class Search { /// [pagetoken] Optional parameters - Returns up to 20 results from a previously run search. Setting a /// pagetoken parameter will execute a search with the same parameters used previously — all parameters /// other than pagetoken will be ignored. - Future getNearBySearch( + Future getNearBySearch( Location location, int radius, { String? keyword, @@ -111,7 +122,7 @@ class Search { String? type, String? pagetoken, }) async { - var queryParameters = _createNearBySearchParameters( + final queryParameters = _createNearBySearchParameters( apiKEY, location, radius, @@ -125,13 +136,14 @@ class Search { type, pagetoken, ); - - var uri = + final uri = Uri.https(_authority, _unencodedPathNearBySearch, queryParameters); - var response = await NetworkUtility.fetchUrl(uri, headers: headers); + final response = await NetworkUtility.fetchUrl(uri, headers: headers); + if (response != null) { - return NearBySearchResponse.parseNearBySearchResult(response); + return NearbySearchResponse.fromJson(jsonDecode(response)); } + return null; } @@ -193,7 +205,7 @@ class Search { String? pagetoken, }) async { assert(query != ""); - var queryParameters = _createTextSearchParameters( + final queryParameters = _createTextSearchParameters( apiKEY, query, region, @@ -206,12 +218,14 @@ class Search { type, pagetoken, ); + final uri = + Uri.https(_authority, _unencodedPathTextSearch, queryParameters); + final response = await NetworkUtility.fetchUrl(uri, headers: headers); - var uri = Uri.https(_authority, _unencodedPathTextSearch, queryParameters); - var response = await NetworkUtility.fetchUrl(uri, headers: headers); if (response != null) { - return TextSearchResponse.parseTextSearchResult(response); + return TextSearchResponse.fromJson(jsonDecode(response)); } + return null; } diff --git a/lib/src/search/search_candidate.dart b/lib/src/search/search_candidate.dart deleted file mode 100644 index 8e77089..0000000 --- a/lib/src/search/search_candidate.dart +++ /dev/null @@ -1,136 +0,0 @@ -import 'package:google_place/src/models/geometry.dart'; -import 'package:google_place/src/models/opening_hours.dart'; -import 'package:google_place/src/models/photo.dart'; -import 'package:google_place/src/models/plus_code.dart'; - -class SearchCandidate { - /// [geometry] contains geometry information about the result, - /// generally including the location (geocode) of the place and (optionally) - /// the viewport identifying its general area of coverage. - final Geometry? geometry; - - /// [businessStatus] indicates the operational status of the place, if it is a business. - /// If no data exists, business_status is not returned. It can contain one of the following values: - /// OPERATIONAL - /// CLOSED_TEMPORARILY - /// CLOSED_PERMANENTLY - final String? businessStatus; - - /// [openingHours] show opening hours - final OpeningHours? openingHours; - - /// [photos] an array of photo objects, each containing a reference to an image. - final List? photos; - - /// [plusCode] is an encoded location reference, derived from latitude and longitude coordinates, - /// that represents an area: 1/8000th of a degree by 1/8000th of a degree (about 14m x 14m at the equator) or smaller. - /// Plus codes can be used as a replacement for street addresses in places where they do not exist - /// (where buildings are not numbered or streets are not named). - final PlusCode? plusCode; - - /// [formattedAddress] is a string containing the human-readable address of this place. - /// Often this address is equivalent to the "postal address". - final String? formattedAddress; - - /// [name] contains the human-readable name for the returned result. - /// For establishment results, this is usually the business name. - final String? name; - - /// [rating] contains the place's rating, from 1.0 to 5.0, based on aggregated user reviews. - final double? rating; - - /// [icon] contains the URL of a recommended icon which may be displayed to the user when indicating this result. - final String? icon; - - /// [id] contains id. - final String? id; - - /// [placeId] a textual identifier that uniquely identifies a place. To retrieve information about the place, - /// pass this identifier in the placeId field of a Places API request. For more information about place IDs. - final String? placeId; - - /// [priceLevel] The price level of the place, on a scale of 0 to 4. - /// The exact amount indicated by a specific value will vary from region to region. Price levels are interpreted as follows: - /// 0 — Free - /// 1 — Inexpensive - /// 2 — Moderate - /// 3 — Expensive - /// 4 — Very Expensive - final int? priceLevel; - - /// [reference] contains reference. - final String? reference; - - /// [scope] contains scope. - final String? scope; - - /// [types] contains an array of feature types describing the given result. See the list of supported types. - /// XML responses include multiple elements if more than one type is assigned to the result. - final List? types; - - /// [userRatingsTotal] is user ratings total. - final int? userRatingsTotal; - - /// [vicinity] contains a feature name of a nearby location. Often this feature refers to a street or - /// neighborhood within the given results. The vicinity property is only returned for a Nearby Search. - final String? vicinity; - - /// [permanentlyClosed] is a boolean flag indicating whether the place has shut down either permanently - /// or temporarily (value true). If the place is operational, or if no data is available, the flag is absent from the response. - @Deprecated( - 'permanently_closed is now deprecated. Instead, use business_status to get the operational status of businesses.') - final bool? permanentlyClosed; - - SearchCandidate({ - this.geometry, - this.businessStatus, - this.openingHours, - this.photos, - this.plusCode, - this.formattedAddress, - this.name, - this.rating, - this.icon, - this.id, - this.placeId, - this.priceLevel, - this.reference, - this.scope, - this.types, - this.userRatingsTotal, - this.vicinity, - this.permanentlyClosed, - }); - - factory SearchCandidate.fromJson(Map json) { - return SearchCandidate( - geometry: - json['geometry'] != null ? Geometry.fromJson(json['geometry']) : null, - businessStatus: json['business_status'], - openingHours: json['opening_hours'] != null - ? OpeningHours.fromJson(json['opening_hours']) - : null, - photos: json['photos'] != null - ? json['photos'].map((json) => Photo.fromJson(json)).toList() - : null, - plusCode: json['plus_code'] != null - ? PlusCode.fromJson(json['plus_code']) - : null, - formattedAddress: json['formatted_address'], - name: json['name'], - rating: json['rating'] != null ? json['rating'].toDouble() : null, - icon: json['icon'], - id: json['id'], - placeId: json['place_id'], - priceLevel: json['price_level'], - reference: json['reference'], - scope: json['scope'], - types: json['types'] != null - ? (json['types'] as List).cast() - : null, - userRatingsTotal: json['user_ratings_total'], - vicinity: json['vicinity'], - permanentlyClosed: json['permanently_closed'], - ); - } -} diff --git a/lib/src/search/search_result.dart b/lib/src/search/search_result/search_result.dart similarity index 72% rename from lib/src/search/search_result.dart rename to lib/src/search/search_result/search_result.dart index 125ac62..f884e59 100644 --- a/lib/src/search/search_result.dart +++ b/lib/src/search/search_result/search_result.dart @@ -1,8 +1,12 @@ -import 'package:google_place/src/models/geometry.dart'; -import 'package:google_place/src/models/opening_hours.dart'; -import 'package:google_place/src/models/photo.dart'; -import 'package:google_place/src/models/plus_code.dart'; +import 'package:google_place/src/models/geometry/geometry.dart'; +import 'package:google_place/src/models/photo/photo.dart'; +import 'package:google_place/src/models/plus_code/plus_code.dart'; +import 'package:google_place/src/models/time_and_day/time_and_day.dart'; +import 'package:json_annotation/json_annotation.dart'; +part 'search_result.g.dart'; + +@JsonSerializable() class SearchResult { /// [geometry] contains geometry information about the result, /// generally including the location (geocode) of the place and (optionally) @@ -17,7 +21,7 @@ class SearchResult { final String? businessStatus; /// [openingHours] show opening hours - final OpeningHours? openingHours; + final TimeAndDay? openingHours; /// [photos] an array of photo objects, each containing a reference to an image. final List? photos; @@ -81,7 +85,7 @@ class SearchResult { 'permanently_closed is now deprecated. Instead, use business_status to get the operational status of businesses.') final bool? permanentlyClosed; - SearchResult({ + const SearchResult({ this.geometry, this.businessStatus, this.openingHours, @@ -102,35 +106,8 @@ class SearchResult { this.permanentlyClosed, }); - factory SearchResult.fromJson(Map json) { - return SearchResult( - geometry: - json['geometry'] != null ? Geometry.fromJson(json['geometry']) : null, - businessStatus: json['business_status'], - openingHours: json['opening_hours'] != null - ? OpeningHours.fromJson(json['opening_hours']) - : null, - photos: json['photos'] != null - ? json['photos'].map((json) => Photo.fromJson(json)).toList() - : null, - plusCode: json['plus_code'] != null - ? PlusCode.fromJson(json['plus_code']) - : null, - formattedAddress: json['formatted_address'], - name: json['name'], - rating: json['rating'] != null ? json['rating'].toDouble() : null, - icon: json['icon'], - id: json['id'], - placeId: json['place_id'], - priceLevel: json['price_level'], - reference: json['reference'], - scope: json['scope'], - types: json['types'] != null - ? (json['types'] as List).cast() - : null, - userRatingsTotal: json['user_ratings_total'], - vicinity: json['vicinity'], - permanentlyClosed: json['permanently_closed'], - ); - } + factory SearchResult.fromJson(Map json) => + _$SearchResultFromJson(json); + + Map toJson() => _$SearchResultToJson(this); } diff --git a/lib/src/search/search_result/search_result.g.dart b/lib/src/search/search_result/search_result.g.dart new file mode 100644 index 0000000..3bd64fe --- /dev/null +++ b/lib/src/search/search_result/search_result.g.dart @@ -0,0 +1,59 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'search_result.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +SearchResult _$SearchResultFromJson(Map json) => SearchResult( + geometry: json['geometry'] == null + ? null + : Geometry.fromJson(json['geometry'] as Map), + businessStatus: json['business_status'] as String?, + openingHours: json['opening_hours'] == null + ? null + : TimeAndDay.fromJson(json['opening_hours'] as Map), + photos: (json['photos'] as List?) + ?.map((e) => Photo.fromJson(e as Map)) + .toList(), + plusCode: json['plus_code'] == null + ? null + : PlusCode.fromJson(json['plus_code'] as Map), + formattedAddress: json['formatted_address'] as String?, + name: json['name'] as String?, + rating: (json['rating'] as num?)?.toDouble(), + icon: json['icon'] as String?, + id: json['id'] as String?, + placeId: json['place_id'] as String?, + priceLevel: json['price_level'] as int?, + reference: json['reference'] as String?, + scope: json['scope'] as String?, + types: + (json['types'] as List?)?.map((e) => e as String).toList(), + userRatingsTotal: json['user_ratings_total'] as int?, + vicinity: json['vicinity'] as String?, + permanentlyClosed: json['permanently_closed'] as bool?, + ); + +Map _$SearchResultToJson(SearchResult instance) => + { + 'geometry': instance.geometry, + 'business_status': instance.businessStatus, + 'opening_hours': instance.openingHours, + 'photos': instance.photos, + 'plus_code': instance.plusCode, + 'formatted_address': instance.formattedAddress, + 'name': instance.name, + 'rating': instance.rating, + 'icon': instance.icon, + 'id': instance.id, + 'place_id': instance.placeId, + 'price_level': instance.priceLevel, + 'reference': instance.reference, + 'scope': instance.scope, + 'types': instance.types, + 'user_ratings_total': instance.userRatingsTotal, + 'vicinity': instance.vicinity, + 'permanently_closed': instance.permanentlyClosed, + }; diff --git a/lib/src/search/text_search_response.dart b/lib/src/search/text_search_response.dart index 52d44d5..3253be9 100644 --- a/lib/src/search/text_search_response.dart +++ b/lib/src/search/text_search_response.dart @@ -1,17 +1,23 @@ -import 'dart:convert'; +import 'package:google_place/src/models/debug_log/debug_log.dart'; +import 'package:google_place/src/search/search_result/search_result.dart'; +import 'package:json_annotation/json_annotation.dart'; -import 'package:google_place/src/models/debug_log.dart'; -import 'package:google_place/src/search/search_result.dart'; +part 'text_search_response.g.dart'; /// The Text Search response contains html Attributions and search results and status +@JsonSerializable() class TextSearchResponse { final String? status; + final List? htmlAttributions; + final String? nextPageToken; + final DebugLog? debugLog; + final List? results; - TextSearchResponse({ + const TextSearchResponse({ this.status, this.htmlAttributions, this.nextPageToken, @@ -19,26 +25,8 @@ class TextSearchResponse { this.results, }); - factory TextSearchResponse.fromJson(Map json) { - return TextSearchResponse( - status: json['status'], - htmlAttributions: json['html_attributions'] != null - ? (json['html_attributions'] as List).cast() - : null, - nextPageToken: json['next_page_token'], - debugLog: json['debug_log'] != null - ? DebugLog.fromJson(json['debug_log']) - : null, - results: json['results'] != null - ? json['results'] - .map((json) => SearchResult.fromJson(json)) - .toList() - : null, - ); - } - - static TextSearchResponse parseTextSearchResult(String responseBody) { - final parsed = json.decode(responseBody).cast(); - return TextSearchResponse.fromJson(parsed); - } + factory TextSearchResponse.fromJson(Map json) => + _$TextSearchResponseFromJson(json); + + Map toJson() => _$TextSearchResponseToJson(this); } diff --git a/lib/src/search/text_search_response.g.dart b/lib/src/search/text_search_response.g.dart new file mode 100644 index 0000000..b567cb9 --- /dev/null +++ b/lib/src/search/text_search_response.g.dart @@ -0,0 +1,31 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'text_search_response.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +TextSearchResponse _$TextSearchResponseFromJson(Map json) => + TextSearchResponse( + status: json['status'] as String?, + htmlAttributions: (json['html_attributions'] as List?) + ?.map((e) => e as String) + .toList(), + nextPageToken: json['next_page_token'] as String?, + debugLog: json['debug_log'] == null + ? null + : DebugLog.fromJson(json['debug_log'] as Map), + results: (json['results'] as List?) + ?.map((e) => SearchResult.fromJson(e as Map)) + .toList(), + ); + +Map _$TextSearchResponseToJson(TextSearchResponse instance) => + { + 'status': instance.status, + 'html_attributions': instance.htmlAttributions, + 'next_page_token': instance.nextPageToken, + 'debug_log': instance.debugLog, + 'results': instance.results, + }; diff --git a/lib/src/utils/network_utility.dart b/lib/src/utils/network_utility.dart index 1e9ecc3..4f6c567 100644 --- a/lib/src/utils/network_utility.dart +++ b/lib/src/utils/network_utility.dart @@ -10,6 +10,7 @@ class NetworkUtility { try { final response = await http.get(uri, headers: headers).timeout(GooglePlace.timeout); + if (response.statusCode == 200) { return response.body; } @@ -24,8 +25,12 @@ class NetworkUtility { /// [authority] Required parameters - the domain name of the google server, usually https://maps.googleapis.com /// [unencodedGoogleMapsPath] Required parameters - the path to the api, usually something like maps/api/... /// [queryParameters] Required parameters - a map of query parameters to be appended to the url - static Uri createUri(String? proxyUrl, String authority, - String unencodedGoogleMapsPath, Map queryParameters) { + static Uri createUri( + String? proxyUrl, + String authority, + String unencodedGoogleMapsPath, + Map queryParameters, + ) { Uri uri; final googleApiUri = Uri.https( authority, @@ -92,7 +97,7 @@ class NetworkUtility { } else { uri = googleApiUri; } - // print(uri.toString()); + return uri; } } diff --git a/pubspec.lock b/pubspec.lock index 31ab8d0..f121ecc 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1,13 +1,34 @@ # Generated by pub # See https://dart.dev/tools/pub/glossary#lockfile packages: + _fe_analyzer_shared: + dependency: transitive + description: + name: _fe_analyzer_shared + url: "https://pub.dartlang.org" + source: hosted + version: "39.0.0" + analyzer: + dependency: transitive + description: + name: analyzer + url: "https://pub.dartlang.org" + source: hosted + version: "4.0.0" + args: + dependency: transitive + description: + name: args + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.0" async: dependency: transitive description: name: async url: "https://pub.dartlang.org" source: hosted - version: "2.6.1" + version: "2.8.2" boolean_selector: dependency: transitive description: @@ -15,20 +36,83 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + build: + dependency: transitive + description: + name: build + url: "https://pub.dartlang.org" + source: hosted + version: "2.3.0" + build_config: + dependency: transitive + description: + name: build_config + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" + build_daemon: + dependency: transitive + description: + name: build_daemon + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" + build_resolvers: + dependency: transitive + description: + name: build_resolvers + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.8" + build_runner: + dependency: "direct dev" + description: + name: build_runner + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.10" + build_runner_core: + dependency: transitive + description: + name: build_runner_core + url: "https://pub.dartlang.org" + source: hosted + version: "7.2.3" + built_collection: + dependency: transitive + description: + name: built_collection + url: "https://pub.dartlang.org" + source: hosted + version: "5.1.1" + built_value: + dependency: transitive + description: + name: built_value + url: "https://pub.dartlang.org" + source: hosted + version: "8.2.3" characters: dependency: transitive description: name: characters url: "https://pub.dartlang.org" source: hosted - version: "1.1.0" + version: "1.2.0" charcode: dependency: transitive description: name: charcode url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.3.1" + checked_yaml: + dependency: transitive + description: + name: checked_yaml + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.1" clock: dependency: transitive description: @@ -36,6 +120,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.0" + code_builder: + dependency: transitive + description: + name: code_builder + url: "https://pub.dartlang.org" + source: hosted + version: "4.1.0" collection: dependency: transitive description: @@ -43,6 +134,27 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.15.0" + convert: + dependency: transitive + description: + name: convert + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.1" + crypto: + dependency: transitive + description: + name: crypto + url: "https://pub.dartlang.org" + source: hosted + version: "3.0.2" + dart_style: + dependency: transitive + description: + name: dart_style + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.3" fake_async: dependency: transitive description: @@ -50,6 +162,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.2.0" + file: + dependency: transitive + description: + name: file + url: "https://pub.dartlang.org" + source: hosted + version: "6.1.2" + fixnum: + dependency: transitive + description: + name: fixnum + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" flutter: dependency: transitive description: flutter @@ -60,6 +186,27 @@ packages: description: flutter source: sdk version: "0.0.0" + frontend_server_client: + dependency: transitive + description: + name: frontend_server_client + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.2" + glob: + dependency: transitive + description: + name: glob + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" + graphs: + dependency: transitive + description: + name: graphs + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.0" http: dependency: "direct main" description: @@ -67,6 +214,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "0.13.3" + http_multi_server: + dependency: transitive + description: + name: http_multi_server + url: "https://pub.dartlang.org" + source: hosted + version: "3.2.0" http_parser: dependency: transitive description: @@ -74,20 +228,76 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.0.0" + io: + dependency: transitive + description: + name: io + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" + js: + dependency: transitive + description: + name: js + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.4" + json_annotation: + dependency: "direct main" + description: + name: json_annotation + url: "https://pub.dartlang.org" + source: hosted + version: "4.5.0" + json_serializable: + dependency: "direct dev" + description: + name: json_serializable + url: "https://pub.dartlang.org" + source: hosted + version: "6.2.0" + logging: + dependency: transitive + description: + name: logging + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.2" matcher: dependency: transitive description: name: matcher url: "https://pub.dartlang.org" source: hosted - version: "0.12.10" + version: "0.12.11" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + url: "https://pub.dartlang.org" + source: hosted + version: "0.1.3" meta: dependency: transitive description: name: meta url: "https://pub.dartlang.org" source: hosted - version: "1.3.0" + version: "1.7.0" + mime: + dependency: transitive + description: + name: mime + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + package_config: + dependency: transitive + description: + name: package_config + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.2" path: dependency: transitive description: @@ -102,11 +312,60 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.11.1" + pool: + dependency: transitive + description: + name: pool + url: "https://pub.dartlang.org" + source: hosted + version: "1.5.0" + pub_semver: + dependency: transitive + description: + name: pub_semver + url: "https://pub.dartlang.org" + source: hosted + version: "2.1.1" + pubspec_parse: + dependency: transitive + description: + name: pubspec_parse + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.0" + shelf: + dependency: transitive + description: + name: shelf + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.0" + shelf_web_socket: + dependency: transitive + description: + name: shelf_web_socket + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" sky_engine: dependency: transitive description: flutter source: sdk version: "0.0.99" + source_gen: + dependency: transitive + description: + name: source_gen + url: "https://pub.dartlang.org" + source: hosted + version: "1.2.2" + source_helper: + dependency: transitive + description: + name: source_helper + url: "https://pub.dartlang.org" + source: hosted + version: "1.3.2" source_span: dependency: transitive description: @@ -128,6 +387,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + stream_transform: + dependency: transitive + description: + name: stream_transform + url: "https://pub.dartlang.org" + source: hosted + version: "2.0.0" string_scanner: dependency: transitive description: @@ -148,7 +414,14 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.3.0" + version: "0.4.8" + timing: + dependency: transitive + description: + name: timing + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" typed_data: dependency: transitive description: @@ -162,6 +435,27 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.0" + version: "2.1.1" + watcher: + dependency: transitive + description: + name: watcher + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" + web_socket_channel: + dependency: transitive + description: + name: web_socket_channel + url: "https://pub.dartlang.org" + source: hosted + version: "2.2.0" + yaml: + dependency: transitive + description: + name: yaml + url: "https://pub.dartlang.org" + source: hosted + version: "3.1.0" sdks: - dart: ">=2.12.0 <3.0.0" + dart: ">=2.16.0 <3.0.0" diff --git a/pubspec.yaml b/pubspec.yaml index c5808ca..2815e42 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1,5 +1,7 @@ name: google_place -description: A new Flutter package for handle google place api that place search and details and photos and autocomplete and query autocomplete requests are available +description: A Flutter package for handle google place api that place search and + details and photos and autocomplete and query autocomplete requests are + available version: 0.4.7 homepage: https://github.com/bazrafkan/google_place @@ -8,7 +10,10 @@ environment: dependencies: http: ^0.13.3 + json_annotation: ^4.5.0 dev_dependencies: + build_runner: ^2.1.10 flutter_test: sdk: flutter + json_serializable: ^6.2.0 From 495d330393d10c771d9062098511f59f3a6b8137 Mon Sep 17 00:00:00 2001 From: Nolence Date: Fri, 29 Apr 2022 12:25:09 -0600 Subject: [PATCH 02/12] fixes linter warnings --- analysis_options.yaml | 29 +++ example/lib/main.dart | 105 ++++---- example/pubspec.lock | 14 ++ example/pubspec.yaml | 2 + lib/google_place.dart | 12 +- lib/src/autocomplete/autocomplete.dart | 17 +- lib/src/details/details.dart | 14 +- .../details_result/details_result.dart | 3 +- lib/src/models/input_type.dart | 5 +- lib/src/models/locationbias.dart | 3 +- lib/src/models/rank_by.dart | 5 +- lib/src/photos/photos.dart | 22 +- .../query_autocomplete.dart | 17 +- lib/src/search/search.dart | 235 +++++------------- .../search/search_result/search_result.dart | 3 +- lib/src/utils/network_utility.dart | 173 ++++++------- pubspec.lock | 14 ++ pubspec.yaml | 1 + test/google_place_test.dart | 14 +- 19 files changed, 328 insertions(+), 360 deletions(-) create mode 100644 analysis_options.yaml diff --git a/analysis_options.yaml b/analysis_options.yaml new file mode 100644 index 0000000..09f7bbf --- /dev/null +++ b/analysis_options.yaml @@ -0,0 +1,29 @@ +include: package:flutter_lints/flutter.yaml + +analyzer: + exclude: + - "**/*.g.dart" + - "**/*.freezed.dart" + - "**/*.gr.dart" + - "lib/generated/**" + - "lib/firebase_options.dart" + strong-mode: + implicit-casts: false + implicit-dynamic: false + errors: + invalid_annotation_target: ignore + +linter: + rules: + - avoid_shadowing_type_parameters + - parameter_assignments + - require_trailing_commas + - only_throw_errors + - always_use_package_imports + - avoid_dynamic_calls + - prefer_void_to_null + - always_declare_return_types + - avoid_classes_with_only_static_members + - unnecessary_lambdas + - unnecessary_const + - avoid_void_async diff --git a/example/lib/main.dart b/example/lib/main.dart index 791718b..085abce 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -4,26 +4,28 @@ import 'package:flutter/material.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:google_place/google_place.dart'; -void main() async { +Future main() async { WidgetsFlutterBinding.ensureInitialized(); await DotEnv().load('.env'); - runApp(MyApp()); + runApp(const MyApp()); } class MyApp extends StatelessWidget { + const MyApp({Key key}) : super(key: key); + @override Widget build(BuildContext context) { return MaterialApp( title: 'Flutter Demo', - theme: ThemeData( - primarySwatch: Colors.blue, - ), - home: HomePage(), + theme: ThemeData(primarySwatch: Colors.blue), + home: const HomePage(), ); } } class HomePage extends StatefulWidget { + const HomePage({Key key}) : super(key: key); + @override _HomePageState createState() => _HomePageState(); } @@ -44,12 +46,12 @@ class _HomePageState extends State { return Scaffold( body: SafeArea( child: Container( - margin: EdgeInsets.only(right: 20, left: 20, top: 20), + margin: const EdgeInsets.only(right: 20, left: 20, top: 20), child: Column( mainAxisSize: MainAxisSize.min, children: [ TextField( - decoration: InputDecoration( + decoration: const InputDecoration( labelText: "Search", focusedBorder: OutlineInputBorder( borderSide: BorderSide( @@ -68,7 +70,7 @@ class _HomePageState extends State { if (value.isNotEmpty) { autoCompleteSearch(value); } else { - if (predictions.length > 0 && mounted) { + if (predictions.isNotEmpty && mounted) { setState(() { predictions = []; }); @@ -76,15 +78,13 @@ class _HomePageState extends State { } }, ), - SizedBox( - height: 10, - ), + const SizedBox(height: 10), Expanded( child: ListView.builder( itemCount: predictions.length, itemBuilder: (context, index) { return ListTile( - leading: CircleAvatar( + leading: const CircleAvatar( child: Icon( Icons.pin_drop, color: Colors.white, @@ -93,7 +93,7 @@ class _HomePageState extends State { title: Text(predictions[index].description), onTap: () { debugPrint(predictions[index].placeId); - Navigator.push( + Navigator.push( context, MaterialPageRoute( builder: (context) => DetailsPage( @@ -108,7 +108,7 @@ class _HomePageState extends State { ), ), Container( - margin: EdgeInsets.only(top: 10, bottom: 10), + margin: const EdgeInsets.only(top: 10, bottom: 10), child: Image.asset("assets/powered_by_google.png"), ), ], @@ -118,7 +118,7 @@ class _HomePageState extends State { ); } - void autoCompleteSearch(String value) async { + Future autoCompleteSearch(String value) async { var result = await googlePlace.autocomplete.get(value); if (result != null && result.predictions != null && mounted) { setState(() { @@ -129,28 +129,25 @@ class _HomePageState extends State { } class DetailsPage extends StatefulWidget { + const DetailsPage({Key key, this.placeId, this.googlePlace}) + : super(key: key); + final String placeId; - final GooglePlace googlePlace; - DetailsPage({Key key, this.placeId, this.googlePlace}) : super(key: key); + final GooglePlace googlePlace; @override - _DetailsPageState createState() => - _DetailsPageState(this.placeId, this.googlePlace); + State createState() => _DetailsPageState(); } class _DetailsPageState extends State { - final String placeId; - final GooglePlace googlePlace; - - _DetailsPageState(this.placeId, this.googlePlace); - DetailsResult detailsResult; + List images = []; @override void initState() { - getDetils(this.placeId); + getDetails(widget.placeId); super.initState(); } @@ -158,29 +155,29 @@ class _DetailsPageState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text("Details"), + title: const Text("Details"), backgroundColor: Colors.blueAccent, ), floatingActionButton: FloatingActionButton( backgroundColor: Colors.blueAccent, onPressed: () { - getDetils(this.placeId); + getDetails(widget.placeId); }, - child: Icon(Icons.refresh), + child: const Icon(Icons.refresh), ), body: SafeArea( child: Container( - margin: EdgeInsets.only(right: 20, left: 20, top: 20), + margin: const EdgeInsets.only(right: 20, left: 20, top: 20), child: Column( mainAxisSize: MainAxisSize.min, children: [ - Container( + SizedBox( height: 200, child: ListView.builder( scrollDirection: Axis.horizontal, itemCount: images.length, itemBuilder: (context, index) { - return Container( + return SizedBox( width: 250, child: Card( elevation: 4, @@ -199,9 +196,7 @@ class _DetailsPageState extends State { }, ), ), - SizedBox( - height: 10, - ), + const SizedBox(height: 10), Expanded( child: Card( elevation: 4, @@ -211,8 +206,8 @@ class _DetailsPageState extends State { child: ListView( children: [ Container( - margin: EdgeInsets.only(left: 15, top: 10), - child: Text( + margin: const EdgeInsets.only(left: 15, top: 10), + child: const Text( "Details", style: TextStyle( fontSize: 20, @@ -222,18 +217,18 @@ class _DetailsPageState extends State { ), detailsResult != null && detailsResult.types != null ? Container( - margin: EdgeInsets.only(left: 15, top: 10), + margin: const EdgeInsets.only(left: 15, top: 10), height: 50, child: ListView.builder( scrollDirection: Axis.horizontal, itemCount: detailsResult.types.length, itemBuilder: (context, index) { return Container( - margin: EdgeInsets.only(right: 10), + margin: const EdgeInsets.only(right: 10), child: Chip( label: Text( detailsResult.types[index], - style: TextStyle( + style: const TextStyle( color: Colors.white, ), ), @@ -245,9 +240,9 @@ class _DetailsPageState extends State { ) : Container(), Container( - margin: EdgeInsets.only(left: 15, top: 10), + margin: const EdgeInsets.only(left: 15, top: 10), child: ListTile( - leading: CircleAvatar( + leading: const CircleAvatar( child: Icon(Icons.location_on), ), title: Text( @@ -259,9 +254,9 @@ class _DetailsPageState extends State { ), ), Container( - margin: EdgeInsets.only(left: 15, top: 10), + margin: const EdgeInsets.only(left: 15, top: 10), child: ListTile( - leading: CircleAvatar( + leading: const CircleAvatar( child: Icon(Icons.location_searching), ), title: Text( @@ -274,9 +269,9 @@ class _DetailsPageState extends State { ), ), Container( - margin: EdgeInsets.only(left: 15, top: 10), + margin: const EdgeInsets.only(left: 15, top: 10), child: ListTile( - leading: CircleAvatar( + leading: const CircleAvatar( child: Icon(Icons.timelapse), ), title: Text( @@ -288,9 +283,9 @@ class _DetailsPageState extends State { ), ), Container( - margin: EdgeInsets.only(left: 15, top: 10), + margin: const EdgeInsets.only(left: 15, top: 10), child: ListTile( - leading: CircleAvatar( + leading: const CircleAvatar( child: Icon(Icons.rate_review), ), title: Text( @@ -302,9 +297,9 @@ class _DetailsPageState extends State { ), ), Container( - margin: EdgeInsets.only(left: 15, top: 10), + margin: const EdgeInsets.only(left: 15, top: 10), child: ListTile( - leading: CircleAvatar( + leading: const CircleAvatar( child: Icon(Icons.attach_money), ), title: Text( @@ -320,7 +315,7 @@ class _DetailsPageState extends State { ), ), Container( - margin: EdgeInsets.only(top: 20, bottom: 10), + margin: const EdgeInsets.only(top: 20, bottom: 10), child: Image.asset("assets/powered_by_google.png"), ), ], @@ -330,8 +325,8 @@ class _DetailsPageState extends State { ); } - void getDetils(String placeId) async { - var result = await this.googlePlace.details.get(placeId); + Future getDetails(String placeId) async { + final result = await widget.googlePlace.details.get(widget.placeId); if (result != null && result.result != null && mounted) { setState(() { detailsResult = result.result; @@ -346,8 +341,8 @@ class _DetailsPageState extends State { } } - void getPhoto(String photoReference) async { - var result = await this.googlePlace.photos.get(photoReference, null, 400); + Future getPhoto(String photoReference) async { + var result = await widget.googlePlace.photos.get(photoReference, null, 400); if (result != null && mounted) { setState(() { images.add(result); diff --git a/example/pubspec.lock b/example/pubspec.lock index f22c74f..022adba 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -69,6 +69,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" flutter_test: dependency: "direct dev" description: flutter @@ -102,6 +109,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "4.5.0" + lints: + dependency: transitive + description: + name: lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" matcher: dependency: transitive description: diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 90933e5..33726ec 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -1,6 +1,7 @@ name: example description: A new Flutter project. version: 1.0.0+1 +publish_to: none environment: sdk: ">=2.1.0 <3.0.0" @@ -14,6 +15,7 @@ dependencies: path: ../ dev_dependencies: + flutter_lints: ^1.0.0 flutter_test: sdk: flutter diff --git a/lib/google_place.dart b/lib/google_place.dart index 85f60ca..f125c65 100644 --- a/lib/google_place.dart +++ b/lib/google_place.dart @@ -56,7 +56,7 @@ class GooglePlace { late QueryAutocomplete queryAutocomplete; /// [timeout] timeout for http call. - static Duration timeout = Duration(milliseconds: 1500); + static Duration timeout = const Duration(milliseconds: 1500); /// Optional headers to pass on each request final Map headers; @@ -71,10 +71,10 @@ class GooglePlace { this.headers = const {}, this.proxyUrl, }) { - this.search = Search(apiKEY, headers, proxyUrl); - this.details = Details(apiKEY, headers, proxyUrl); - this.photos = Photos(apiKEY, headers, proxyUrl); - this.autocomplete = Autocomplete(apiKEY, headers, proxyUrl); - this.queryAutocomplete = QueryAutocomplete(apiKEY, headers, proxyUrl); + search = Search(apiKEY, headers, proxyUrl); + details = Details(apiKEY, headers, proxyUrl); + photos = Photos(apiKEY, headers, proxyUrl); + autocomplete = Autocomplete(apiKEY, headers, proxyUrl); + queryAutocomplete = QueryAutocomplete(apiKEY, headers, proxyUrl); } } diff --git a/lib/src/autocomplete/autocomplete.dart b/lib/src/autocomplete/autocomplete.dart index f4701d3..b105dd6 100644 --- a/lib/src/autocomplete/autocomplete.dart +++ b/lib/src/autocomplete/autocomplete.dart @@ -1,13 +1,12 @@ import 'dart:convert'; import 'package:google_place/google_place.dart'; -import 'package:google_place/src/autocomplete/autocomplete_response/autocomplete_response.dart'; import 'package:google_place/src/utils/network_utility.dart'; class Autocomplete { - static final _authority = 'maps.googleapis.com'; + static const _authority = 'maps.googleapis.com'; - static final _unencodedPath = 'maps/api/place/autocomplete/json'; + static const _unencodedPath = 'maps/api/place/autocomplete/json'; final String apiKEY; @@ -110,17 +109,19 @@ class Autocomplete { strictbounds, ); - var uri = NetworkUtility.createUri( + var uri = createUri( proxyUrl, _authority, _unencodedPath, queryParameters, ); - final response = await NetworkUtility.fetchUrl(uri, headers: headers); + final response = await fetchUrl(uri, headers: headers); if (response != null) { - return AutocompleteResponse.fromJson(jsonDecode(response)); + return AutocompleteResponse.fromJson( + jsonDecode(response) as Map, + ); } return null; @@ -221,7 +222,7 @@ class Autocomplete { : _unencodedPath, queryParameters, ); - return await NetworkUtility.fetchUrl(uri, headers: headers); + return await fetchUrl(uri, headers: headers); } /// Prepare query Parameters @@ -257,7 +258,7 @@ class Autocomplete { }; // TODO: What is this doing? - if (components != null && components.length > 0) { + if (components != null && components.isNotEmpty) { String result = ''; for (int i = 0; i < components.length; i++) { result += '${components[i].component}:${components[i].value}'; diff --git a/lib/src/details/details.dart b/lib/src/details/details.dart index f2c4d39..54035c9 100644 --- a/lib/src/details/details.dart +++ b/lib/src/details/details.dart @@ -4,9 +4,9 @@ import 'package:google_place/src/details/details_response/details_response.dart' import 'package:google_place/src/utils/network_utility.dart'; class Details { - static final _authority = 'maps.googleapis.com'; + static const _authority = 'maps.googleapis.com'; - static final _unencodedPath = 'maps/api/place/details/json'; + static const _unencodedPath = 'maps/api/place/details/json'; final String apiKEY; @@ -57,16 +57,18 @@ class Details { sessionToken, fields, ); - final uri = NetworkUtility.createUri( + final uri = createUri( proxyUrl, _authority, _unencodedPath, queryParameters, ); - final response = await NetworkUtility.fetchUrl(uri, headers: headers); + final response = await fetchUrl(uri, headers: headers); if (response != null) { - return DetailsResponse.fromJson(jsonDecode(response)); + return DetailsResponse.fromJson( + jsonDecode(response) as Map, + ); } return null; @@ -121,7 +123,7 @@ class Details { queryParameters, ); - return await NetworkUtility.fetchUrl(uri, headers: headers); + return await fetchUrl(uri, headers: headers); } /// Prepare query Parameters diff --git a/lib/src/details/details_result/details_result.dart b/lib/src/details/details_result/details_result.dart index 0fe4c88..9455357 100644 --- a/lib/src/details/details_result/details_result.dart +++ b/lib/src/details/details_result/details_result.dart @@ -114,7 +114,8 @@ class DetailsResult { /// [permanentlyClosed] is a boolean flag indicating whether the place has shut down either permanently /// or temporarily (value true). If the place is operational, or if no data is available, the flag is absent from the response. @Deprecated( - 'permanently_closed is now deprecated. Instead, use business_status to get the operational status of businesses.') + 'permanently_closed is now deprecated. Instead, use business_status to get the operational status of businesses.', + ) final bool? permanentlyClosed; const DetailsResult({ diff --git a/lib/src/models/input_type.dart b/lib/src/models/input_type.dart index a99c132..ad700e7 100644 --- a/lib/src/models/input_type.dart +++ b/lib/src/models/input_type.dart @@ -1,4 +1,7 @@ +import 'package:json_annotation/json_annotation.dart'; + /// [InputType] - The type of input. This can be one of either textquery or phonenumber. /// Phone numbers must be in international format (prefixed by a plus sign ("+"), /// followed by the country code, then the phone number itself). -enum InputType { TextQuery, PhoneNumber } +@JsonEnum(fieldRename: FieldRename.snake) +enum InputType { textQuery, phoneNumber } diff --git a/lib/src/models/locationbias.dart b/lib/src/models/locationbias.dart index a051f37..7498104 100644 --- a/lib/src/models/locationbias.dart +++ b/lib/src/models/locationbias.dart @@ -38,8 +38,9 @@ class Locationbias { assert(point == null); assert(circular == null); } - if (ipbias == null || ipbias!) + if (ipbias == null || ipbias!) { assert(point != null && circular != null && rectangular != null); + } } } diff --git a/lib/src/models/rank_by.dart b/lib/src/models/rank_by.dart index bfc3cb4..001d05c 100644 --- a/lib/src/models/rank_by.dart +++ b/lib/src/models/rank_by.dart @@ -1 +1,4 @@ -enum RankBy { Prominence, Distance } +import 'package:json_annotation/json_annotation.dart'; + +@JsonEnum(fieldRename: FieldRename.snake) +enum RankBy { prominence, distance } diff --git a/lib/src/photos/photos.dart b/lib/src/photos/photos.dart index 4e61b53..3d151ee 100644 --- a/lib/src/photos/photos.dart +++ b/lib/src/photos/photos.dart @@ -3,13 +3,17 @@ import 'dart:typed_data'; import 'package:google_place/src/utils/network_utility.dart'; class Photos { - static final _authority = 'maps.googleapis.com'; - static final _unencodedPath = 'maps/api/place/photo'; + static const _authority = 'maps.googleapis.com'; + + static const _unencodedPath = 'maps/api/place/photo'; + final String apiKEY; + final Map headers; + final String? proxyUrl; - Photos(this.apiKEY, this.headers, this.proxyUrl); + const Photos(this.apiKEY, this.headers, this.proxyUrl); /// The Place Photo service, part of the Places API, is a read- only API that allows you to /// add high quality photographic content to your application. The Place Photo service gives @@ -40,9 +44,13 @@ class Photos { maxHeight, maxWidth, ); - var uri = NetworkUtility.createUri( - proxyUrl, _authority, _unencodedPath, queryParameters); - var response = await NetworkUtility.fetchUrl(uri, headers: headers); + var uri = createUri( + proxyUrl, + _authority, + _unencodedPath, + queryParameters, + ); + var response = await fetchUrl(uri, headers: headers); if (response != null) { List list = response.codeUnits; return Uint8List.fromList(list); @@ -86,7 +94,7 @@ class Photos { : _unencodedPath, queryParameters, ); - return await NetworkUtility.fetchUrl(uri, headers: headers); + return await fetchUrl(uri, headers: headers); } /// Prepare query Parameters diff --git a/lib/src/query_autocomplete/query_autocomplete.dart b/lib/src/query_autocomplete/query_autocomplete.dart index e460036..33c1da8 100644 --- a/lib/src/query_autocomplete/query_autocomplete.dart +++ b/lib/src/query_autocomplete/query_autocomplete.dart @@ -1,13 +1,12 @@ import 'dart:convert'; import 'package:google_place/google_place.dart'; -import 'package:google_place/src/autocomplete/autocomplete_response/autocomplete_response.dart'; import 'package:google_place/src/utils/network_utility.dart'; class QueryAutocomplete { - static final _authority = 'maps.googleapis.com'; + static const _authority = 'maps.googleapis.com'; - static final _unencodedPath = 'maps/api/place/queryautocomplete/json'; + static const _unencodedPath = 'maps/api/place/queryautocomplete/json'; final String apiKEY; @@ -55,16 +54,18 @@ class QueryAutocomplete { radius, language, ); - final uri = NetworkUtility.createUri( + final uri = createUri( proxyUrl, _authority, _unencodedPath, queryParameters, ); - final response = await NetworkUtility.fetchUrl(uri, headers: headers); + final response = await fetchUrl(uri, headers: headers); if (response != null) { - return AutocompleteResponse.fromJson(jsonDecode(response)); + return AutocompleteResponse.fromJson( + jsonDecode(response) as Map, + ); } return null; @@ -108,14 +109,14 @@ class QueryAutocomplete { radius, language, ); - final uri = NetworkUtility.createUri( + final uri = createUri( proxyUrl, _authority, _unencodedPath, queryParameters, ); - return await NetworkUtility.fetchUrl(uri, headers: headers); + return await fetchUrl(uri, headers: headers); } /// Prepare query Parameters diff --git a/lib/src/search/search.dart b/lib/src/search/search.dart index 00b8b26..75f95aa 100644 --- a/lib/src/search/search.dart +++ b/lib/src/search/search.dart @@ -1,19 +1,17 @@ import 'dart:convert'; import 'package:google_place/google_place.dart'; -import 'package:google_place/src/search/find_place_response/find_place_response.dart'; -import 'package:google_place/src/search/nearby_search_response/nearby_search_response.dart'; import 'package:google_place/src/utils/network_utility.dart'; class Search { - static final _authority = 'maps.googleapis.com'; + static const _authority = 'maps.googleapis.com'; - static final _unencodedPathFindPlace = + static const _unencodedPathFindPlace = 'maps/api/place/findplacefromtext/json'; - static final _unencodedPathNearBySearch = 'maps/api/place/nearbysearch/json'; + static const _unencodedPathNearBySearch = 'maps/api/place/nearbysearch/json'; - static final _unencodedPathTextSearch = 'maps/api/place/textsearch/json'; + static const _unencodedPathTextSearch = 'maps/api/place/textsearch/json'; final String apiKEY; @@ -59,12 +57,18 @@ class Search { fields, locationbias, ); - final uri = NetworkUtility.createUri( - proxyUrl, _authority, _unencodedPathFindPlace, queryParameters); - final response = await NetworkUtility.fetchUrl(uri, headers: headers); + final uri = createUri( + proxyUrl, + _authority, + _unencodedPathFindPlace, + queryParameters, + ); + final response = await fetchUrl(uri, headers: headers); if (response != null) { - return FindPlaceResponse.fromJson(jsonDecode(response)); + return FindPlaceResponse.fromJson( + jsonDecode(response) as Map, + ); } return null; @@ -138,10 +142,12 @@ class Search { ); final uri = Uri.https(_authority, _unencodedPathNearBySearch, queryParameters); - final response = await NetworkUtility.fetchUrl(uri, headers: headers); + final response = await fetchUrl(uri, headers: headers); if (response != null) { - return NearbySearchResponse.fromJson(jsonDecode(response)); + return NearbySearchResponse.fromJson( + jsonDecode(response) as Map, + ); } return null; @@ -220,10 +226,12 @@ class Search { ); final uri = Uri.https(_authority, _unencodedPathTextSearch, queryParameters); - final response = await NetworkUtility.fetchUrl(uri, headers: headers); + final response = await fetchUrl(uri, headers: headers); if (response != null) { - return TextSearchResponse.fromJson(jsonDecode(response)); + return TextSearchResponse.fromJson( + jsonDecode(response) as Map, + ); } return null; @@ -273,7 +281,7 @@ class Search { : _unencodedPathFindPlace, queryParameters, ); - return await NetworkUtility.fetchUrl(uri, headers: headers); + return await fetchUrl(uri, headers: headers); } /// A Nearby Search lets you search for places within a specified area. @@ -345,7 +353,7 @@ class Search { var uri = Uri.https(_authority, _unencodedPathNearBySearch, queryParameters); - return await NetworkUtility.fetchUrl(uri, headers: headers); + return await fetchUrl(uri, headers: headers); } /// The Google Places API Text Search Service is a web service that returns information about a set of places @@ -421,7 +429,7 @@ class Search { ); var uri = Uri.https(_authority, _unencodedPathTextSearch, queryParameters); - return await NetworkUtility.fetchUrl(uri, headers: headers); + return await fetchUrl(uri, headers: headers); } /// Prepare query Parameters for find place @@ -433,32 +441,19 @@ class Search { String? fields, Locationbias? locationbias, ) { - String result = input.trimRight(); - result = result.trimLeft(); - Map queryParameters = { - 'input': result, + final cleanedInput = input.trimRight().trimLeft(); + final queryParameters = { + 'input': cleanedInput, 'key': apiKEY, - 'inputtype': inputType == InputType.TextQuery + 'inputtype': inputType == InputType.textQuery ? 'textquery' - : inputType == InputType.PhoneNumber + : inputType == InputType.phoneNumber ? 'phonenumber' : 'textquery', + if (language != null && language != '') 'language': language, + if (fields != null && fields != '') 'fields': fields, }; - if (language != null && language != '') { - var item = { - 'language': language, - }; - queryParameters.addAll(item); - } - - if (fields != null && fields != '') { - var item = { - 'fields': fields, - }; - queryParameters.addAll(item); - } - if (locationbias != null) { String? value; if (locationbias.ipbias != null && locationbias.ipbias!) { @@ -476,17 +471,17 @@ class Search { value = 'rectangle:${locationbias.rectangular!.southWest.latitude},${locationbias.rectangular!.southWest.longitude}|${locationbias.rectangular!.northEast.latitude},${locationbias.rectangular!.northEast.longitude}'; } - var item = { - 'locationbias': value, - }; + + final item = {'locationbias': value}; queryParameters.addAll(item); } + return queryParameters; } /// Prepare query Parameters for near by search Map _createNearBySearchParameters( - apiKEY, + String apiKEY, Location location, int radius, String? keyword, @@ -499,81 +494,28 @@ class Search { String? type, String? pagetoken, ) { - Map queryParameters = { + final queryParameters = { 'location': '${location.lat},${location.lng}', 'key': apiKEY, 'radius': radius.toString(), + if (keyword != null && keyword != '') 'keyword': keyword, + if (language != null && language != '') 'language': language, + if (minprice != null) 'minprice': minprice.toString(), + if (maxprice != null) 'maxprice': maxprice.toString(), + if (name != null && name != '') 'name': name, + if (opennow != null && opennow) 'opennow': 'opennow', + if (type != null && type != '') 'type': type, + if (pagetoken != null && pagetoken != '') 'pagetoken': pagetoken, }; - if (keyword != null && keyword != '') { - var item = { - 'keyword': keyword, - }; - queryParameters.addAll(item); - } - - if (language != null && language != '') { - var item = { - 'language': language, - }; - queryParameters.addAll(item); - } - - if (minprice != null) { - var item = { - 'minprice': minprice.toString(), - }; - queryParameters.addAll(item); - } - - if (maxprice != null) { - var item = { - 'maxprice': maxprice.toString(), - }; - queryParameters.addAll(item); - } - - if (name != null && name != '') { - var item = { - 'name': name, - }; - queryParameters.addAll(item); - } - - if (opennow != null && opennow) { - var item = { - 'opennow': 'opennow', - }; - queryParameters.addAll(item); - } - + // TODO: Clean this up if (rankby != null) { - String? value; - if (rankby == RankBy.Prominence) { - value = 'prominence'; - } - if (rankby == RankBy.Distance) { - value = 'distance'; + if (rankby == RankBy.distance) { queryParameters.remove('radius'); } - var item = { - 'rankby': value, - }; - queryParameters.addAll(item); - } - - if (type != null && type != '') { - var item = { - 'type': type, - }; - queryParameters.addAll(item); - } + final item = {'rankby': rankby.name}; - if (pagetoken != null && pagetoken != '') { - var item = { - 'pagetoken': pagetoken, - }; queryParameters.addAll(item); } @@ -582,7 +524,7 @@ class Search { /// Prepare query Parameters for text search Map _createTextSearchParameters( - apiKEY, + String apiKEY, String query, String? region, Location? location, @@ -594,76 +536,21 @@ class Search { String? type, String? pagetoken, ) { - String result = query.trimRight(); - result = result.trimLeft(); - Map queryParameters = { - 'query': result, + final cleanedQuery = query.trimRight().trimLeft(); + final queryParameters = { + 'query': cleanedQuery, 'key': apiKEY, + if (region != null && region != '') 'region': region, + if (location != null) 'location': '${location.lat},${location.lng}', + if (radius != null) 'radius': radius.toString(), + if (language != null && language != '') 'language': language, + if (minprice != null) 'minprice': minprice.toString(), + if (maxprice != null) 'maxprice': maxprice.toString(), + if (opennow != null && opennow) 'opennow': 'opennow', + if (type != null && type != '') 'type': type, + if (pagetoken != null && pagetoken != '') 'pagetoken': pagetoken, }; - if (region != null && region != '') { - var item = { - 'region': region, - }; - queryParameters.addAll(item); - } - - if (location != null) { - var item = { - 'location': '${location.lat},${location.lng}', - }; - queryParameters.addAll(item); - } - - if (radius != null) { - var item = { - 'radius': radius.toString(), - }; - queryParameters.addAll(item); - } - - if (language != null && language != '') { - var item = { - 'language': language, - }; - queryParameters.addAll(item); - } - - if (minprice != null) { - var item = { - 'minprice': minprice.toString(), - }; - queryParameters.addAll(item); - } - - if (maxprice != null) { - var item = { - 'maxprice': maxprice.toString(), - }; - queryParameters.addAll(item); - } - - if (opennow != null && opennow) { - var item = { - 'opennow': 'opennow', - }; - queryParameters.addAll(item); - } - - if (type != null && type != '') { - var item = { - 'type': type, - }; - queryParameters.addAll(item); - } - - if (pagetoken != null && pagetoken != '') { - var item = { - 'pagetoken': pagetoken, - }; - queryParameters.addAll(item); - } - return queryParameters; } } diff --git a/lib/src/search/search_result/search_result.dart b/lib/src/search/search_result/search_result.dart index f884e59..7d5ea7a 100644 --- a/lib/src/search/search_result/search_result.dart +++ b/lib/src/search/search_result/search_result.dart @@ -82,7 +82,8 @@ class SearchResult { /// [permanentlyClosed] is a boolean flag indicating whether the place has shut down either permanently /// or temporarily (value true). If the place is operational, or if no data is available, the flag is absent from the response. @Deprecated( - 'permanently_closed is now deprecated. Instead, use business_status to get the operational status of businesses.') + 'permanently_closed is now deprecated. Instead, use business_status to get the operational status of businesses.', + ) final bool? permanentlyClosed; const SearchResult({ diff --git a/lib/src/utils/network_utility.dart b/lib/src/utils/network_utility.dart index 4f6c567..732918b 100644 --- a/lib/src/utils/network_utility.dart +++ b/lib/src/utils/network_utility.dart @@ -2,102 +2,103 @@ import 'package:google_place/google_place.dart'; import 'package:http/http.dart' as http; /// The Network Utility -class NetworkUtility { - static Future fetchUrl( - Uri uri, { - Map? headers, - }) async { - try { - final response = - await http.get(uri, headers: headers).timeout(GooglePlace.timeout); +Future fetchUrl( + Uri uri, { + Map? headers, +}) async { + try { + final response = + await http.get(uri, headers: headers).timeout(GooglePlace.timeout); - if (response.statusCode == 200) { - return response.body; - } - return null; - } catch (e) { - return null; + if (response.statusCode == 200) { + return response.body; } + return null; + } catch (e) { + return null; } +} - /// Creates a uri with the proxy url if it is set - /// [proxyUrl] Required parameters - can be formatted as [https://]host[:][/][?=] only https proxies are supported. - /// [authority] Required parameters - the domain name of the google server, usually https://maps.googleapis.com - /// [unencodedGoogleMapsPath] Required parameters - the path to the api, usually something like maps/api/... - /// [queryParameters] Required parameters - a map of query parameters to be appended to the url - static Uri createUri( - String? proxyUrl, - String authority, - String unencodedGoogleMapsPath, - Map queryParameters, - ) { - Uri uri; - final googleApiUri = Uri.https( - authority, - unencodedGoogleMapsPath, - queryParameters, - ); +/// Creates a uri with the proxy url if it is set +/// [proxyUrl] Required parameters - can be formatted as [https://]host[:][/][?=] only https proxies are supported. +/// [authority] Required parameters - the domain name of the google server, usually https://maps.googleapis.com +/// [unencodedGoogleMapsPath] Required parameters - the path to the api, usually something like maps/api/... +/// [queryParameters] Required parameters - a map of query parameters to be appended to the url +Uri createUri( + String? proxyUrl, + String authority, + String unencodedGoogleMapsPath, + Map queryParameters, +) { + Uri uri; + final googleApiUri = Uri.https( + authority, + unencodedGoogleMapsPath, + queryParameters, + ); - if (proxyUrl != null && proxyUrl != '') { - bool usingHttps = true; - String everythingAfterHostname = ''; - String proxyHostname = proxyUrl; - if (proxyUrl.startsWith('https://')) { - proxyHostname = proxyUrl.replaceFirst("https://", ""); - usingHttps = true; - } else if (proxyUrl.startsWith('http://')) { - proxyHostname = proxyUrl.replaceFirst("http://", ""); - usingHttps = false; - } + if (proxyUrl != null && proxyUrl != '') { + bool usingHttps = true; + String everythingAfterHostname = ''; + String proxyHostname = proxyUrl; + if (proxyUrl.startsWith('https://')) { + proxyHostname = proxyUrl.replaceFirst("https://", ""); + usingHttps = true; + } else if (proxyUrl.startsWith('http://')) { + proxyHostname = proxyUrl.replaceFirst("http://", ""); + usingHttps = false; + } - if (proxyHostname.contains("/")) { - everythingAfterHostname = - proxyHostname.substring(proxyHostname.indexOf("/")); - proxyHostname = proxyHostname.substring(0, proxyHostname.indexOf("/")); - } + if (proxyHostname.contains("/")) { + everythingAfterHostname = + proxyHostname.substring(proxyHostname.indexOf("/")); + proxyHostname = proxyHostname.substring(0, proxyHostname.indexOf("/")); + } - if (everythingAfterHostname.contains("?") && - everythingAfterHostname.contains("=")) { - var proxyPath = everythingAfterHostname.substring( - 0, everythingAfterHostname.indexOf("?")); - var parameterName = everythingAfterHostname.substring( - everythingAfterHostname.indexOf("?") + 1, - everythingAfterHostname.indexOf("=")); - var googleMapsUrlParam = {parameterName: googleApiUri.toString()}; - queryParameters.addAll(googleMapsUrlParam); - if (usingHttps) { - uri = Uri.https( - proxyHostname, - proxyPath, - queryParameters, - ); - } else { - uri = Uri.http( - proxyHostname, - proxyPath, - queryParameters, - ); - } + if (everythingAfterHostname.contains("?") && + everythingAfterHostname.contains("=")) { + var proxyPath = everythingAfterHostname.substring( + 0, + everythingAfterHostname.indexOf("?"), + ); + var parameterName = everythingAfterHostname.substring( + everythingAfterHostname.indexOf("?") + 1, + everythingAfterHostname.indexOf("="), + ); + var googleMapsUrlParam = {parameterName: googleApiUri.toString()}; + queryParameters.addAll(googleMapsUrlParam); + if (usingHttps) { + uri = Uri.https( + proxyHostname, + proxyPath, + queryParameters, + ); } else { - //no parameter - if (usingHttps) { - uri = Uri.https( - proxyHostname, - '${everythingAfterHostname}https://$authority/$unencodedGoogleMapsPath', - queryParameters, - ); - } else { - uri = Uri.http( - proxyHostname, - '${everythingAfterHostname}http://$authority/$unencodedGoogleMapsPath', - queryParameters, - ); - } + uri = Uri.http( + proxyHostname, + proxyPath, + queryParameters, + ); } } else { - uri = googleApiUri; + //no parameter + if (usingHttps) { + uri = Uri.https( + proxyHostname, + '${everythingAfterHostname}https://$authority/$unencodedGoogleMapsPath', + queryParameters, + ); + } else { + uri = Uri.http( + proxyHostname, + '${everythingAfterHostname}http://$authority/$unencodedGoogleMapsPath', + queryParameters, + ); + } } - - return uri; + } else { + uri = googleApiUri; } + + return uri; } diff --git a/pubspec.lock b/pubspec.lock index f121ecc..3b5b2c1 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -181,6 +181,13 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.4" flutter_test: dependency: "direct dev" description: flutter @@ -256,6 +263,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "6.2.0" + lints: + dependency: transitive + description: + name: lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" logging: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 2815e42..7b71c2c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -14,6 +14,7 @@ dependencies: dev_dependencies: build_runner: ^2.1.10 + flutter_lints: ^1.0.0 flutter_test: sdk: flutter json_serializable: ^6.2.0 diff --git a/test/google_place_test.dart b/test/google_place_test.dart index 12cf0c9..7330ac5 100644 --- a/test/google_place_test.dart +++ b/test/google_place_test.dart @@ -23,11 +23,15 @@ void main() { await googlePlace.photos.get("photoReference", 10, 10); googlePlace = GooglePlace(apiKey, proxyUrl: 'https://1.2.3.4/proxy'); await googlePlace.queryAutocomplete.get("some place"); - googlePlace = GooglePlace(apiKey, - proxyUrl: 'https://localhost:6969/proxy/proxy-two/'); - await googlePlace.search.getFindPlace("some place", InputType.TextQuery); - googlePlace = GooglePlace(apiKey, - proxyUrl: 'localhost:6969/proxy/proxy-two?gmapsurl='); + googlePlace = GooglePlace( + apiKey, + proxyUrl: 'https://localhost:6969/proxy/proxy-two/', + ); + await googlePlace.search.getFindPlace("some place", InputType.textQuery); + googlePlace = GooglePlace( + apiKey, + proxyUrl: 'localhost:6969/proxy/proxy-two?gmapsurl=', + ); await googlePlace.autocomplete.get("some place"); //try a bad hostname googlePlace = GooglePlace(apiKey, proxyUrl: 'localhost:6969******'); From 0179716b34b0a96f0419d734db7bfdfa391b70c6 Mon Sep 17 00:00:00 2001 From: Nolence Date: Fri, 29 Apr 2022 12:28:30 -0600 Subject: [PATCH 03/12] small improvements to photos --- lib/src/models/lat_lon.dart | 1 + lib/src/photos/photos.dart | 23 +++++++++++------------ test/google_place_test.dart | 4 +++- 3 files changed, 15 insertions(+), 13 deletions(-) diff --git a/lib/src/models/lat_lon.dart b/lib/src/models/lat_lon.dart index 75a86d5..14db9aa 100644 --- a/lib/src/models/lat_lon.dart +++ b/lib/src/models/lat_lon.dart @@ -1,3 +1,4 @@ +// TODO: Why do we have this when we have Location? class LatLon { const LatLon(double latitude, double longitude) : latitude = diff --git a/lib/src/photos/photos.dart b/lib/src/photos/photos.dart index 3d151ee..53abc05 100644 --- a/lib/src/photos/photos.dart +++ b/lib/src/photos/photos.dart @@ -38,23 +38,25 @@ class Photos { int maxWidth, ) async { assert(photoReference != ""); - var queryParameters = _createParameters( + final queryParameters = _createParameters( apiKEY, photoReference, maxHeight, maxWidth, ); - var uri = createUri( + final uri = createUri( proxyUrl, _authority, _unencodedPath, queryParameters, ); - var response = await fetchUrl(uri, headers: headers); + final response = await fetchUrl(uri, headers: headers); + if (response != null) { List list = response.codeUnits; return Uint8List.fromList(list); } + return null; } @@ -81,19 +83,20 @@ class Photos { int maxWidth, ) async { assert(photoReference != ""); - var queryParameters = _createParameters( + final queryParameters = _createParameters( apiKEY, photoReference, maxHeight, maxWidth, ); - var uri = Uri.https( + final uri = Uri.https( proxyUrl != null && proxyUrl != '' ? proxyUrl! : _authority, proxyUrl != null && proxyUrl != '' ? 'https://$_authority/$_unencodedPath' : _unencodedPath, queryParameters, ); + return await fetchUrl(uri, headers: headers); } @@ -107,14 +110,10 @@ class Photos { Map queryParameters = { 'photoreference': photoReference, 'key': apiKEY, + if (maxWidth != null) 'maxwidth': maxWidth.toString(), + if (maxHeight != null) 'maxheight': maxHeight.toString(), }; - if (maxHeight != null) {} - if (maxWidth != null) { - var item = { - 'maxwidth': maxWidth.toString(), - }; - queryParameters.addAll(item); - } + return queryParameters; } } diff --git a/test/google_place_test.dart b/test/google_place_test.dart index 7330ac5..f765148 100644 --- a/test/google_place_test.dart +++ b/test/google_place_test.dart @@ -3,8 +3,9 @@ import 'package:google_place/google_place.dart'; void main() { String apiKey = "Your-Key"; + test('init', () async { - var googlePlace = + final googlePlace = GooglePlace(apiKey, proxyUrl: 'cors-anywhere.herokuapp.com'); expect(googlePlace.apiKEY, apiKey); expect(googlePlace.search.apiKEY, apiKey); @@ -14,6 +15,7 @@ void main() { expect(googlePlace.autocomplete.apiKEY, apiKey); expect(googlePlace.queryAutocomplete.apiKEY, apiKey); }); + test('proxies with paths and parameters', () async { GooglePlace googlePlace; //try some good proxy urls From 6477e03405c5ad64574148cdf0a18254a877e23e Mon Sep 17 00:00:00 2001 From: Nolence Date: Fri, 29 Apr 2022 14:28:35 -0600 Subject: [PATCH 04/12] stricted more non nullable types --- example/lib/main.dart | 2 +- lib/google_place.dart | 30 ++--- .../details_response/details_response.dart | 25 ---- .../address_component/address_component.dart | 12 +- .../address_component.g.dart | 7 +- lib/src/models/bounds/bounds.dart | 12 +- lib/src/models/bounds/bounds.g.dart | 10 +- lib/src/models/debug_log/debug_log.dart | 1 + lib/src/models/geometry/geometry.dart | 14 +-- lib/src/models/geometry/geometry.g.dart | 13 +- .../lat_lng_literal.dart} | 12 +- .../lat_lng_literal.g.dart} | 8 +- lib/src/models/period/period.dart | 22 ---- lib/src/models/period/period.g.dart | 19 --- lib/src/models/photo/photo.dart | 29 ----- .../place_opening_hours.dart} | 27 +++-- .../place_opening_hours.g.dart} | 18 +-- .../place_opening_hours_period.dart | 26 ++++ .../place_opening_hours_period.g.dart | 25 ++++ .../place_opening_hours_period_detail.dart | 23 ++++ .../place_opening_hours_period_detail.g.dart | 21 ++++ lib/src/models/place_photo/place_photo.dart | 30 +++++ .../place_photo.g.dart} | 17 +-- .../place_review.dart} | 39 +++--- .../place_review.g.dart} | 21 ++-- lib/src/models/plus_code/plus_code.dart | 8 +- lib/src/models/plus_code/plus_code.g.dart | 2 +- lib/src/models/time_and_day/time_and_day.dart | 20 --- .../models/time_and_day/time_and_day.g.dart | 18 --- .../place/place.dart} | 23 ++-- .../place/place.g.dart} | 14 +-- .../places_details.dart} | 10 +- .../places_details_response.dart | 32 +++++ .../places_details_response.g.dart} | 22 ++-- .../find_place_response.dart | 32 ----- .../find_place_response.g.dart | 31 ----- .../nearby_search_response.dart | 32 ----- ...places_find_place__from_text_response.dart | 32 +++++ ...aces_find_place__from_text_response.g.dart | 33 +++++ .../places_nearby_search_response.dart | 35 ++++++ .../places_nearby_search_response.g.dart | 35 ++++++ .../places_text_search_response.dart | 34 ++++++ .../places_text_search_response.g.dart} | 34 +++--- lib/src/search/search.dart | 24 ++-- .../search/search_result/search_result.dart | 114 ------------------ .../search/search_result/search_result.g.dart | 59 --------- lib/src/search/text_search_response.dart | 32 ----- lib/src/search/text_search_response.g.dart | 31 ----- 48 files changed, 523 insertions(+), 647 deletions(-) delete mode 100644 lib/src/details/details_response/details_response.dart rename lib/src/models/{location/location.dart => lat_lng_literal/lat_lng_literal.dart} (63%) rename lib/src/models/{location/location.g.dart => lat_lng_literal/lat_lng_literal.g.dart} (64%) delete mode 100644 lib/src/models/period/period.dart delete mode 100644 lib/src/models/period/period.g.dart delete mode 100644 lib/src/models/photo/photo.dart rename lib/src/models/{opening_hours/opening_hours.dart => place_opening_hours/place_opening_hours.dart} (53%) rename lib/src/models/{opening_hours/opening_hours.g.dart => place_opening_hours/place_opening_hours.g.dart} (54%) create mode 100644 lib/src/models/place_opening_hours_period/place_opening_hours_period.dart create mode 100644 lib/src/models/place_opening_hours_period/place_opening_hours_period.g.dart create mode 100644 lib/src/models/place_opening_hours_period_detail/place_opening_hours_period_detail.dart create mode 100644 lib/src/models/place_opening_hours_period_detail/place_opening_hours_period_detail.g.dart create mode 100644 lib/src/models/place_photo/place_photo.dart rename lib/src/models/{photo/photo.g.dart => place_photo/place_photo.g.dart} (58%) rename lib/src/models/{review/review.dart => place_review/place_review.dart} (76%) rename lib/src/models/{review/review.g.dart => place_review/place_review.g.dart} (71%) delete mode 100644 lib/src/models/time_and_day/time_and_day.dart delete mode 100644 lib/src/models/time_and_day/time_and_day.g.dart rename lib/src/{details/details_result/details_result.dart => places_details/place/place.dart} (91%) rename lib/src/{details/details_result/details_result.g.dart => places_details/place/place.g.dart} (88%) rename lib/src/{details/details.dart => places_details/places_details.dart} (95%) create mode 100644 lib/src/places_details/places_details_response/places_details_response.dart rename lib/src/{details/details_response/details_response.g.dart => places_details/places_details_response/places_details_response.g.dart} (52%) delete mode 100644 lib/src/search/find_place_response/find_place_response.dart delete mode 100644 lib/src/search/find_place_response/find_place_response.g.dart delete mode 100644 lib/src/search/nearby_search_response/nearby_search_response.dart create mode 100644 lib/src/search/places_find_place__from_text_response/places_find_place__from_text_response.dart create mode 100644 lib/src/search/places_find_place__from_text_response/places_find_place__from_text_response.g.dart create mode 100644 lib/src/search/places_nearby_search_response/places_nearby_search_response.dart create mode 100644 lib/src/search/places_nearby_search_response/places_nearby_search_response.g.dart create mode 100644 lib/src/search/places_text_search_response/places_text_search_response.dart rename lib/src/search/{nearby_search_response/nearby_search_response.g.dart => places_text_search_response/places_text_search_response.g.dart} (50%) delete mode 100644 lib/src/search/search_result/search_result.dart delete mode 100644 lib/src/search/search_result/search_result.g.dart delete mode 100644 lib/src/search/text_search_response.dart delete mode 100644 lib/src/search/text_search_response.g.dart diff --git a/example/lib/main.dart b/example/lib/main.dart index 085abce..2d1ddfb 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -141,7 +141,7 @@ class DetailsPage extends StatefulWidget { } class _DetailsPageState extends State { - DetailsResult detailsResult; + Place detailsResult; List images = []; diff --git a/lib/google_place.dart b/lib/google_place.dart index f125c65..318a4f7 100644 --- a/lib/google_place.dart +++ b/lib/google_place.dart @@ -1,38 +1,38 @@ library google_place; import 'package:google_place/src/autocomplete/autocomplete.dart'; -import 'package:google_place/src/details/details.dart'; import 'package:google_place/src/photos/photos.dart'; +import 'package:google_place/src/places_details/places_details.dart'; import 'package:google_place/src/query_autocomplete/query_autocomplete.dart'; import 'package:google_place/src/search/search.dart'; export 'package:google_place/src/autocomplete/autocomplete_prediction/autocomplete_prediction.dart'; export 'package:google_place/src/autocomplete/autocomplete_response/autocomplete_response.dart'; -export 'package:google_place/src/details/details_response/details_response.dart'; -export 'package:google_place/src/details/details_result/details_result.dart'; export 'package:google_place/src/models/address_component/address_component.dart'; export 'package:google_place/src/models/bounds/bounds.dart'; export 'package:google_place/src/models/component.dart'; export 'package:google_place/src/models/debug_log/debug_log.dart'; export 'package:google_place/src/models/geometry/geometry.dart'; export 'package:google_place/src/models/input_type.dart'; +export 'package:google_place/src/models/lat_lng_literal/lat_lng_literal.dart'; export 'package:google_place/src/models/lat_lon.dart'; -export 'package:google_place/src/models/location/location.dart'; export 'package:google_place/src/models/locationbias.dart'; export 'package:google_place/src/models/matched_substring/matched_substring.dart'; -export 'package:google_place/src/models/opening_hours/opening_hours.dart'; -export 'package:google_place/src/models/period/period.dart'; -export 'package:google_place/src/models/photo/photo.dart'; +export 'package:google_place/src/models/place_opening_hours/place_opening_hours.dart'; +export 'package:google_place/src/models/place_opening_hours_period/place_opening_hours_period.dart'; +export 'package:google_place/src/models/place_opening_hours_period_detail/place_opening_hours_period_detail.dart'; +export 'package:google_place/src/models/place_photo/place_photo.dart'; +export 'package:google_place/src/models/place_review/place_review.dart'; export 'package:google_place/src/models/plus_code/plus_code.dart'; export 'package:google_place/src/models/rank_by.dart'; -export 'package:google_place/src/models/review/review.dart'; export 'package:google_place/src/models/structured_formatting/structured_formatting.dart'; export 'package:google_place/src/models/term/term.dart'; -export 'package:google_place/src/models/time_and_day/time_and_day.dart'; -export 'package:google_place/src/search/find_place_response/find_place_response.dart'; -export 'package:google_place/src/search/nearby_search_response/nearby_search_response.dart'; -export 'package:google_place/src/search/search_result/search_result.dart'; -export 'package:google_place/src/search/text_search_response.dart'; +export 'package:google_place/src/places_details/place/place.dart'; +export 'package:google_place/src/places_details/places_details.dart'; +export 'package:google_place/src/places_details/places_details_response/places_details_response.dart'; +export 'package:google_place/src/search/places_find_place__from_text_response/places_find_place__from_text_response.dart'; +export 'package:google_place/src/search/places_nearby_search_response/places_nearby_search_response.dart'; +export 'package:google_place/src/search/places_text_search_response/places_text_search_response.dart'; /// The Places API is a service that returns information about places. /// Places are defined within this API as establishments, geographic locations, or prominent points of interest. @@ -44,7 +44,7 @@ class GooglePlace { late Search search; /// [details] returns more detailed information about a specific place, including user reviews. - late Details details; + late PlacesDetails details; /// [photos] provides access to the millions of place-related photos stored in Google's Place database. late Photos photos; @@ -72,7 +72,7 @@ class GooglePlace { this.proxyUrl, }) { search = Search(apiKEY, headers, proxyUrl); - details = Details(apiKEY, headers, proxyUrl); + details = PlacesDetails(apiKEY, headers, proxyUrl); photos = Photos(apiKEY, headers, proxyUrl); autocomplete = Autocomplete(apiKEY, headers, proxyUrl); queryAutocomplete = QueryAutocomplete(apiKEY, headers, proxyUrl); diff --git a/lib/src/details/details_response/details_response.dart b/lib/src/details/details_response/details_response.dart deleted file mode 100644 index 9d50769..0000000 --- a/lib/src/details/details_response/details_response.dart +++ /dev/null @@ -1,25 +0,0 @@ -import 'package:google_place/src/details/details_result/details_result.dart'; -import 'package:json_annotation/json_annotation.dart'; - -part 'details_response.g.dart'; - -/// The Details response contains html Attributions and details and status -@JsonSerializable() -class DetailsResponse { - final String? status; - - final List? htmlAttributions; - - final DetailsResult? result; - - const DetailsResponse({ - this.status, - this.htmlAttributions, - this.result, - }); - - factory DetailsResponse.fromJson(Map json) => - _$DetailsResponseFromJson(json); - - Map toJson() => _$DetailsResponseToJson(this); -} diff --git a/lib/src/models/address_component/address_component.dart b/lib/src/models/address_component/address_component.dart index 1c4419d..f27c4d0 100644 --- a/lib/src/models/address_component/address_component.dart +++ b/lib/src/models/address_component/address_component.dart @@ -5,20 +5,20 @@ part 'address_component.g.dart'; @JsonSerializable() class AddressComponent { /// [longName] is the full text description or name of the address component as returned by the Geocoder. - final String? longName; + final String longName; /// [shortName] is an abbreviated textual name for the address component, if available. /// For example, an address component for the state of Alaska may have a long_name of "Alaska" /// and a short_name of "AK" using the 2-letter postal abbreviation. - final String? shortName; + final String shortName; /// [types] is an array indicating the type of the address component. - final List? types; + final List types; const AddressComponent({ - this.longName, - this.shortName, - this.types, + required this.longName, + required this.shortName, + required this.types, }); factory AddressComponent.fromJson(Map json) => diff --git a/lib/src/models/address_component/address_component.g.dart b/lib/src/models/address_component/address_component.g.dart index 82ec465..1f5d1d4 100644 --- a/lib/src/models/address_component/address_component.g.dart +++ b/lib/src/models/address_component/address_component.g.dart @@ -8,10 +8,9 @@ part of 'address_component.dart'; AddressComponent _$AddressComponentFromJson(Map json) => AddressComponent( - longName: json['long_name'] as String?, - shortName: json['short_name'] as String?, - types: - (json['types'] as List?)?.map((e) => e as String).toList(), + longName: json['long_name'] as String, + shortName: json['short_name'] as String, + types: (json['types'] as List).map((e) => e as String).toList(), ); Map _$AddressComponentToJson(AddressComponent instance) => diff --git a/lib/src/models/bounds/bounds.dart b/lib/src/models/bounds/bounds.dart index cc01b07..a9c0d2e 100644 --- a/lib/src/models/bounds/bounds.dart +++ b/lib/src/models/bounds/bounds.dart @@ -1,15 +1,19 @@ -import 'package:google_place/src/models/location/location.dart'; +import 'package:google_place/src/models/lat_lng_literal/lat_lng_literal.dart'; import 'package:json_annotation/json_annotation.dart'; part 'bounds.g.dart'; +/// A rectangle in geographical coordinates from points at the southwest and northeast corners. @JsonSerializable() class Bounds { - final Location? northeast; + final LatLngLiteral northeast; - final Location? southwest; + final LatLngLiteral southwest; - const Bounds({this.northeast, this.southwest}); + const Bounds({ + required this.northeast, + required this.southwest, + }); factory Bounds.fromJson(Map json) => _$BoundsFromJson(json); diff --git a/lib/src/models/bounds/bounds.g.dart b/lib/src/models/bounds/bounds.g.dart index c5946cd..a9b7687 100644 --- a/lib/src/models/bounds/bounds.g.dart +++ b/lib/src/models/bounds/bounds.g.dart @@ -7,12 +7,10 @@ part of 'bounds.dart'; // ************************************************************************** Bounds _$BoundsFromJson(Map json) => Bounds( - northeast: json['northeast'] == null - ? null - : Location.fromJson(json['northeast'] as Map), - southwest: json['southwest'] == null - ? null - : Location.fromJson(json['southwest'] as Map), + northeast: + LatLngLiteral.fromJson(json['northeast'] as Map), + southwest: + LatLngLiteral.fromJson(json['southwest'] as Map), ); Map _$BoundsToJson(Bounds instance) => { diff --git a/lib/src/models/debug_log/debug_log.dart b/lib/src/models/debug_log/debug_log.dart index c4e5951..54f4f10 100644 --- a/lib/src/models/debug_log/debug_log.dart +++ b/lib/src/models/debug_log/debug_log.dart @@ -2,6 +2,7 @@ import 'package:json_annotation/json_annotation.dart'; part 'debug_log.g.dart'; +// TODO: I don't think this is a real thing @JsonSerializable() class DebugLog { final List? line; diff --git a/lib/src/models/geometry/geometry.dart b/lib/src/models/geometry/geometry.dart index fb1252f..2cb3c0e 100644 --- a/lib/src/models/geometry/geometry.dart +++ b/lib/src/models/geometry/geometry.dart @@ -1,5 +1,5 @@ import 'package:google_place/src/models/bounds/bounds.dart'; -import 'package:google_place/src/models/location/location.dart'; +import 'package:google_place/src/models/lat_lng_literal/lat_lng_literal.dart'; import 'package:json_annotation/json_annotation.dart'; part 'geometry.g.dart'; @@ -7,15 +7,15 @@ part 'geometry.g.dart'; @JsonSerializable() class Geometry { /// [location] contains the geocoded latitude,longitude value for this place. - final Location? location; + final LatLngLiteral location; /// [viewport] contains the preferred viewport when displaying this place on a map as a LatLngBounds if it is known. - final Bounds? viewport; + final Bounds viewport; - /// [bounds] contains bounds object - final Bounds? bounds; - - const Geometry({this.location, this.viewport, this.bounds}); + const Geometry({ + required this.location, + required this.viewport, + }); factory Geometry.fromJson(Map json) => _$GeometryFromJson(json); diff --git a/lib/src/models/geometry/geometry.g.dart b/lib/src/models/geometry/geometry.g.dart index e59abcf..8fdc114 100644 --- a/lib/src/models/geometry/geometry.g.dart +++ b/lib/src/models/geometry/geometry.g.dart @@ -7,19 +7,12 @@ part of 'geometry.dart'; // ************************************************************************** Geometry _$GeometryFromJson(Map json) => Geometry( - location: json['location'] == null - ? null - : Location.fromJson(json['location'] as Map), - viewport: json['viewport'] == null - ? null - : Bounds.fromJson(json['viewport'] as Map), - bounds: json['bounds'] == null - ? null - : Bounds.fromJson(json['bounds'] as Map), + location: + LatLngLiteral.fromJson(json['location'] as Map), + viewport: Bounds.fromJson(json['viewport'] as Map), ); Map _$GeometryToJson(Geometry instance) => { 'location': instance.location, 'viewport': instance.viewport, - 'bounds': instance.bounds, }; diff --git a/lib/src/models/location/location.dart b/lib/src/models/lat_lng_literal/lat_lng_literal.dart similarity index 63% rename from lib/src/models/location/location.dart rename to lib/src/models/lat_lng_literal/lat_lng_literal.dart index e11e2b7..8105ad2 100644 --- a/lib/src/models/location/location.dart +++ b/lib/src/models/lat_lng_literal/lat_lng_literal.dart @@ -1,10 +1,10 @@ import 'package:json_annotation/json_annotation.dart'; -part 'location.g.dart'; +part 'lat_lng_literal.g.dart'; /// A pair of latitude and longitude coordinates, stored as degrees. @JsonSerializable() -class Location { +class LatLngLiteral { final double lat; final double lng; @@ -16,10 +16,10 @@ class Location { /// /// The longitude is normalized to the half-open interval from -180.0 /// (inclusive) to +180.0 (exclusive) - const Location({required this.lat, required this.lng}); + const LatLngLiteral({required this.lat, required this.lng}); - factory Location.fromJson(Map json) => - _$LocationFromJson(json); + factory LatLngLiteral.fromJson(Map json) => + _$LatLngLiteralFromJson(json); - Map toJson() => _$LocationToJson(this); + Map toJson() => _$LatLngLiteralToJson(this); } diff --git a/lib/src/models/location/location.g.dart b/lib/src/models/lat_lng_literal/lat_lng_literal.g.dart similarity index 64% rename from lib/src/models/location/location.g.dart rename to lib/src/models/lat_lng_literal/lat_lng_literal.g.dart index aca57f1..ac58ca3 100644 --- a/lib/src/models/location/location.g.dart +++ b/lib/src/models/lat_lng_literal/lat_lng_literal.g.dart @@ -1,17 +1,19 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'location.dart'; +part of 'lat_lng_literal.dart'; // ************************************************************************** // JsonSerializableGenerator // ************************************************************************** -Location _$LocationFromJson(Map json) => Location( +LatLngLiteral _$LatLngLiteralFromJson(Map json) => + LatLngLiteral( lat: (json['lat'] as num).toDouble(), lng: (json['lng'] as num).toDouble(), ); -Map _$LocationToJson(Location instance) => { +Map _$LatLngLiteralToJson(LatLngLiteral instance) => + { 'lat': instance.lat, 'lng': instance.lng, }; diff --git a/lib/src/models/period/period.dart b/lib/src/models/period/period.dart deleted file mode 100644 index bb5ab75..0000000 --- a/lib/src/models/period/period.dart +++ /dev/null @@ -1,22 +0,0 @@ -import 'package:google_place/src/models/time_and_day/time_and_day.dart'; -import 'package:json_annotation/json_annotation.dart'; - -part 'period.g.dart'; - -@JsonSerializable() -class Period { - /// [close] may contain a pair of day and time objects describing when the place closes. - /// Note: If a place is always open, the close section will be missing from the response. - /// Clients can rely on always-open being represented as an open period containing day with - /// value 0 and time with value 0000, and no close. - final TimeAndDay? close; - - /// [open] contains a pair of day and time objects describing when the place opens. - final TimeAndDay open; - - const Period({required this.open, this.close}); - - factory Period.fromJson(Map json) => _$PeriodFromJson(json); - - Map toJson() => _$PeriodToJson(this); -} diff --git a/lib/src/models/period/period.g.dart b/lib/src/models/period/period.g.dart deleted file mode 100644 index cfb8bbf..0000000 --- a/lib/src/models/period/period.g.dart +++ /dev/null @@ -1,19 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'period.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -Period _$PeriodFromJson(Map json) => Period( - open: TimeAndDay.fromJson(json['open'] as Map), - close: json['close'] == null - ? null - : TimeAndDay.fromJson(json['close'] as Map), - ); - -Map _$PeriodToJson(Period instance) => { - 'close': instance.close, - 'open': instance.open, - }; diff --git a/lib/src/models/photo/photo.dart b/lib/src/models/photo/photo.dart deleted file mode 100644 index d1f027a..0000000 --- a/lib/src/models/photo/photo.dart +++ /dev/null @@ -1,29 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; - -part 'photo.g.dart'; - -@JsonSerializable() -class Photo { - /// [photoReference] a string used to identify the photo when you perform a Photo request. - final String? photoReference; - - /// [height] the maximum height of the image. - final int? height; - - /// [width] the maximum width of the image. - final int? width; - - /// [htmlAttributions] contains any required attributions. This field will always be present, but may be empty. - final List? htmlAttributions; - - const Photo({ - this.photoReference, - this.height, - this.width, - this.htmlAttributions, - }); - - factory Photo.fromJson(Map json) => _$PhotoFromJson(json); - - Map toJson() => _$PhotoToJson(this); -} diff --git a/lib/src/models/opening_hours/opening_hours.dart b/lib/src/models/place_opening_hours/place_opening_hours.dart similarity index 53% rename from lib/src/models/opening_hours/opening_hours.dart rename to lib/src/models/place_opening_hours/place_opening_hours.dart index 3b6084e..c7fe70e 100644 --- a/lib/src/models/opening_hours/opening_hours.dart +++ b/lib/src/models/place_opening_hours/place_opening_hours.dart @@ -1,10 +1,11 @@ -import 'package:google_place/src/models/period/period.dart'; +import 'package:google_place/src/models/place_opening_hours_period/place_opening_hours_period.dart'; import 'package:json_annotation/json_annotation.dart'; -part 'opening_hours.g.dart'; +part 'place_opening_hours.g.dart'; +/// An object describing the opening hours of a place. @JsonSerializable() -class OpeningHours { +class PlaceOpeningHours { /// [openNow] is a boolean value indicating if the place is open at the current time. final bool? openNow; @@ -13,19 +14,21 @@ class OpeningHours { /// the Places Service will format and localize the opening hours appropriately for that language. /// The ordering of the elements in this array depends on the language parameter. /// ∂Some languages start the week on Monday while others start on Sunday. - final List? weekdayText; + @JsonKey(defaultValue: []) + final List weekdayText; /// [periods] is an array of opening periods covering seven days, starting from Sunday, in chronological order. - final List? periods; + @JsonKey(defaultValue: []) + final List periods; - const OpeningHours({ - this.openNow, - this.weekdayText, - this.periods, + const PlaceOpeningHours({ + required this.openNow, + required this.weekdayText, + required this.periods, }); - factory OpeningHours.fromJson(Map json) => - _$OpeningHoursFromJson(json); + factory PlaceOpeningHours.fromJson(Map json) => + _$PlaceOpeningHoursFromJson(json); - Map toJson() => _$OpeningHoursToJson(this); + Map toJson() => _$PlaceOpeningHoursToJson(this); } diff --git a/lib/src/models/opening_hours/opening_hours.g.dart b/lib/src/models/place_opening_hours/place_opening_hours.g.dart similarity index 54% rename from lib/src/models/opening_hours/opening_hours.g.dart rename to lib/src/models/place_opening_hours/place_opening_hours.g.dart index 7a8df9f..4e54ac7 100644 --- a/lib/src/models/opening_hours/opening_hours.g.dart +++ b/lib/src/models/place_opening_hours/place_opening_hours.g.dart @@ -1,22 +1,26 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'opening_hours.dart'; +part of 'place_opening_hours.dart'; // ************************************************************************** // JsonSerializableGenerator // ************************************************************************** -OpeningHours _$OpeningHoursFromJson(Map json) => OpeningHours( +PlaceOpeningHours _$PlaceOpeningHoursFromJson(Map json) => + PlaceOpeningHours( openNow: json['open_now'] as bool?, weekdayText: (json['weekday_text'] as List?) - ?.map((e) => e as String) - .toList(), + ?.map((e) => e as String) + .toList() ?? + [], periods: (json['periods'] as List?) - ?.map((e) => Period.fromJson(e as Map)) - .toList(), + ?.map((e) => + PlaceOpeningHoursPeriod.fromJson(e as Map)) + .toList() ?? + [], ); -Map _$OpeningHoursToJson(OpeningHours instance) => +Map _$PlaceOpeningHoursToJson(PlaceOpeningHours instance) => { 'open_now': instance.openNow, 'weekday_text': instance.weekdayText, diff --git a/lib/src/models/place_opening_hours_period/place_opening_hours_period.dart b/lib/src/models/place_opening_hours_period/place_opening_hours_period.dart new file mode 100644 index 0000000..d9d8d64 --- /dev/null +++ b/lib/src/models/place_opening_hours_period/place_opening_hours_period.dart @@ -0,0 +1,26 @@ +import 'package:google_place/src/models/place_opening_hours_period_detail/place_opening_hours_period_detail.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'place_opening_hours_period.g.dart'; + +@JsonSerializable() +class PlaceOpeningHoursPeriod { + /// [open] contains a pair of day and time objects describing when the place opens. + final PlaceOpeningHoursPeriodDetail open; + + /// [close] may contain a pair of day and time objects describing when the place closes. + /// Note: If a place is always open, the close section will be missing from the response. + /// Clients can rely on always-open being represented as an open period containing day with + /// value 0 and time with value 0000, and no close. + final PlaceOpeningHoursPeriodDetail? close; + + const PlaceOpeningHoursPeriod({ + required this.open, + this.close, + }); + + factory PlaceOpeningHoursPeriod.fromJson(Map json) => + _$PlaceOpeningHoursPeriodFromJson(json); + + Map toJson() => _$PlaceOpeningHoursPeriodToJson(this); +} diff --git a/lib/src/models/place_opening_hours_period/place_opening_hours_period.g.dart b/lib/src/models/place_opening_hours_period/place_opening_hours_period.g.dart new file mode 100644 index 0000000..b564684 --- /dev/null +++ b/lib/src/models/place_opening_hours_period/place_opening_hours_period.g.dart @@ -0,0 +1,25 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'place_opening_hours_period.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +PlaceOpeningHoursPeriod _$PlaceOpeningHoursPeriodFromJson( + Map json) => + PlaceOpeningHoursPeriod( + open: PlaceOpeningHoursPeriodDetail.fromJson( + json['open'] as Map), + close: json['close'] == null + ? null + : PlaceOpeningHoursPeriodDetail.fromJson( + json['close'] as Map), + ); + +Map _$PlaceOpeningHoursPeriodToJson( + PlaceOpeningHoursPeriod instance) => + { + 'open': instance.open, + 'close': instance.close, + }; diff --git a/lib/src/models/place_opening_hours_period_detail/place_opening_hours_period_detail.dart b/lib/src/models/place_opening_hours_period_detail/place_opening_hours_period_detail.dart new file mode 100644 index 0000000..ad02f95 --- /dev/null +++ b/lib/src/models/place_opening_hours_period_detail/place_opening_hours_period_detail.dart @@ -0,0 +1,23 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'place_opening_hours_period_detail.g.dart'; + +@JsonSerializable() +class PlaceOpeningHoursPeriodDetail { + /// [day] a number from 0–6, corresponding to the days of the week, starting on Sunday. For example, 2 means Tuesday. + final int day; + + /// [time] may contain a time of day in 24-hour hhmm format. Values are in the range 0000–2359. + /// The time will be reported in the place’s time zone. + final String time; + + const PlaceOpeningHoursPeriodDetail({ + required this.day, + required this.time, + }); + + factory PlaceOpeningHoursPeriodDetail.fromJson(Map json) => + _$PlaceOpeningHoursPeriodDetailFromJson(json); + + Map toJson() => _$PlaceOpeningHoursPeriodDetailToJson(this); +} diff --git a/lib/src/models/place_opening_hours_period_detail/place_opening_hours_period_detail.g.dart b/lib/src/models/place_opening_hours_period_detail/place_opening_hours_period_detail.g.dart new file mode 100644 index 0000000..4b98557 --- /dev/null +++ b/lib/src/models/place_opening_hours_period_detail/place_opening_hours_period_detail.g.dart @@ -0,0 +1,21 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'place_opening_hours_period_detail.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +PlaceOpeningHoursPeriodDetail _$PlaceOpeningHoursPeriodDetailFromJson( + Map json) => + PlaceOpeningHoursPeriodDetail( + day: json['day'] as int, + time: json['time'] as String, + ); + +Map _$PlaceOpeningHoursPeriodDetailToJson( + PlaceOpeningHoursPeriodDetail instance) => + { + 'day': instance.day, + 'time': instance.time, + }; diff --git a/lib/src/models/place_photo/place_photo.dart b/lib/src/models/place_photo/place_photo.dart new file mode 100644 index 0000000..7eed91d --- /dev/null +++ b/lib/src/models/place_photo/place_photo.dart @@ -0,0 +1,30 @@ +import 'package:json_annotation/json_annotation.dart'; + +part 'place_photo.g.dart'; + +@JsonSerializable() +class PlacePhoto { + /// [photoReference] a string used to identify the photo when you perform a Photo request. + final String photoReference; + + /// [height] the maximum height of the image. + final int height; + + /// [width] the maximum width of the image. + final int width; + + /// [htmlAttributions] contains any required attributions. This field will always be present, but may be empty. + final List htmlAttributions; + + const PlacePhoto({ + required this.photoReference, + required this.height, + required this.width, + required this.htmlAttributions, + }); + + factory PlacePhoto.fromJson(Map json) => + _$PlacePhotoFromJson(json); + + Map toJson() => _$PlacePhotoToJson(this); +} diff --git a/lib/src/models/photo/photo.g.dart b/lib/src/models/place_photo/place_photo.g.dart similarity index 58% rename from lib/src/models/photo/photo.g.dart rename to lib/src/models/place_photo/place_photo.g.dart index d0193e4..e5c9b38 100644 --- a/lib/src/models/photo/photo.g.dart +++ b/lib/src/models/place_photo/place_photo.g.dart @@ -1,21 +1,22 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'photo.dart'; +part of 'place_photo.dart'; // ************************************************************************** // JsonSerializableGenerator // ************************************************************************** -Photo _$PhotoFromJson(Map json) => Photo( - photoReference: json['photo_reference'] as String?, - height: json['height'] as int?, - width: json['width'] as int?, - htmlAttributions: (json['html_attributions'] as List?) - ?.map((e) => e as String) +PlacePhoto _$PlacePhotoFromJson(Map json) => PlacePhoto( + photoReference: json['photo_reference'] as String, + height: json['height'] as int, + width: json['width'] as int, + htmlAttributions: (json['html_attributions'] as List) + .map((e) => e as String) .toList(), ); -Map _$PhotoToJson(Photo instance) => { +Map _$PlacePhotoToJson(PlacePhoto instance) => + { 'photo_reference': instance.photoReference, 'height': instance.height, 'width': instance.width, diff --git a/lib/src/models/review/review.dart b/lib/src/models/place_review/place_review.dart similarity index 76% rename from lib/src/models/review/review.dart rename to lib/src/models/place_review/place_review.dart index e23a8ea..5bd4aab 100644 --- a/lib/src/models/review/review.dart +++ b/lib/src/models/place_review/place_review.dart @@ -1,11 +1,20 @@ import 'package:json_annotation/json_annotation.dart'; -part 'review.g.dart'; +part 'place_review.g.dart'; @JsonSerializable() -class Review { +class PlaceReview { /// [authorName] the name of the user who submitted the review. Anonymous reviews are attributed to "A Google user". - final String? authorName; + final String authorName; + + /// [rating] the user's overall rating for this place. This is a whole number, ranging from 1 to 5. + final int rating; + + /// [relativeTimeDescription] the time that the review was submitted, relative to the current time. + final String relativeTimeDescription; + + /// [time] the time that the review was submitted, measured in the number of seconds since since midnight, January 1, 1970 UTC. + final int time; /// [authorUrl] the URL to the user's Google Maps Local Guides profile, if available. final String? authorUrl; @@ -18,32 +27,24 @@ class Review { /// [profilePhotoUrl] the URL to the user's profile photo, if available. final String? profilePhotoUrl; - /// [rating] the user's overall rating for this place. This is a whole number, ranging from 1 to 5. - final int? rating; - - /// [relativeTimeDescription] the time that the review was submitted, relative to the current time. - final String? relativeTimeDescription; - /// [text] the user's review. When reviewing a location with Google Places, text reviews are considered optional. /// Therefore, this field may by empty. Note that this field may include simple HTML markup. For example, /// the entity reference & may represent an ampersand character. final String? text; - /// [time] the time that the review was submitted, measured in the number of seconds since since midnight, January 1, 1970 UTC. - final int? time; - - const Review({ - this.authorName, + const PlaceReview({ + required this.authorName, + required this.rating, + required this.relativeTimeDescription, + required this.time, this.authorUrl, this.language, this.profilePhotoUrl, - this.rating, - this.relativeTimeDescription, this.text, - this.time, }); - factory Review.fromJson(Map json) => _$ReviewFromJson(json); + factory PlaceReview.fromJson(Map json) => + _$PlaceReviewFromJson(json); - Map toJson() => _$ReviewToJson(this); + Map toJson() => _$PlaceReviewToJson(this); } diff --git a/lib/src/models/review/review.g.dart b/lib/src/models/place_review/place_review.g.dart similarity index 71% rename from lib/src/models/review/review.g.dart rename to lib/src/models/place_review/place_review.g.dart index 3986fe8..c3aa042 100644 --- a/lib/src/models/review/review.g.dart +++ b/lib/src/models/place_review/place_review.g.dart @@ -1,29 +1,30 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'review.dart'; +part of 'place_review.dart'; // ************************************************************************** // JsonSerializableGenerator // ************************************************************************** -Review _$ReviewFromJson(Map json) => Review( - authorName: json['author_name'] as String?, +PlaceReview _$PlaceReviewFromJson(Map json) => PlaceReview( + authorName: json['author_name'] as String, + rating: json['rating'] as int, + relativeTimeDescription: json['relative_time_description'] as String, + time: json['time'] as int, authorUrl: json['author_url'] as String?, language: json['language'] as String?, profilePhotoUrl: json['profile_photo_url'] as String?, - rating: json['rating'] as int?, - relativeTimeDescription: json['relative_time_description'] as String?, text: json['text'] as String?, - time: json['time'] as int?, ); -Map _$ReviewToJson(Review instance) => { +Map _$PlaceReviewToJson(PlaceReview instance) => + { 'author_name': instance.authorName, + 'rating': instance.rating, + 'relative_time_description': instance.relativeTimeDescription, + 'time': instance.time, 'author_url': instance.authorUrl, 'language': instance.language, 'profile_photo_url': instance.profilePhotoUrl, - 'rating': instance.rating, - 'relative_time_description': instance.relativeTimeDescription, 'text': instance.text, - 'time': instance.time, }; diff --git a/lib/src/models/plus_code/plus_code.dart b/lib/src/models/plus_code/plus_code.dart index 89de481..7649e7d 100644 --- a/lib/src/models/plus_code/plus_code.dart +++ b/lib/src/models/plus_code/plus_code.dart @@ -2,15 +2,19 @@ import 'package:json_annotation/json_annotation.dart'; part 'plus_code.g.dart'; +/// An encoded location reference, derived from latitude and longitude coordinates, that represents an area, 1/8000th of a degree by 1/8000th of a degree (about 14m x 14m at the equator) or smaller. Plus codes can be used as a replacement for street addresses in places where they do not exist (where buildings are not numbered or streets are not named). @JsonSerializable() class PlusCode { /// [globalCode] is a 4 character area code and 6 character or longer local code (849VCWC8+R9). - final String? globalCode; + final String globalCode; /// [compoundCode] is a 6 character or longer local code with an explicit location (CWC8+R9, Mountain View, CA, USA). final String? compoundCode; - const PlusCode({this.globalCode, this.compoundCode}); + const PlusCode({ + required this.globalCode, + this.compoundCode, + }); factory PlusCode.fromJson(Map json) => _$PlusCodeFromJson(json); diff --git a/lib/src/models/plus_code/plus_code.g.dart b/lib/src/models/plus_code/plus_code.g.dart index d18ecdc..0dc6333 100644 --- a/lib/src/models/plus_code/plus_code.g.dart +++ b/lib/src/models/plus_code/plus_code.g.dart @@ -7,7 +7,7 @@ part of 'plus_code.dart'; // ************************************************************************** PlusCode _$PlusCodeFromJson(Map json) => PlusCode( - globalCode: json['global_code'] as String?, + globalCode: json['global_code'] as String, compoundCode: json['compound_code'] as String?, ); diff --git a/lib/src/models/time_and_day/time_and_day.dart b/lib/src/models/time_and_day/time_and_day.dart deleted file mode 100644 index 07545be..0000000 --- a/lib/src/models/time_and_day/time_and_day.dart +++ /dev/null @@ -1,20 +0,0 @@ -import 'package:json_annotation/json_annotation.dart'; - -part 'time_and_day.g.dart'; - -@JsonSerializable() -class TimeAndDay { - /// [day] a number from 0–6, corresponding to the days of the week, starting on Sunday. For example, 2 means Tuesday. - final int? day; - - /// [time] may contain a time of day in 24-hour hhmm format. Values are in the range 0000–2359. - /// The time will be reported in the place’s time zone. - final String? time; - - const TimeAndDay({this.day, this.time}); - - factory TimeAndDay.fromJson(Map json) => - _$TimeAndDayFromJson(json); - - Map toJson() => _$TimeAndDayToJson(this); -} diff --git a/lib/src/models/time_and_day/time_and_day.g.dart b/lib/src/models/time_and_day/time_and_day.g.dart deleted file mode 100644 index 0ad0aad..0000000 --- a/lib/src/models/time_and_day/time_and_day.g.dart +++ /dev/null @@ -1,18 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'time_and_day.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -TimeAndDay _$TimeAndDayFromJson(Map json) => TimeAndDay( - day: json['day'] as int?, - time: json['time'] as String?, - ); - -Map _$TimeAndDayToJson(TimeAndDay instance) => - { - 'day': instance.day, - 'time': instance.time, - }; diff --git a/lib/src/details/details_result/details_result.dart b/lib/src/places_details/place/place.dart similarity index 91% rename from lib/src/details/details_result/details_result.dart rename to lib/src/places_details/place/place.dart index 9455357..7d72eb1 100644 --- a/lib/src/details/details_result/details_result.dart +++ b/lib/src/places_details/place/place.dart @@ -1,15 +1,15 @@ import 'package:google_place/src/models/address_component/address_component.dart'; import 'package:google_place/src/models/geometry/geometry.dart'; -import 'package:google_place/src/models/opening_hours/opening_hours.dart'; -import 'package:google_place/src/models/photo/photo.dart'; +import 'package:google_place/src/models/place_opening_hours/place_opening_hours.dart'; +import 'package:google_place/src/models/place_photo/place_photo.dart'; +import 'package:google_place/src/models/place_review/place_review.dart'; import 'package:google_place/src/models/plus_code/plus_code.dart'; -import 'package:google_place/src/models/review/review.dart'; import 'package:json_annotation/json_annotation.dart'; -part 'details_result.g.dart'; +part 'place.g.dart'; @JsonSerializable() -class DetailsResult { +class Place { /// [addressComponents] is an array containing the separate components applicable to this address. final List? addressComponents; @@ -49,10 +49,10 @@ class DetailsResult { final String? name; /// [geometry] contains OpeningHours object. - final OpeningHours? openingHours; + final PlaceOpeningHours? openingHours; /// [photos] an array of photo objects, each containing a reference to an image. - final List? photos; + final List? photos; /// [placeId] A textual identifier that uniquely identifies a place. To retrieve information about the place, /// pass this identifier in the placeId field of a Places API request. For more information about place IDs. @@ -72,7 +72,7 @@ class DetailsResult { /// [reviews] a JSON array of up to five reviews. If a language parameter was specified in the Place Details request, /// the Places Service will bias the results to prefer reviews written in that language. - final List? reviews; + final List? reviews; /// [scope] contains scope. final String? scope; @@ -118,7 +118,7 @@ class DetailsResult { ) final bool? permanentlyClosed; - const DetailsResult({ + const Place({ this.addressComponents, this.businessStatus, this.adrAddress, @@ -147,8 +147,7 @@ class DetailsResult { this.permanentlyClosed, }); - factory DetailsResult.fromJson(Map json) => - _$DetailsResultFromJson(json); + factory Place.fromJson(Map json) => _$PlaceFromJson(json); - Map toJson() => _$DetailsResultToJson(this); + Map toJson() => _$PlaceToJson(this); } diff --git a/lib/src/details/details_result/details_result.g.dart b/lib/src/places_details/place/place.g.dart similarity index 88% rename from lib/src/details/details_result/details_result.g.dart rename to lib/src/places_details/place/place.g.dart index 4025eca..320cff5 100644 --- a/lib/src/details/details_result/details_result.g.dart +++ b/lib/src/places_details/place/place.g.dart @@ -1,13 +1,12 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'details_result.dart'; +part of 'place.dart'; // ************************************************************************** // JsonSerializableGenerator // ************************************************************************** -DetailsResult _$DetailsResultFromJson(Map json) => - DetailsResult( +Place _$PlaceFromJson(Map json) => Place( addressComponents: (json['address_components'] as List?) ?.map((e) => AddressComponent.fromJson(e as Map)) .toList(), @@ -24,10 +23,10 @@ DetailsResult _$DetailsResultFromJson(Map json) => name: json['name'] as String?, openingHours: json['opening_hours'] == null ? null - : OpeningHours.fromJson( + : PlaceOpeningHours.fromJson( json['opening_hours'] as Map), photos: (json['photos'] as List?) - ?.map((e) => Photo.fromJson(e as Map)) + ?.map((e) => PlacePhoto.fromJson(e as Map)) .toList(), placeId: json['place_id'] as String?, plusCode: json['plus_code'] == null @@ -36,7 +35,7 @@ DetailsResult _$DetailsResultFromJson(Map json) => rating: (json['rating'] as num?)?.toDouble(), reference: json['reference'] as String?, reviews: (json['reviews'] as List?) - ?.map((e) => Review.fromJson(e as Map)) + ?.map((e) => PlaceReview.fromJson(e as Map)) .toList(), scope: json['scope'] as String?, types: @@ -50,8 +49,7 @@ DetailsResult _$DetailsResultFromJson(Map json) => permanentlyClosed: json['permanently_closed'] as bool?, ); -Map _$DetailsResultToJson(DetailsResult instance) => - { +Map _$PlaceToJson(Place instance) => { 'address_components': instance.addressComponents, 'business_status': instance.businessStatus, 'adr_address': instance.adrAddress, diff --git a/lib/src/details/details.dart b/lib/src/places_details/places_details.dart similarity index 95% rename from lib/src/details/details.dart rename to lib/src/places_details/places_details.dart index 54035c9..f3e689f 100644 --- a/lib/src/details/details.dart +++ b/lib/src/places_details/places_details.dart @@ -1,9 +1,9 @@ import 'dart:convert'; -import 'package:google_place/src/details/details_response/details_response.dart'; +import 'package:google_place/src/places_details/places_details_response/places_details_response.dart'; import 'package:google_place/src/utils/network_utility.dart'; -class Details { +class PlacesDetails { static const _authority = 'maps.googleapis.com'; static const _unencodedPath = 'maps/api/place/details/json'; @@ -14,7 +14,7 @@ class Details { final String? proxyUrl; - const Details(this.apiKEY, this.headers, this.proxyUrl); + const PlacesDetails(this.apiKEY, this.headers, this.proxyUrl); /// Once you have a place_id from a Place Search, you can request more details about a /// particular establishment or point of interest by initiating a Place Details request. @@ -41,7 +41,7 @@ class Details { /// /// [fields] Optional parameters - One or more fields, specifying the types of place data to return, /// separated by a comma. - Future get( + Future get( String placeId, { String? language, String? region, @@ -66,7 +66,7 @@ class Details { final response = await fetchUrl(uri, headers: headers); if (response != null) { - return DetailsResponse.fromJson( + return PlacesDetailsResponse.fromJson( jsonDecode(response) as Map, ); } diff --git a/lib/src/places_details/places_details_response/places_details_response.dart b/lib/src/places_details/places_details_response/places_details_response.dart new file mode 100644 index 0000000..1deac93 --- /dev/null +++ b/lib/src/places_details/places_details_response/places_details_response.dart @@ -0,0 +1,32 @@ +import 'package:google_place/src/places_details/place/place.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'places_details_response.g.dart'; + +/// The Details response contains html Attributions and details and status +@JsonSerializable() +class PlacesDetailsResponse { + /// May contain a set of attributions about this listing which must be displayed to the user (some listings may not have attribution). + final List htmlAttributions; + + /// Contains the detailed information about the place requested. + final Place result; + + /// Contains the status of the request, and may contain debugging information to help you track down why the request failed. + final String? status; + + /// When the service returns additional information about the request specification, there may be an additional info_messages field within the response object. This field is only returned for successful requests. It may not always be returned, and its content is subject to change. + final List? infoMessages; + + const PlacesDetailsResponse({ + required this.htmlAttributions, + required this.status, + required this.result, + this.infoMessages, + }); + + factory PlacesDetailsResponse.fromJson(Map json) => + _$PlacesDetailsResponseFromJson(json); + + Map toJson() => _$PlacesDetailsResponseToJson(this); +} diff --git a/lib/src/details/details_response/details_response.g.dart b/lib/src/places_details/places_details_response/places_details_response.g.dart similarity index 52% rename from lib/src/details/details_response/details_response.g.dart rename to lib/src/places_details/places_details_response/places_details_response.g.dart index 7c9b98d..03ef2fd 100644 --- a/lib/src/details/details_response/details_response.g.dart +++ b/lib/src/places_details/places_details_response/places_details_response.g.dart @@ -1,25 +1,29 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'details_response.dart'; +part of 'places_details_response.dart'; // ************************************************************************** // JsonSerializableGenerator // ************************************************************************** -DetailsResponse _$DetailsResponseFromJson(Map json) => - DetailsResponse( +PlacesDetailsResponse _$PlacesDetailsResponseFromJson( + Map json) => + PlacesDetailsResponse( + htmlAttributions: (json['html_attributions'] as List) + .map((e) => e as String) + .toList(), status: json['status'] as String?, - htmlAttributions: (json['html_attributions'] as List?) + result: Place.fromJson(json['result'] as Map), + infoMessages: (json['info_messages'] as List?) ?.map((e) => e as String) .toList(), - result: json['result'] == null - ? null - : DetailsResult.fromJson(json['result'] as Map), ); -Map _$DetailsResponseToJson(DetailsResponse instance) => +Map _$PlacesDetailsResponseToJson( + PlacesDetailsResponse instance) => { - 'status': instance.status, 'html_attributions': instance.htmlAttributions, 'result': instance.result, + 'status': instance.status, + 'info_messages': instance.infoMessages, }; diff --git a/lib/src/search/find_place_response/find_place_response.dart b/lib/src/search/find_place_response/find_place_response.dart deleted file mode 100644 index 7e51401..0000000 --- a/lib/src/search/find_place_response/find_place_response.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:google_place/src/models/debug_log/debug_log.dart'; -import 'package:google_place/src/search/search_result/search_result.dart'; -import 'package:json_annotation/json_annotation.dart'; - -part 'find_place_response.g.dart'; - -/// The Find Place Search response contains html Attributions and search results and status -@JsonSerializable() -class FindPlaceResponse { - final String? status; - - final List? htmlAttributions; - - final String? nextPageToken; - - final DebugLog? debugLog; - - final List? candidates; - - const FindPlaceResponse({ - this.status, - this.htmlAttributions, - this.nextPageToken, - this.debugLog, - this.candidates, - }); - - factory FindPlaceResponse.fromJson(Map json) => - _$FindPlaceResponseFromJson(json); - - Map toJson() => _$FindPlaceResponseToJson(this); -} diff --git a/lib/src/search/find_place_response/find_place_response.g.dart b/lib/src/search/find_place_response/find_place_response.g.dart deleted file mode 100644 index 975c53f..0000000 --- a/lib/src/search/find_place_response/find_place_response.g.dart +++ /dev/null @@ -1,31 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'find_place_response.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -FindPlaceResponse _$FindPlaceResponseFromJson(Map json) => - FindPlaceResponse( - status: json['status'] as String?, - htmlAttributions: (json['html_attributions'] as List?) - ?.map((e) => e as String) - .toList(), - nextPageToken: json['next_page_token'] as String?, - debugLog: json['debug_log'] == null - ? null - : DebugLog.fromJson(json['debug_log'] as Map), - candidates: (json['candidates'] as List?) - ?.map((e) => SearchResult.fromJson(e as Map)) - .toList(), - ); - -Map _$FindPlaceResponseToJson(FindPlaceResponse instance) => - { - 'status': instance.status, - 'html_attributions': instance.htmlAttributions, - 'next_page_token': instance.nextPageToken, - 'debug_log': instance.debugLog, - 'candidates': instance.candidates, - }; diff --git a/lib/src/search/nearby_search_response/nearby_search_response.dart b/lib/src/search/nearby_search_response/nearby_search_response.dart deleted file mode 100644 index 3e4389c..0000000 --- a/lib/src/search/nearby_search_response/nearby_search_response.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:google_place/src/models/debug_log/debug_log.dart'; -import 'package:google_place/src/search/search_result/search_result.dart'; -import 'package:json_annotation/json_annotation.dart'; - -part 'nearby_search_response.g.dart'; - -/// The Near By Search response contains html Attributions and search results and status -@JsonSerializable() -class NearbySearchResponse { - final String? status; - - final List? htmlAttributions; - - final String? nextPageToken; - - final DebugLog? debugLog; - - final List? results; - - const NearbySearchResponse({ - this.status, - this.htmlAttributions, - this.nextPageToken, - this.debugLog, - this.results, - }); - - factory NearbySearchResponse.fromJson(Map json) => - _$NearbySearchResponseFromJson(json); - - Map toJson() => _$NearbySearchResponseToJson(this); -} diff --git a/lib/src/search/places_find_place__from_text_response/places_find_place__from_text_response.dart b/lib/src/search/places_find_place__from_text_response/places_find_place__from_text_response.dart new file mode 100644 index 0000000..a829ab6 --- /dev/null +++ b/lib/src/search/places_find_place__from_text_response/places_find_place__from_text_response.dart @@ -0,0 +1,32 @@ +import 'package:google_place/src/places_details/place/place.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'places_find_place__from_text_response.g.dart'; + +/// The Find Place Search response contains html Attributions and search results and status +@JsonSerializable() +class PlacesFindPlaceFromTextResponse { + final List htmlAttributions; + + final List candidates; + + final String status; + + final String? errorMessage; + + final List? infoMessages; + + const PlacesFindPlaceFromTextResponse({ + required this.htmlAttributions, + required this.candidates, + required this.status, + this.errorMessage, + this.infoMessages, + }); + + factory PlacesFindPlaceFromTextResponse.fromJson(Map json) => + _$PlacesFindPlaceFromTextResponseFromJson(json); + + Map toJson() => + _$PlacesFindPlaceFromTextResponseToJson(this); +} diff --git a/lib/src/search/places_find_place__from_text_response/places_find_place__from_text_response.g.dart b/lib/src/search/places_find_place__from_text_response/places_find_place__from_text_response.g.dart new file mode 100644 index 0000000..940656f --- /dev/null +++ b/lib/src/search/places_find_place__from_text_response/places_find_place__from_text_response.g.dart @@ -0,0 +1,33 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'places_find_place__from_text_response.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +PlacesFindPlaceFromTextResponse _$PlacesFindPlaceFromTextResponseFromJson( + Map json) => + PlacesFindPlaceFromTextResponse( + htmlAttributions: (json['html_attributions'] as List) + .map((e) => e as String) + .toList(), + candidates: (json['candidates'] as List) + .map((e) => Place.fromJson(e as Map)) + .toList(), + status: json['status'] as String, + errorMessage: json['error_message'] as String?, + infoMessages: (json['info_messages'] as List?) + ?.map((e) => e as String) + .toList(), + ); + +Map _$PlacesFindPlaceFromTextResponseToJson( + PlacesFindPlaceFromTextResponse instance) => + { + 'html_attributions': instance.htmlAttributions, + 'candidates': instance.candidates, + 'status': instance.status, + 'error_message': instance.errorMessage, + 'info_messages': instance.infoMessages, + }; diff --git a/lib/src/search/places_nearby_search_response/places_nearby_search_response.dart b/lib/src/search/places_nearby_search_response/places_nearby_search_response.dart new file mode 100644 index 0000000..050e9e2 --- /dev/null +++ b/lib/src/search/places_nearby_search_response/places_nearby_search_response.dart @@ -0,0 +1,35 @@ +import 'package:google_place/src/places_details/place/place.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'places_nearby_search_response.g.dart'; + +/// The Near By Search response contains html Attributions and search results and status +@JsonSerializable() +class PlacesNearbySearchResponse { + final List htmlAttributions; + + final List results; + + // TODO: This should be an enum + final String status; + + final String? errorMessage; + + final List? infoMessages; + + final String? nextPageToken; + + const PlacesNearbySearchResponse({ + required this.htmlAttributions, + required this.results, + required this.status, + this.errorMessage, + this.infoMessages, + this.nextPageToken, + }); + + factory PlacesNearbySearchResponse.fromJson(Map json) => + _$PlacesNearbySearchResponseFromJson(json); + + Map toJson() => _$PlacesNearbySearchResponseToJson(this); +} diff --git a/lib/src/search/places_nearby_search_response/places_nearby_search_response.g.dart b/lib/src/search/places_nearby_search_response/places_nearby_search_response.g.dart new file mode 100644 index 0000000..28aada1 --- /dev/null +++ b/lib/src/search/places_nearby_search_response/places_nearby_search_response.g.dart @@ -0,0 +1,35 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'places_nearby_search_response.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +PlacesNearbySearchResponse _$PlacesNearbySearchResponseFromJson( + Map json) => + PlacesNearbySearchResponse( + htmlAttributions: (json['html_attributions'] as List) + .map((e) => e as String) + .toList(), + results: (json['results'] as List) + .map((e) => Place.fromJson(e as Map)) + .toList(), + status: json['status'] as String, + errorMessage: json['error_message'] as String?, + infoMessages: (json['info_messages'] as List?) + ?.map((e) => e as String) + .toList(), + nextPageToken: json['next_page_token'] as String?, + ); + +Map _$PlacesNearbySearchResponseToJson( + PlacesNearbySearchResponse instance) => + { + 'html_attributions': instance.htmlAttributions, + 'results': instance.results, + 'status': instance.status, + 'error_message': instance.errorMessage, + 'info_messages': instance.infoMessages, + 'next_page_token': instance.nextPageToken, + }; diff --git a/lib/src/search/places_text_search_response/places_text_search_response.dart b/lib/src/search/places_text_search_response/places_text_search_response.dart new file mode 100644 index 0000000..c6b678d --- /dev/null +++ b/lib/src/search/places_text_search_response/places_text_search_response.dart @@ -0,0 +1,34 @@ +import 'package:google_place/src/places_details/place/place.dart'; +import 'package:json_annotation/json_annotation.dart'; + +part 'places_text_search_response.g.dart'; + +/// The Text Search response contains html Attributions and search results and status +@JsonSerializable() +class PlacesTextSearchResponse { + final List htmlAttributions; + + final List results; + + final String status; + + final String? errorMessage; + + final List? infoMessages; + + final String? nextPageToken; + + const PlacesTextSearchResponse({ + required this.htmlAttributions, + required this.results, + required this.status, + this.errorMessage, + this.infoMessages, + this.nextPageToken, + }); + + factory PlacesTextSearchResponse.fromJson(Map json) => + _$PlacesTextSearchResponseFromJson(json); + + Map toJson() => _$PlacesTextSearchResponseToJson(this); +} diff --git a/lib/src/search/nearby_search_response/nearby_search_response.g.dart b/lib/src/search/places_text_search_response/places_text_search_response.g.dart similarity index 50% rename from lib/src/search/nearby_search_response/nearby_search_response.g.dart rename to lib/src/search/places_text_search_response/places_text_search_response.g.dart index f2e65d4..c0bcad3 100644 --- a/lib/src/search/nearby_search_response/nearby_search_response.g.dart +++ b/lib/src/search/places_text_search_response/places_text_search_response.g.dart @@ -1,33 +1,35 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'nearby_search_response.dart'; +part of 'places_text_search_response.dart'; // ************************************************************************** // JsonSerializableGenerator // ************************************************************************** -NearbySearchResponse _$NearbySearchResponseFromJson( +PlacesTextSearchResponse _$PlacesTextSearchResponseFromJson( Map json) => - NearbySearchResponse( - status: json['status'] as String?, - htmlAttributions: (json['html_attributions'] as List?) + PlacesTextSearchResponse( + htmlAttributions: (json['html_attributions'] as List) + .map((e) => e as String) + .toList(), + results: (json['results'] as List) + .map((e) => Place.fromJson(e as Map)) + .toList(), + status: json['status'] as String, + errorMessage: json['error_message'] as String?, + infoMessages: (json['info_messages'] as List?) ?.map((e) => e as String) .toList(), nextPageToken: json['next_page_token'] as String?, - debugLog: json['debug_log'] == null - ? null - : DebugLog.fromJson(json['debug_log'] as Map), - results: (json['results'] as List?) - ?.map((e) => SearchResult.fromJson(e as Map)) - .toList(), ); -Map _$NearbySearchResponseToJson( - NearbySearchResponse instance) => +Map _$PlacesTextSearchResponseToJson( + PlacesTextSearchResponse instance) => { - 'status': instance.status, 'html_attributions': instance.htmlAttributions, - 'next_page_token': instance.nextPageToken, - 'debug_log': instance.debugLog, 'results': instance.results, + 'status': instance.status, + 'error_message': instance.errorMessage, + 'info_messages': instance.infoMessages, + 'next_page_token': instance.nextPageToken, }; diff --git a/lib/src/search/search.dart b/lib/src/search/search.dart index 75f95aa..b97930b 100644 --- a/lib/src/search/search.dart +++ b/lib/src/search/search.dart @@ -41,7 +41,7 @@ class Search { /// /// [locationbias] Optional parameters - Prefer results in a specified area, by specifying either a radius plus /// lat/lng, or two lat/lng pairs representing the points of a rectangle. - Future getFindPlace( + Future getFindPlace( String input, InputType inputType, { String? language, @@ -66,7 +66,7 @@ class Search { final response = await fetchUrl(uri, headers: headers); if (response != null) { - return FindPlaceResponse.fromJson( + return PlacesFindPlaceFromTextResponse.fromJson( jsonDecode(response) as Map, ); } @@ -113,8 +113,8 @@ class Search { /// [pagetoken] Optional parameters - Returns up to 20 results from a previously run search. Setting a /// pagetoken parameter will execute a search with the same parameters used previously — all parameters /// other than pagetoken will be ignored. - Future getNearBySearch( - Location location, + Future getNearBySearch( + LatLngLiteral location, int radius, { String? keyword, String? language, @@ -145,7 +145,7 @@ class Search { final response = await fetchUrl(uri, headers: headers); if (response != null) { - return NearbySearchResponse.fromJson( + return PlacesNearbySearchResponse.fromJson( jsonDecode(response) as Map, ); } @@ -198,10 +198,10 @@ class Search { /// [pagetoken] Optional parameters - Returns up to 20 results from a previously run search. Setting a pagetoken /// parameter will execute a search with the same parameters used previously — all parameters other than pagetoken /// will be ignored. - Future getTextSearch( + Future getTextSearch( String query, { String? region, - Location? location, + LatLngLiteral? location, int? radius, String? language, int? minprice, @@ -229,7 +229,7 @@ class Search { final response = await fetchUrl(uri, headers: headers); if (response != null) { - return TextSearchResponse.fromJson( + return PlacesTextSearchResponse.fromJson( jsonDecode(response) as Map, ); } @@ -324,7 +324,7 @@ class Search { /// pagetoken parameter will execute a search with the same parameters used previously — all parameters /// other than pagetoken will be ignored. Future getNearBySearchJson( - Location location, + LatLngLiteral location, int radius, { String? keyword, String? language, @@ -404,7 +404,7 @@ class Search { Future getTextSearchJson( String query, { String? region, - Location? location, + LatLngLiteral? location, int? radius, String? language, int? minprice, @@ -482,7 +482,7 @@ class Search { /// Prepare query Parameters for near by search Map _createNearBySearchParameters( String apiKEY, - Location location, + LatLngLiteral location, int radius, String? keyword, String? language, @@ -527,7 +527,7 @@ class Search { String apiKEY, String query, String? region, - Location? location, + LatLngLiteral? location, int? radius, String? language, int? minprice, diff --git a/lib/src/search/search_result/search_result.dart b/lib/src/search/search_result/search_result.dart deleted file mode 100644 index 7d5ea7a..0000000 --- a/lib/src/search/search_result/search_result.dart +++ /dev/null @@ -1,114 +0,0 @@ -import 'package:google_place/src/models/geometry/geometry.dart'; -import 'package:google_place/src/models/photo/photo.dart'; -import 'package:google_place/src/models/plus_code/plus_code.dart'; -import 'package:google_place/src/models/time_and_day/time_and_day.dart'; -import 'package:json_annotation/json_annotation.dart'; - -part 'search_result.g.dart'; - -@JsonSerializable() -class SearchResult { - /// [geometry] contains geometry information about the result, - /// generally including the location (geocode) of the place and (optionally) - /// the viewport identifying its general area of coverage. - final Geometry? geometry; - - /// [businessStatus] indicates the operational status of the place, if it is a business. - /// If no data exists, business_status is not returned. It can contain one of the following values: - /// OPERATIONAL - /// CLOSED_TEMPORARILY - /// CLOSED_PERMANENTLY - final String? businessStatus; - - /// [openingHours] show opening hours - final TimeAndDay? openingHours; - - /// [photos] an array of photo objects, each containing a reference to an image. - final List? photos; - - /// [plusCode] is an encoded location reference, derived from latitude and longitude coordinates, - /// that represents an area: 1/8000th of a degree by 1/8000th of a degree (about 14m x 14m at the equator) or smaller. - /// Plus codes can be used as a replacement for street addresses in places where they do not exist - /// (where buildings are not numbered or streets are not named). - final PlusCode? plusCode; - - /// [formattedAddress] is a string containing the human-readable address of this place. - /// Often this address is equivalent to the "postal address". - final String? formattedAddress; - - /// [name] contains the human-readable name for the returned result. - /// For establishment results, this is usually the business name. - final String? name; - - /// [rating] contains the place's rating, from 1.0 to 5.0, based on aggregated user reviews. - final double? rating; - - /// [icon] contains the URL of a recommended icon which may be displayed to the user when indicating this result. - final String? icon; - - /// [id] contains id. - final String? id; - - /// [placeId] a textual identifier that uniquely identifies a place. To retrieve information about the place, - /// pass this identifier in the placeId field of a Places API request. For more information about place IDs. - final String? placeId; - - /// [priceLevel] The price level of the place, on a scale of 0 to 4. - /// The exact amount indicated by a specific value will vary from region to region. Price levels are interpreted as follows: - /// 0 — Free - /// 1 — Inexpensive - /// 2 — Moderate - /// 3 — Expensive - /// 4 — Very Expensive - final int? priceLevel; - - /// [reference] contains reference. - final String? reference; - - /// [scope] contains scope. - final String? scope; - - /// [types] contains an array of feature types describing the given result. See the list of supported types. - /// XML responses include multiple elements if more than one type is assigned to the result. - final List? types; - - /// [userRatingsTotal] is user ratings total. - final int? userRatingsTotal; - - /// [vicinity] contains a feature name of a nearby location. Often this feature refers to a street or - /// neighborhood within the given results. The vicinity property is only returned for a Nearby Search. - final String? vicinity; - - /// [permanentlyClosed] is a boolean flag indicating whether the place has shut down either permanently - /// or temporarily (value true). If the place is operational, or if no data is available, the flag is absent from the response. - @Deprecated( - 'permanently_closed is now deprecated. Instead, use business_status to get the operational status of businesses.', - ) - final bool? permanentlyClosed; - - const SearchResult({ - this.geometry, - this.businessStatus, - this.openingHours, - this.photos, - this.plusCode, - this.formattedAddress, - this.name, - this.rating, - this.icon, - this.id, - this.placeId, - this.priceLevel, - this.reference, - this.scope, - this.types, - this.userRatingsTotal, - this.vicinity, - this.permanentlyClosed, - }); - - factory SearchResult.fromJson(Map json) => - _$SearchResultFromJson(json); - - Map toJson() => _$SearchResultToJson(this); -} diff --git a/lib/src/search/search_result/search_result.g.dart b/lib/src/search/search_result/search_result.g.dart deleted file mode 100644 index 3bd64fe..0000000 --- a/lib/src/search/search_result/search_result.g.dart +++ /dev/null @@ -1,59 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'search_result.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -SearchResult _$SearchResultFromJson(Map json) => SearchResult( - geometry: json['geometry'] == null - ? null - : Geometry.fromJson(json['geometry'] as Map), - businessStatus: json['business_status'] as String?, - openingHours: json['opening_hours'] == null - ? null - : TimeAndDay.fromJson(json['opening_hours'] as Map), - photos: (json['photos'] as List?) - ?.map((e) => Photo.fromJson(e as Map)) - .toList(), - plusCode: json['plus_code'] == null - ? null - : PlusCode.fromJson(json['plus_code'] as Map), - formattedAddress: json['formatted_address'] as String?, - name: json['name'] as String?, - rating: (json['rating'] as num?)?.toDouble(), - icon: json['icon'] as String?, - id: json['id'] as String?, - placeId: json['place_id'] as String?, - priceLevel: json['price_level'] as int?, - reference: json['reference'] as String?, - scope: json['scope'] as String?, - types: - (json['types'] as List?)?.map((e) => e as String).toList(), - userRatingsTotal: json['user_ratings_total'] as int?, - vicinity: json['vicinity'] as String?, - permanentlyClosed: json['permanently_closed'] as bool?, - ); - -Map _$SearchResultToJson(SearchResult instance) => - { - 'geometry': instance.geometry, - 'business_status': instance.businessStatus, - 'opening_hours': instance.openingHours, - 'photos': instance.photos, - 'plus_code': instance.plusCode, - 'formatted_address': instance.formattedAddress, - 'name': instance.name, - 'rating': instance.rating, - 'icon': instance.icon, - 'id': instance.id, - 'place_id': instance.placeId, - 'price_level': instance.priceLevel, - 'reference': instance.reference, - 'scope': instance.scope, - 'types': instance.types, - 'user_ratings_total': instance.userRatingsTotal, - 'vicinity': instance.vicinity, - 'permanently_closed': instance.permanentlyClosed, - }; diff --git a/lib/src/search/text_search_response.dart b/lib/src/search/text_search_response.dart deleted file mode 100644 index 3253be9..0000000 --- a/lib/src/search/text_search_response.dart +++ /dev/null @@ -1,32 +0,0 @@ -import 'package:google_place/src/models/debug_log/debug_log.dart'; -import 'package:google_place/src/search/search_result/search_result.dart'; -import 'package:json_annotation/json_annotation.dart'; - -part 'text_search_response.g.dart'; - -/// The Text Search response contains html Attributions and search results and status -@JsonSerializable() -class TextSearchResponse { - final String? status; - - final List? htmlAttributions; - - final String? nextPageToken; - - final DebugLog? debugLog; - - final List? results; - - const TextSearchResponse({ - this.status, - this.htmlAttributions, - this.nextPageToken, - this.debugLog, - this.results, - }); - - factory TextSearchResponse.fromJson(Map json) => - _$TextSearchResponseFromJson(json); - - Map toJson() => _$TextSearchResponseToJson(this); -} diff --git a/lib/src/search/text_search_response.g.dart b/lib/src/search/text_search_response.g.dart deleted file mode 100644 index b567cb9..0000000 --- a/lib/src/search/text_search_response.g.dart +++ /dev/null @@ -1,31 +0,0 @@ -// GENERATED CODE - DO NOT MODIFY BY HAND - -part of 'text_search_response.dart'; - -// ************************************************************************** -// JsonSerializableGenerator -// ************************************************************************** - -TextSearchResponse _$TextSearchResponseFromJson(Map json) => - TextSearchResponse( - status: json['status'] as String?, - htmlAttributions: (json['html_attributions'] as List?) - ?.map((e) => e as String) - .toList(), - nextPageToken: json['next_page_token'] as String?, - debugLog: json['debug_log'] == null - ? null - : DebugLog.fromJson(json['debug_log'] as Map), - results: (json['results'] as List?) - ?.map((e) => SearchResult.fromJson(e as Map)) - .toList(), - ); - -Map _$TextSearchResponseToJson(TextSearchResponse instance) => - { - 'status': instance.status, - 'html_attributions': instance.htmlAttributions, - 'next_page_token': instance.nextPageToken, - 'debug_log': instance.debugLog, - 'results': instance.results, - }; From e2b9f35cc60c1e86e1da47c934ce913518335ae7 Mon Sep 17 00:00:00 2001 From: Nolence Date: Fri, 29 Apr 2022 14:33:26 -0600 Subject: [PATCH 05/12] fixed underscore issue --- lib/google_place.dart | 2 +- .../places_find_place_from_text_response.dart} | 2 +- .../places_find_place_from_text_response.g.dart} | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) rename lib/src/search/{places_find_place__from_text_response/places_find_place__from_text_response.dart => places_find_place_from_text_response/places_find_place_from_text_response.dart} (94%) rename lib/src/search/{places_find_place__from_text_response/places_find_place__from_text_response.g.dart => places_find_place_from_text_response/places_find_place_from_text_response.g.dart} (95%) diff --git a/lib/google_place.dart b/lib/google_place.dart index 318a4f7..abfe1fa 100644 --- a/lib/google_place.dart +++ b/lib/google_place.dart @@ -30,7 +30,7 @@ export 'package:google_place/src/models/term/term.dart'; export 'package:google_place/src/places_details/place/place.dart'; export 'package:google_place/src/places_details/places_details.dart'; export 'package:google_place/src/places_details/places_details_response/places_details_response.dart'; -export 'package:google_place/src/search/places_find_place__from_text_response/places_find_place__from_text_response.dart'; +export 'package:google_place/src/search/places_find_place_from_text_response/places_find_place_from_text_response.dart'; export 'package:google_place/src/search/places_nearby_search_response/places_nearby_search_response.dart'; export 'package:google_place/src/search/places_text_search_response/places_text_search_response.dart'; diff --git a/lib/src/search/places_find_place__from_text_response/places_find_place__from_text_response.dart b/lib/src/search/places_find_place_from_text_response/places_find_place_from_text_response.dart similarity index 94% rename from lib/src/search/places_find_place__from_text_response/places_find_place__from_text_response.dart rename to lib/src/search/places_find_place_from_text_response/places_find_place_from_text_response.dart index a829ab6..ab6d43d 100644 --- a/lib/src/search/places_find_place__from_text_response/places_find_place__from_text_response.dart +++ b/lib/src/search/places_find_place_from_text_response/places_find_place_from_text_response.dart @@ -1,7 +1,7 @@ import 'package:google_place/src/places_details/place/place.dart'; import 'package:json_annotation/json_annotation.dart'; -part 'places_find_place__from_text_response.g.dart'; +part 'places_find_place_from_text_response.g.dart'; /// The Find Place Search response contains html Attributions and search results and status @JsonSerializable() diff --git a/lib/src/search/places_find_place__from_text_response/places_find_place__from_text_response.g.dart b/lib/src/search/places_find_place_from_text_response/places_find_place_from_text_response.g.dart similarity index 95% rename from lib/src/search/places_find_place__from_text_response/places_find_place__from_text_response.g.dart rename to lib/src/search/places_find_place_from_text_response/places_find_place_from_text_response.g.dart index 940656f..1c15145 100644 --- a/lib/src/search/places_find_place__from_text_response/places_find_place__from_text_response.g.dart +++ b/lib/src/search/places_find_place_from_text_response/places_find_place_from_text_response.g.dart @@ -1,6 +1,6 @@ // GENERATED CODE - DO NOT MODIFY BY HAND -part of 'places_find_place__from_text_response.dart'; +part of 'places_find_place_from_text_response.dart'; // ************************************************************************** // JsonSerializableGenerator From 0d936ad1a2d53d909d1301ca22b34b602b8f64cf Mon Sep 17 00:00:00 2001 From: Nolence Date: Mon, 2 May 2022 09:22:35 -0600 Subject: [PATCH 06/12] throws exception instead of passing thru null --- lib/src/autocomplete/autocomplete.dart | 24 ++++----- lib/src/photos/photos.dart | 10 ++-- lib/src/places_details/places_details.dart | 13 ++--- .../query_autocomplete.dart | 12 ++--- lib/src/search/search.dart | 52 ++++++++----------- lib/src/utils/network_utility.dart | 23 ++++---- 6 files changed, 56 insertions(+), 78 deletions(-) diff --git a/lib/src/autocomplete/autocomplete.dart b/lib/src/autocomplete/autocomplete.dart index b105dd6..f4144a1 100644 --- a/lib/src/autocomplete/autocomplete.dart +++ b/lib/src/autocomplete/autocomplete.dart @@ -94,7 +94,7 @@ class Autocomplete { assert(location != null); assert(radius != null); } - var queryParameters = _createParameters( + final queryParameters = _createParameters( apiKEY, input, sessionToken, @@ -109,7 +109,7 @@ class Autocomplete { strictbounds, ); - var uri = createUri( + final uri = createUri( proxyUrl, _authority, _unencodedPath, @@ -118,13 +118,9 @@ class Autocomplete { final response = await fetchUrl(uri, headers: headers); - if (response != null) { - return AutocompleteResponse.fromJson( - jsonDecode(response) as Map, - ); - } - - return null; + return AutocompleteResponse.fromJson( + jsonDecode(response.body) as Map, + ); } /// The Place Autocomplete service is a web service that returns place predictions in response @@ -200,7 +196,7 @@ class Autocomplete { assert(location != null); assert(radius != null); } - var queryParameters = _createParameters( + final queryParameters = _createParameters( apiKEY, input, sessionToken, @@ -214,15 +210,15 @@ class Autocomplete { components, strictbounds, ); - - var uri = Uri.https( + final uri = Uri.https( proxyUrl != null && proxyUrl != '' ? proxyUrl! : _authority, proxyUrl != null && proxyUrl != '' ? 'https://$_authority/$_unencodedPath' : _unencodedPath, queryParameters, ); - return await fetchUrl(uri, headers: headers); + + return (await fetchUrl(uri, headers: headers)).body; } /// Prepare query Parameters @@ -266,7 +262,7 @@ class Autocomplete { result += '|'; } } - var item = { + final item = { 'components': result, }; queryParameters.addAll(item); diff --git a/lib/src/photos/photos.dart b/lib/src/photos/photos.dart index 53abc05..91b3c86 100644 --- a/lib/src/photos/photos.dart +++ b/lib/src/photos/photos.dart @@ -51,13 +51,9 @@ class Photos { queryParameters, ); final response = await fetchUrl(uri, headers: headers); + final list = response.body.codeUnits; - if (response != null) { - List list = response.codeUnits; - return Uint8List.fromList(list); - } - - return null; + return Uint8List.fromList(list); } /// The Place Photo service, part of the Places API, is a read- only API that allows you to @@ -97,7 +93,7 @@ class Photos { queryParameters, ); - return await fetchUrl(uri, headers: headers); + return (await fetchUrl(uri, headers: headers)).body; } /// Prepare query Parameters diff --git a/lib/src/places_details/places_details.dart b/lib/src/places_details/places_details.dart index f3e689f..2d71f4d 100644 --- a/lib/src/places_details/places_details.dart +++ b/lib/src/places_details/places_details.dart @@ -65,13 +65,9 @@ class PlacesDetails { ); final response = await fetchUrl(uri, headers: headers); - if (response != null) { - return PlacesDetailsResponse.fromJson( - jsonDecode(response) as Map, - ); - } - - return null; + return PlacesDetailsResponse.fromJson( + jsonDecode(response.body) as Map, + ); } /// Once you have a place_id from a Place Search, you can request more details about a @@ -99,6 +95,7 @@ class PlacesDetails { /// /// [fields] Optional parameters - One or more fields, specifying the types of place data to return, /// separated by a comma. + // FIXME: This should be named getJsonString Future getJson( String placeId, { String? language, @@ -123,7 +120,7 @@ class PlacesDetails { queryParameters, ); - return await fetchUrl(uri, headers: headers); + return (await fetchUrl(uri, headers: headers)).body; } /// Prepare query Parameters diff --git a/lib/src/query_autocomplete/query_autocomplete.dart b/lib/src/query_autocomplete/query_autocomplete.dart index 33c1da8..ea51151 100644 --- a/lib/src/query_autocomplete/query_autocomplete.dart +++ b/lib/src/query_autocomplete/query_autocomplete.dart @@ -62,13 +62,9 @@ class QueryAutocomplete { ); final response = await fetchUrl(uri, headers: headers); - if (response != null) { - return AutocompleteResponse.fromJson( - jsonDecode(response) as Map, - ); - } - - return null; + return AutocompleteResponse.fromJson( + jsonDecode(response.body) as Map, + ); } /// The Query Autocomplete service can be used to provide a query prediction for text-based @@ -116,7 +112,7 @@ class QueryAutocomplete { queryParameters, ); - return await fetchUrl(uri, headers: headers); + return (await fetchUrl(uri, headers: headers)).body; } /// Prepare query Parameters diff --git a/lib/src/search/search.dart b/lib/src/search/search.dart index b97930b..47d0a0b 100644 --- a/lib/src/search/search.dart +++ b/lib/src/search/search.dart @@ -65,13 +65,9 @@ class Search { ); final response = await fetchUrl(uri, headers: headers); - if (response != null) { - return PlacesFindPlaceFromTextResponse.fromJson( - jsonDecode(response) as Map, - ); - } - - return null; + return PlacesFindPlaceFromTextResponse.fromJson( + jsonDecode(response.body) as Map, + ); } /// A Nearby Search lets you search for places within a specified area. @@ -144,13 +140,9 @@ class Search { Uri.https(_authority, _unencodedPathNearBySearch, queryParameters); final response = await fetchUrl(uri, headers: headers); - if (response != null) { - return PlacesNearbySearchResponse.fromJson( - jsonDecode(response) as Map, - ); - } - - return null; + return PlacesNearbySearchResponse.fromJson( + jsonDecode(response.body) as Map, + ); } /// The Google Places API Text Search Service is a web service that returns information about a set of places @@ -228,13 +220,9 @@ class Search { Uri.https(_authority, _unencodedPathTextSearch, queryParameters); final response = await fetchUrl(uri, headers: headers); - if (response != null) { - return PlacesTextSearchResponse.fromJson( - jsonDecode(response) as Map, - ); - } - - return null; + return PlacesTextSearchResponse.fromJson( + jsonDecode(response.body) as Map, + ); } /// A Find Place request takes a text input and returns a place. @@ -257,6 +245,7 @@ class Search { /// /// [locationbias] Optional parameters - Prefer results in a specified area, by specifying either a radius plus /// lat/lng, or two lat/lng pairs representing the points of a rectangle. + // TODO: Why do we expose this? Whose gonna use this? Future getFindPlaceJson( String input, InputType inputType, { @@ -265,7 +254,7 @@ class Search { Locationbias? locationbias, }) async { assert(input != ""); - var queryParameters = _createFindPlaceParameters( + final queryParameters = _createFindPlaceParameters( apiKEY, input, inputType, @@ -274,14 +263,14 @@ class Search { locationbias, ); - var uri = Uri.https( + final uri = Uri.https( proxyUrl != null && proxyUrl != '' ? proxyUrl! : _authority, proxyUrl != null && proxyUrl != '' ? 'https://$_authority/$_unencodedPathFindPlace' : _unencodedPathFindPlace, queryParameters, ); - return await fetchUrl(uri, headers: headers); + return (await fetchUrl(uri, headers: headers)).body; } /// A Nearby Search lets you search for places within a specified area. @@ -336,7 +325,7 @@ class Search { String? type, String? pagetoken, }) async { - var queryParameters = _createNearBySearchParameters( + final queryParameters = _createNearBySearchParameters( apiKEY, location, radius, @@ -350,10 +339,10 @@ class Search { type, pagetoken, ); - - var uri = + final uri = Uri.https(_authority, _unencodedPathNearBySearch, queryParameters); - return await fetchUrl(uri, headers: headers); + + return (await fetchUrl(uri, headers: headers)).body; } /// The Google Places API Text Search Service is a web service that returns information about a set of places @@ -414,7 +403,7 @@ class Search { String? pagetoken, }) async { assert(query != ""); - var queryParameters = _createTextSearchParameters( + final queryParameters = _createTextSearchParameters( apiKEY, query, region, @@ -427,9 +416,10 @@ class Search { type, pagetoken, ); + final uri = + Uri.https(_authority, _unencodedPathTextSearch, queryParameters); - var uri = Uri.https(_authority, _unencodedPathTextSearch, queryParameters); - return await fetchUrl(uri, headers: headers); + return (await fetchUrl(uri, headers: headers)).body; } /// Prepare query Parameters for find place diff --git a/lib/src/utils/network_utility.dart b/lib/src/utils/network_utility.dart index 732918b..c7ea4bb 100644 --- a/lib/src/utils/network_utility.dart +++ b/lib/src/utils/network_utility.dart @@ -1,22 +1,25 @@ import 'package:google_place/google_place.dart'; import 'package:http/http.dart' as http; +import 'package:http/http.dart'; /// The Network Utility -Future fetchUrl( +Future fetchUrl( Uri uri, { Map? headers, }) async { - try { - final response = - await http.get(uri, headers: headers).timeout(GooglePlace.timeout); + final response = + await http.get(uri, headers: headers).timeout(GooglePlace.timeout); - if (response.statusCode == 200) { - return response.body; - } - return null; - } catch (e) { - return null; + if (response.statusCode != 200) { + // Include all information, including statusCode and reasonPhrase + throw Exception( + 'Failed to load url: $uri\n' + 'Status code: ${response.statusCode}\n' + 'Reason phrase: ${response.reasonPhrase}', + ); } + + return response; } /// Creates a uri with the proxy url if it is set From c50a6fb45694e5f008d20df4345070829590e607 Mon Sep 17 00:00:00 2001 From: Nolence Date: Mon, 2 May 2022 09:28:10 -0600 Subject: [PATCH 07/12] stops return types from being nullable --- lib/src/autocomplete/autocomplete.dart | 5 ++- lib/src/photos/photos.dart | 4 +-- lib/src/places_details/places_details.dart | 4 +-- .../query_autocomplete.dart | 4 +-- lib/src/search/search.dart | 34 +++++++++++-------- 5 files changed, 27 insertions(+), 24 deletions(-) diff --git a/lib/src/autocomplete/autocomplete.dart b/lib/src/autocomplete/autocomplete.dart index f4144a1..9c12770 100644 --- a/lib/src/autocomplete/autocomplete.dart +++ b/lib/src/autocomplete/autocomplete.dart @@ -76,7 +76,7 @@ class Autocomplete { /// [strictbounds] Optional parameters - Returns only those places that are strictly within /// the region defined by location and radius. This is a restriction, rather than a bias, /// meaning that results outside this region will not be returned even if they match the user input. - Future get( + Future get( String input, { String? sessionToken, int? offset, @@ -108,7 +108,6 @@ class Autocomplete { components, strictbounds, ); - final uri = createUri( proxyUrl, _authority, @@ -178,7 +177,7 @@ class Autocomplete { /// [strictbounds] Optional parameters - Returns only those places that are strictly within /// the region defined by location and radius. This is a restriction, rather than a bias, /// meaning that results outside this region will not be returned even if they match the user input. - Future getJson( + Future getJson( String input, { String? sessionToken, int? offset, diff --git a/lib/src/photos/photos.dart b/lib/src/photos/photos.dart index 91b3c86..d252c8f 100644 --- a/lib/src/photos/photos.dart +++ b/lib/src/photos/photos.dart @@ -32,7 +32,7 @@ class Photos { /// dimension, it will be scaled to match the smaller of the two dimensions, restricted to its /// original aspect ratio. Both the maxheight and maxwidth properties accept an integer /// between 1 and 1600. - Future get( + Future get( String photoReference, int maxHeight, int maxWidth, @@ -73,7 +73,7 @@ class Photos { /// dimension, it will be scaled to match the smaller of the two dimensions, restricted to its /// original aspect ratio. Both the maxheight and maxwidth properties accept an integer /// between 1 and 1600. - Future getJson( + Future getJson( String photoReference, int maxHeight, int maxWidth, diff --git a/lib/src/places_details/places_details.dart b/lib/src/places_details/places_details.dart index 2d71f4d..c1aa5e8 100644 --- a/lib/src/places_details/places_details.dart +++ b/lib/src/places_details/places_details.dart @@ -41,7 +41,7 @@ class PlacesDetails { /// /// [fields] Optional parameters - One or more fields, specifying the types of place data to return, /// separated by a comma. - Future get( + Future get( String placeId, { String? language, String? region, @@ -96,7 +96,7 @@ class PlacesDetails { /// [fields] Optional parameters - One or more fields, specifying the types of place data to return, /// separated by a comma. // FIXME: This should be named getJsonString - Future getJson( + Future getJson( String placeId, { String? language, String? region, diff --git a/lib/src/query_autocomplete/query_autocomplete.dart b/lib/src/query_autocomplete/query_autocomplete.dart index ea51151..af3a74a 100644 --- a/lib/src/query_autocomplete/query_autocomplete.dart +++ b/lib/src/query_autocomplete/query_autocomplete.dart @@ -38,7 +38,7 @@ class QueryAutocomplete { /// the selected language may be given a higher ranking. See the supported list of domain languages. /// If language is not supplied, the Places service will attempt to use the native language of the /// domain from which the request is sent. - Future get( + Future get( String input, { int? offset, LatLon? location, @@ -89,7 +89,7 @@ class QueryAutocomplete { /// the selected language may be given a higher ranking. See the supported list of domain languages. /// If language is not supplied, the Places service will attempt to use the native language of the /// domain from which the request is sent. - Future getJson( + Future getJson( String input, { int? offset, LatLon? location, diff --git a/lib/src/search/search.dart b/lib/src/search/search.dart index 47d0a0b..ac6d284 100644 --- a/lib/src/search/search.dart +++ b/lib/src/search/search.dart @@ -41,7 +41,7 @@ class Search { /// /// [locationbias] Optional parameters - Prefer results in a specified area, by specifying either a radius plus /// lat/lng, or two lat/lng pairs representing the points of a rectangle. - Future getFindPlace( + Future getFindPlace( String input, InputType inputType, { String? language, @@ -109,7 +109,7 @@ class Search { /// [pagetoken] Optional parameters - Returns up to 20 results from a previously run search. Setting a /// pagetoken parameter will execute a search with the same parameters used previously — all parameters /// other than pagetoken will be ignored. - Future getNearBySearch( + Future getNearBySearch( LatLngLiteral location, int radius, { String? keyword, @@ -190,7 +190,7 @@ class Search { /// [pagetoken] Optional parameters - Returns up to 20 results from a previously run search. Setting a pagetoken /// parameter will execute a search with the same parameters used previously — all parameters other than pagetoken /// will be ignored. - Future getTextSearch( + Future getTextSearch( String query, { String? region, LatLngLiteral? location, @@ -246,7 +246,7 @@ class Search { /// [locationbias] Optional parameters - Prefer results in a specified area, by specifying either a radius plus /// lat/lng, or two lat/lng pairs representing the points of a rectangle. // TODO: Why do we expose this? Whose gonna use this? - Future getFindPlaceJson( + Future getFindPlaceJson( String input, InputType inputType, { String? language, @@ -262,7 +262,6 @@ class Search { fields, locationbias, ); - final uri = Uri.https( proxyUrl != null && proxyUrl != '' ? proxyUrl! : _authority, proxyUrl != null && proxyUrl != '' @@ -270,6 +269,7 @@ class Search { : _unencodedPathFindPlace, queryParameters, ); + return (await fetchUrl(uri, headers: headers)).body; } @@ -312,7 +312,7 @@ class Search { /// [pagetoken] Optional parameters - Returns up to 20 results from a previously run search. Setting a /// pagetoken parameter will execute a search with the same parameters used previously — all parameters /// other than pagetoken will be ignored. - Future getNearBySearchJson( + Future getNearBySearchJson( LatLngLiteral location, int radius, { String? keyword, @@ -390,7 +390,7 @@ class Search { /// [pagetoken] Optional parameters - Returns up to 20 results from a previously run search. Setting a pagetoken /// parameter will execute a search with the same parameters used previously — all parameters other than pagetoken /// will be ignored. - Future getTextSearchJson( + Future getTextSearchJson( String query, { String? region, LatLngLiteral? location, @@ -423,7 +423,7 @@ class Search { } /// Prepare query Parameters for find place - Map _createFindPlaceParameters( + Map _createFindPlaceParameters( String apiKEY, String input, InputType inputType, @@ -432,7 +432,7 @@ class Search { Locationbias? locationbias, ) { final cleanedInput = input.trimRight().trimLeft(); - final queryParameters = { + final queryParameters = { 'input': cleanedInput, 'key': apiKEY, 'inputtype': inputType == InputType.textQuery @@ -457,20 +457,24 @@ class Search { value = 'circle:${locationbias.circular!.radius}@${locationbias.circular!.latLng.latitude},${locationbias.circular!.latLng.longitude}'; } - if (locationbias.rectangular != null) { + final _rectangle = locationbias.rectangular; + + if (_rectangle != null) { value = - 'rectangle:${locationbias.rectangular!.southWest.latitude},${locationbias.rectangular!.southWest.longitude}|${locationbias.rectangular!.northEast.latitude},${locationbias.rectangular!.northEast.longitude}'; + 'rectangle:${_rectangle.southWest.latitude},${_rectangle.southWest.longitude}|${_rectangle.northEast.latitude},${_rectangle.northEast.longitude}'; } - final item = {'locationbias': value}; - queryParameters.addAll(item); + if (value != null) { + final item = {'locationbias': value}; + queryParameters.addAll(item); + } } return queryParameters; } /// Prepare query Parameters for near by search - Map _createNearBySearchParameters( + Map _createNearBySearchParameters( String apiKEY, LatLngLiteral location, int radius, @@ -484,7 +488,7 @@ class Search { String? type, String? pagetoken, ) { - final queryParameters = { + final queryParameters = { 'location': '${location.lat},${location.lng}', 'key': apiKEY, 'radius': radius.toString(), From 8bf6997447578bf2538da86f83909525ac940274 Mon Sep 17 00:00:00 2001 From: Nolence Date: Mon, 2 May 2022 12:01:16 -0600 Subject: [PATCH 08/12] instead of bytes, returns full response --- example/lib/main.dart | 7 ++++--- lib/src/photos/photos.dart | 18 ++++++++++++------ 2 files changed, 16 insertions(+), 9 deletions(-) diff --git a/example/lib/main.dart b/example/lib/main.dart index 2d1ddfb..dcf3ab2 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -342,10 +342,11 @@ class _DetailsPageState extends State { } Future getPhoto(String photoReference) async { - var result = await widget.googlePlace.photos.get(photoReference, null, 400); - if (result != null && mounted) { + final response = + await widget.googlePlace.photos.get(photoReference, null, 400); + if (response != null && mounted) { setState(() { - images.add(result); + images.add(Uint8List.fromList(response.body.codeUnits)); }); } } diff --git a/lib/src/photos/photos.dart b/lib/src/photos/photos.dart index d252c8f..2a3b9c3 100644 --- a/lib/src/photos/photos.dart +++ b/lib/src/photos/photos.dart @@ -1,6 +1,5 @@ -import 'dart:typed_data'; - import 'package:google_place/src/utils/network_utility.dart'; +import 'package:http/http.dart'; class Photos { static const _authority = 'maps.googleapis.com'; @@ -26,13 +25,13 @@ class Photos { /// [photoReference] Required parameters - A string identifier that uniquely identifies a photo. /// Photo references are returned from either a Place Search or Place Details request. /// - /// [minprice] or [maxprice] Required parameters - Specifies the maximum desired height or width, + /// [maxheight] or [maxwidth] Required parameters - Specifies the maximum desired height or width, /// in pixels, of the image returned by the Place Photos service. If the image is smaller than /// the values specified, the original image will be returned. If the image is larger in either /// dimension, it will be scaled to match the smaller of the two dimensions, restricted to its /// original aspect ratio. Both the maxheight and maxwidth properties accept an integer /// between 1 and 1600. - Future get( + Future get( String photoReference, int maxHeight, int maxWidth, @@ -51,9 +50,16 @@ class Photos { queryParameters, ); final response = await fetchUrl(uri, headers: headers); - final list = response.body.codeUnits; - return Uint8List.fromList(list); + if (response.statusCode != 200) { + throw Exception( + 'Failed to load photo reference $photoReference\n' + 'Status Code: ${response.statusCode}\n' + 'Reason: ${response.reasonPhrase}', + ); + } + + return response; } /// The Place Photo service, part of the Places API, is a read- only API that allows you to From ac72615c1387d68deb4df9c0f7e35979df18465e Mon Sep 17 00:00:00 2001 From: Nolence Date: Tue, 3 May 2022 09:02:48 -0600 Subject: [PATCH 09/12] nearby should be considered one word --- README.md | 2 +- lib/src/search/search.dart | 16 ++++++++-------- 2 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index bd1f04f..a713d75 100644 --- a/README.md +++ b/README.md @@ -77,7 +77,7 @@ Uint8List result = await googlePlace.details.get("ChIJN1t_tDeuEmsRUsoyG83frY4", ```dart var googlePlace = GooglePlace("Your-Key"); - var result = await googlePlace.search.getNearBySearch( + var result = await googlePlace.search.getNearbySearch( Location(lat: -33.8670522, lng: 151.1957362), 1500, type: "restaurant", keyword: "cruise"); ``` diff --git a/lib/src/search/search.dart b/lib/src/search/search.dart index ac6d284..283ad66 100644 --- a/lib/src/search/search.dart +++ b/lib/src/search/search.dart @@ -9,7 +9,7 @@ class Search { static const _unencodedPathFindPlace = 'maps/api/place/findplacefromtext/json'; - static const _unencodedPathNearBySearch = 'maps/api/place/nearbysearch/json'; + static const _unencodedPathNearbySearch = 'maps/api/place/nearbysearch/json'; static const _unencodedPathTextSearch = 'maps/api/place/textsearch/json'; @@ -109,7 +109,7 @@ class Search { /// [pagetoken] Optional parameters - Returns up to 20 results from a previously run search. Setting a /// pagetoken parameter will execute a search with the same parameters used previously — all parameters /// other than pagetoken will be ignored. - Future getNearBySearch( + Future getNearbySearch( LatLngLiteral location, int radius, { String? keyword, @@ -122,7 +122,7 @@ class Search { String? type, String? pagetoken, }) async { - final queryParameters = _createNearBySearchParameters( + final queryParameters = _createNearbySearchParameters( apiKEY, location, radius, @@ -137,7 +137,7 @@ class Search { pagetoken, ); final uri = - Uri.https(_authority, _unencodedPathNearBySearch, queryParameters); + Uri.https(_authority, _unencodedPathNearbySearch, queryParameters); final response = await fetchUrl(uri, headers: headers); return PlacesNearbySearchResponse.fromJson( @@ -312,7 +312,7 @@ class Search { /// [pagetoken] Optional parameters - Returns up to 20 results from a previously run search. Setting a /// pagetoken parameter will execute a search with the same parameters used previously — all parameters /// other than pagetoken will be ignored. - Future getNearBySearchJson( + Future getNearbySearchJson( LatLngLiteral location, int radius, { String? keyword, @@ -325,7 +325,7 @@ class Search { String? type, String? pagetoken, }) async { - final queryParameters = _createNearBySearchParameters( + final queryParameters = _createNearbySearchParameters( apiKEY, location, radius, @@ -340,7 +340,7 @@ class Search { pagetoken, ); final uri = - Uri.https(_authority, _unencodedPathNearBySearch, queryParameters); + Uri.https(_authority, _unencodedPathNearbySearch, queryParameters); return (await fetchUrl(uri, headers: headers)).body; } @@ -474,7 +474,7 @@ class Search { } /// Prepare query Parameters for near by search - Map _createNearBySearchParameters( + Map _createNearbySearchParameters( String apiKEY, LatLngLiteral location, int radius, From b99ab4c95157bfbb201f4205ae1572d29ef6253b Mon Sep 17 00:00:00 2001 From: Nolence Date: Tue, 17 May 2022 12:26:16 -0600 Subject: [PATCH 10/12] updated version number --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 7b71c2c..bdde58a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -2,7 +2,7 @@ name: google_place description: A Flutter package for handle google place api that place search and details and photos and autocomplete and query autocomplete requests are available -version: 0.4.7 +version: 0.5.0 homepage: https://github.com/bazrafkan/google_place environment: From ffba3e8b6021a8e2322fb562c8cd5ba0520996e6 Mon Sep 17 00:00:00 2001 From: Nolence Date: Wed, 8 Jun 2022 19:09:37 -0600 Subject: [PATCH 11/12] remove lates and made timeout 30 seconds --- example/pubspec.lock | 18 +++++++++--------- lib/google_place.dart | 25 ++++++++++++------------- pubspec.lock | 16 ++++++++-------- 3 files changed, 29 insertions(+), 30 deletions(-) diff --git a/example/pubspec.lock b/example/pubspec.lock index 022adba..a38d924 100644 --- a/example/pubspec.lock +++ b/example/pubspec.lock @@ -42,7 +42,7 @@ packages: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.15.0" + version: "1.16.0" cupertino_icons: dependency: "direct main" description: @@ -56,7 +56,7 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.3.0" flutter: dependency: "direct main" description: flutter @@ -87,7 +87,7 @@ packages: path: ".." relative: true source: path - version: "0.4.7" + version: "0.5.0" http: dependency: transitive description: @@ -129,7 +129,7 @@ packages: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" + version: "0.1.4" meta: dependency: transitive description: @@ -143,7 +143,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0" + version: "1.8.1" pedantic: dependency: transitive description: @@ -162,7 +162,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.2" stack_trace: dependency: transitive description: @@ -197,7 +197,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.8" + version: "0.4.9" typed_data: dependency: transitive description: @@ -211,6 +211,6 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "2.1.2" sdks: - dart: ">=2.14.0 <3.0.0" + dart: ">=2.17.0-0 <3.0.0" diff --git a/lib/google_place.dart b/lib/google_place.dart index abfe1fa..181f033 100644 --- a/lib/google_place.dart +++ b/lib/google_place.dart @@ -41,22 +41,22 @@ class GooglePlace { final String apiKEY; /// [search] returns a list of places based on a user's location or search string. - late Search search; + final Search search; /// [details] returns more detailed information about a specific place, including user reviews. - late PlacesDetails details; + final PlacesDetails details; /// [photos] provides access to the millions of place-related photos stored in Google's Place database. - late Photos photos; + final Photos photos; /// [autocomplete] automatically fills in the name and/or address of a place as users type. - late Autocomplete autocomplete; + final Autocomplete autocomplete; /// [queryAutocomplete] provides a query prediction service for text-based geographic searches, returning suggested queries as users type. - late QueryAutocomplete queryAutocomplete; + final QueryAutocomplete queryAutocomplete; /// [timeout] timeout for http call. - static Duration timeout = const Duration(milliseconds: 1500); + final Duration timeout; /// Optional headers to pass on each request final Map headers; @@ -70,11 +70,10 @@ class GooglePlace { this.apiKEY, { this.headers = const {}, this.proxyUrl, - }) { - search = Search(apiKEY, headers, proxyUrl); - details = PlacesDetails(apiKEY, headers, proxyUrl); - photos = Photos(apiKEY, headers, proxyUrl); - autocomplete = Autocomplete(apiKEY, headers, proxyUrl); - queryAutocomplete = QueryAutocomplete(apiKEY, headers, proxyUrl); - } + this.timeout = const Duration(milliseconds: 30000), + }) : search = Search(apiKEY, headers, proxyUrl), + details = PlacesDetails(apiKEY, headers, proxyUrl), + photos = Photos(apiKEY, headers, proxyUrl), + autocomplete = Autocomplete(apiKEY, headers, proxyUrl), + queryAutocomplete = QueryAutocomplete(apiKEY, headers, proxyUrl); } diff --git a/pubspec.lock b/pubspec.lock index 3b5b2c1..8b289dc 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -133,7 +133,7 @@ packages: name: collection url: "https://pub.dartlang.org" source: hosted - version: "1.15.0" + version: "1.16.0" convert: dependency: transitive description: @@ -161,7 +161,7 @@ packages: name: fake_async url: "https://pub.dartlang.org" source: hosted - version: "1.2.0" + version: "1.3.0" file: dependency: transitive description: @@ -290,7 +290,7 @@ packages: name: material_color_utilities url: "https://pub.dartlang.org" source: hosted - version: "0.1.3" + version: "0.1.4" meta: dependency: transitive description: @@ -318,7 +318,7 @@ packages: name: path url: "https://pub.dartlang.org" source: hosted - version: "1.8.0" + version: "1.8.1" pedantic: dependency: transitive description: @@ -386,7 +386,7 @@ packages: name: source_span url: "https://pub.dartlang.org" source: hosted - version: "1.8.1" + version: "1.8.2" stack_trace: dependency: transitive description: @@ -428,7 +428,7 @@ packages: name: test_api url: "https://pub.dartlang.org" source: hosted - version: "0.4.8" + version: "0.4.9" timing: dependency: transitive description: @@ -449,7 +449,7 @@ packages: name: vector_math url: "https://pub.dartlang.org" source: hosted - version: "2.1.1" + version: "2.1.2" watcher: dependency: transitive description: @@ -472,4 +472,4 @@ packages: source: hosted version: "3.1.0" sdks: - dart: ">=2.16.0 <3.0.0" + dart: ">=2.17.0-0 <3.0.0" From 7208c144ac7d32ececf5fadd9a9474b64f20fbb0 Mon Sep 17 00:00:00 2001 From: Nolence Date: Wed, 8 Jun 2022 19:16:28 -0600 Subject: [PATCH 12/12] pass through parameters --- lib/google_place.dart | 11 ++++++----- lib/src/autocomplete/autocomplete.dart | 7 +++++-- lib/src/photos/photos.dart | 13 ++++++++++--- lib/src/places_details/places_details.dart | 8 +++++--- .../query_autocomplete/query_autocomplete.dart | 13 ++++++++++--- lib/src/search/search.dart | 16 +++++++++------- lib/src/utils/network_utility.dart | 5 ++--- 7 files changed, 47 insertions(+), 26 deletions(-) diff --git a/lib/google_place.dart b/lib/google_place.dart index 181f033..1d36553 100644 --- a/lib/google_place.dart +++ b/lib/google_place.dart @@ -71,9 +71,10 @@ class GooglePlace { this.headers = const {}, this.proxyUrl, this.timeout = const Duration(milliseconds: 30000), - }) : search = Search(apiKEY, headers, proxyUrl), - details = PlacesDetails(apiKEY, headers, proxyUrl), - photos = Photos(apiKEY, headers, proxyUrl), - autocomplete = Autocomplete(apiKEY, headers, proxyUrl), - queryAutocomplete = QueryAutocomplete(apiKEY, headers, proxyUrl); + }) : search = Search(apiKEY, headers, proxyUrl, timeout), + details = PlacesDetails(apiKEY, headers, proxyUrl, timeout), + photos = Photos(apiKEY, headers, proxyUrl, timeout), + autocomplete = Autocomplete(apiKEY, headers, proxyUrl, timeout), + queryAutocomplete = + QueryAutocomplete(apiKEY, headers, proxyUrl, timeout); } diff --git a/lib/src/autocomplete/autocomplete.dart b/lib/src/autocomplete/autocomplete.dart index 9c12770..99ff4b7 100644 --- a/lib/src/autocomplete/autocomplete.dart +++ b/lib/src/autocomplete/autocomplete.dart @@ -14,10 +14,13 @@ class Autocomplete { final String? proxyUrl; + final Duration timeout; + const Autocomplete( this.apiKEY, this.headers, this.proxyUrl, + this.timeout, ); /// The Place Autocomplete service is a web service that returns place predictions in response @@ -115,7 +118,7 @@ class Autocomplete { queryParameters, ); - final response = await fetchUrl(uri, headers: headers); + final response = await fetchUrl(uri, headers: headers, timeout: timeout); return AutocompleteResponse.fromJson( jsonDecode(response.body) as Map, @@ -217,7 +220,7 @@ class Autocomplete { queryParameters, ); - return (await fetchUrl(uri, headers: headers)).body; + return (await fetchUrl(uri, headers: headers, timeout: timeout)).body; } /// Prepare query Parameters diff --git a/lib/src/photos/photos.dart b/lib/src/photos/photos.dart index 2a3b9c3..f68d626 100644 --- a/lib/src/photos/photos.dart +++ b/lib/src/photos/photos.dart @@ -12,7 +12,14 @@ class Photos { final String? proxyUrl; - const Photos(this.apiKEY, this.headers, this.proxyUrl); + final Duration timeout; + + const Photos( + this.apiKEY, + this.headers, + this.proxyUrl, + this.timeout, + ); /// The Place Photo service, part of the Places API, is a read- only API that allows you to /// add high quality photographic content to your application. The Place Photo service gives @@ -49,7 +56,7 @@ class Photos { _unencodedPath, queryParameters, ); - final response = await fetchUrl(uri, headers: headers); + final response = await fetchUrl(uri, headers: headers, timeout: timeout); if (response.statusCode != 200) { throw Exception( @@ -99,7 +106,7 @@ class Photos { queryParameters, ); - return (await fetchUrl(uri, headers: headers)).body; + return (await fetchUrl(uri, headers: headers, timeout: timeout)).body; } /// Prepare query Parameters diff --git a/lib/src/places_details/places_details.dart b/lib/src/places_details/places_details.dart index c1aa5e8..ccdd4af 100644 --- a/lib/src/places_details/places_details.dart +++ b/lib/src/places_details/places_details.dart @@ -14,7 +14,9 @@ class PlacesDetails { final String? proxyUrl; - const PlacesDetails(this.apiKEY, this.headers, this.proxyUrl); + final Duration timeout; + + const PlacesDetails(this.apiKEY, this.headers, this.proxyUrl, this.timeout); /// Once you have a place_id from a Place Search, you can request more details about a /// particular establishment or point of interest by initiating a Place Details request. @@ -63,7 +65,7 @@ class PlacesDetails { _unencodedPath, queryParameters, ); - final response = await fetchUrl(uri, headers: headers); + final response = await fetchUrl(uri, headers: headers, timeout: timeout); return PlacesDetailsResponse.fromJson( jsonDecode(response.body) as Map, @@ -120,7 +122,7 @@ class PlacesDetails { queryParameters, ); - return (await fetchUrl(uri, headers: headers)).body; + return (await fetchUrl(uri, headers: headers, timeout: timeout)).body; } /// Prepare query Parameters diff --git a/lib/src/query_autocomplete/query_autocomplete.dart b/lib/src/query_autocomplete/query_autocomplete.dart index af3a74a..3908e8c 100644 --- a/lib/src/query_autocomplete/query_autocomplete.dart +++ b/lib/src/query_autocomplete/query_autocomplete.dart @@ -14,7 +14,14 @@ class QueryAutocomplete { final String? proxyUrl; - const QueryAutocomplete(this.apiKEY, this.headers, this.proxyUrl); + final Duration timeout; + + const QueryAutocomplete( + this.apiKEY, + this.headers, + this.proxyUrl, + this.timeout, + ); /// The Query Autocomplete service can be used to provide a query prediction for text-based /// geographic searches, by returning suggested queries as you type. @@ -60,7 +67,7 @@ class QueryAutocomplete { _unencodedPath, queryParameters, ); - final response = await fetchUrl(uri, headers: headers); + final response = await fetchUrl(uri, headers: headers, timeout: timeout); return AutocompleteResponse.fromJson( jsonDecode(response.body) as Map, @@ -112,7 +119,7 @@ class QueryAutocomplete { queryParameters, ); - return (await fetchUrl(uri, headers: headers)).body; + return (await fetchUrl(uri, headers: headers, timeout: timeout)).body; } /// Prepare query Parameters diff --git a/lib/src/search/search.dart b/lib/src/search/search.dart index 283ad66..667ee3a 100644 --- a/lib/src/search/search.dart +++ b/lib/src/search/search.dart @@ -19,7 +19,9 @@ class Search { final String? proxyUrl; - const Search(this.apiKEY, this.headers, this.proxyUrl); + final Duration timeout; + + const Search(this.apiKEY, this.headers, this.proxyUrl, this.timeout); /// A Find Place request takes a text input and returns a place. /// The input can be any kind of Places text data, such as a name, address, or phone number. @@ -63,7 +65,7 @@ class Search { _unencodedPathFindPlace, queryParameters, ); - final response = await fetchUrl(uri, headers: headers); + final response = await fetchUrl(uri, headers: headers, timeout: timeout); return PlacesFindPlaceFromTextResponse.fromJson( jsonDecode(response.body) as Map, @@ -138,7 +140,7 @@ class Search { ); final uri = Uri.https(_authority, _unencodedPathNearbySearch, queryParameters); - final response = await fetchUrl(uri, headers: headers); + final response = await fetchUrl(uri, headers: headers, timeout: timeout); return PlacesNearbySearchResponse.fromJson( jsonDecode(response.body) as Map, @@ -218,7 +220,7 @@ class Search { ); final uri = Uri.https(_authority, _unencodedPathTextSearch, queryParameters); - final response = await fetchUrl(uri, headers: headers); + final response = await fetchUrl(uri, headers: headers, timeout: timeout); return PlacesTextSearchResponse.fromJson( jsonDecode(response.body) as Map, @@ -270,7 +272,7 @@ class Search { queryParameters, ); - return (await fetchUrl(uri, headers: headers)).body; + return (await fetchUrl(uri, headers: headers, timeout: timeout)).body; } /// A Nearby Search lets you search for places within a specified area. @@ -342,7 +344,7 @@ class Search { final uri = Uri.https(_authority, _unencodedPathNearbySearch, queryParameters); - return (await fetchUrl(uri, headers: headers)).body; + return (await fetchUrl(uri, headers: headers, timeout: timeout)).body; } /// The Google Places API Text Search Service is a web service that returns information about a set of places @@ -419,7 +421,7 @@ class Search { final uri = Uri.https(_authority, _unencodedPathTextSearch, queryParameters); - return (await fetchUrl(uri, headers: headers)).body; + return (await fetchUrl(uri, headers: headers, timeout: timeout)).body; } /// Prepare query Parameters for find place diff --git a/lib/src/utils/network_utility.dart b/lib/src/utils/network_utility.dart index c7ea4bb..d1aafaa 100644 --- a/lib/src/utils/network_utility.dart +++ b/lib/src/utils/network_utility.dart @@ -1,4 +1,3 @@ -import 'package:google_place/google_place.dart'; import 'package:http/http.dart' as http; import 'package:http/http.dart'; @@ -6,9 +5,9 @@ import 'package:http/http.dart'; Future fetchUrl( Uri uri, { Map? headers, + Duration timeout = const Duration(milliseconds: 30000), }) async { - final response = - await http.get(uri, headers: headers).timeout(GooglePlace.timeout); + final response = await http.get(uri, headers: headers).timeout(timeout); if (response.statusCode != 200) { // Include all information, including statusCode and reasonPhrase