├── test └── flutter_google_places_test.dart ├── example ├── ios │ ├── Runner │ │ ├── Runner-Bridging-Header.h │ │ ├── Assets.xcassets │ │ │ ├── LaunchImage.imageset │ │ │ │ ├── LaunchImage.png │ │ │ │ ├── LaunchImage@2x.png │ │ │ │ ├── LaunchImage@3x.png │ │ │ │ ├── README.md │ │ │ │ └── Contents.json │ │ │ └── AppIcon.appiconset │ │ │ │ ├── Icon-App-20x20@1x.png │ │ │ │ ├── Icon-App-20x20@2x.png │ │ │ │ ├── Icon-App-20x20@3x.png │ │ │ │ ├── Icon-App-29x29@1x.png │ │ │ │ ├── Icon-App-29x29@2x.png │ │ │ │ ├── Icon-App-29x29@3x.png │ │ │ │ ├── Icon-App-40x40@1x.png │ │ │ │ ├── Icon-App-40x40@2x.png │ │ │ │ ├── Icon-App-40x40@3x.png │ │ │ │ ├── Icon-App-60x60@2x.png │ │ │ │ ├── Icon-App-60x60@3x.png │ │ │ │ ├── Icon-App-76x76@1x.png │ │ │ │ ├── Icon-App-76x76@2x.png │ │ │ │ ├── Icon-App-1024x1024@1x.png │ │ │ │ ├── Icon-App-83.5x83.5@2x.png │ │ │ │ └── Contents.json │ │ ├── AppDelegate.swift │ │ ├── Base.lproj │ │ │ ├── Main.storyboard │ │ │ └── LaunchScreen.storyboard │ │ └── Info.plist │ ├── Flutter │ │ ├── Debug.xcconfig │ │ ├── Release.xcconfig │ │ └── AppFrameworkInfo.plist │ ├── Runner.xcodeproj │ │ ├── project.xcworkspace │ │ │ ├── contents.xcworkspacedata │ │ │ └── xcshareddata │ │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ │ └── IDEWorkspaceChecks.plist │ │ ├── xcshareddata │ │ │ └── xcschemes │ │ │ │ └── Runner.xcscheme │ │ └── project.pbxproj │ ├── Runner.xcworkspace │ │ ├── contents.xcworkspacedata │ │ └── xcshareddata │ │ │ ├── WorkspaceSettings.xcsettings │ │ │ └── IDEWorkspaceChecks.plist │ ├── Podfile.lock │ ├── .gitignore │ └── Podfile ├── web │ ├── favicon.png │ ├── icons │ │ ├── Icon-192.png │ │ └── Icon-512.png │ ├── manifest.json │ └── index.html ├── android │ ├── gradle.properties │ ├── app │ │ ├── src │ │ │ ├── main │ │ │ │ ├── res │ │ │ │ │ ├── mipmap-hdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-mdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── mipmap-xxxhdpi │ │ │ │ │ │ └── ic_launcher.png │ │ │ │ │ ├── drawable │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── drawable-v21 │ │ │ │ │ │ └── launch_background.xml │ │ │ │ │ ├── values │ │ │ │ │ │ └── styles.xml │ │ │ │ │ └── values-night │ │ │ │ │ │ └── styles.xml │ │ │ │ ├── kotlin │ │ │ │ │ └── com │ │ │ │ │ │ └── hoc │ │ │ │ │ │ └── example │ │ │ │ │ │ └── MainActivity.kt │ │ │ │ └── AndroidManifest.xml │ │ │ ├── debug │ │ │ │ └── AndroidManifest.xml │ │ │ └── profile │ │ │ │ └── AndroidManifest.xml │ │ └── build.gradle │ ├── gradle │ │ └── wrapper │ │ │ └── gradle-wrapper.properties │ ├── .gitignore │ ├── settings.gradle │ └── build.gradle ├── README.md ├── analysis_options.yaml ├── .metadata ├── .gitignore ├── test │ └── widget_test.dart ├── pubspec.yaml ├── lib │ ├── custom.dart │ └── main.dart └── pubspec.lock ├── lib ├── src │ ├── google_maps_webservice │ │ ├── places.dart │ │ └── src │ │ │ ├── utils.dart │ │ │ ├── core.g.dart │ │ │ ├── core.dart │ │ │ ├── places.g.dart │ │ │ └── places.dart │ ├── places_autocomplete_form_field.dart │ └── places_autocomplete_field.dart ├── assets │ ├── google_black.png │ └── google_white.png ├── google_maps_webservice_places.dart └── flutter_google_places_hoc081098.dart ├── flutter_01.png ├── flutter_02.png ├── analysis_options.yaml ├── .all-contributorsrc ├── pubspec.yaml ├── LICENSE ├── .gitignore ├── .github └── workflows │ └── build-example.yml ├── README.md ├── CHANGELOG.md └── pubspec.lock /test/flutter_google_places_test.dart: -------------------------------------------------------------------------------- 1 | void main() {} 2 | -------------------------------------------------------------------------------- /example/ios/Runner/Runner-Bridging-Header.h: -------------------------------------------------------------------------------- 1 | #import "GeneratedPluginRegistrant.h" 2 | -------------------------------------------------------------------------------- /lib/src/google_maps_webservice/places.dart: -------------------------------------------------------------------------------- 1 | export 'src/core.dart'; 2 | export 'src/places.dart'; 3 | -------------------------------------------------------------------------------- /flutter_01.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/flutter_01.png -------------------------------------------------------------------------------- /flutter_02.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/flutter_02.png -------------------------------------------------------------------------------- /example/web/favicon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/web/favicon.png -------------------------------------------------------------------------------- /example/android/gradle.properties: -------------------------------------------------------------------------------- 1 | org.gradle.jvmargs=-Xmx1536M 2 | android.useAndroidX=true 3 | android.enableJetifier=true 4 | -------------------------------------------------------------------------------- /lib/assets/google_black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/lib/assets/google_black.png -------------------------------------------------------------------------------- /lib/assets/google_white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/lib/assets/google_white.png -------------------------------------------------------------------------------- /example/web/icons/Icon-192.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/web/icons/Icon-192.png -------------------------------------------------------------------------------- /example/web/icons/Icon-512.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/web/icons/Icon-512.png -------------------------------------------------------------------------------- /example/ios/Flutter/Debug.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /example/ios/Flutter/Release.xcconfig: -------------------------------------------------------------------------------- 1 | #include? "Pods/Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig" 2 | #include "Generated.xcconfig" 3 | -------------------------------------------------------------------------------- /lib/google_maps_webservice_places.dart: -------------------------------------------------------------------------------- 1 | library google_maps_webservice_hoc081098.places; 2 | 3 | export 'src/google_maps_webservice/places.dart'; 4 | -------------------------------------------------------------------------------- /example/README.md: -------------------------------------------------------------------------------- 1 | # example 2 | 3 | A new Flutter project. 4 | 5 | ## Getting Started 6 | 7 | For help getting started with Flutter, view our online 8 | [documentation](https://flutter.dev/). 9 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/android/app/src/main/res/mipmap-hdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/android/app/src/main/res/mipmap-mdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/android/app/src/main/res/mipmap-xhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/android/app/src/main/res/mipmap-xxxhdpi/ic_launcher.png -------------------------------------------------------------------------------- /example/android/app/src/main/kotlin/com/hoc/example/MainActivity.kt: -------------------------------------------------------------------------------- 1 | package com.hoc.example 2 | 3 | import io.flutter.embedding.android.FlutterActivity 4 | 5 | class MainActivity: FlutterActivity() { 6 | } 7 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-20x20@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-29x29@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-40x40@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-60x60@3x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-76x76@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@2x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/ios/Runner/Assets.xcassets/LaunchImage.imageset/LaunchImage@3x.png -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-1024x1024@1x.png -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/hoc081098/flutter_google_places_hoc081098/HEAD/example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Icon-App-83.5x83.5@2x.png -------------------------------------------------------------------------------- /lib/flutter_google_places_hoc081098.dart: -------------------------------------------------------------------------------- 1 | library flutter_google_places_hoc081098; 2 | 3 | export 'src/flutter_google_places.dart'; 4 | export 'src/places_autocomplete_field.dart'; 5 | export 'src/places_autocomplete_form_field.dart'; 6 | -------------------------------------------------------------------------------- /example/android/gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Fri Jun 23 08:50:38 CEST 2017 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.1-all.zip 7 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/android/.gitignore: -------------------------------------------------------------------------------- 1 | gradle-wrapper.jar 2 | /.gradle 3 | /captures/ 4 | /gradlew 5 | /gradlew.bat 6 | /local.properties 7 | GeneratedPluginRegistrant.java 8 | 9 | # Remember to never publicly share your keystore. 10 | # See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app 11 | key.properties 12 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/WorkspaceSettings.xcsettings: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | PreviewsEnabled 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | IDEDidComputeMac32BitWarning 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /example/analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:flutter_lints/flutter.yaml 2 | linter: 3 | rules: 4 | - prefer_final_locals 5 | - prefer_relative_imports 6 | # https://github.com/dart-lang/lints#migrating-from-packagepedantic 7 | - always_declare_return_types 8 | - prefer_single_quotes 9 | - unawaited_futures 10 | - unsafe_html -------------------------------------------------------------------------------- /example/.metadata: -------------------------------------------------------------------------------- 1 | # This file tracks properties of this Flutter project. 2 | # Used by Flutter tool to assess capabilities and perform upgrades etc. 3 | # 4 | # This file should be version controlled and should not be manually edited. 5 | 6 | version: 7 | revision: c5a4b4029c0798f37c4a39b479d7cb75daa7b05c 8 | channel: stable 9 | 10 | project_type: app 11 | -------------------------------------------------------------------------------- /example/android/app/src/debug/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/android/app/src/profile/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/README.md: -------------------------------------------------------------------------------- 1 | # Launch Screen Assets 2 | 3 | You can customize the launch screen with your own desired assets by replacing the image files in this directory. 4 | 5 | You can also do it by opening your Flutter project's Xcode project with `open ios/Runner.xcworkspace`, selecting `Runner/Assets.xcassets` in the Project Navigator and dropping in the desired images. -------------------------------------------------------------------------------- /example/ios/Runner/AppDelegate.swift: -------------------------------------------------------------------------------- 1 | import UIKit 2 | import Flutter 3 | 4 | @UIApplicationMain 5 | @objc class AppDelegate: FlutterAppDelegate { 6 | override func application( 7 | _ application: UIApplication, 8 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 9 | ) -> Bool { 10 | GeneratedPluginRegistrant.register(with: self) 11 | return super.application(application, didFinishLaunchingWithOptions: launchOptions) 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /example/android/settings.gradle: -------------------------------------------------------------------------------- 1 | include ':app' 2 | 3 | def localPropertiesFile = new File(rootProject.projectDir, "local.properties") 4 | def properties = new Properties() 5 | 6 | assert localPropertiesFile.exists() 7 | localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } 8 | 9 | def flutterSdkPath = properties.getProperty("flutter.sdk") 10 | assert flutterSdkPath != null, "flutter.sdk not set in local.properties" 11 | apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" 12 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/drawable-v21/launch_background.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 12 | 13 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/LaunchImage.imageset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "universal", 5 | "filename" : "LaunchImage.png", 6 | "scale" : "1x" 7 | }, 8 | { 9 | "idiom" : "universal", 10 | "filename" : "LaunchImage@2x.png", 11 | "scale" : "2x" 12 | }, 13 | { 14 | "idiom" : "universal", 15 | "filename" : "LaunchImage@3x.png", 16 | "scale" : "3x" 17 | } 18 | ], 19 | "info" : { 20 | "version" : 1, 21 | "author" : "xcode" 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /analysis_options.yaml: -------------------------------------------------------------------------------- 1 | include: package:flutter_lints/flutter.yaml 2 | 3 | analyzer: 4 | language: 5 | strict-casts: true 6 | strict-raw-types: true 7 | 8 | linter: 9 | rules: 10 | - prefer_final_locals 11 | - prefer_relative_imports 12 | # https://github.com/dart-lang/lints#migrating-from-packagepedantic 13 | - always_declare_return_types 14 | - prefer_single_quotes 15 | - unawaited_futures 16 | - unsafe_html 17 | - prefer_const_constructors 18 | - prefer_const_constructors_in_immutables 19 | - prefer_const_declarations 20 | - prefer_const_literals_to_create_immutables -------------------------------------------------------------------------------- /example/ios/Podfile.lock: -------------------------------------------------------------------------------- 1 | PODS: 2 | - Flutter (1.0.0) 3 | - package_info_plus (0.4.5): 4 | - Flutter 5 | 6 | DEPENDENCIES: 7 | - Flutter (from `Flutter`) 8 | - package_info_plus (from `.symlinks/plugins/package_info_plus/ios`) 9 | 10 | EXTERNAL SOURCES: 11 | Flutter: 12 | :path: Flutter 13 | package_info_plus: 14 | :path: ".symlinks/plugins/package_info_plus/ios" 15 | 16 | SPEC CHECKSUMS: 17 | Flutter: 50d75fe2f02b26cc09d224853bb45737f8b3214a 18 | package_info_plus: 6c92f08e1f853dc01228d6f553146438dafcd14e 19 | 20 | PODFILE CHECKSUM: aafe91acc616949ddb318b77800a7f51bffa2a4c 21 | 22 | COCOAPODS: 1.11.2 23 | -------------------------------------------------------------------------------- /example/web/manifest.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "example", 3 | "short_name": "example", 4 | "start_url": ".", 5 | "display": "standalone", 6 | "background_color": "#0175C2", 7 | "theme_color": "#0175C2", 8 | "description": "A new Flutter project.", 9 | "orientation": "portrait-primary", 10 | "prefer_related_applications": false, 11 | "icons": [ 12 | { 13 | "src": "icons/Icon-192.png", 14 | "sizes": "192x192", 15 | "type": "image/png" 16 | }, 17 | { 18 | "src": "icons/Icon-512.png", 19 | "sizes": "512x512", 20 | "type": "image/png" 21 | } 22 | ] 23 | } 24 | -------------------------------------------------------------------------------- /example/ios/.gitignore: -------------------------------------------------------------------------------- 1 | *.mode1v3 2 | *.mode2v3 3 | *.moved-aside 4 | *.pbxuser 5 | *.perspectivev3 6 | **/*sync/ 7 | .sconsign.dblite 8 | .tags* 9 | **/.vagrant/ 10 | **/DerivedData/ 11 | Icon? 12 | **/Pods/ 13 | **/.symlinks/ 14 | profile 15 | xcuserdata 16 | **/.generated/ 17 | Flutter/App.framework 18 | Flutter/Flutter.framework 19 | Flutter/Flutter.podspec 20 | Flutter/Generated.xcconfig 21 | Flutter/app.flx 22 | Flutter/app.zip 23 | Flutter/flutter_assets/ 24 | Flutter/flutter_export_environment.sh 25 | ServiceDefinitions.json 26 | Runner/GeneratedPluginRegistrant.* 27 | 28 | # Exceptions to above rules. 29 | !default.mode1v3 30 | !default.mode2v3 31 | !default.pbxuser 32 | !default.perspectivev3 33 | -------------------------------------------------------------------------------- /example/android/build.gradle: -------------------------------------------------------------------------------- 1 | buildscript { 2 | ext.kotlin_version = '1.8.22' 3 | repositories { 4 | google() 5 | jcenter() 6 | } 7 | 8 | dependencies { 9 | classpath 'com.android.tools.build:gradle:7.4.2' 10 | classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" 11 | } 12 | } 13 | 14 | allprojects { 15 | repositories { 16 | google() 17 | jcenter() 18 | } 19 | } 20 | 21 | rootProject.buildDir = '../build' 22 | subprojects { 23 | project.buildDir = "${rootProject.buildDir}/${project.name}" 24 | } 25 | subprojects { 26 | project.evaluationDependsOn(':app') 27 | } 28 | 29 | task clean(type: Delete) { 30 | delete rootProject.buildDir 31 | } 32 | -------------------------------------------------------------------------------- /example/.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | /build/ 32 | 33 | # Web related 34 | lib/generated_plugin_registrant.dart 35 | 36 | # Exceptions to above rules. 37 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 38 | /res/ -------------------------------------------------------------------------------- /example/ios/Flutter/AppFrameworkInfo.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | App 9 | CFBundleIdentifier 10 | io.flutter.flutter.app 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | App 15 | CFBundlePackageType 16 | FMWK 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | 1.0 23 | MinimumOSVersion 24 | 9.0 25 | 26 | 27 | -------------------------------------------------------------------------------- /.all-contributorsrc: -------------------------------------------------------------------------------- 1 | { 2 | "files": [ 3 | "README.md" 4 | ], 5 | "imageSize": 100, 6 | "commit": false, 7 | "contributors": [ 8 | { 9 | "login": "hoc081098", 10 | "name": "Petrus Nguyễn Thái Học", 11 | "avatar_url": "https://avatars.githubusercontent.com/u/36917223?v=4", 12 | "profile": "https://www.linkedin.com/in/hoc081098/", 13 | "contributions": [ 14 | "code", 15 | "maintenance" 16 | ] 17 | }, 18 | { 19 | "login": "corentingiraud", 20 | "name": "Corentin Giraud", 21 | "avatar_url": "https://avatars.githubusercontent.com/u/29222996?v=4", 22 | "profile": "https://corentin.giraud.dev/", 23 | "contributions": [ 24 | "code" 25 | ] 26 | } 27 | ], 28 | "contributorsPerLine": 7, 29 | "projectName": "flutter_google_places", 30 | "projectOwner": "hoc081098", 31 | "repoType": "github", 32 | "repoHost": "https://github.com", 33 | "skipCi": true 34 | } 35 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/android/app/src/main/res/values-night/styles.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 9 | 15 | 18 | 19 | -------------------------------------------------------------------------------- /example/test/widget_test.dart: -------------------------------------------------------------------------------- 1 | // This is a basic Flutter widget test. 2 | // 3 | // To perform an interaction with a widget in your test, use the WidgetTester 4 | // utility that Flutter provides. For example, you can send tap and scroll 5 | // gestures. You can also use WidgetTester to find child widgets in the widget 6 | // tree, read text, and verify that the values of widget properties are correct. 7 | 8 | import 'package:flutter/material.dart'; 9 | import 'package:flutter_test/flutter_test.dart'; 10 | 11 | import 'package:example/main.dart'; 12 | 13 | void main() { 14 | testWidgets('Counter increments smoke test', (WidgetTester tester) async { 15 | // Build our app and trigger a frame. 16 | await tester.pumpWidget(const MyApp()); 17 | 18 | // Verify that our counter starts at 0. 19 | expect(find.text('0'), findsOneWidget); 20 | expect(find.text('1'), findsNothing); 21 | 22 | // Tap the '+' icon and trigger a frame. 23 | await tester.tap(find.byIcon(Icons.add)); 24 | await tester.pump(); 25 | 26 | // Verify that our counter has incremented. 27 | expect(find.text('0'), findsNothing); 28 | expect(find.text('1'), findsOneWidget); 29 | }); 30 | } 31 | -------------------------------------------------------------------------------- /pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: flutter_google_places_hoc081098 2 | description: Google places autocomplete widgets for flutter. No wrapper, use https://pub.dartlang.org/packages/google_maps_webservice. Better flutter_google_places, updated by @hoc081098 3 | version: 2.0.0 4 | homepage: https://github.com/hoc081098/flutter_google_places 5 | repository: https://github.com/hoc081098/flutter_google_places 6 | funding: 7 | - https://www.buymeacoffee.com/hoc081098 8 | 9 | topics: 10 | - rxdart 11 | - hoc081098 12 | - google-places 13 | - google-places-autocomplete 14 | - flutter-google-places 15 | 16 | environment: 17 | sdk: '>=3.3.4 <4.0.0' 18 | flutter: '>=3.19.6' 19 | 20 | dependencies: 21 | flutter: 22 | sdk: flutter 23 | google_api_headers: ^4.0.3 24 | http: ^1.2.1 25 | rxdart: ^0.28.0 26 | rxdart_ext: ^0.3.0 27 | listenable_stream: ^2.0.1 28 | collection: ^1.18.0 29 | flutter_bloc_pattern: ^3.0.0 30 | json_annotation: ^4.9.0 31 | meta: ^1.11.0 32 | 33 | dev_dependencies: 34 | flutter_test: 35 | sdk: flutter 36 | flutter_lints: ^4.0.0 37 | build_runner: ^2.4.11 38 | json_serializable: ^6.8.0 39 | 40 | flutter: 41 | assets: 42 | - packages/flutter_google_places_hoc081098/assets/google_black.png 43 | - packages/flutter_google_places_hoc081098/assets/google_white.png 44 | 45 | # dart run build_runner build --delete-conflicting-outputs -------------------------------------------------------------------------------- /example/ios/Podfile: -------------------------------------------------------------------------------- 1 | # Uncomment this line to define a global platform for your project 2 | # platform :ios, '9.0' 3 | 4 | # CocoaPods analytics sends network stats synchronously affecting flutter build latency. 5 | ENV['COCOAPODS_DISABLE_STATS'] = 'true' 6 | 7 | project 'Runner', { 8 | 'Debug' => :debug, 9 | 'Profile' => :release, 10 | 'Release' => :release, 11 | } 12 | 13 | def flutter_root 14 | generated_xcode_build_settings_path = File.expand_path(File.join('..', 'Flutter', 'Generated.xcconfig'), __FILE__) 15 | unless File.exist?(generated_xcode_build_settings_path) 16 | raise "#{generated_xcode_build_settings_path} must exist. If you're running pod install manually, make sure flutter pub get is executed first" 17 | end 18 | 19 | File.foreach(generated_xcode_build_settings_path) do |line| 20 | matches = line.match(/FLUTTER_ROOT\=(.*)/) 21 | return matches[1].strip if matches 22 | end 23 | raise "FLUTTER_ROOT not found in #{generated_xcode_build_settings_path}. Try deleting Generated.xcconfig, then run flutter pub get" 24 | end 25 | 26 | require File.expand_path(File.join('packages', 'flutter_tools', 'bin', 'podhelper'), flutter_root) 27 | 28 | flutter_ios_podfile_setup 29 | 30 | target 'Runner' do 31 | use_frameworks! 32 | use_modular_headers! 33 | 34 | flutter_install_all_ios_pods File.dirname(File.realpath(__FILE__)) 35 | end 36 | 37 | post_install do |installer| 38 | installer.pods_project.targets.each do |target| 39 | flutter_additional_ios_build_settings(target) 40 | end 41 | end 42 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2018, lejard_h. 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | * Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | * Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | * Neither the name of the nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 16 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18 | DISCLAIMED. IN NO EVENT SHALL Hadrien Lejard BE LIABLE FOR ANY 19 | DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 21 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 22 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 24 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -------------------------------------------------------------------------------- /example/web/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | example 30 | 31 | 32 | 33 | 36 | 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/Main.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /example/ios/Runner/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | example 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | $(FLUTTER_BUILD_NAME) 19 | CFBundleSignature 20 | ???? 21 | CFBundleVersion 22 | $(FLUTTER_BUILD_NUMBER) 23 | LSRequiresIPhoneOS 24 | 25 | UILaunchStoryboardName 26 | LaunchScreen 27 | UIMainStoryboardFile 28 | Main 29 | UISupportedInterfaceOrientations 30 | 31 | UIInterfaceOrientationPortrait 32 | UIInterfaceOrientationLandscapeLeft 33 | UIInterfaceOrientationLandscapeRight 34 | 35 | UISupportedInterfaceOrientations~ipad 36 | 37 | UIInterfaceOrientationPortrait 38 | UIInterfaceOrientationPortraitUpsideDown 39 | UIInterfaceOrientationLandscapeLeft 40 | UIInterfaceOrientationLandscapeRight 41 | 42 | UIViewControllerBasedStatusBarAppearance 43 | 44 | CADisableMinimumFrameDurationOnPhone 45 | 46 | 47 | 48 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Miscellaneous 2 | *.class 3 | *.log 4 | *.pyc 5 | *.swp 6 | .DS_Store 7 | .atom/ 8 | .buildlog/ 9 | .history 10 | .svn/ 11 | 12 | # IntelliJ related 13 | *.iml 14 | *.ipr 15 | *.iws 16 | .idea/ 17 | 18 | # The .vscode folder contains launch configuration and tasks you configure in 19 | # VS Code which you may wish to be included in version control, so this line 20 | # is commented out by default. 21 | #.vscode/ 22 | 23 | # Flutter/Dart/Pub related 24 | **/doc/api/ 25 | .dart_tool/ 26 | .flutter-plugins 27 | .flutter-plugins-dependencies 28 | .packages 29 | .pub-cache/ 30 | .pub/ 31 | build/ 32 | 33 | # Android related 34 | **/android/**/gradle-wrapper.jar 35 | **/android/.gradle 36 | **/android/captures/ 37 | **/android/gradlew 38 | **/android/gradlew.bat 39 | **/android/local.properties 40 | **/android/**/GeneratedPluginRegistrant.java 41 | 42 | # iOS/XCode related 43 | **/ios/**/*.mode1v3 44 | **/ios/**/*.mode2v3 45 | **/ios/**/*.moved-aside 46 | **/ios/**/*.pbxuser 47 | **/ios/**/*.perspectivev3 48 | **/ios/**/*sync/ 49 | **/ios/**/.sconsign.dblite 50 | **/ios/**/.tags* 51 | **/ios/**/.vagrant/ 52 | **/ios/**/DerivedData/ 53 | **/ios/**/Icon? 54 | **/ios/**/Pods/ 55 | **/ios/**/.symlinks/ 56 | **/ios/**/profile 57 | **/ios/**/xcuserdata 58 | **/ios/.generated/ 59 | **/ios/Flutter/App.framework 60 | **/ios/Flutter/Flutter.framework 61 | **/ios/Flutter/Flutter.podspec 62 | **/ios/Flutter/Generated.xcconfig 63 | **/ios/Flutter/app.flx 64 | **/ios/Flutter/app.zip 65 | **/ios/Flutter/flutter_assets/ 66 | **/ios/Flutter/flutter_export_environment.sh 67 | **/ios/ServiceDefinitions.json 68 | **/ios/Runner/GeneratedPluginRegistrant.* 69 | 70 | # Exceptions to above rules. 71 | !**/ios/**/default.mode1v3 72 | !**/ios/**/default.mode2v3 73 | !**/ios/**/default.pbxuser 74 | !**/ios/**/default.perspectivev3 75 | !/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages 76 | /res/ -------------------------------------------------------------------------------- /.github/workflows/build-example.yml: -------------------------------------------------------------------------------- 1 | name: Build example 2 | 3 | on: 4 | push: 5 | branches: [ main ] 6 | paths-ignore: [ '**.md' ] 7 | pull_request: 8 | branches: [ main ] 9 | paths-ignore: [ '**.md' ] 10 | 11 | jobs: 12 | build-stable-beta: 13 | runs-on: ubuntu-latest 14 | strategy: 15 | matrix: 16 | channel: [ 'stable', 'beta' ] 17 | defaults: 18 | run: 19 | working-directory: ./example 20 | steps: 21 | - uses: actions/checkout@v3 22 | 23 | - uses: actions/setup-java@v3 24 | with: 25 | distribution: 'zulu' 26 | java-version: '17' 27 | 28 | - uses: subosito/flutter-action@v2.4.0 29 | with: 30 | channel: ${{ matrix.channel }} 31 | 32 | - name: Print Dart SDK version 33 | run: dart --version 34 | 35 | - name: Print Flutter SDK version 36 | run: flutter --version 37 | 38 | - name: Install dependencies 39 | run: flutter pub get 40 | 41 | - name: Format code 42 | if: ${{ matrix.channel == 'stable' }} 43 | run: dart format lib --set-exit-if-changed 44 | 45 | - name: Analyze 46 | run: flutter analyze lib 47 | 48 | - name: Build APK 49 | run: flutter build apk --no-shrink 50 | 51 | build-old-versions: 52 | runs-on: ubuntu-latest 53 | strategy: 54 | matrix: 55 | version: [ '3.19.6', '3.22.0' ] 56 | defaults: 57 | run: 58 | working-directory: ./example 59 | steps: 60 | - uses: actions/checkout@v3 61 | 62 | - uses: actions/setup-java@v3 63 | with: 64 | distribution: 'zulu' 65 | java-version: '17' 66 | 67 | - uses: subosito/flutter-action@v2.4.0 68 | with: 69 | flutter-version: ${{ matrix.version }} 70 | 71 | - name: Print Dart SDK version 72 | run: dart --version 73 | 74 | - name: Print Flutter SDK version 75 | run: flutter --version 76 | 77 | - name: Install dependencies 78 | run: flutter pub get 79 | 80 | - name: Build APK 81 | run: flutter build apk --debug --no-shrink 82 | -------------------------------------------------------------------------------- /example/android/app/build.gradle: -------------------------------------------------------------------------------- 1 | def localProperties = new Properties() 2 | def localPropertiesFile = rootProject.file('local.properties') 3 | if (localPropertiesFile.exists()) { 4 | localPropertiesFile.withReader('UTF-8') { reader -> 5 | localProperties.load(reader) 6 | } 7 | } 8 | 9 | def flutterRoot = localProperties.getProperty('flutter.sdk') 10 | if (flutterRoot == null) { 11 | throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.") 12 | } 13 | 14 | def flutterVersionCode = localProperties.getProperty('flutter.versionCode') 15 | if (flutterVersionCode == null) { 16 | flutterVersionCode = '1' 17 | } 18 | 19 | def flutterVersionName = localProperties.getProperty('flutter.versionName') 20 | if (flutterVersionName == null) { 21 | flutterVersionName = '1.0' 22 | } 23 | 24 | apply plugin: 'com.android.application' 25 | apply plugin: 'kotlin-android' 26 | apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" 27 | 28 | android { 29 | compileSdkVersion flutter.compileSdkVersion 30 | 31 | compileOptions { 32 | sourceCompatibility JavaVersion.VERSION_1_8 33 | targetCompatibility JavaVersion.VERSION_1_8 34 | } 35 | 36 | kotlinOptions { 37 | jvmTarget = '1.8' 38 | } 39 | 40 | sourceSets { 41 | main.java.srcDirs += 'src/main/kotlin' 42 | } 43 | 44 | defaultConfig { 45 | // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). 46 | applicationId "com.hoc.example" 47 | minSdkVersion 23 48 | targetSdkVersion flutter.targetSdkVersion 49 | versionCode flutterVersionCode.toInteger() 50 | versionName flutterVersionName 51 | } 52 | 53 | buildTypes { 54 | release { 55 | // TODO: Add your own signing config for the release build. 56 | // Signing with the debug keys for now, so `flutter run --release` works. 57 | signingConfig signingConfigs.debug 58 | } 59 | } 60 | } 61 | 62 | flutter { 63 | source '../..' 64 | } 65 | 66 | dependencies { 67 | implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlin_version" 68 | } 69 | -------------------------------------------------------------------------------- /example/pubspec.yaml: -------------------------------------------------------------------------------- 1 | name: example 2 | version: 1.1.0+1 3 | publish_to: none 4 | description: A new Flutter project. 5 | 6 | environment: 7 | sdk: '>=3.3.4 <4.0.0' 8 | flutter: '>=3.19.6' 9 | 10 | dependencies: 11 | flutter: 12 | sdk: flutter 13 | flutter_google_places_hoc081098: 14 | path: ../ 15 | google_api_headers: ^4.0.3 16 | uuid: ^4.4.0 17 | 18 | dev_dependencies: 19 | flutter_lints: ^4.0.0 20 | flutter_test: 21 | sdk: flutter 22 | 23 | # For information on the generic Dart part of this file, see the 24 | # following page: https://www.dartlang.org/tools/pub/pubspec 25 | 26 | # The following section is specific to Flutter. 27 | flutter: 28 | # The following line ensures that the Material Icons font is 29 | # included with your application, so that you can use the icons in 30 | # the Icons class. 31 | uses-material-design: true 32 | 33 | # To add assets to your application, add an assets section, like this: 34 | # assets: 35 | # - images/a_dot_burr.jpeg 36 | # - images/a_dot_ham.jpeg 37 | 38 | # An image asset can refer to one or more resolution-specific "variants", see 39 | # https://flutter.io/assets-and-images/. 40 | 41 | # To add assets from package dependencies, first ensure the asset 42 | # is in the lib/ directory of the dependency. Then, 43 | # refer to the asset with a path prefixed with 44 | # `packages/PACKAGE_NAME/`. The `lib/` is implied, do not 45 | # include `lib/` in the asset path. 46 | # 47 | # Here is an example: 48 | # 49 | # assets: 50 | # - packages/PACKAGE_NAME/path/to/asset 51 | 52 | # To add custom fonts to your application, add a fonts section here, 53 | # in this "flutter" section. Each entry in this list should have a 54 | # "family" key with the font family name, and a "fonts" key with a 55 | # list giving the asset and other descriptors for the font. For 56 | # example: 57 | # fonts: 58 | # - family: Schyler 59 | # fonts: 60 | # - asset: fonts/Schyler-Regular.ttf 61 | # - asset: fonts/Schyler-Italic.ttf 62 | # style: italic 63 | # - family: Trajan Pro 64 | # fonts: 65 | # - asset: fonts/TrajanPro.ttf 66 | # - asset: fonts/TrajanPro_Bold.ttf 67 | # weight: 700 68 | -------------------------------------------------------------------------------- /example/lib/custom.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | import 'package:flutter_google_places_hoc081098/flutter_google_places_hoc081098.dart'; 3 | import 'package:flutter_google_places_hoc081098/google_maps_webservice_places.dart'; 4 | import 'package:uuid/uuid.dart'; 5 | 6 | import 'main.dart'; 7 | 8 | // custom scaffold that handle search 9 | // basically your widget need to extends [GooglePlacesAutocompleteWidget] 10 | // and your state [GooglePlacesAutocompleteState] 11 | class CustomSearchScaffold extends PlacesAutocompleteWidget { 12 | CustomSearchScaffold({super.key}) 13 | : super( 14 | apiKey: kGoogleApiKey, 15 | sessionToken: const Uuid().v4(), 16 | language: 'en', 17 | components: [const Component(Component.country, 'uk')], 18 | ); 19 | 20 | @override 21 | PlacesAutocompleteState createState() => _CustomSearchScaffoldState(); 22 | } 23 | 24 | class _CustomSearchScaffoldState extends PlacesAutocompleteState { 25 | @override 26 | Widget build(BuildContext context) { 27 | return Scaffold( 28 | appBar: AppBar( 29 | title: const AppBarPlacesAutoCompleteTextField( 30 | textStyle: null, 31 | textDecoration: null, 32 | cursorColor: null, 33 | ), 34 | ), 35 | body: PlacesAutocompleteResult( 36 | onTap: (p) => displayPrediction(p, ScaffoldMessenger.of(context)), 37 | logo: const Row( 38 | mainAxisAlignment: MainAxisAlignment.center, 39 | children: [FlutterLogo()], 40 | ), 41 | resultTextStyle: Theme.of(context).textTheme.titleMedium, 42 | ), 43 | ); 44 | } 45 | 46 | @override 47 | void onResponseError(PlacesAutocompleteResponse response) { 48 | super.onResponseError(response); 49 | 50 | ScaffoldMessenger.of(context).showSnackBar( 51 | SnackBar(content: Text(response.errorMessage ?? 'Unknown error')), 52 | ); 53 | } 54 | 55 | @override 56 | void onResponse(PlacesAutocompleteResponse response) { 57 | super.onResponse(response); 58 | 59 | if (response.predictions.isNotEmpty) { 60 | ScaffoldMessenger.of(context).showSnackBar( 61 | const SnackBar(content: Text('Got answer')), 62 | ); 63 | } 64 | } 65 | } 66 | -------------------------------------------------------------------------------- /example/android/app/src/main/AndroidManifest.xml: -------------------------------------------------------------------------------- 1 | 3 | 4 | 8 | 9 | 17 | 21 | 25 | 30 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 42 | 45 | 46 | 47 | -------------------------------------------------------------------------------- /example/ios/Runner/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | -------------------------------------------------------------------------------- /lib/src/google_maps_webservice/src/utils.dart: -------------------------------------------------------------------------------- 1 | library google_maps_webservice_hoc081098.utils; 2 | 3 | import 'dart:async'; 4 | 5 | import 'package:http/http.dart'; 6 | import 'package:meta/meta.dart'; 7 | 8 | final kGMapsUrl = Uri.parse('https://maps.googleapis.com/maps/api'); 9 | 10 | abstract class GoogleWebService { 11 | @protected 12 | final Client _httpClient; 13 | 14 | @protected 15 | late final Uri _url; 16 | 17 | @protected 18 | final String? _apiKey; 19 | 20 | @protected 21 | final Map? _apiHeaders; 22 | 23 | Uri get url => _url; 24 | 25 | Client get httpClient => _httpClient; 26 | 27 | String? get apiKey => _apiKey; 28 | 29 | Map? get apiHeaders => _apiHeaders; 30 | 31 | GoogleWebService({ 32 | String? apiKey, 33 | required String apiPath, 34 | String? baseUrl, 35 | Client? httpClient, 36 | Map? apiHeaders, 37 | }) : _httpClient = httpClient ?? Client(), 38 | _apiKey = apiKey, 39 | _apiHeaders = apiHeaders { 40 | var uri = kGMapsUrl; 41 | 42 | if (baseUrl != null) { 43 | uri = Uri.parse(baseUrl); 44 | } 45 | 46 | _url = uri.replace(path: '${uri.path}$apiPath'); 47 | } 48 | 49 | @protected 50 | String buildQuery(Map params) { 51 | final query = []; 52 | params.forEach((key, val) { 53 | if (val != null) { 54 | if (val is Iterable) { 55 | query.add("$key=${val.map((v) => v.toString()).join("|")}"); 56 | } else { 57 | query.add('$key=${val.toString()}'); 58 | } 59 | } 60 | }); 61 | return query.join('&'); 62 | } 63 | 64 | void dispose() => httpClient.close(); 65 | 66 | @protected 67 | Future doGet(String url, {Map? headers}) { 68 | return httpClient.get(Uri.parse(url), headers: headers); 69 | } 70 | 71 | @protected 72 | Future doPost( 73 | String url, 74 | String body, { 75 | Map? headers, 76 | }) { 77 | final postHeaders = { 78 | 'Content-type': 'application/json', 79 | }; 80 | if (headers != null) postHeaders.addAll(headers); 81 | return httpClient.post(Uri.parse(url), body: body, headers: postHeaders); 82 | } 83 | } 84 | 85 | DateTime dayTimeToDateTime(int day, String time) { 86 | if (time.length < 4) { 87 | throw ArgumentError( 88 | "'time' is not a valid string. It must be four integers."); 89 | } 90 | 91 | day = day == 0 ? DateTime.sunday : day; 92 | 93 | final now = DateTime.now(); 94 | final mondayOfThisWeek = now.day - now.weekday; 95 | final computedWeekday = mondayOfThisWeek + day; 96 | 97 | final hour = int.parse(time.substring(0, 2)); 98 | final minute = int.parse(time.substring(2)); 99 | 100 | return DateTime.utc(now.year, now.month, computedWeekday, hour, minute); 101 | } 102 | -------------------------------------------------------------------------------- /example/ios/Runner/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "size" : "20x20", 5 | "idiom" : "iphone", 6 | "filename" : "Icon-App-20x20@2x.png", 7 | "scale" : "2x" 8 | }, 9 | { 10 | "size" : "20x20", 11 | "idiom" : "iphone", 12 | "filename" : "Icon-App-20x20@3x.png", 13 | "scale" : "3x" 14 | }, 15 | { 16 | "size" : "29x29", 17 | "idiom" : "iphone", 18 | "filename" : "Icon-App-29x29@1x.png", 19 | "scale" : "1x" 20 | }, 21 | { 22 | "size" : "29x29", 23 | "idiom" : "iphone", 24 | "filename" : "Icon-App-29x29@2x.png", 25 | "scale" : "2x" 26 | }, 27 | { 28 | "size" : "29x29", 29 | "idiom" : "iphone", 30 | "filename" : "Icon-App-29x29@3x.png", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "size" : "40x40", 35 | "idiom" : "iphone", 36 | "filename" : "Icon-App-40x40@2x.png", 37 | "scale" : "2x" 38 | }, 39 | { 40 | "size" : "40x40", 41 | "idiom" : "iphone", 42 | "filename" : "Icon-App-40x40@3x.png", 43 | "scale" : "3x" 44 | }, 45 | { 46 | "size" : "60x60", 47 | "idiom" : "iphone", 48 | "filename" : "Icon-App-60x60@2x.png", 49 | "scale" : "2x" 50 | }, 51 | { 52 | "size" : "60x60", 53 | "idiom" : "iphone", 54 | "filename" : "Icon-App-60x60@3x.png", 55 | "scale" : "3x" 56 | }, 57 | { 58 | "size" : "20x20", 59 | "idiom" : "ipad", 60 | "filename" : "Icon-App-20x20@1x.png", 61 | "scale" : "1x" 62 | }, 63 | { 64 | "size" : "20x20", 65 | "idiom" : "ipad", 66 | "filename" : "Icon-App-20x20@2x.png", 67 | "scale" : "2x" 68 | }, 69 | { 70 | "size" : "29x29", 71 | "idiom" : "ipad", 72 | "filename" : "Icon-App-29x29@1x.png", 73 | "scale" : "1x" 74 | }, 75 | { 76 | "size" : "29x29", 77 | "idiom" : "ipad", 78 | "filename" : "Icon-App-29x29@2x.png", 79 | "scale" : "2x" 80 | }, 81 | { 82 | "size" : "40x40", 83 | "idiom" : "ipad", 84 | "filename" : "Icon-App-40x40@1x.png", 85 | "scale" : "1x" 86 | }, 87 | { 88 | "size" : "40x40", 89 | "idiom" : "ipad", 90 | "filename" : "Icon-App-40x40@2x.png", 91 | "scale" : "2x" 92 | }, 93 | { 94 | "size" : "76x76", 95 | "idiom" : "ipad", 96 | "filename" : "Icon-App-76x76@1x.png", 97 | "scale" : "1x" 98 | }, 99 | { 100 | "size" : "76x76", 101 | "idiom" : "ipad", 102 | "filename" : "Icon-App-76x76@2x.png", 103 | "scale" : "2x" 104 | }, 105 | { 106 | "size" : "83.5x83.5", 107 | "idiom" : "ipad", 108 | "filename" : "Icon-App-83.5x83.5@2x.png", 109 | "scale" : "2x" 110 | }, 111 | { 112 | "size" : "1024x1024", 113 | "idiom" : "ios-marketing", 114 | "filename" : "Icon-App-1024x1024@1x.png", 115 | "scale" : "1x" 116 | } 117 | ], 118 | "info" : { 119 | "version" : 1, 120 | "author" : "xcode" 121 | } 122 | } 123 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme: -------------------------------------------------------------------------------- 1 | 2 | 5 | 8 | 9 | 15 | 21 | 22 | 23 | 24 | 25 | 30 | 31 | 32 | 33 | 39 | 40 | 41 | 42 | 43 | 44 | 54 | 56 | 62 | 63 | 64 | 65 | 66 | 67 | 73 | 75 | 81 | 82 | 83 | 84 | 86 | 87 | 90 | 91 | 92 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # flutter_google_places_hoc081098 2 | 3 | [![All Contributors](https://img.shields.io/badge/all_contributors-2-orange.svg?style=flat-square)](#contributors-) 4 | 5 | 6 | Google places autocomplete widgets for flutter. 7 | 8 | ## Updated by [@hoc081098](https://github.com/hoc081098). See [files changed](https://github.com/fluttercommunity/flutter_google_places/compare/master...hoc081098:main) 9 | 10 | [![Pub](https://img.shields.io/pub/v/flutter_google_places_hoc081098?include_prereleases)](https://pub.dev/packages/flutter_google_places_hoc081098) 11 | [![Hits](https://hits.seeyoufarm.com/api/count/incr/badge.svg?url=https%3A%2F%2Fgithub.com%2Fhoc081098%2Fflutter_google_places&count_bg=%2379C83D&title_bg=%23555555&icon=&icon_color=%23E7E7E7&title=hits&edge_flat=false)](https://hits.seeyoufarm.com) 12 | [![Build example](https://github.com/hoc081098/flutter_google_places/actions/workflows/build-example.yml/badge.svg?branch=main)](https://github.com/hoc081098/flutter_google_places/actions/workflows/build-example.yml) 13 | 14 | Liked some of my work? Buy me a coffee (or more likely a beer). Thanks for your support :heart: 15 | 16 | Buy Me A Coffee 17 | 18 | - Migrated to **null-safety**. 19 | - Updated dependencies to latest release. 20 | - Refactoring by using **RxDart** for more power. 21 | - Fixed many issues. 22 | - Applied [flutter_lints](https://pub.dev/packages/flutter_lints). 23 | - Refactored example, migrated to Android v2 embedding. 24 | 25 | ```yaml 26 | dependencies: 27 | flutter: 28 | sdk: flutter 29 | flutter_google_places_hoc081098: 30 | ``` 31 | 32 |
33 | 34 | 35 | 38 | 41 | 42 |
36 | 37 | 39 | 40 |
43 |
44 | 45 | ## Simple usage 46 | 47 | 48 | According to https://stackoverflow.com/a/52545293, you need to enable billing on your account, even if you are only using the free quota. 49 | 50 | ```dart 51 | // replace flutter_google_places by flutter_google_places_hoc081098 52 | import 'package:flutter_google_places_hoc081098/flutter_google_places_hoc081098.dart'; 53 | 54 | const kGoogleApiKey = 'API_KEY'; 55 | 56 | void onError(PlacesAutocompleteResponse response) { 57 | ScaffoldMessenger.of(context).showSnackBar( 58 | SnackBar( 59 | content: Text(response.errorMessage ?? 'Unknown error'), 60 | ), 61 | ); 62 | } 63 | 64 | final Prediction? p = await PlacesAutocomplete.show( 65 | context: context, 66 | apiKey: kGoogleApiKey, 67 | onError: onError, 68 | mode: Mode.overlay, // or Mode.fullscreen 69 | language: 'fr', 70 | components: [Component(Component.country, 'fr')], 71 | ); 72 | 73 | ``` 74 | 75 | The library use [google_maps_webservice](https://github.com/lejard-h/google_maps_webservice) library which directly refer to the official [documentation](https://developers.google.com/maps/web-services/) for google maps web service. 76 | 77 | ## Contributors ✨ 78 | 79 | Thanks goes to these wonderful people ([emoji key](https://allcontributors.org/docs/en/emoji-key)): 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 |

Petrus Nguyễn Thái Học

💻 🚧

Corentin Giraud

💻
90 | 91 | 92 | 93 | 94 | 95 | 96 | This project follows the [all-contributors](https://github.com/all-contributors/all-contributors) specification. Contributions of any kind welcome! 97 | -------------------------------------------------------------------------------- /example/lib/main.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'package:flutter_google_places_hoc081098/flutter_google_places_hoc081098.dart'; 5 | import 'package:flutter_google_places_hoc081098/google_maps_webservice_places.dart'; 6 | import 'package:google_api_headers/google_api_headers.dart'; 7 | 8 | import 'custom.dart'; 9 | 10 | const kGoogleApiKey = 'API_KEY'; 11 | 12 | void main() => runApp(const RoutesWidget()); 13 | 14 | final customTheme = ThemeData( 15 | primarySwatch: Colors.blue, 16 | brightness: Brightness.dark, 17 | colorScheme: ColorScheme.fromSwatch( 18 | primarySwatch: Colors.blue, 19 | brightness: Brightness.dark, 20 | accentColor: Colors.redAccent, 21 | ), 22 | inputDecorationTheme: const InputDecorationTheme( 23 | border: OutlineInputBorder( 24 | borderRadius: BorderRadius.all(Radius.circular(4.00)), 25 | ), 26 | contentPadding: EdgeInsets.symmetric( 27 | vertical: 12.50, 28 | horizontal: 10.00, 29 | ), 30 | ), 31 | useMaterial3: true, 32 | ); 33 | 34 | class RoutesWidget extends StatelessWidget { 35 | const RoutesWidget({super.key}); 36 | 37 | @override 38 | Widget build(BuildContext context) { 39 | return MaterialApp( 40 | title: 'My App', 41 | theme: customTheme, 42 | routes: { 43 | '/': (_) => const MyApp(), 44 | '/search': (_) => CustomSearchScaffold(), 45 | }, 46 | ); 47 | } 48 | } 49 | 50 | class MyApp extends StatefulWidget { 51 | const MyApp({super.key}); 52 | 53 | @override 54 | State createState() => _MyAppState(); 55 | } 56 | 57 | class _MyAppState extends State { 58 | Mode _mode = Mode.overlay; 59 | 60 | @override 61 | Widget build(BuildContext context) { 62 | return Scaffold( 63 | appBar: AppBar( 64 | title: const Text('My App'), 65 | ), 66 | body: Center( 67 | child: Column( 68 | mainAxisAlignment: MainAxisAlignment.center, 69 | children: [ 70 | _buildDropdownMenu(), 71 | const SizedBox(height: 12), 72 | ElevatedButton( 73 | onPressed: _handlePressButton, 74 | child: const Text('Search places'), 75 | ), 76 | const SizedBox(height: 12), 77 | ElevatedButton( 78 | onPressed: () { 79 | Navigator.of(context).pushNamed('/search'); 80 | }, 81 | child: const Text('Custom'), 82 | ), 83 | ], 84 | ), 85 | ), 86 | ); 87 | } 88 | 89 | Widget _buildDropdownMenu() { 90 | return DropdownButton( 91 | value: _mode, 92 | items: const >[ 93 | DropdownMenuItem( 94 | value: Mode.overlay, 95 | child: Text('Overlay'), 96 | ), 97 | DropdownMenuItem( 98 | value: Mode.fullscreen, 99 | child: Text('Fullscreen'), 100 | ), 101 | ], 102 | onChanged: (m) { 103 | if (m != null) { 104 | setState(() => _mode = m); 105 | } 106 | }, 107 | ); 108 | } 109 | 110 | Future _handlePressButton() async { 111 | void onError(PlacesAutocompleteResponse response) { 112 | ScaffoldMessenger.of(context).showSnackBar( 113 | SnackBar( 114 | content: Text(response.errorMessage ?? 'Unknown error'), 115 | ), 116 | ); 117 | } 118 | 119 | // show input autocomplete with selected mode 120 | // then get the Prediction selected 121 | final p = await PlacesAutocomplete.show( 122 | context: context, 123 | apiKey: kGoogleApiKey, 124 | onError: onError, 125 | mode: _mode, 126 | language: 'fr', 127 | components: [const Component(Component.country, 'fr')], 128 | resultTextStyle: Theme.of(context).textTheme.titleMedium, 129 | ); 130 | if (!mounted) { 131 | return; 132 | } 133 | await displayPrediction(p, ScaffoldMessenger.of(context)); 134 | } 135 | } 136 | 137 | Future displayPrediction( 138 | Prediction? p, ScaffoldMessengerState messengerState) async { 139 | if (p == null) { 140 | return; 141 | } 142 | 143 | // get detail (lat/lng) 144 | final places = GoogleMapsPlaces( 145 | apiKey: kGoogleApiKey, 146 | apiHeaders: await const GoogleApiHeaders().getHeaders(), 147 | ); 148 | 149 | final detail = await places.getDetailsByPlaceId(p.placeId!); 150 | final geometry = detail.result.geometry!; 151 | final lat = geometry.location.lat; 152 | final lng = geometry.location.lng; 153 | 154 | messengerState.showSnackBar( 155 | SnackBar( 156 | content: Text('${p.description} - $lat/$lng'), 157 | ), 158 | ); 159 | } 160 | -------------------------------------------------------------------------------- /lib/src/google_maps_webservice/src/core.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'core.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | Location _$LocationFromJson(Map json) => Location( 10 | lat: (json['lat'] as num).toDouble(), 11 | lng: (json['lng'] as num).toDouble(), 12 | ); 13 | 14 | Map _$LocationToJson(Location instance) => { 15 | 'lat': instance.lat, 16 | 'lng': instance.lng, 17 | }; 18 | 19 | Geometry _$GeometryFromJson(Map json) => Geometry( 20 | location: Location.fromJson(json['location'] as Map), 21 | locationType: json['location_type'] as String?, 22 | viewport: json['viewport'] == null 23 | ? null 24 | : Bounds.fromJson(json['viewport'] as Map), 25 | bounds: json['bounds'] == null 26 | ? null 27 | : Bounds.fromJson(json['bounds'] as Map), 28 | ); 29 | 30 | Map _$GeometryToJson(Geometry instance) => { 31 | 'location': instance.location.toJson(), 32 | 'location_type': instance.locationType, 33 | 'viewport': instance.viewport?.toJson(), 34 | 'bounds': instance.bounds?.toJson(), 35 | }; 36 | 37 | Bounds _$BoundsFromJson(Map json) => Bounds( 38 | northeast: Location.fromJson(json['northeast'] as Map), 39 | southwest: Location.fromJson(json['southwest'] as Map), 40 | ); 41 | 42 | Map _$BoundsToJson(Bounds instance) => { 43 | 'northeast': instance.northeast.toJson(), 44 | 'southwest': instance.southwest.toJson(), 45 | }; 46 | 47 | AddressComponent _$AddressComponentFromJson(Map json) => 48 | AddressComponent( 49 | types: 50 | (json['types'] as List?)?.map((e) => e as String).toList() ?? 51 | [], 52 | longName: json['long_name'] as String, 53 | shortName: json['short_name'] as String, 54 | ); 55 | 56 | Map _$AddressComponentToJson(AddressComponent instance) => 57 | { 58 | 'types': instance.types, 59 | 'long_name': instance.longName, 60 | 'short_name': instance.shortName, 61 | }; 62 | 63 | _TravelMode _$TravelModeFromJson(Map json) => _TravelMode( 64 | $enumDecode(_$TravelModeEnumMap, json['value']), 65 | ); 66 | 67 | Map _$TravelModeToJson(_TravelMode instance) => 68 | { 69 | 'value': _$TravelModeEnumMap[instance.value]!, 70 | }; 71 | 72 | const _$TravelModeEnumMap = { 73 | TravelMode.driving: 'DRIVING', 74 | TravelMode.walking: 'WALKING', 75 | TravelMode.bicycling: 'BICYCLING', 76 | TravelMode.transit: 'TRANSIT', 77 | }; 78 | 79 | _RouteType _$RouteTypeFromJson(Map json) => _RouteType( 80 | $enumDecode(_$RouteTypeEnumMap, json['value']), 81 | ); 82 | 83 | Map _$RouteTypeToJson(_RouteType instance) => 84 | { 85 | 'value': _$RouteTypeEnumMap[instance.value]!, 86 | }; 87 | 88 | const _$RouteTypeEnumMap = { 89 | RouteType.tolls: 'tolls', 90 | RouteType.highways: 'highways', 91 | RouteType.ferries: 'ferries', 92 | RouteType.indoor: 'indoor', 93 | }; 94 | 95 | _Unit _$UnitFromJson(Map json) => _Unit( 96 | $enumDecode(_$UnitEnumMap, json['value']), 97 | ); 98 | 99 | Map _$UnitToJson(_Unit instance) => { 100 | 'value': _$UnitEnumMap[instance.value]!, 101 | }; 102 | 103 | const _$UnitEnumMap = { 104 | Unit.metric: 'metric', 105 | Unit.imperial: 'imperial', 106 | }; 107 | 108 | _TrafficModel _$TrafficModelFromJson(Map json) => 109 | _TrafficModel( 110 | $enumDecode(_$TrafficModelEnumMap, json['value']), 111 | ); 112 | 113 | Map _$TrafficModelToJson(_TrafficModel instance) => 114 | { 115 | 'value': _$TrafficModelEnumMap[instance.value]!, 116 | }; 117 | 118 | const _$TrafficModelEnumMap = { 119 | TrafficModel.bestGuess: 'best_guess', 120 | TrafficModel.pessimistic: 'pessimistic', 121 | TrafficModel.optimistic: 'optimistic', 122 | }; 123 | 124 | _TransitMode _$TransitModeFromJson(Map json) => _TransitMode( 125 | $enumDecode(_$TransitModeEnumMap, json['value']), 126 | ); 127 | 128 | Map _$TransitModeToJson(_TransitMode instance) => 129 | { 130 | 'value': _$TransitModeEnumMap[instance.value]!, 131 | }; 132 | 133 | const _$TransitModeEnumMap = { 134 | TransitMode.bus: 'bus', 135 | TransitMode.subway: 'subway', 136 | TransitMode.train: 'train', 137 | TransitMode.tram: 'tram', 138 | TransitMode.rail: 'rail', 139 | }; 140 | 141 | _TransitRoutingPreferences _$TransitRoutingPreferencesFromJson( 142 | Map json) => 143 | _TransitRoutingPreferences( 144 | $enumDecode(_$TransitRoutingPreferencesEnumMap, json['value']), 145 | ); 146 | 147 | Map _$TransitRoutingPreferencesToJson( 148 | _TransitRoutingPreferences instance) => 149 | { 150 | 'value': _$TransitRoutingPreferencesEnumMap[instance.value]!, 151 | }; 152 | 153 | const _$TransitRoutingPreferencesEnumMap = { 154 | TransitRoutingPreferences.lessWalking: 'less_walking', 155 | TransitRoutingPreferences.fewerTransfers: 'fewer_transfers', 156 | }; 157 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # flutter_google_places_hoc081098 changelog 2 | 3 | ## 2.0.0 - Jun 21, 2024 4 | 5 | - Update Dart SDK constraint to `'>=3.3.4 <4.0.0'`. 6 | - Update Flutter SDK constraint to `'>=3.19.6'`. 7 | - Remove `google_maps_webservice` dependency. 8 | - Update dependencies 9 | - `google_api_headers: ^4.0.3`. 10 | - `http: ^1.2.1`. 11 | - `rxdart: ^0.28.0`. 12 | - `rxdart_ext: ^0.3.0`. 13 | - `listenable_stream: ^2.0.1`. 14 | - `collection: ^1.18.0`. 15 | - `flutter_bloc_pattern: ^3.0.0`. 16 | - `meta: ^1.11.0`. 17 | 18 | ## 2.0.0-beta.1 - Sep 30, 2023 19 | 20 | - Fix: update generated files. 21 | 22 | ## 2.0.0-beta.0 - Jun 27, 2023 23 | 24 | - Requires `Dart 3.0` or later. 25 | 26 | - Requires `Flutter 3.10.0` or later. 27 | 28 | - Update dependencies 29 | - `google_api_headers: ^2.0.0`. 30 | - `http: ^1.0.0`. 31 | - `rxdart: ^0.27.7`. 32 | - `rxdart_ext: ^0.2.9`. 33 | - `collection: ^1.17.1`. 34 | 35 | - Remove `google_maps_webservice` dependency. 36 | 37 | ## 1.2.0 - Feb 5, 2023 38 | 39 | - Add `resultTextStyle`: used to change the style of `Text` of result. 40 | - Add `overlayBorderRadius`, `textStyle`, `textStyleFormField` to `PlacesAutocompleteField` and `PlacesAutocompleteFormField`. 41 | - Various docs improvements. 42 | 43 | ## 1.1.0 - Jun 20, 2022 44 | 45 | - Update dependencies 46 | - `google_api_headers: ^1.3.0`. 47 | - `rxdart: ^0.27.4`. 48 | - `rxdart_ext: ^0.2.2`. 49 | 50 | - Update `Flutter` constraint to `'>=2.8.0'`. 51 | 52 | ## 1.0.1 - Jan 24, 2022 53 | 54 | - Change Dart SDK constraint to `>=2.14.0 <3.0.0` and Flutter constraint to `>=2.5.0`. 55 | 56 | - Update dependencies to latest release 57 | - `rxdart: ^0.27.3` 58 | - `google_api_headers: ^1.1.1` 59 | - `http: ^0.13.4` 60 | 61 | - Add `insetPadding` and `backArrowIcon` field (thanks to [@corentingiraud](https://github.com/corentingiraud)). 62 | - `insetPadding`: used to configure the padding around the dialog in overlay mode. 63 | - `backArrowIcon`: used to configure the back arrow icon. 64 | 65 | - Refactor internal implementation. 66 | 67 | - Internal: migrated from `pedantic` to `lints` and `flutter_lints`. 68 | 69 | ## 1.0.0-nullsafety.5 - Sep 23, 2021 70 | 71 | - Set Flutter constraint `>=2.2.0`. 72 | 73 | ## 1.0.0-nullsafety.4 - Jul 29, 2021 74 | 75 | - Add `Color? cursorColor` param to `PlacesAutocomplete.show` and `PlacesAutocompleteWidget`: 76 | 77 | ## 1.0.0-nullsafety.3 - Jul 29, 2021 78 | 79 | - Update dependencies to latest release 80 | - `rxdart: ^0.27.1` 81 | - `google_api_headers: ^1.1.0` 82 | 83 | - Add two params to `PlacesAutocomplete.show` and `PlacesAutocompleteWidget`: 84 | - `InputDecoration? textDecoration` 85 | - `TextStyle? textStyle` 86 | 87 | ## 1.0.0-nullsafety.2 - May 9, 2021 88 | 89 | - Update dependencies to latest release 90 | - `google_maps_webservice: ^0.0.20-nullsafety.5` 91 | - `http: ^0.13.3` 92 | - `rxdart: ^0.27.0` 93 | - `listenable_stream: ^1.1.0` 94 | 95 | ## 1.0.0-nullsafety.1 - Apr 02, 2021 96 | 97 | - Add `headers` param to `PlacesAutocomplete.show`, `PlacesAutocompleteWidget`, `PlacesAutocompleteField` 98 | and `PlacesAutocompleteFormField`. 99 | - Change `apiKey` to nullable string (when using a proxy to request Google APIs, the `apiKey` is added on the proxy 100 | itself, consequently the `apiKey` should be `null`) (thanks to [@corentingiraud](https://github.com/corentingiraud)). 101 | 102 | ## 1.0.0-nullsafety.0 - Mar 18, 2021 103 | 104 | - Initial version of `flutter_google_places_hoc081098`. Forked 105 | from [fluttercommunity/flutter_google_places](https://github.com/fluttercommunity/flutter_google_places). 106 | - Opt into **null safety**. 107 | - Sdk constraints: `>=2.12.0 <3.0.0`. 108 | - Compatible with **flutter 2.0.0 stable**. 109 | - Updated dependencies to latest release. 110 | - Refactoring by using **RxDart** for more power. 111 | - Fixed many issues. 112 | - Applied [pedantic](https://pub.dev/packages/pedantic). 113 | - Refactored example, migrated it to Android v2 embedding. 114 | 115 | ---------- 116 | 117 | # [fluttercommunity/flutter_google_places](https://github.com/fluttercommunity/flutter_google_places/blob/master/CHANGELOG.md) changelog 118 | 119 | ## 0.2.8 120 | 121 | - Fix pub.dev complaints 122 | - Remove unsecure links 123 | - Replace deprecated `autovalidate` bool with `AutovalidateMode` 124 | - Formatted with dartfmt 125 | 126 | ## 0.2.7 127 | 128 | - Add expected label behaviour to PlacesAutocompleteField (PR #108) 129 | - Auto select text (PR #109) 130 | - Add to support app restricted API keys (PR #136) 131 | - Replaced deprecated `ancestorStateOfType` method (PR #141) 132 | - Updating rxdart version in pubspec.yaml (PR #143) 133 | 134 | ## 0.2.6 135 | 136 | - Fix error on select place 137 | - Fix bug where `controller.text` is not properly updated 138 | - Fix issue when close the widget and "_queryBehavior" is trying to add text 139 | 140 | ## 0.2.5 141 | 142 | - Updates rxdart to 0.24.0 143 | - Updates google_maps_webservice to 0.0.16 144 | 145 | ## 0.2.4 146 | 147 | - Added support for flutter web 148 | - Update rxdart 149 | - Add overlayBorderRadius parameter 150 | - Add startText parameter 151 | 152 | ## 0.2.3 153 | 154 | - Update rxdart and google_maps_webservice 155 | 156 | ## 0.2.0 157 | 158 | - Better text theme for text input 159 | - Allow proxyUrl with `proxyBaseUrl` and override http client with `httpClient` 160 | 161 | ## 0.1.4 162 | 163 | - Rename footer to logo to be less confusing 164 | 165 | ## 0.1.3 166 | 167 | - Update rxdart 168 | 169 | ## 0.1.2 170 | 171 | - Fix dark mode 172 | 173 | ## 0.1.1 174 | 175 | - Fix icons quality 176 | - Fix input border when custom theme 177 | 178 | ## 0.1.0 179 | 180 | - Update sdk and fix warnings 181 | 182 | ## 0.0.5 183 | 184 | - Fix usage of radius 185 | 186 | ## 0.0.4 187 | 188 | - Open widgets to create your own UI 189 | - Add onError callback 190 | 191 | ## 0.0.3 192 | 193 | - Add padding for overlay on iOS 194 | 195 | ## 0.0.2 196 | 197 | - Update google_maps_webservice to ^0.0.3 198 | - Fix placeholder position 199 | - Fix keyboard clipping on overlay 200 | 201 | ## 0.0.1 202 | 203 | - Initial version 204 | -------------------------------------------------------------------------------- /lib/src/places_autocomplete_form_field.dart: -------------------------------------------------------------------------------- 1 | import 'package:flutter/material.dart'; 2 | 3 | import 'flutter_google_places.dart'; 4 | import 'google_maps_webservice/places.dart'; 5 | import 'places_autocomplete_field.dart'; 6 | 7 | /// A [FormField] that contains a [PlacesAutocompleteField]. 8 | /// 9 | /// This is a convenience widget that wraps a [PlacesAutocompleteField] widget in a 10 | /// [FormField]. 11 | /// 12 | /// A [Form] ancestor is not required. The [Form] simply makes it easier to 13 | /// save, reset, or validate multiple fields at once. To use without a [Form], 14 | /// pass a [GlobalKey] to the constructor and use [GlobalKey.currentState] to 15 | /// save or reset the form field. 16 | /// 17 | /// When a [controller] is specified, its [TextEditingController.text] 18 | /// defines the [initialValue]. If this [FormField] is part of a scrolling 19 | /// container that lazily constructs its children, like a [ListView] or a 20 | /// [CustomScrollView], then a [controller] should be specified. 21 | /// The controller's lifetime should be managed by a stateful widget ancestor 22 | /// of the scrolling container. 23 | /// 24 | /// If a [controller] is not specified, [initialValue] can be used to give 25 | /// the automatically generated controller an initial value. 26 | /// 27 | /// For a documentation about the various parameters, see [PlacesAutocompleteField]. 28 | /// 29 | /// See also: 30 | /// 31 | /// * [PlacesAutocompleteField], which is the underlying widget without the [Form] 32 | /// integration. 33 | /// * [InputDecorator], which shows the labels and other visual elements that 34 | /// surround the actual text editing widget. 35 | class PlacesAutocompleteFormField extends FormField { 36 | /// Creates a [FormField] that contains a [PlacesAutocompleteField]. 37 | /// 38 | /// When a [controller] is specified, [initialValue] must be null (the 39 | /// default). If [controller] is null, then a [TextEditingController] 40 | /// will be constructed automatically and its `text` will be initialized 41 | /// to [initalValue] or the empty string. 42 | /// 43 | /// For documentation about the various parameters, see the [PlacesAutocompleteField] class 44 | /// and [PlacesAutocompleteField], the constructor. 45 | PlacesAutocompleteFormField({ 46 | super.key, 47 | required String? apiKey, 48 | this.controller, 49 | Icon? leading, 50 | String? initialValue, 51 | String? hint = 'Search', 52 | Icon? trailing, 53 | VoidCallback? trailingOnTap, 54 | Mode mode = Mode.fullscreen, 55 | num? offset, 56 | Location? location, 57 | num? radius, 58 | String? language, 59 | String? sessionToken, 60 | List? types, 61 | List? components, 62 | bool? strictbounds, 63 | ValueChanged? onError, 64 | InputDecoration? inputDecoration = const InputDecoration(), 65 | AutovalidateMode super.autovalidateMode = AutovalidateMode.disabled, 66 | super.onSaved, 67 | super.validator, 68 | Map? headers, 69 | BorderRadius? overlayBorderRadius, 70 | TextStyle? textStyle, 71 | TextStyle? textStyleFormField, 72 | }) : assert(initialValue == null || controller == null), 73 | super( 74 | initialValue: 75 | controller != null ? controller.text : (initialValue ?? ''), 76 | builder: (FormFieldState field) { 77 | final state = field as _TextFormFieldState; 78 | final effectiveDecoration = inputDecoration 79 | ?.applyDefaults(Theme.of(state.context).inputDecorationTheme); 80 | return PlacesAutocompleteField( 81 | key: key, 82 | inputDecoration: 83 | effectiveDecoration?.copyWith(errorText: state.errorText), 84 | controller: state._effectiveController, 85 | apiKey: apiKey, 86 | leading: leading, 87 | trailing: trailing, 88 | offset: offset, 89 | trailingOnTap: trailingOnTap, 90 | hint: hint, 91 | location: location, 92 | radius: radius, 93 | components: components, 94 | language: language, 95 | sessionToken: sessionToken, 96 | types: types, 97 | mode: mode, 98 | strictbounds: strictbounds, 99 | onChanged: state.didChange, 100 | onError: onError, 101 | headers: headers, 102 | overlayBorderRadius: overlayBorderRadius, 103 | textStyle: textStyle, 104 | textStyleFormField: textStyleFormField, 105 | ); 106 | }, 107 | ); 108 | 109 | /// Controls the text being edited. 110 | /// 111 | /// If null, this widget will create its own [TextEditingController] and 112 | /// initialize its [TextEditingController.text] with [initialValue]. 113 | final TextEditingController? controller; 114 | 115 | @override 116 | FormFieldState createState() => _TextFormFieldState(); 117 | } 118 | 119 | class _TextFormFieldState extends FormFieldState { 120 | TextEditingController? _controller; 121 | 122 | TextEditingController get _effectiveController => 123 | widget.controller ?? _controller!; 124 | 125 | @override 126 | PlacesAutocompleteFormField get widget => 127 | super.widget as PlacesAutocompleteFormField; 128 | 129 | @override 130 | void initState() { 131 | super.initState(); 132 | if (widget.controller == null) { 133 | _controller = TextEditingController(text: widget.initialValue); 134 | } else { 135 | widget.controller!.addListener(_handleControllerChanged); 136 | } 137 | } 138 | 139 | @override 140 | void didUpdateWidget(PlacesAutocompleteFormField oldWidget) { 141 | super.didUpdateWidget(oldWidget); 142 | if (widget.controller != oldWidget.controller) { 143 | oldWidget.controller?.removeListener(_handleControllerChanged); 144 | widget.controller?.addListener(_handleControllerChanged); 145 | 146 | if (oldWidget.controller != null && widget.controller == null) { 147 | _controller = 148 | TextEditingController.fromValue(oldWidget.controller!.value); 149 | } 150 | if (widget.controller != null) { 151 | setValue(widget.controller!.text); 152 | if (oldWidget.controller == null) { 153 | _controller = null; 154 | } 155 | } 156 | } 157 | } 158 | 159 | @override 160 | void dispose() { 161 | widget.controller?.removeListener(_handleControllerChanged); 162 | super.dispose(); 163 | } 164 | 165 | @override 166 | void reset() { 167 | super.reset(); 168 | setState(() { 169 | _effectiveController.text = widget.initialValue ?? ''; 170 | }); 171 | } 172 | 173 | void _handleControllerChanged() { 174 | // Suppress changes that originated from within this class. 175 | // 176 | // In the case where a controller has been passed in to this widget, we 177 | // register this change listener. In these cases, we'll also receive change 178 | // notifications for changes originating from within this class -- for 179 | // example, the reset() method. In such cases, the FormField value will 180 | // already have been set. 181 | if (_effectiveController.text != value) { 182 | didChange(_effectiveController.text); 183 | } 184 | } 185 | } 186 | -------------------------------------------------------------------------------- /lib/src/google_maps_webservice/src/core.dart: -------------------------------------------------------------------------------- 1 | import 'package:json_annotation/json_annotation.dart'; 2 | import 'package:meta/meta.dart'; 3 | 4 | part 'core.g.dart'; 5 | 6 | const _jsonSerializable = JsonSerializable( 7 | fieldRename: FieldRename.snake, 8 | explicitToJson: true, 9 | ); 10 | 11 | @_jsonSerializable 12 | @immutable 13 | class Location { 14 | final double lat; 15 | final double lng; 16 | 17 | const Location({ 18 | required this.lat, 19 | required this.lng, 20 | }); 21 | 22 | factory Location.fromJson(Map json) => 23 | _$LocationFromJson(json); 24 | Map toJson() => _$LocationToJson(this); 25 | 26 | @override 27 | String toString() => '$lat,$lng'; 28 | } 29 | 30 | @_jsonSerializable 31 | @immutable 32 | class Geometry { 33 | final Location location; 34 | 35 | /// JSON location_type 36 | final String? locationType; 37 | 38 | final Bounds? viewport; 39 | 40 | final Bounds? bounds; 41 | 42 | const Geometry({ 43 | required this.location, 44 | this.locationType, 45 | this.viewport, 46 | this.bounds, 47 | }); 48 | 49 | factory Geometry.fromJson(Map json) => 50 | _$GeometryFromJson(json); 51 | Map toJson() => _$GeometryToJson(this); 52 | } 53 | 54 | @_jsonSerializable 55 | @immutable 56 | class Bounds { 57 | final Location northeast; 58 | final Location southwest; 59 | 60 | const Bounds({ 61 | required this.northeast, 62 | required this.southwest, 63 | }); 64 | 65 | @override 66 | String toString() => 67 | '${northeast.lat},${northeast.lng}|${southwest.lat},${southwest.lng}'; 68 | 69 | factory Bounds.fromJson(Map json) => _$BoundsFromJson(json); 70 | Map toJson() => _$BoundsToJson(this); 71 | } 72 | 73 | abstract class GoogleResponseStatus { 74 | static const okay = 'OK'; 75 | static const zeroResults = 'ZERO_RESULTS'; 76 | static const overQueryLimit = 'OVER_QUERY_LIMIT'; 77 | static const requestDenied = 'REQUEST_DENIED'; 78 | static const invalidRequest = 'INVALID_REQUEST'; 79 | static const unknownErrorStatus = 'UNKNOWN_ERROR'; 80 | static const notFound = 'NOT_FOUND'; 81 | static const maxWaypointsExceeded = 'MAX_WAYPOINTS_EXCEEDED'; 82 | static const maxRouteLengthExceeded = 'MAX_ROUTE_LENGTH_EXCEEDED'; 83 | 84 | // TODO use enum for Response status 85 | final String status; 86 | 87 | /// JSON error_message 88 | final String? errorMessage; 89 | 90 | bool get isOkay => status == okay; 91 | bool get hasNoResults => status == zeroResults; 92 | bool get isOverQueryLimit => status == overQueryLimit; 93 | bool get isDenied => status == requestDenied; 94 | bool get isInvalid => status == invalidRequest; 95 | bool get unknownError => status == unknownErrorStatus; 96 | bool get isNotFound => status == notFound; 97 | 98 | GoogleResponseStatus({required this.status, this.errorMessage}); 99 | } 100 | 101 | abstract class GoogleResponseList extends GoogleResponseStatus { 102 | @JsonKey(defaultValue: []) 103 | final List results; 104 | 105 | GoogleResponseList(String status, String? errorMessage, this.results) 106 | : super(status: status, errorMessage: errorMessage); 107 | } 108 | 109 | abstract class GoogleResponse extends GoogleResponseStatus { 110 | final T result; 111 | 112 | GoogleResponse(String status, String? errorMessage, this.result) 113 | : super(status: status, errorMessage: errorMessage); 114 | } 115 | 116 | @_jsonSerializable 117 | @immutable 118 | class AddressComponent { 119 | @JsonKey(defaultValue: []) 120 | final List types; 121 | 122 | /// JSON long_name 123 | final String longName; 124 | 125 | /// JSON short_name 126 | final String shortName; 127 | 128 | const AddressComponent({ 129 | required this.types, 130 | required this.longName, 131 | required this.shortName, 132 | }); 133 | 134 | factory AddressComponent.fromJson(Map json) => 135 | _$AddressComponentFromJson(json); 136 | Map toJson() => _$AddressComponentToJson(this); 137 | } 138 | 139 | @immutable 140 | class Component { 141 | static const route = 'route'; 142 | static const locality = 'locality'; 143 | static const administrativeArea = 'administrative_area'; 144 | static const postalCode = 'postal_code'; 145 | static const country = 'country'; 146 | 147 | final String component; 148 | final String value; 149 | 150 | const Component(this.component, this.value); 151 | 152 | @override 153 | String toString() => '$component:$value'; 154 | } 155 | 156 | enum TravelMode { 157 | @JsonValue('DRIVING') 158 | driving, 159 | @JsonValue('WALKING') 160 | walking, 161 | @JsonValue('BICYCLING') 162 | bicycling, 163 | @JsonValue('TRANSIT') 164 | transit, 165 | } 166 | 167 | @_jsonSerializable 168 | @immutable 169 | class _TravelMode { 170 | final TravelMode value; 171 | 172 | const _TravelMode(this.value); 173 | 174 | // ignore: unused_element 175 | factory _TravelMode.fromJson(Map json) => 176 | _$TravelModeFromJson(json); 177 | 178 | Map toJson() => _$TravelModeToJson(this); 179 | } 180 | 181 | extension TravelModeExt on TravelMode { 182 | static TravelMode fromApiString(String mode) { 183 | return $enumDecode(_$TravelModeEnumMap, mode); 184 | } 185 | 186 | String toApiString() { 187 | return _$TravelModeEnumMap[this] ?? ''; 188 | } 189 | } 190 | 191 | enum RouteType { 192 | tolls, 193 | highways, 194 | ferries, 195 | indoor, 196 | } 197 | 198 | @_jsonSerializable 199 | @immutable 200 | class _RouteType { 201 | final RouteType value; 202 | 203 | const _RouteType(this.value); 204 | 205 | // ignore: unused_element 206 | factory _RouteType.fromJson(Map json) => 207 | _$RouteTypeFromJson(json); 208 | Map toJson() => _$RouteTypeToJson(this); 209 | } 210 | 211 | extension RouteTypeExt on RouteType { 212 | static RouteType fromApiString(String mode) { 213 | return $enumDecode(_$RouteTypeEnumMap, mode); 214 | } 215 | 216 | String toApiString() { 217 | return _$RouteTypeEnumMap[this] ?? ''; 218 | } 219 | } 220 | 221 | enum Unit { 222 | metric, 223 | imperial, 224 | } 225 | 226 | @_jsonSerializable 227 | @immutable 228 | class _Unit { 229 | final Unit value; 230 | 231 | const _Unit(this.value); 232 | 233 | // ignore: unused_element 234 | factory _Unit.fromJson(Map json) => _$UnitFromJson(json); 235 | Map toJson() => _$UnitToJson(this); 236 | } 237 | 238 | extension UnitExt on Unit { 239 | static Unit fromApiString(String mode) { 240 | return $enumDecode(_$UnitEnumMap, mode); 241 | } 242 | 243 | String toApiString() { 244 | return _$UnitEnumMap[this] ?? ''; 245 | } 246 | } 247 | 248 | enum TrafficModel { 249 | @JsonValue('best_guess') 250 | bestGuess, 251 | pessimistic, 252 | optimistic, 253 | } 254 | 255 | @_jsonSerializable 256 | @immutable 257 | class _TrafficModel { 258 | final TrafficModel value; 259 | 260 | const _TrafficModel(this.value); 261 | 262 | // ignore: unused_element 263 | factory _TrafficModel.fromJson(Map json) => 264 | _$TrafficModelFromJson(json); 265 | Map toJson() => _$TrafficModelToJson(this); 266 | } 267 | 268 | extension TrafficModelExt on TrafficModel { 269 | static TrafficModel fromApiString(String mode) { 270 | return $enumDecode(_$TrafficModelEnumMap, mode); 271 | } 272 | 273 | String toApiString() { 274 | return _$TrafficModelEnumMap[this] ?? ''; 275 | } 276 | } 277 | 278 | enum TransitMode { 279 | bus, 280 | subway, 281 | train, 282 | tram, 283 | rail, 284 | } 285 | 286 | @_jsonSerializable 287 | @immutable 288 | class _TransitMode { 289 | final TransitMode value; 290 | 291 | const _TransitMode(this.value); 292 | 293 | // ignore: unused_element 294 | factory _TransitMode.fromJson(Map json) => 295 | _$TransitModeFromJson(json); 296 | Map toJson() => _$TransitModeToJson(this); 297 | } 298 | 299 | extension TransitModeExt on TransitMode { 300 | static TransitMode fromApiString(String mode) { 301 | return $enumDecode(_$TransitModeEnumMap, mode); 302 | } 303 | 304 | String toApiString() { 305 | return _$TransitModeEnumMap[this] ?? ''; 306 | } 307 | } 308 | 309 | enum TransitRoutingPreferences { 310 | @JsonValue('less_walking') 311 | lessWalking, 312 | @JsonValue('fewer_transfers') 313 | fewerTransfers, 314 | } 315 | 316 | @_jsonSerializable 317 | @immutable 318 | class _TransitRoutingPreferences { 319 | final TransitRoutingPreferences value; 320 | 321 | const _TransitRoutingPreferences(this.value); 322 | 323 | // ignore: unused_element 324 | factory _TransitRoutingPreferences.fromJson(Map json) => 325 | _$TransitRoutingPreferencesFromJson(json); 326 | 327 | Map toJson() => _$TransitRoutingPreferencesToJson(this); 328 | } 329 | 330 | extension TransitRoutingPreferencesExt on TransitRoutingPreferences { 331 | static TransitRoutingPreferences fromApiString(String mode) { 332 | return $enumDecode(_$TransitRoutingPreferencesEnumMap, mode); 333 | } 334 | 335 | String toApiString() { 336 | return _$TransitRoutingPreferencesEnumMap[this] ?? ''; 337 | } 338 | } 339 | -------------------------------------------------------------------------------- /lib/src/places_autocomplete_field.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | 3 | import 'package:flutter/material.dart'; 4 | import 'google_maps_webservice/places.dart'; 5 | 6 | import 'flutter_google_places.dart'; 7 | 8 | /// A text field like widget to input places with autocomplete. 9 | /// 10 | /// The autocomplete field calls [onChanged] with the new address line 11 | /// whenever the user input a new location. 12 | /// 13 | /// To control the text that is displayed in the text field, use the 14 | /// [controller]. For example, to set the initial value of the text field, use 15 | /// a [controller] that already contains some text. 16 | /// 17 | /// By default, an autocomplete field has a [decoration] that draws a divider 18 | /// below the field. You can use the [decoration] property to control the 19 | /// decoration, for example by adding a label or an icon. If you set the [decoration] 20 | /// property to null, the decoration will be removed entirely, including the 21 | /// extra padding introduced by the decoration to save space for the labels. 22 | /// If you want the icon to be outside the input field use [decoration.icon]. 23 | /// If it should be inside the field use [leading]. 24 | /// 25 | /// To integrate the [PlacesAutocompleteField] into a [Form] with other [FormField] 26 | /// widgets, consider using [PlacesAutocompleteFormField]. 27 | /// 28 | /// See also: 29 | /// 30 | /// * [PlacesAutocompleteFormField], which integrates with the [Form] widget. 31 | /// * [InputDecorator], which shows the labels and other visual elements that 32 | /// surround the actual text editing widget. 33 | class PlacesAutocompleteField extends StatefulWidget { 34 | /// Creates a text field like widget. 35 | /// 36 | /// To remove the decoration entirely (including the extra padding introduced 37 | /// by the decoration to save space for the labels), set the [decoration] to 38 | /// null. 39 | const PlacesAutocompleteField({ 40 | super.key, 41 | required this.apiKey, 42 | this.controller, 43 | this.leading, 44 | this.hint = 'Search', 45 | this.trailing, 46 | this.trailingOnTap, 47 | this.mode = Mode.fullscreen, 48 | this.offset, 49 | this.location, 50 | this.radius, 51 | this.language, 52 | this.sessionToken, 53 | this.types, 54 | this.components, 55 | this.strictbounds, 56 | this.onChanged, 57 | this.onSelected, 58 | this.onError, 59 | this.inputDecoration = const InputDecoration(), 60 | this.headers, 61 | this.overlayBorderRadius, 62 | this.textStyle, 63 | this.textStyleFormField, 64 | }); 65 | 66 | /// Controls the text being edited. 67 | /// 68 | /// If null, this widget will create its own [TextEditingController]. 69 | final TextEditingController? controller; 70 | 71 | /// Icon shown inside the field left to the text. 72 | final Icon? leading; 73 | 74 | /// Icon shown inside the field right to the text. 75 | final Icon? trailing; 76 | 77 | /// Callback when [trailing] is tapped on. 78 | final VoidCallback? trailingOnTap; 79 | 80 | /// Text that is shown, when no input was done, yet. 81 | final String? hint; 82 | 83 | /// Your Google Maps Places API Key. 84 | /// 85 | /// For this key the Places Web API needs to be activated. For further 86 | /// information on how to do this, see their official documentation below. 87 | /// 88 | /// See also: 89 | /// 90 | /// * 91 | final String? apiKey; 92 | 93 | /// The decoration to show around the text field. 94 | /// 95 | /// By default, draws a horizontal line under the autocomplete field but can be 96 | /// configured to show an icon, label, hint text, and error text. 97 | /// 98 | /// Specify null to remove the decoration entirely (including the 99 | /// extra padding introduced by the decoration to save space for the labels). 100 | final InputDecoration? inputDecoration; 101 | 102 | /// The position, in the input term, of the last character that the service 103 | /// uses to match predictions. 104 | /// 105 | /// For example, if the input is 'Google' and the 106 | /// offset is 3, the service will match on 'Goo'. The string determined by the 107 | /// offset is matched against the first word in the input term only. For 108 | /// example, if the input term is 'Google abc' and the offset is 3, the service 109 | /// will attempt to match against 'Goo abc'. If no offset is supplied, the 110 | /// service will use the whole term. The offset should generally be set to the 111 | /// position of the text caret. 112 | /// 113 | /// Source: https://developers.google.com/places/web-service/autocomplete 114 | final num? offset; 115 | 116 | final Mode mode; 117 | 118 | final String? language; 119 | 120 | final String? sessionToken; 121 | 122 | final List? types; 123 | 124 | final List? components; 125 | 126 | final Location? location; 127 | 128 | final num? radius; 129 | 130 | final bool? strictbounds; 131 | 132 | /// Called when the text being edited changes. 133 | final ValueChanged? onChanged; 134 | 135 | /// Called when an autocomplete entry is selected. 136 | final ValueChanged? onSelected; 137 | 138 | /// Callback when autocomplete has error. 139 | final ValueChanged? onError; 140 | 141 | final Map? headers; 142 | 143 | final BorderRadius? overlayBorderRadius; 144 | 145 | final TextStyle? textStyle; 146 | 147 | final TextStyle? textStyleFormField; 148 | 149 | @override 150 | State createState() => 151 | _LocationAutocompleteFieldState(); 152 | } 153 | 154 | class _LocationAutocompleteFieldState extends State { 155 | TextEditingController? _controller; 156 | 157 | TextEditingController get _effectiveController => 158 | widget.controller ?? _controller!; 159 | 160 | @override 161 | void initState() { 162 | super.initState(); 163 | if (widget.controller == null) _controller = TextEditingController(); 164 | } 165 | 166 | @override 167 | void didUpdateWidget(PlacesAutocompleteField oldWidget) { 168 | super.didUpdateWidget(oldWidget); 169 | if (widget.controller != null) { 170 | widget.controller!.text = oldWidget.controller!.text; 171 | } 172 | if (widget.controller == null && oldWidget.controller != null) { 173 | _controller = 174 | TextEditingController.fromValue(oldWidget.controller!.value); 175 | } else if (widget.controller != null && oldWidget.controller == null) { 176 | _controller = null; 177 | } 178 | } 179 | 180 | Future _showAutocomplete() async => PlacesAutocomplete.show( 181 | context: context, 182 | apiKey: widget.apiKey, 183 | offset: widget.offset, 184 | onError: widget.onError, 185 | mode: widget.mode, 186 | hint: widget.hint, 187 | language: widget.language, 188 | sessionToken: widget.sessionToken, 189 | components: widget.components, 190 | location: widget.location, 191 | radius: widget.radius, 192 | types: widget.types, 193 | strictbounds: widget.strictbounds, 194 | headers: widget.headers, 195 | overlayBorderRadius: widget.overlayBorderRadius, 196 | textStyle: widget.textStyle, 197 | ); 198 | 199 | void _handleTap() async { 200 | final p = await _showAutocomplete(); 201 | 202 | if (p == null) return; 203 | 204 | setState(() { 205 | _effectiveController.text = p.description ?? ''; 206 | if (widget.onChanged != null) { 207 | widget.onChanged!(p.description ?? ''); 208 | } 209 | if (widget.onSelected != null) { 210 | widget.onSelected!(p); 211 | } 212 | }); 213 | } 214 | 215 | @override 216 | Widget build(BuildContext context) { 217 | final controller = _effectiveController; 218 | 219 | final text = controller.text.isNotEmpty 220 | ? Text( 221 | controller.text, 222 | softWrap: true, 223 | style: widget.textStyleFormField ?? 224 | const TextStyle(color: Colors.black38), 225 | ) 226 | : Text( 227 | widget.hint ?? '', 228 | style: widget.textStyleFormField ?? 229 | const TextStyle(color: Colors.black38), 230 | ); 231 | 232 | Widget child = Row( 233 | children: [ 234 | widget.leading ?? const SizedBox(), 235 | const SizedBox( 236 | width: 16.0, 237 | ), 238 | Expanded( 239 | child: text, 240 | ), 241 | widget.trailing != null 242 | ? GestureDetector( 243 | onTap: widget.trailingOnTap, 244 | child: widget.trailingOnTap != null 245 | ? widget.trailing! 246 | : Icon( 247 | widget.trailing!.icon, 248 | color: Colors.grey, 249 | ), 250 | ) 251 | : const SizedBox() 252 | ], 253 | ); 254 | 255 | if (widget.inputDecoration != null) { 256 | child = InputDecorator( 257 | decoration: widget.inputDecoration!, 258 | isEmpty: controller.value.text.isEmpty, 259 | child: child, 260 | ); 261 | } 262 | 263 | return GestureDetector( 264 | behavior: HitTestBehavior.translucent, 265 | onTap: _handleTap, 266 | child: child, 267 | ); 268 | } 269 | } 270 | -------------------------------------------------------------------------------- /example/pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | async: 5 | dependency: transitive 6 | description: 7 | name: async 8 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "2.11.0" 12 | boolean_selector: 13 | dependency: transitive 14 | description: 15 | name: boolean_selector 16 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "2.1.1" 20 | built_collection: 21 | dependency: transitive 22 | description: 23 | name: built_collection 24 | sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "5.1.1" 28 | characters: 29 | dependency: transitive 30 | description: 31 | name: characters 32 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "1.3.0" 36 | clock: 37 | dependency: transitive 38 | description: 39 | name: clock 40 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 41 | url: "https://pub.dev" 42 | source: hosted 43 | version: "1.1.1" 44 | collection: 45 | dependency: transitive 46 | description: 47 | name: collection 48 | sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a 49 | url: "https://pub.dev" 50 | source: hosted 51 | version: "1.18.0" 52 | crypto: 53 | dependency: transitive 54 | description: 55 | name: crypto 56 | sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab 57 | url: "https://pub.dev" 58 | source: hosted 59 | version: "3.0.3" 60 | dart_either: 61 | dependency: transitive 62 | description: 63 | name: dart_either 64 | sha256: "928895b8266ac5906eb4e2993fead563a73b17fc86eec6b40172100d56ca2507" 65 | url: "https://pub.dev" 66 | source: hosted 67 | version: "1.0.0" 68 | fake_async: 69 | dependency: transitive 70 | description: 71 | name: fake_async 72 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 73 | url: "https://pub.dev" 74 | source: hosted 75 | version: "1.3.1" 76 | ffi: 77 | dependency: transitive 78 | description: 79 | name: ffi 80 | sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21" 81 | url: "https://pub.dev" 82 | source: hosted 83 | version: "2.1.2" 84 | fixnum: 85 | dependency: transitive 86 | description: 87 | name: fixnum 88 | sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" 89 | url: "https://pub.dev" 90 | source: hosted 91 | version: "1.1.0" 92 | flutter: 93 | dependency: "direct main" 94 | description: flutter 95 | source: sdk 96 | version: "0.0.0" 97 | flutter_bloc_pattern: 98 | dependency: transitive 99 | description: 100 | name: flutter_bloc_pattern 101 | sha256: "934b42da57797a759b62659bb157625749f602239c26f13adde7c61ee65d3e3f" 102 | url: "https://pub.dev" 103 | source: hosted 104 | version: "3.0.0" 105 | flutter_google_places_hoc081098: 106 | dependency: "direct main" 107 | description: 108 | path: ".." 109 | relative: true 110 | source: path 111 | version: "2.0.0" 112 | flutter_lints: 113 | dependency: "direct dev" 114 | description: 115 | name: flutter_lints 116 | sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" 117 | url: "https://pub.dev" 118 | source: hosted 119 | version: "4.0.0" 120 | flutter_provider: 121 | dependency: transitive 122 | description: 123 | name: flutter_provider 124 | sha256: "5bc7d1e9edcf364397f312b9eb901337a644a5e4a907225bcd1d7e9b020ac914" 125 | url: "https://pub.dev" 126 | source: hosted 127 | version: "2.1.0" 128 | flutter_test: 129 | dependency: "direct dev" 130 | description: flutter 131 | source: sdk 132 | version: "0.0.0" 133 | flutter_web_plugins: 134 | dependency: transitive 135 | description: flutter 136 | source: sdk 137 | version: "0.0.0" 138 | google_api_headers: 139 | dependency: "direct main" 140 | description: 141 | name: google_api_headers 142 | sha256: a4f0a82dc4a2019a4fea0724ef3db91769c67b954115ae1088962507f5ecc6c9 143 | url: "https://pub.dev" 144 | source: hosted 145 | version: "4.1.2" 146 | http: 147 | dependency: transitive 148 | description: 149 | name: http 150 | sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" 151 | url: "https://pub.dev" 152 | source: hosted 153 | version: "1.2.1" 154 | http_parser: 155 | dependency: transitive 156 | description: 157 | name: http_parser 158 | sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" 159 | url: "https://pub.dev" 160 | source: hosted 161 | version: "4.0.2" 162 | json_annotation: 163 | dependency: transitive 164 | description: 165 | name: json_annotation 166 | sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" 167 | url: "https://pub.dev" 168 | source: hosted 169 | version: "4.9.0" 170 | leak_tracker: 171 | dependency: transitive 172 | description: 173 | name: leak_tracker 174 | sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" 175 | url: "https://pub.dev" 176 | source: hosted 177 | version: "10.0.4" 178 | leak_tracker_flutter_testing: 179 | dependency: transitive 180 | description: 181 | name: leak_tracker_flutter_testing 182 | sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" 183 | url: "https://pub.dev" 184 | source: hosted 185 | version: "3.0.3" 186 | leak_tracker_testing: 187 | dependency: transitive 188 | description: 189 | name: leak_tracker_testing 190 | sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" 191 | url: "https://pub.dev" 192 | source: hosted 193 | version: "3.0.1" 194 | lints: 195 | dependency: transitive 196 | description: 197 | name: lints 198 | sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" 199 | url: "https://pub.dev" 200 | source: hosted 201 | version: "4.0.0" 202 | listenable_stream: 203 | dependency: transitive 204 | description: 205 | name: listenable_stream 206 | sha256: "80decc4ef1dd999b42cf696d63f7729d1298a68f75b6bf3c944851ce5bf0eafd" 207 | url: "https://pub.dev" 208 | source: hosted 209 | version: "2.0.1" 210 | matcher: 211 | dependency: transitive 212 | description: 213 | name: matcher 214 | sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb 215 | url: "https://pub.dev" 216 | source: hosted 217 | version: "0.12.16+1" 218 | material_color_utilities: 219 | dependency: transitive 220 | description: 221 | name: material_color_utilities 222 | sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" 223 | url: "https://pub.dev" 224 | source: hosted 225 | version: "0.8.0" 226 | meta: 227 | dependency: transitive 228 | description: 229 | name: meta 230 | sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" 231 | url: "https://pub.dev" 232 | source: hosted 233 | version: "1.12.0" 234 | package_info_plus: 235 | dependency: transitive 236 | description: 237 | name: package_info_plus 238 | sha256: b93d8b4d624b4ea19b0a5a208b2d6eff06004bc3ce74c06040b120eeadd00ce0 239 | url: "https://pub.dev" 240 | source: hosted 241 | version: "8.0.0" 242 | package_info_plus_platform_interface: 243 | dependency: transitive 244 | description: 245 | name: package_info_plus_platform_interface 246 | sha256: f49918f3433a3146047372f9d4f1f847511f2acd5cd030e1f44fe5a50036b70e 247 | url: "https://pub.dev" 248 | source: hosted 249 | version: "3.0.0" 250 | path: 251 | dependency: transitive 252 | description: 253 | name: path 254 | sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" 255 | url: "https://pub.dev" 256 | source: hosted 257 | version: "1.9.0" 258 | plugin_platform_interface: 259 | dependency: transitive 260 | description: 261 | name: plugin_platform_interface 262 | sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" 263 | url: "https://pub.dev" 264 | source: hosted 265 | version: "2.1.8" 266 | rxdart: 267 | dependency: transitive 268 | description: 269 | name: rxdart 270 | sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962" 271 | url: "https://pub.dev" 272 | source: hosted 273 | version: "0.28.0" 274 | rxdart_ext: 275 | dependency: transitive 276 | description: 277 | name: rxdart_ext 278 | sha256: "95df7e8b13140e2c3fdb3b943569a51f18090e82aaaf6ca6e8e6437e434a6fb0" 279 | url: "https://pub.dev" 280 | source: hosted 281 | version: "0.3.0" 282 | sky_engine: 283 | dependency: transitive 284 | description: flutter 285 | source: sdk 286 | version: "0.0.99" 287 | source_span: 288 | dependency: transitive 289 | description: 290 | name: source_span 291 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 292 | url: "https://pub.dev" 293 | source: hosted 294 | version: "1.10.0" 295 | sprintf: 296 | dependency: transitive 297 | description: 298 | name: sprintf 299 | sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23" 300 | url: "https://pub.dev" 301 | source: hosted 302 | version: "7.0.0" 303 | stack_trace: 304 | dependency: transitive 305 | description: 306 | name: stack_trace 307 | sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" 308 | url: "https://pub.dev" 309 | source: hosted 310 | version: "1.11.1" 311 | stream_channel: 312 | dependency: transitive 313 | description: 314 | name: stream_channel 315 | sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 316 | url: "https://pub.dev" 317 | source: hosted 318 | version: "2.1.2" 319 | string_scanner: 320 | dependency: transitive 321 | description: 322 | name: string_scanner 323 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 324 | url: "https://pub.dev" 325 | source: hosted 326 | version: "1.2.0" 327 | term_glyph: 328 | dependency: transitive 329 | description: 330 | name: term_glyph 331 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 332 | url: "https://pub.dev" 333 | source: hosted 334 | version: "1.2.1" 335 | test_api: 336 | dependency: transitive 337 | description: 338 | name: test_api 339 | sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" 340 | url: "https://pub.dev" 341 | source: hosted 342 | version: "0.7.0" 343 | typed_data: 344 | dependency: transitive 345 | description: 346 | name: typed_data 347 | sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c 348 | url: "https://pub.dev" 349 | source: hosted 350 | version: "1.3.2" 351 | uuid: 352 | dependency: "direct main" 353 | description: 354 | name: uuid 355 | sha256: "814e9e88f21a176ae1359149021870e87f7cddaf633ab678a5d2b0bff7fd1ba8" 356 | url: "https://pub.dev" 357 | source: hosted 358 | version: "4.4.0" 359 | vector_math: 360 | dependency: transitive 361 | description: 362 | name: vector_math 363 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 364 | url: "https://pub.dev" 365 | source: hosted 366 | version: "2.1.4" 367 | vm_service: 368 | dependency: transitive 369 | description: 370 | name: vm_service 371 | sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" 372 | url: "https://pub.dev" 373 | source: hosted 374 | version: "14.2.1" 375 | web: 376 | dependency: transitive 377 | description: 378 | name: web 379 | sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" 380 | url: "https://pub.dev" 381 | source: hosted 382 | version: "0.5.1" 383 | win32: 384 | dependency: transitive 385 | description: 386 | name: win32 387 | sha256: a79dbe579cb51ecd6d30b17e0cae4e0ea15e2c0e66f69ad4198f22a6789e94f4 388 | url: "https://pub.dev" 389 | source: hosted 390 | version: "5.5.1" 391 | sdks: 392 | dart: ">=3.4.3 <4.0.0" 393 | flutter: ">=3.22.2" 394 | -------------------------------------------------------------------------------- /lib/src/google_maps_webservice/src/places.g.dart: -------------------------------------------------------------------------------- 1 | // GENERATED CODE - DO NOT MODIFY BY HAND 2 | 3 | part of 'places.dart'; 4 | 5 | // ************************************************************************** 6 | // JsonSerializableGenerator 7 | // ************************************************************************** 8 | 9 | PlacesSearchResponse _$PlacesSearchResponseFromJson( 10 | Map json) => 11 | PlacesSearchResponse( 12 | status: json['status'] as String, 13 | errorMessage: json['error_message'] as String?, 14 | results: (json['results'] as List?) 15 | ?.map( 16 | (e) => PlacesSearchResult.fromJson(e as Map)) 17 | .toList() ?? 18 | [], 19 | htmlAttributions: (json['html_attributions'] as List?) 20 | ?.map((e) => e as String) 21 | .toList() ?? 22 | [], 23 | nextPageToken: json['next_page_token'] as String?, 24 | ); 25 | 26 | Map _$PlacesSearchResponseToJson( 27 | PlacesSearchResponse instance) => 28 | { 29 | 'status': instance.status, 30 | 'error_message': instance.errorMessage, 31 | 'results': instance.results.map((e) => e.toJson()).toList(), 32 | 'html_attributions': instance.htmlAttributions, 33 | 'next_page_token': instance.nextPageToken, 34 | }; 35 | 36 | PlacesSearchResult _$PlacesSearchResultFromJson(Map json) => 37 | PlacesSearchResult( 38 | id: json['id'] as String?, 39 | reference: json['reference'] as String, 40 | name: json['name'] as String, 41 | placeId: json['place_id'] as String, 42 | formattedAddress: json['formatted_address'] as String?, 43 | photos: (json['photos'] as List?) 44 | ?.map((e) => Photo.fromJson(e as Map)) 45 | .toList() ?? 46 | [], 47 | altIds: (json['alt_ids'] as List?) 48 | ?.map((e) => AlternativeId.fromJson(e as Map)) 49 | .toList() ?? 50 | [], 51 | types: 52 | (json['types'] as List?)?.map((e) => e as String).toList() ?? 53 | [], 54 | permanentlyClosed: json['permanently_closed'] as bool? ?? false, 55 | icon: json['icon'] as String?, 56 | geometry: json['geometry'] == null 57 | ? null 58 | : Geometry.fromJson(json['geometry'] as Map), 59 | openingHours: json['opening_hours'] == null 60 | ? null 61 | : OpeningHoursDetail.fromJson( 62 | json['opening_hours'] as Map), 63 | scope: json['scope'] as String?, 64 | priceLevel: $enumDecodeNullable(_$PriceLevelEnumMap, json['price_level']), 65 | rating: json['rating'] as num?, 66 | vicinity: json['vicinity'] as String?, 67 | ); 68 | 69 | Map _$PlacesSearchResultToJson(PlacesSearchResult instance) => 70 | { 71 | 'icon': instance.icon, 72 | 'geometry': instance.geometry?.toJson(), 73 | 'name': instance.name, 74 | 'opening_hours': instance.openingHours?.toJson(), 75 | 'photos': instance.photos.map((e) => e.toJson()).toList(), 76 | 'place_id': instance.placeId, 77 | 'scope': instance.scope, 78 | 'alt_ids': instance.altIds.map((e) => e.toJson()).toList(), 79 | 'price_level': _$PriceLevelEnumMap[instance.priceLevel], 80 | 'rating': instance.rating, 81 | 'types': instance.types, 82 | 'vicinity': instance.vicinity, 83 | 'formatted_address': instance.formattedAddress, 84 | 'permanently_closed': instance.permanentlyClosed, 85 | 'id': instance.id, 86 | 'reference': instance.reference, 87 | }; 88 | 89 | const _$PriceLevelEnumMap = { 90 | PriceLevel.free: 0, 91 | PriceLevel.inexpensive: 1, 92 | PriceLevel.moderate: 2, 93 | PriceLevel.expensive: 3, 94 | PriceLevel.veryExpensive: 4, 95 | }; 96 | 97 | PlaceDetails _$PlaceDetailsFromJson(Map json) => PlaceDetails( 98 | adrAddress: json['adr_address'] as String?, 99 | name: json['name'] as String, 100 | placeId: json['place_id'] as String, 101 | utcOffset: json['utc_offset'] as num?, 102 | id: json['id'] as String?, 103 | internationalPhoneNumber: json['international_phone_number'] as String?, 104 | addressComponents: (json['address_components'] as List?) 105 | ?.map((e) => AddressComponent.fromJson(e as Map)) 106 | .toList() ?? 107 | [], 108 | photos: (json['photos'] as List?) 109 | ?.map((e) => Photo.fromJson(e as Map)) 110 | .toList() ?? 111 | [], 112 | types: 113 | (json['types'] as List?)?.map((e) => e as String).toList() ?? 114 | [], 115 | reviews: (json['reviews'] as List?) 116 | ?.map((e) => Review.fromJson(e as Map)) 117 | .toList() ?? 118 | [], 119 | formattedAddress: json['formatted_address'] as String?, 120 | formattedPhoneNumber: json['formatted_phone_number'] as String?, 121 | reference: json['reference'] as String?, 122 | icon: json['icon'] as String?, 123 | rating: json['rating'] as num?, 124 | openingHours: json['opening_hours'] == null 125 | ? null 126 | : OpeningHoursDetail.fromJson( 127 | json['opening_hours'] as Map), 128 | priceLevel: $enumDecodeNullable(_$PriceLevelEnumMap, json['price_level']), 129 | scope: json['scope'] as String?, 130 | url: json['url'] as String?, 131 | vicinity: json['vicinity'] as String?, 132 | website: json['website'] as String?, 133 | geometry: json['geometry'] == null 134 | ? null 135 | : Geometry.fromJson(json['geometry'] as Map), 136 | ); 137 | 138 | Map _$PlaceDetailsToJson(PlaceDetails instance) => 139 | { 140 | 'address_components': 141 | instance.addressComponents.map((e) => e.toJson()).toList(), 142 | 'adr_address': instance.adrAddress, 143 | 'formatted_address': instance.formattedAddress, 144 | 'formatted_phone_number': instance.formattedPhoneNumber, 145 | 'id': instance.id, 146 | 'reference': instance.reference, 147 | 'icon': instance.icon, 148 | 'name': instance.name, 149 | 'opening_hours': instance.openingHours?.toJson(), 150 | 'photos': instance.photos.map((e) => e.toJson()).toList(), 151 | 'place_id': instance.placeId, 152 | 'international_phone_number': instance.internationalPhoneNumber, 153 | 'price_level': _$PriceLevelEnumMap[instance.priceLevel], 154 | 'rating': instance.rating, 155 | 'scope': instance.scope, 156 | 'types': instance.types, 157 | 'url': instance.url, 158 | 'vicinity': instance.vicinity, 159 | 'utc_offset': instance.utcOffset, 160 | 'website': instance.website, 161 | 'reviews': instance.reviews.map((e) => e.toJson()).toList(), 162 | 'geometry': instance.geometry?.toJson(), 163 | }; 164 | 165 | OpeningHoursDetail _$OpeningHoursDetailFromJson(Map json) => 166 | OpeningHoursDetail( 167 | openNow: json['open_now'] as bool? ?? false, 168 | periods: (json['periods'] as List?) 169 | ?.map( 170 | (e) => OpeningHoursPeriod.fromJson(e as Map)) 171 | .toList() ?? 172 | [], 173 | weekdayText: (json['weekday_text'] as List?) 174 | ?.map((e) => e as String) 175 | .toList() ?? 176 | [], 177 | ); 178 | 179 | Map _$OpeningHoursDetailToJson(OpeningHoursDetail instance) => 180 | { 181 | 'open_now': instance.openNow, 182 | 'periods': instance.periods.map((e) => e.toJson()).toList(), 183 | 'weekday_text': instance.weekdayText, 184 | }; 185 | 186 | OpeningHoursPeriodDate _$OpeningHoursPeriodDateFromJson( 187 | Map json) => 188 | OpeningHoursPeriodDate( 189 | day: (json['day'] as num).toInt(), 190 | time: json['time'] as String, 191 | ); 192 | 193 | Map _$OpeningHoursPeriodDateToJson( 194 | OpeningHoursPeriodDate instance) => 195 | { 196 | 'day': instance.day, 197 | 'time': instance.time, 198 | }; 199 | 200 | OpeningHoursPeriod _$OpeningHoursPeriodFromJson(Map json) => 201 | OpeningHoursPeriod( 202 | open: json['open'] == null 203 | ? null 204 | : OpeningHoursPeriodDate.fromJson( 205 | json['open'] as Map), 206 | close: json['close'] == null 207 | ? null 208 | : OpeningHoursPeriodDate.fromJson( 209 | json['close'] as Map), 210 | ); 211 | 212 | Map _$OpeningHoursPeriodToJson(OpeningHoursPeriod instance) => 213 | { 214 | 'open': instance.open?.toJson(), 215 | 'close': instance.close?.toJson(), 216 | }; 217 | 218 | Photo _$PhotoFromJson(Map json) => Photo( 219 | photoReference: json['photo_reference'] as String, 220 | height: json['height'] as num, 221 | width: json['width'] as num, 222 | htmlAttributions: (json['html_attributions'] as List?) 223 | ?.map((e) => e as String) 224 | .toList() ?? 225 | [], 226 | ); 227 | 228 | Map _$PhotoToJson(Photo instance) => { 229 | 'photo_reference': instance.photoReference, 230 | 'height': instance.height, 231 | 'width': instance.width, 232 | 'html_attributions': instance.htmlAttributions, 233 | }; 234 | 235 | AlternativeId _$AlternativeIdFromJson(Map json) => 236 | AlternativeId( 237 | placeId: json['place_id'] as String, 238 | scope: json['scope'] as String, 239 | ); 240 | 241 | Map _$AlternativeIdToJson(AlternativeId instance) => 242 | { 243 | 'place_id': instance.placeId, 244 | 'scope': instance.scope, 245 | }; 246 | 247 | PlacesDetailsResponse _$PlacesDetailsResponseFromJson( 248 | Map json) => 249 | PlacesDetailsResponse( 250 | status: json['status'] as String, 251 | errorMessage: json['error_message'] as String?, 252 | result: PlaceDetails.fromJson(json['result'] as Map), 253 | htmlAttributions: (json['html_attributions'] as List?) 254 | ?.map((e) => e as String) 255 | .toList() ?? 256 | [], 257 | ); 258 | 259 | Map _$PlacesDetailsResponseToJson( 260 | PlacesDetailsResponse instance) => 261 | { 262 | 'status': instance.status, 263 | 'error_message': instance.errorMessage, 264 | 'result': instance.result.toJson(), 265 | 'html_attributions': instance.htmlAttributions, 266 | }; 267 | 268 | Review _$ReviewFromJson(Map json) => Review( 269 | authorName: json['author_name'] as String, 270 | authorUrl: json['author_url'] as String, 271 | language: json['language'] as String?, 272 | profilePhotoUrl: json['profile_photo_url'] as String, 273 | rating: json['rating'] as num, 274 | relativeTimeDescription: json['relative_time_description'] as String, 275 | text: json['text'] as String, 276 | time: json['time'] as num, 277 | ); 278 | 279 | Map _$ReviewToJson(Review instance) => { 280 | 'author_name': instance.authorName, 281 | 'author_url': instance.authorUrl, 282 | 'language': instance.language, 283 | 'profile_photo_url': instance.profilePhotoUrl, 284 | 'rating': instance.rating, 285 | 'relative_time_description': instance.relativeTimeDescription, 286 | 'text': instance.text, 287 | 'time': instance.time, 288 | }; 289 | 290 | PlacesAutocompleteResponse _$PlacesAutocompleteResponseFromJson( 291 | Map json) => 292 | PlacesAutocompleteResponse( 293 | status: json['status'] as String, 294 | errorMessage: json['error_message'] as String?, 295 | predictions: (json['predictions'] as List?) 296 | ?.map((e) => Prediction.fromJson(e as Map)) 297 | .toList() ?? 298 | [], 299 | ); 300 | 301 | Map _$PlacesAutocompleteResponseToJson( 302 | PlacesAutocompleteResponse instance) => 303 | { 304 | 'status': instance.status, 305 | 'error_message': instance.errorMessage, 306 | 'predictions': instance.predictions.map((e) => e.toJson()).toList(), 307 | }; 308 | 309 | Prediction _$PredictionFromJson(Map json) => Prediction( 310 | description: json['description'] as String?, 311 | id: json['id'] as String?, 312 | terms: (json['terms'] as List?) 313 | ?.map((e) => Term.fromJson(e as Map)) 314 | .toList() ?? 315 | [], 316 | distanceMeters: (json['distance_meters'] as num?)?.toInt(), 317 | placeId: json['place_id'] as String?, 318 | reference: json['reference'] as String?, 319 | types: 320 | (json['types'] as List?)?.map((e) => e as String).toList() ?? 321 | [], 322 | matchedSubstrings: (json['matched_substrings'] as List?) 323 | ?.map((e) => MatchedSubstring.fromJson(e as Map)) 324 | .toList() ?? 325 | [], 326 | structuredFormatting: json['structured_formatting'] == null 327 | ? null 328 | : StructuredFormatting.fromJson( 329 | json['structured_formatting'] as Map), 330 | ); 331 | 332 | Map _$PredictionToJson(Prediction instance) => 333 | { 334 | 'description': instance.description, 335 | 'id': instance.id, 336 | 'terms': instance.terms.map((e) => e.toJson()).toList(), 337 | 'distance_meters': instance.distanceMeters, 338 | 'place_id': instance.placeId, 339 | 'reference': instance.reference, 340 | 'types': instance.types, 341 | 'matched_substrings': 342 | instance.matchedSubstrings.map((e) => e.toJson()).toList(), 343 | 'structured_formatting': instance.structuredFormatting?.toJson(), 344 | }; 345 | 346 | Term _$TermFromJson(Map json) => Term( 347 | offset: json['offset'] as num, 348 | value: json['value'] as String, 349 | ); 350 | 351 | Map _$TermToJson(Term instance) => { 352 | 'offset': instance.offset, 353 | 'value': instance.value, 354 | }; 355 | 356 | MatchedSubstring _$MatchedSubstringFromJson(Map json) => 357 | MatchedSubstring( 358 | offset: json['offset'] as num, 359 | length: json['length'] as num, 360 | ); 361 | 362 | Map _$MatchedSubstringToJson(MatchedSubstring instance) => 363 | { 364 | 'offset': instance.offset, 365 | 'length': instance.length, 366 | }; 367 | 368 | StructuredFormatting _$StructuredFormattingFromJson( 369 | Map json) => 370 | StructuredFormatting( 371 | mainText: json['main_text'] as String, 372 | mainTextMatchedSubstrings: (json['main_text_matched_substrings'] 373 | as List?) 374 | ?.map((e) => MatchedSubstring.fromJson(e as Map)) 375 | .toList() ?? 376 | [], 377 | secondaryText: json['secondary_text'] as String?, 378 | ); 379 | 380 | Map _$StructuredFormattingToJson( 381 | StructuredFormatting instance) => 382 | { 383 | 'main_text': instance.mainText, 384 | 'main_text_matched_substrings': 385 | instance.mainTextMatchedSubstrings.map((e) => e.toJson()).toList(), 386 | 'secondary_text': instance.secondaryText, 387 | }; 388 | -------------------------------------------------------------------------------- /pubspec.lock: -------------------------------------------------------------------------------- 1 | # Generated by pub 2 | # See https://dart.dev/tools/pub/glossary#lockfile 3 | packages: 4 | _fe_analyzer_shared: 5 | dependency: transitive 6 | description: 7 | name: _fe_analyzer_shared 8 | sha256: "0b2f2bd91ba804e53a61d757b986f89f1f9eaed5b11e4b2f5a2468d86d6c9fc7" 9 | url: "https://pub.dev" 10 | source: hosted 11 | version: "67.0.0" 12 | analyzer: 13 | dependency: transitive 14 | description: 15 | name: analyzer 16 | sha256: "37577842a27e4338429a1cbc32679d508836510b056f1eedf0c8d20e39c1383d" 17 | url: "https://pub.dev" 18 | source: hosted 19 | version: "6.4.1" 20 | args: 21 | dependency: transitive 22 | description: 23 | name: args 24 | sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a" 25 | url: "https://pub.dev" 26 | source: hosted 27 | version: "2.5.0" 28 | async: 29 | dependency: transitive 30 | description: 31 | name: async 32 | sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" 33 | url: "https://pub.dev" 34 | source: hosted 35 | version: "2.11.0" 36 | boolean_selector: 37 | dependency: transitive 38 | description: 39 | name: boolean_selector 40 | sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" 41 | url: "https://pub.dev" 42 | source: hosted 43 | version: "2.1.1" 44 | build: 45 | dependency: transitive 46 | description: 47 | name: build 48 | sha256: "80184af8b6cb3e5c1c4ec6d8544d27711700bc3e6d2efad04238c7b5290889f0" 49 | url: "https://pub.dev" 50 | source: hosted 51 | version: "2.4.1" 52 | build_config: 53 | dependency: transitive 54 | description: 55 | name: build_config 56 | sha256: bf80fcfb46a29945b423bd9aad884590fb1dc69b330a4d4700cac476af1708d1 57 | url: "https://pub.dev" 58 | source: hosted 59 | version: "1.1.1" 60 | build_daemon: 61 | dependency: transitive 62 | description: 63 | name: build_daemon 64 | sha256: "79b2aef6ac2ed00046867ed354c88778c9c0f029df8a20fe10b5436826721ef9" 65 | url: "https://pub.dev" 66 | source: hosted 67 | version: "4.0.2" 68 | build_resolvers: 69 | dependency: transitive 70 | description: 71 | name: build_resolvers 72 | sha256: "339086358431fa15d7eca8b6a36e5d783728cf025e559b834f4609a1fcfb7b0a" 73 | url: "https://pub.dev" 74 | source: hosted 75 | version: "2.4.2" 76 | build_runner: 77 | dependency: "direct dev" 78 | description: 79 | name: build_runner 80 | sha256: "644dc98a0f179b872f612d3eb627924b578897c629788e858157fa5e704ca0c7" 81 | url: "https://pub.dev" 82 | source: hosted 83 | version: "2.4.11" 84 | build_runner_core: 85 | dependency: transitive 86 | description: 87 | name: build_runner_core 88 | sha256: e3c79f69a64bdfcd8a776a3c28db4eb6e3fb5356d013ae5eb2e52007706d5dbe 89 | url: "https://pub.dev" 90 | source: hosted 91 | version: "7.3.1" 92 | built_collection: 93 | dependency: transitive 94 | description: 95 | name: built_collection 96 | sha256: "376e3dd27b51ea877c28d525560790aee2e6fbb5f20e2f85d5081027d94e2100" 97 | url: "https://pub.dev" 98 | source: hosted 99 | version: "5.1.1" 100 | built_value: 101 | dependency: transitive 102 | description: 103 | name: built_value 104 | sha256: c7913a9737ee4007efedaffc968c049fd0f3d0e49109e778edc10de9426005cb 105 | url: "https://pub.dev" 106 | source: hosted 107 | version: "8.9.2" 108 | characters: 109 | dependency: transitive 110 | description: 111 | name: characters 112 | sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" 113 | url: "https://pub.dev" 114 | source: hosted 115 | version: "1.3.0" 116 | checked_yaml: 117 | dependency: transitive 118 | description: 119 | name: checked_yaml 120 | sha256: feb6bed21949061731a7a75fc5d2aa727cf160b91af9a3e464c5e3a32e28b5ff 121 | url: "https://pub.dev" 122 | source: hosted 123 | version: "2.0.3" 124 | clock: 125 | dependency: transitive 126 | description: 127 | name: clock 128 | sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf 129 | url: "https://pub.dev" 130 | source: hosted 131 | version: "1.1.1" 132 | code_builder: 133 | dependency: transitive 134 | description: 135 | name: code_builder 136 | sha256: f692079e25e7869c14132d39f223f8eec9830eb76131925143b2129c4bb01b37 137 | url: "https://pub.dev" 138 | source: hosted 139 | version: "4.10.0" 140 | collection: 141 | dependency: "direct main" 142 | description: 143 | name: collection 144 | sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a 145 | url: "https://pub.dev" 146 | source: hosted 147 | version: "1.18.0" 148 | convert: 149 | dependency: transitive 150 | description: 151 | name: convert 152 | sha256: "0f08b14755d163f6e2134cb58222dd25ea2a2ee8a195e53983d57c075324d592" 153 | url: "https://pub.dev" 154 | source: hosted 155 | version: "3.1.1" 156 | crypto: 157 | dependency: transitive 158 | description: 159 | name: crypto 160 | sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab 161 | url: "https://pub.dev" 162 | source: hosted 163 | version: "3.0.3" 164 | dart_either: 165 | dependency: transitive 166 | description: 167 | name: dart_either 168 | sha256: "928895b8266ac5906eb4e2993fead563a73b17fc86eec6b40172100d56ca2507" 169 | url: "https://pub.dev" 170 | source: hosted 171 | version: "1.0.0" 172 | dart_style: 173 | dependency: transitive 174 | description: 175 | name: dart_style 176 | sha256: "99e066ce75c89d6b29903d788a7bb9369cf754f7b24bf70bf4b6d6d6b26853b9" 177 | url: "https://pub.dev" 178 | source: hosted 179 | version: "2.3.6" 180 | fake_async: 181 | dependency: transitive 182 | description: 183 | name: fake_async 184 | sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" 185 | url: "https://pub.dev" 186 | source: hosted 187 | version: "1.3.1" 188 | ffi: 189 | dependency: transitive 190 | description: 191 | name: ffi 192 | sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21" 193 | url: "https://pub.dev" 194 | source: hosted 195 | version: "2.1.2" 196 | file: 197 | dependency: transitive 198 | description: 199 | name: file 200 | sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c" 201 | url: "https://pub.dev" 202 | source: hosted 203 | version: "7.0.0" 204 | fixnum: 205 | dependency: transitive 206 | description: 207 | name: fixnum 208 | sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1" 209 | url: "https://pub.dev" 210 | source: hosted 211 | version: "1.1.0" 212 | flutter: 213 | dependency: "direct main" 214 | description: flutter 215 | source: sdk 216 | version: "0.0.0" 217 | flutter_bloc_pattern: 218 | dependency: "direct main" 219 | description: 220 | name: flutter_bloc_pattern 221 | sha256: "934b42da57797a759b62659bb157625749f602239c26f13adde7c61ee65d3e3f" 222 | url: "https://pub.dev" 223 | source: hosted 224 | version: "3.0.0" 225 | flutter_lints: 226 | dependency: "direct dev" 227 | description: 228 | name: flutter_lints 229 | sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c" 230 | url: "https://pub.dev" 231 | source: hosted 232 | version: "4.0.0" 233 | flutter_provider: 234 | dependency: transitive 235 | description: 236 | name: flutter_provider 237 | sha256: "5bc7d1e9edcf364397f312b9eb901337a644a5e4a907225bcd1d7e9b020ac914" 238 | url: "https://pub.dev" 239 | source: hosted 240 | version: "2.1.0" 241 | flutter_test: 242 | dependency: "direct dev" 243 | description: flutter 244 | source: sdk 245 | version: "0.0.0" 246 | flutter_web_plugins: 247 | dependency: transitive 248 | description: flutter 249 | source: sdk 250 | version: "0.0.0" 251 | frontend_server_client: 252 | dependency: transitive 253 | description: 254 | name: frontend_server_client 255 | sha256: f64a0333a82f30b0cca061bc3d143813a486dc086b574bfb233b7c1372427694 256 | url: "https://pub.dev" 257 | source: hosted 258 | version: "4.0.0" 259 | glob: 260 | dependency: transitive 261 | description: 262 | name: glob 263 | sha256: "0e7014b3b7d4dac1ca4d6114f82bf1782ee86745b9b42a92c9289c23d8a0ab63" 264 | url: "https://pub.dev" 265 | source: hosted 266 | version: "2.1.2" 267 | google_api_headers: 268 | dependency: "direct main" 269 | description: 270 | name: google_api_headers 271 | sha256: a4f0a82dc4a2019a4fea0724ef3db91769c67b954115ae1088962507f5ecc6c9 272 | url: "https://pub.dev" 273 | source: hosted 274 | version: "4.1.2" 275 | graphs: 276 | dependency: transitive 277 | description: 278 | name: graphs 279 | sha256: aedc5a15e78fc65a6e23bcd927f24c64dd995062bcd1ca6eda65a3cff92a4d19 280 | url: "https://pub.dev" 281 | source: hosted 282 | version: "2.3.1" 283 | http: 284 | dependency: "direct main" 285 | description: 286 | name: http 287 | sha256: "761a297c042deedc1ffbb156d6e2af13886bb305c2a343a4d972504cd67dd938" 288 | url: "https://pub.dev" 289 | source: hosted 290 | version: "1.2.1" 291 | http_multi_server: 292 | dependency: transitive 293 | description: 294 | name: http_multi_server 295 | sha256: "97486f20f9c2f7be8f514851703d0119c3596d14ea63227af6f7a481ef2b2f8b" 296 | url: "https://pub.dev" 297 | source: hosted 298 | version: "3.2.1" 299 | http_parser: 300 | dependency: transitive 301 | description: 302 | name: http_parser 303 | sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b" 304 | url: "https://pub.dev" 305 | source: hosted 306 | version: "4.0.2" 307 | io: 308 | dependency: transitive 309 | description: 310 | name: io 311 | sha256: "2ec25704aba361659e10e3e5f5d672068d332fc8ac516421d483a11e5cbd061e" 312 | url: "https://pub.dev" 313 | source: hosted 314 | version: "1.0.4" 315 | js: 316 | dependency: transitive 317 | description: 318 | name: js 319 | sha256: c1b2e9b5ea78c45e1a0788d29606ba27dc5f71f019f32ca5140f61ef071838cf 320 | url: "https://pub.dev" 321 | source: hosted 322 | version: "0.7.1" 323 | json_annotation: 324 | dependency: "direct main" 325 | description: 326 | name: json_annotation 327 | sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1" 328 | url: "https://pub.dev" 329 | source: hosted 330 | version: "4.9.0" 331 | json_serializable: 332 | dependency: "direct dev" 333 | description: 334 | name: json_serializable 335 | sha256: ea1432d167339ea9b5bb153f0571d0039607a873d6e04e0117af043f14a1fd4b 336 | url: "https://pub.dev" 337 | source: hosted 338 | version: "6.8.0" 339 | leak_tracker: 340 | dependency: transitive 341 | description: 342 | name: leak_tracker 343 | sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" 344 | url: "https://pub.dev" 345 | source: hosted 346 | version: "10.0.4" 347 | leak_tracker_flutter_testing: 348 | dependency: transitive 349 | description: 350 | name: leak_tracker_flutter_testing 351 | sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" 352 | url: "https://pub.dev" 353 | source: hosted 354 | version: "3.0.3" 355 | leak_tracker_testing: 356 | dependency: transitive 357 | description: 358 | name: leak_tracker_testing 359 | sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" 360 | url: "https://pub.dev" 361 | source: hosted 362 | version: "3.0.1" 363 | lints: 364 | dependency: transitive 365 | description: 366 | name: lints 367 | sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235" 368 | url: "https://pub.dev" 369 | source: hosted 370 | version: "4.0.0" 371 | listenable_stream: 372 | dependency: "direct main" 373 | description: 374 | name: listenable_stream 375 | sha256: "80decc4ef1dd999b42cf696d63f7729d1298a68f75b6bf3c944851ce5bf0eafd" 376 | url: "https://pub.dev" 377 | source: hosted 378 | version: "2.0.1" 379 | logging: 380 | dependency: transitive 381 | description: 382 | name: logging 383 | sha256: "623a88c9594aa774443aa3eb2d41807a48486b5613e67599fb4c41c0ad47c340" 384 | url: "https://pub.dev" 385 | source: hosted 386 | version: "1.2.0" 387 | matcher: 388 | dependency: transitive 389 | description: 390 | name: matcher 391 | sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb 392 | url: "https://pub.dev" 393 | source: hosted 394 | version: "0.12.16+1" 395 | material_color_utilities: 396 | dependency: transitive 397 | description: 398 | name: material_color_utilities 399 | sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" 400 | url: "https://pub.dev" 401 | source: hosted 402 | version: "0.8.0" 403 | meta: 404 | dependency: "direct main" 405 | description: 406 | name: meta 407 | sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" 408 | url: "https://pub.dev" 409 | source: hosted 410 | version: "1.12.0" 411 | mime: 412 | dependency: transitive 413 | description: 414 | name: mime 415 | sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2" 416 | url: "https://pub.dev" 417 | source: hosted 418 | version: "1.0.5" 419 | package_config: 420 | dependency: transitive 421 | description: 422 | name: package_config 423 | sha256: "1c5b77ccc91e4823a5af61ee74e6b972db1ef98c2ff5a18d3161c982a55448bd" 424 | url: "https://pub.dev" 425 | source: hosted 426 | version: "2.1.0" 427 | package_info_plus: 428 | dependency: transitive 429 | description: 430 | name: package_info_plus 431 | sha256: b93d8b4d624b4ea19b0a5a208b2d6eff06004bc3ce74c06040b120eeadd00ce0 432 | url: "https://pub.dev" 433 | source: hosted 434 | version: "8.0.0" 435 | package_info_plus_platform_interface: 436 | dependency: transitive 437 | description: 438 | name: package_info_plus_platform_interface 439 | sha256: f49918f3433a3146047372f9d4f1f847511f2acd5cd030e1f44fe5a50036b70e 440 | url: "https://pub.dev" 441 | source: hosted 442 | version: "3.0.0" 443 | path: 444 | dependency: transitive 445 | description: 446 | name: path 447 | sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af" 448 | url: "https://pub.dev" 449 | source: hosted 450 | version: "1.9.0" 451 | plugin_platform_interface: 452 | dependency: transitive 453 | description: 454 | name: plugin_platform_interface 455 | sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" 456 | url: "https://pub.dev" 457 | source: hosted 458 | version: "2.1.8" 459 | pool: 460 | dependency: transitive 461 | description: 462 | name: pool 463 | sha256: "20fe868b6314b322ea036ba325e6fc0711a22948856475e2c2b6306e8ab39c2a" 464 | url: "https://pub.dev" 465 | source: hosted 466 | version: "1.5.1" 467 | pub_semver: 468 | dependency: transitive 469 | description: 470 | name: pub_semver 471 | sha256: "40d3ab1bbd474c4c2328c91e3a7df8c6dd629b79ece4c4bd04bee496a224fb0c" 472 | url: "https://pub.dev" 473 | source: hosted 474 | version: "2.1.4" 475 | pubspec_parse: 476 | dependency: transitive 477 | description: 478 | name: pubspec_parse 479 | sha256: c799b721d79eb6ee6fa56f00c04b472dcd44a30d258fac2174a6ec57302678f8 480 | url: "https://pub.dev" 481 | source: hosted 482 | version: "1.3.0" 483 | rxdart: 484 | dependency: "direct main" 485 | description: 486 | name: rxdart 487 | sha256: "5c3004a4a8dbb94bd4bf5412a4def4acdaa12e12f269737a5751369e12d1a962" 488 | url: "https://pub.dev" 489 | source: hosted 490 | version: "0.28.0" 491 | rxdart_ext: 492 | dependency: "direct main" 493 | description: 494 | name: rxdart_ext 495 | sha256: "95df7e8b13140e2c3fdb3b943569a51f18090e82aaaf6ca6e8e6437e434a6fb0" 496 | url: "https://pub.dev" 497 | source: hosted 498 | version: "0.3.0" 499 | shelf: 500 | dependency: transitive 501 | description: 502 | name: shelf 503 | sha256: ad29c505aee705f41a4d8963641f91ac4cee3c8fad5947e033390a7bd8180fa4 504 | url: "https://pub.dev" 505 | source: hosted 506 | version: "1.4.1" 507 | shelf_web_socket: 508 | dependency: transitive 509 | description: 510 | name: shelf_web_socket 511 | sha256: "073c147238594ecd0d193f3456a5fe91c4b0abbcc68bf5cd95b36c4e194ac611" 512 | url: "https://pub.dev" 513 | source: hosted 514 | version: "2.0.0" 515 | sky_engine: 516 | dependency: transitive 517 | description: flutter 518 | source: sdk 519 | version: "0.0.99" 520 | source_gen: 521 | dependency: transitive 522 | description: 523 | name: source_gen 524 | sha256: "14658ba5f669685cd3d63701d01b31ea748310f7ab854e471962670abcf57832" 525 | url: "https://pub.dev" 526 | source: hosted 527 | version: "1.5.0" 528 | source_helper: 529 | dependency: transitive 530 | description: 531 | name: source_helper 532 | sha256: "6adebc0006c37dd63fe05bca0a929b99f06402fc95aa35bf36d67f5c06de01fd" 533 | url: "https://pub.dev" 534 | source: hosted 535 | version: "1.3.4" 536 | source_span: 537 | dependency: transitive 538 | description: 539 | name: source_span 540 | sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" 541 | url: "https://pub.dev" 542 | source: hosted 543 | version: "1.10.0" 544 | stack_trace: 545 | dependency: transitive 546 | description: 547 | name: stack_trace 548 | sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" 549 | url: "https://pub.dev" 550 | source: hosted 551 | version: "1.11.1" 552 | stream_channel: 553 | dependency: transitive 554 | description: 555 | name: stream_channel 556 | sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 557 | url: "https://pub.dev" 558 | source: hosted 559 | version: "2.1.2" 560 | stream_transform: 561 | dependency: transitive 562 | description: 563 | name: stream_transform 564 | sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f" 565 | url: "https://pub.dev" 566 | source: hosted 567 | version: "2.1.0" 568 | string_scanner: 569 | dependency: transitive 570 | description: 571 | name: string_scanner 572 | sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" 573 | url: "https://pub.dev" 574 | source: hosted 575 | version: "1.2.0" 576 | term_glyph: 577 | dependency: transitive 578 | description: 579 | name: term_glyph 580 | sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 581 | url: "https://pub.dev" 582 | source: hosted 583 | version: "1.2.1" 584 | test_api: 585 | dependency: transitive 586 | description: 587 | name: test_api 588 | sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" 589 | url: "https://pub.dev" 590 | source: hosted 591 | version: "0.7.0" 592 | timing: 593 | dependency: transitive 594 | description: 595 | name: timing 596 | sha256: "70a3b636575d4163c477e6de42f247a23b315ae20e86442bebe32d3cabf61c32" 597 | url: "https://pub.dev" 598 | source: hosted 599 | version: "1.0.1" 600 | typed_data: 601 | dependency: transitive 602 | description: 603 | name: typed_data 604 | sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c 605 | url: "https://pub.dev" 606 | source: hosted 607 | version: "1.3.2" 608 | vector_math: 609 | dependency: transitive 610 | description: 611 | name: vector_math 612 | sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" 613 | url: "https://pub.dev" 614 | source: hosted 615 | version: "2.1.4" 616 | vm_service: 617 | dependency: transitive 618 | description: 619 | name: vm_service 620 | sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" 621 | url: "https://pub.dev" 622 | source: hosted 623 | version: "14.2.1" 624 | watcher: 625 | dependency: transitive 626 | description: 627 | name: watcher 628 | sha256: "3d2ad6751b3c16cf07c7fca317a1413b3f26530319181b37e3b9039b84fc01d8" 629 | url: "https://pub.dev" 630 | source: hosted 631 | version: "1.1.0" 632 | web: 633 | dependency: transitive 634 | description: 635 | name: web 636 | sha256: "97da13628db363c635202ad97068d47c5b8aa555808e7a9411963c533b449b27" 637 | url: "https://pub.dev" 638 | source: hosted 639 | version: "0.5.1" 640 | web_socket: 641 | dependency: transitive 642 | description: 643 | name: web_socket 644 | sha256: "24301d8c293ce6fe327ffe6f59d8fd8834735f0ec36e4fd383ec7ff8a64aa078" 645 | url: "https://pub.dev" 646 | source: hosted 647 | version: "0.1.5" 648 | web_socket_channel: 649 | dependency: transitive 650 | description: 651 | name: web_socket_channel 652 | sha256: a2d56211ee4d35d9b344d9d4ce60f362e4f5d1aafb988302906bd732bc731276 653 | url: "https://pub.dev" 654 | source: hosted 655 | version: "3.0.0" 656 | win32: 657 | dependency: transitive 658 | description: 659 | name: win32 660 | sha256: a79dbe579cb51ecd6d30b17e0cae4e0ea15e2c0e66f69ad4198f22a6789e94f4 661 | url: "https://pub.dev" 662 | source: hosted 663 | version: "5.5.1" 664 | yaml: 665 | dependency: transitive 666 | description: 667 | name: yaml 668 | sha256: "75769501ea3489fca56601ff33454fe45507ea3bfb014161abc3b43ae25989d5" 669 | url: "https://pub.dev" 670 | source: hosted 671 | version: "3.1.2" 672 | sdks: 673 | dart: ">=3.4.3 <4.0.0" 674 | flutter: ">=3.22.2" 675 | -------------------------------------------------------------------------------- /example/ios/Runner.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 50; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; }; 11 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; }; 12 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; }; 13 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; }; 14 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; }; 15 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; }; 16 | A53C4ACF100A571722B4FE45 /* Pods_Runner.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = F55E527395A985A262997E48 /* Pods_Runner.framework */; }; 17 | /* End PBXBuildFile section */ 18 | 19 | /* Begin PBXCopyFilesBuildPhase section */ 20 | 9705A1C41CF9048500538489 /* Embed Frameworks */ = { 21 | isa = PBXCopyFilesBuildPhase; 22 | buildActionMask = 2147483647; 23 | dstPath = ""; 24 | dstSubfolderSpec = 10; 25 | files = ( 26 | ); 27 | name = "Embed Frameworks"; 28 | runOnlyForDeploymentPostprocessing = 0; 29 | }; 30 | /* End PBXCopyFilesBuildPhase section */ 31 | 32 | /* Begin PBXFileReference section */ 33 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = ""; }; 34 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = ""; }; 35 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = ""; }; 36 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = ""; }; 37 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = ""; }; 38 | 790E0307469183588C7A095E /* Pods-Runner.profile.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.profile.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.profile.xcconfig"; sourceTree = ""; }; 39 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = ""; }; 40 | 8C36BE0A12D4F57D63C415EC /* Pods-Runner.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.release.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.release.xcconfig"; sourceTree = ""; }; 41 | 9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = ""; }; 42 | 9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = ""; }; 43 | 97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; }; 44 | 97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = ""; }; 45 | 97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = ""; }; 46 | 97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = ""; }; 47 | 97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 48 | DC44DB469C080F925825CF0C /* Pods-Runner.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Runner.debug.xcconfig"; path = "Target Support Files/Pods-Runner/Pods-Runner.debug.xcconfig"; sourceTree = ""; }; 49 | F55E527395A985A262997E48 /* Pods_Runner.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_Runner.framework; sourceTree = BUILT_PRODUCTS_DIR; }; 50 | /* End PBXFileReference section */ 51 | 52 | /* Begin PBXFrameworksBuildPhase section */ 53 | 97C146EB1CF9000F007C117D /* Frameworks */ = { 54 | isa = PBXFrameworksBuildPhase; 55 | buildActionMask = 2147483647; 56 | files = ( 57 | A53C4ACF100A571722B4FE45 /* Pods_Runner.framework in Frameworks */, 58 | ); 59 | runOnlyForDeploymentPostprocessing = 0; 60 | }; 61 | /* End PBXFrameworksBuildPhase section */ 62 | 63 | /* Begin PBXGroup section */ 64 | 280028E80BA7D784B1648066 /* Pods */ = { 65 | isa = PBXGroup; 66 | children = ( 67 | DC44DB469C080F925825CF0C /* Pods-Runner.debug.xcconfig */, 68 | 8C36BE0A12D4F57D63C415EC /* Pods-Runner.release.xcconfig */, 69 | 790E0307469183588C7A095E /* Pods-Runner.profile.xcconfig */, 70 | ); 71 | name = Pods; 72 | path = Pods; 73 | sourceTree = ""; 74 | }; 75 | 9740EEB11CF90186004384FC /* Flutter */ = { 76 | isa = PBXGroup; 77 | children = ( 78 | 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */, 79 | 9740EEB21CF90195004384FC /* Debug.xcconfig */, 80 | 7AFA3C8E1D35360C0083082E /* Release.xcconfig */, 81 | 9740EEB31CF90195004384FC /* Generated.xcconfig */, 82 | ); 83 | name = Flutter; 84 | sourceTree = ""; 85 | }; 86 | 97C146E51CF9000F007C117D = { 87 | isa = PBXGroup; 88 | children = ( 89 | 9740EEB11CF90186004384FC /* Flutter */, 90 | 97C146F01CF9000F007C117D /* Runner */, 91 | 97C146EF1CF9000F007C117D /* Products */, 92 | 280028E80BA7D784B1648066 /* Pods */, 93 | 9A00FECBDC6A2B7895E85FE7 /* Frameworks */, 94 | ); 95 | sourceTree = ""; 96 | }; 97 | 97C146EF1CF9000F007C117D /* Products */ = { 98 | isa = PBXGroup; 99 | children = ( 100 | 97C146EE1CF9000F007C117D /* Runner.app */, 101 | ); 102 | name = Products; 103 | sourceTree = ""; 104 | }; 105 | 97C146F01CF9000F007C117D /* Runner */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 97C146FA1CF9000F007C117D /* Main.storyboard */, 109 | 97C146FD1CF9000F007C117D /* Assets.xcassets */, 110 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */, 111 | 97C147021CF9000F007C117D /* Info.plist */, 112 | 1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */, 113 | 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */, 114 | 74858FAE1ED2DC5600515810 /* AppDelegate.swift */, 115 | 74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */, 116 | ); 117 | path = Runner; 118 | sourceTree = ""; 119 | }; 120 | 9A00FECBDC6A2B7895E85FE7 /* Frameworks */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | F55E527395A985A262997E48 /* Pods_Runner.framework */, 124 | ); 125 | name = Frameworks; 126 | sourceTree = ""; 127 | }; 128 | /* End PBXGroup section */ 129 | 130 | /* Begin PBXNativeTarget section */ 131 | 97C146ED1CF9000F007C117D /* Runner */ = { 132 | isa = PBXNativeTarget; 133 | buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */; 134 | buildPhases = ( 135 | E37CF6BA9B1B5F086818B584 /* [CP] Check Pods Manifest.lock */, 136 | 9740EEB61CF901F6004384FC /* Run Script */, 137 | 97C146EA1CF9000F007C117D /* Sources */, 138 | 97C146EB1CF9000F007C117D /* Frameworks */, 139 | 97C146EC1CF9000F007C117D /* Resources */, 140 | 9705A1C41CF9048500538489 /* Embed Frameworks */, 141 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */, 142 | 128558EFE18960854AEAB07F /* [CP] Embed Pods Frameworks */, 143 | ); 144 | buildRules = ( 145 | ); 146 | dependencies = ( 147 | ); 148 | name = Runner; 149 | productName = Runner; 150 | productReference = 97C146EE1CF9000F007C117D /* Runner.app */; 151 | productType = "com.apple.product-type.application"; 152 | }; 153 | /* End PBXNativeTarget section */ 154 | 155 | /* Begin PBXProject section */ 156 | 97C146E61CF9000F007C117D /* Project object */ = { 157 | isa = PBXProject; 158 | attributes = { 159 | LastUpgradeCheck = 1300; 160 | ORGANIZATIONNAME = ""; 161 | TargetAttributes = { 162 | 97C146ED1CF9000F007C117D = { 163 | CreatedOnToolsVersion = 7.3.1; 164 | LastSwiftMigration = 1100; 165 | }; 166 | }; 167 | }; 168 | buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */; 169 | compatibilityVersion = "Xcode 9.3"; 170 | developmentRegion = en; 171 | hasScannedForEncodings = 0; 172 | knownRegions = ( 173 | en, 174 | Base, 175 | ); 176 | mainGroup = 97C146E51CF9000F007C117D; 177 | productRefGroup = 97C146EF1CF9000F007C117D /* Products */; 178 | projectDirPath = ""; 179 | projectRoot = ""; 180 | targets = ( 181 | 97C146ED1CF9000F007C117D /* Runner */, 182 | ); 183 | }; 184 | /* End PBXProject section */ 185 | 186 | /* Begin PBXResourcesBuildPhase section */ 187 | 97C146EC1CF9000F007C117D /* Resources */ = { 188 | isa = PBXResourcesBuildPhase; 189 | buildActionMask = 2147483647; 190 | files = ( 191 | 97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */, 192 | 3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */, 193 | 97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */, 194 | 97C146FC1CF9000F007C117D /* Main.storyboard in Resources */, 195 | ); 196 | runOnlyForDeploymentPostprocessing = 0; 197 | }; 198 | /* End PBXResourcesBuildPhase section */ 199 | 200 | /* Begin PBXShellScriptBuildPhase section */ 201 | 128558EFE18960854AEAB07F /* [CP] Embed Pods Frameworks */ = { 202 | isa = PBXShellScriptBuildPhase; 203 | buildActionMask = 2147483647; 204 | files = ( 205 | ); 206 | inputFileListPaths = ( 207 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-input-files.xcfilelist", 208 | ); 209 | name = "[CP] Embed Pods Frameworks"; 210 | outputFileListPaths = ( 211 | "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks-${CONFIGURATION}-output-files.xcfilelist", 212 | ); 213 | runOnlyForDeploymentPostprocessing = 0; 214 | shellPath = /bin/sh; 215 | shellScript = "\"${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh\"\n"; 216 | showEnvVarsInLog = 0; 217 | }; 218 | 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 219 | isa = PBXShellScriptBuildPhase; 220 | buildActionMask = 2147483647; 221 | files = ( 222 | ); 223 | inputPaths = ( 224 | ); 225 | name = "Thin Binary"; 226 | outputPaths = ( 227 | ); 228 | runOnlyForDeploymentPostprocessing = 0; 229 | shellPath = /bin/sh; 230 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin"; 231 | }; 232 | 9740EEB61CF901F6004384FC /* Run Script */ = { 233 | isa = PBXShellScriptBuildPhase; 234 | buildActionMask = 2147483647; 235 | files = ( 236 | ); 237 | inputPaths = ( 238 | ); 239 | name = "Run Script"; 240 | outputPaths = ( 241 | ); 242 | runOnlyForDeploymentPostprocessing = 0; 243 | shellPath = /bin/sh; 244 | shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build"; 245 | }; 246 | E37CF6BA9B1B5F086818B584 /* [CP] Check Pods Manifest.lock */ = { 247 | isa = PBXShellScriptBuildPhase; 248 | buildActionMask = 2147483647; 249 | files = ( 250 | ); 251 | inputFileListPaths = ( 252 | ); 253 | inputPaths = ( 254 | "${PODS_PODFILE_DIR_PATH}/Podfile.lock", 255 | "${PODS_ROOT}/Manifest.lock", 256 | ); 257 | name = "[CP] Check Pods Manifest.lock"; 258 | outputFileListPaths = ( 259 | ); 260 | outputPaths = ( 261 | "$(DERIVED_FILE_DIR)/Pods-Runner-checkManifestLockResult.txt", 262 | ); 263 | runOnlyForDeploymentPostprocessing = 0; 264 | shellPath = /bin/sh; 265 | shellScript = "diff \"${PODS_PODFILE_DIR_PATH}/Podfile.lock\" \"${PODS_ROOT}/Manifest.lock\" > /dev/null\nif [ $? != 0 ] ; then\n # print error to STDERR\n echo \"error: The sandbox is not in sync with the Podfile.lock. Run 'pod install' or update your CocoaPods installation.\" >&2\n exit 1\nfi\n# This output is used by Xcode 'outputs' to avoid re-running this script phase.\necho \"SUCCESS\" > \"${SCRIPT_OUTPUT_FILE_0}\"\n"; 266 | showEnvVarsInLog = 0; 267 | }; 268 | /* End PBXShellScriptBuildPhase section */ 269 | 270 | /* Begin PBXSourcesBuildPhase section */ 271 | 97C146EA1CF9000F007C117D /* Sources */ = { 272 | isa = PBXSourcesBuildPhase; 273 | buildActionMask = 2147483647; 274 | files = ( 275 | 74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */, 276 | 1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */, 277 | ); 278 | runOnlyForDeploymentPostprocessing = 0; 279 | }; 280 | /* End PBXSourcesBuildPhase section */ 281 | 282 | /* Begin PBXVariantGroup section */ 283 | 97C146FA1CF9000F007C117D /* Main.storyboard */ = { 284 | isa = PBXVariantGroup; 285 | children = ( 286 | 97C146FB1CF9000F007C117D /* Base */, 287 | ); 288 | name = Main.storyboard; 289 | sourceTree = ""; 290 | }; 291 | 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = { 292 | isa = PBXVariantGroup; 293 | children = ( 294 | 97C147001CF9000F007C117D /* Base */, 295 | ); 296 | name = LaunchScreen.storyboard; 297 | sourceTree = ""; 298 | }; 299 | /* End PBXVariantGroup section */ 300 | 301 | /* Begin XCBuildConfiguration section */ 302 | 249021D3217E4FDB00AE95B9 /* Profile */ = { 303 | isa = XCBuildConfiguration; 304 | buildSettings = { 305 | ALWAYS_SEARCH_USER_PATHS = NO; 306 | CLANG_ANALYZER_NONNULL = YES; 307 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 308 | CLANG_CXX_LIBRARY = "libc++"; 309 | CLANG_ENABLE_MODULES = YES; 310 | CLANG_ENABLE_OBJC_ARC = YES; 311 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 312 | CLANG_WARN_BOOL_CONVERSION = YES; 313 | CLANG_WARN_COMMA = YES; 314 | CLANG_WARN_CONSTANT_CONVERSION = YES; 315 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 316 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 317 | CLANG_WARN_EMPTY_BODY = YES; 318 | CLANG_WARN_ENUM_CONVERSION = YES; 319 | CLANG_WARN_INFINITE_RECURSION = YES; 320 | CLANG_WARN_INT_CONVERSION = YES; 321 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 322 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 323 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 324 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 325 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 326 | CLANG_WARN_STRICT_PROTOTYPES = YES; 327 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 328 | CLANG_WARN_UNREACHABLE_CODE = YES; 329 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 330 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 331 | COPY_PHASE_STRIP = NO; 332 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 333 | ENABLE_NS_ASSERTIONS = NO; 334 | ENABLE_STRICT_OBJC_MSGSEND = YES; 335 | GCC_C_LANGUAGE_STANDARD = gnu99; 336 | GCC_NO_COMMON_BLOCKS = YES; 337 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 338 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 339 | GCC_WARN_UNDECLARED_SELECTOR = YES; 340 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 341 | GCC_WARN_UNUSED_FUNCTION = YES; 342 | GCC_WARN_UNUSED_VARIABLE = YES; 343 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 344 | MTL_ENABLE_DEBUG_INFO = NO; 345 | SDKROOT = iphoneos; 346 | SUPPORTED_PLATFORMS = iphoneos; 347 | TARGETED_DEVICE_FAMILY = "1,2"; 348 | VALIDATE_PRODUCT = YES; 349 | }; 350 | name = Profile; 351 | }; 352 | 249021D4217E4FDB00AE95B9 /* Profile */ = { 353 | isa = XCBuildConfiguration; 354 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 355 | buildSettings = { 356 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 357 | CLANG_ENABLE_MODULES = YES; 358 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 359 | ENABLE_BITCODE = NO; 360 | INFOPLIST_FILE = Runner/Info.plist; 361 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 362 | PRODUCT_BUNDLE_IDENTIFIER = com.hoc.example; 363 | PRODUCT_NAME = "$(TARGET_NAME)"; 364 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 365 | SWIFT_VERSION = 5.0; 366 | VERSIONING_SYSTEM = "apple-generic"; 367 | }; 368 | name = Profile; 369 | }; 370 | 97C147031CF9000F007C117D /* Debug */ = { 371 | isa = XCBuildConfiguration; 372 | buildSettings = { 373 | ALWAYS_SEARCH_USER_PATHS = NO; 374 | CLANG_ANALYZER_NONNULL = YES; 375 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 376 | CLANG_CXX_LIBRARY = "libc++"; 377 | CLANG_ENABLE_MODULES = YES; 378 | CLANG_ENABLE_OBJC_ARC = YES; 379 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 380 | CLANG_WARN_BOOL_CONVERSION = YES; 381 | CLANG_WARN_COMMA = YES; 382 | CLANG_WARN_CONSTANT_CONVERSION = YES; 383 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 384 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 385 | CLANG_WARN_EMPTY_BODY = YES; 386 | CLANG_WARN_ENUM_CONVERSION = YES; 387 | CLANG_WARN_INFINITE_RECURSION = YES; 388 | CLANG_WARN_INT_CONVERSION = YES; 389 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 390 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 391 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 392 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 393 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 394 | CLANG_WARN_STRICT_PROTOTYPES = YES; 395 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 396 | CLANG_WARN_UNREACHABLE_CODE = YES; 397 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 398 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 399 | COPY_PHASE_STRIP = NO; 400 | DEBUG_INFORMATION_FORMAT = dwarf; 401 | ENABLE_STRICT_OBJC_MSGSEND = YES; 402 | ENABLE_TESTABILITY = YES; 403 | GCC_C_LANGUAGE_STANDARD = gnu99; 404 | GCC_DYNAMIC_NO_PIC = NO; 405 | GCC_NO_COMMON_BLOCKS = YES; 406 | GCC_OPTIMIZATION_LEVEL = 0; 407 | GCC_PREPROCESSOR_DEFINITIONS = ( 408 | "DEBUG=1", 409 | "$(inherited)", 410 | ); 411 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 412 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 413 | GCC_WARN_UNDECLARED_SELECTOR = YES; 414 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 415 | GCC_WARN_UNUSED_FUNCTION = YES; 416 | GCC_WARN_UNUSED_VARIABLE = YES; 417 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 418 | MTL_ENABLE_DEBUG_INFO = YES; 419 | ONLY_ACTIVE_ARCH = YES; 420 | SDKROOT = iphoneos; 421 | TARGETED_DEVICE_FAMILY = "1,2"; 422 | }; 423 | name = Debug; 424 | }; 425 | 97C147041CF9000F007C117D /* Release */ = { 426 | isa = XCBuildConfiguration; 427 | buildSettings = { 428 | ALWAYS_SEARCH_USER_PATHS = NO; 429 | CLANG_ANALYZER_NONNULL = YES; 430 | CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x"; 431 | CLANG_CXX_LIBRARY = "libc++"; 432 | CLANG_ENABLE_MODULES = YES; 433 | CLANG_ENABLE_OBJC_ARC = YES; 434 | CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES; 435 | CLANG_WARN_BOOL_CONVERSION = YES; 436 | CLANG_WARN_COMMA = YES; 437 | CLANG_WARN_CONSTANT_CONVERSION = YES; 438 | CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES; 439 | CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR; 440 | CLANG_WARN_EMPTY_BODY = YES; 441 | CLANG_WARN_ENUM_CONVERSION = YES; 442 | CLANG_WARN_INFINITE_RECURSION = YES; 443 | CLANG_WARN_INT_CONVERSION = YES; 444 | CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES; 445 | CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES; 446 | CLANG_WARN_OBJC_LITERAL_CONVERSION = YES; 447 | CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR; 448 | CLANG_WARN_RANGE_LOOP_ANALYSIS = YES; 449 | CLANG_WARN_STRICT_PROTOTYPES = YES; 450 | CLANG_WARN_SUSPICIOUS_MOVE = YES; 451 | CLANG_WARN_UNREACHABLE_CODE = YES; 452 | CLANG_WARN__DUPLICATE_METHOD_MATCH = YES; 453 | "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; 454 | COPY_PHASE_STRIP = NO; 455 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 456 | ENABLE_NS_ASSERTIONS = NO; 457 | ENABLE_STRICT_OBJC_MSGSEND = YES; 458 | GCC_C_LANGUAGE_STANDARD = gnu99; 459 | GCC_NO_COMMON_BLOCKS = YES; 460 | GCC_WARN_64_TO_32_BIT_CONVERSION = YES; 461 | GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR; 462 | GCC_WARN_UNDECLARED_SELECTOR = YES; 463 | GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; 464 | GCC_WARN_UNUSED_FUNCTION = YES; 465 | GCC_WARN_UNUSED_VARIABLE = YES; 466 | IPHONEOS_DEPLOYMENT_TARGET = 9.0; 467 | MTL_ENABLE_DEBUG_INFO = NO; 468 | SDKROOT = iphoneos; 469 | SUPPORTED_PLATFORMS = iphoneos; 470 | SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule"; 471 | TARGETED_DEVICE_FAMILY = "1,2"; 472 | VALIDATE_PRODUCT = YES; 473 | }; 474 | name = Release; 475 | }; 476 | 97C147061CF9000F007C117D /* Debug */ = { 477 | isa = XCBuildConfiguration; 478 | baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */; 479 | buildSettings = { 480 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 481 | CLANG_ENABLE_MODULES = YES; 482 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 483 | ENABLE_BITCODE = NO; 484 | INFOPLIST_FILE = Runner/Info.plist; 485 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 486 | PRODUCT_BUNDLE_IDENTIFIER = com.hoc.example; 487 | PRODUCT_NAME = "$(TARGET_NAME)"; 488 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 489 | SWIFT_OPTIMIZATION_LEVEL = "-Onone"; 490 | SWIFT_VERSION = 5.0; 491 | VERSIONING_SYSTEM = "apple-generic"; 492 | }; 493 | name = Debug; 494 | }; 495 | 97C147071CF9000F007C117D /* Release */ = { 496 | isa = XCBuildConfiguration; 497 | baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */; 498 | buildSettings = { 499 | ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; 500 | CLANG_ENABLE_MODULES = YES; 501 | CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; 502 | ENABLE_BITCODE = NO; 503 | INFOPLIST_FILE = Runner/Info.plist; 504 | LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; 505 | PRODUCT_BUNDLE_IDENTIFIER = com.hoc.example; 506 | PRODUCT_NAME = "$(TARGET_NAME)"; 507 | SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; 508 | SWIFT_VERSION = 5.0; 509 | VERSIONING_SYSTEM = "apple-generic"; 510 | }; 511 | name = Release; 512 | }; 513 | /* End XCBuildConfiguration section */ 514 | 515 | /* Begin XCConfigurationList section */ 516 | 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = { 517 | isa = XCConfigurationList; 518 | buildConfigurations = ( 519 | 97C147031CF9000F007C117D /* Debug */, 520 | 97C147041CF9000F007C117D /* Release */, 521 | 249021D3217E4FDB00AE95B9 /* Profile */, 522 | ); 523 | defaultConfigurationIsVisible = 0; 524 | defaultConfigurationName = Release; 525 | }; 526 | 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = { 527 | isa = XCConfigurationList; 528 | buildConfigurations = ( 529 | 97C147061CF9000F007C117D /* Debug */, 530 | 97C147071CF9000F007C117D /* Release */, 531 | 249021D4217E4FDB00AE95B9 /* Profile */, 532 | ); 533 | defaultConfigurationIsVisible = 0; 534 | defaultConfigurationName = Release; 535 | }; 536 | /* End XCConfigurationList section */ 537 | }; 538 | rootObject = 97C146E61CF9000F007C117D /* Project object */; 539 | } 540 | -------------------------------------------------------------------------------- /lib/src/google_maps_webservice/src/places.dart: -------------------------------------------------------------------------------- 1 | import 'dart:async'; 2 | import 'dart:convert'; 3 | 4 | import 'package:http/http.dart'; 5 | import 'package:json_annotation/json_annotation.dart'; 6 | import 'package:meta/meta.dart'; 7 | 8 | import 'core.dart'; 9 | import 'utils.dart'; 10 | 11 | part 'places.g.dart'; 12 | 13 | const _placesUrl = '/place'; 14 | const _nearbySearchUrl = '/nearbysearch/json'; 15 | const _textSearchUrl = '/textsearch/json'; 16 | const _detailsSearchUrl = '/details/json'; 17 | const _autocompleteUrl = '/autocomplete/json'; 18 | const _photoUrl = '/photo'; 19 | const _queryAutocompleteUrl = '/queryautocomplete/json'; 20 | 21 | /// https://developers.google.com/places/web-service/ 22 | class GoogleMapsPlaces extends GoogleWebService { 23 | GoogleMapsPlaces({ 24 | super.apiKey, 25 | super.baseUrl, 26 | super.httpClient, 27 | super.apiHeaders, 28 | }) : super( 29 | apiPath: _placesUrl, 30 | ); 31 | 32 | Future searchNearbyWithRadius( 33 | Location location, 34 | num radius, { 35 | String? type, 36 | String? keyword, 37 | String? language, 38 | PriceLevel? minprice, 39 | PriceLevel? maxprice, 40 | String? name, 41 | String? pagetoken, 42 | }) async { 43 | final url = buildNearbySearchUrl( 44 | location: location, 45 | language: language, 46 | radius: radius, 47 | type: type, 48 | keyword: keyword, 49 | minprice: minprice, 50 | maxprice: maxprice, 51 | name: name, 52 | pagetoken: pagetoken, 53 | ); 54 | return _decodeSearchResponse(await doGet(url, headers: apiHeaders)); 55 | } 56 | 57 | Future searchNearbyWithRankBy( 58 | Location location, 59 | String rankby, { 60 | String? type, 61 | String? keyword, 62 | String? language, 63 | PriceLevel? minprice, 64 | PriceLevel? maxprice, 65 | String? name, 66 | String? pagetoken, 67 | }) async { 68 | final url = buildNearbySearchUrl( 69 | location: location, 70 | language: language, 71 | type: type, 72 | rankby: rankby, 73 | keyword: keyword, 74 | minprice: minprice, 75 | maxprice: maxprice, 76 | name: name, 77 | pagetoken: pagetoken, 78 | ); 79 | return _decodeSearchResponse(await doGet(url, headers: apiHeaders)); 80 | } 81 | 82 | Future searchByText( 83 | String query, { 84 | Location? location, 85 | num? radius, 86 | PriceLevel? minprice, 87 | PriceLevel? maxprice, 88 | bool opennow = false, 89 | String? type, 90 | String? pagetoken, 91 | String? language, 92 | String? region, 93 | }) async { 94 | final url = buildTextSearchUrl( 95 | query: query, 96 | location: location, 97 | language: language, 98 | region: region, 99 | type: type, 100 | radius: radius, 101 | minprice: minprice, 102 | maxprice: maxprice, 103 | pagetoken: pagetoken, 104 | opennow: opennow, 105 | ); 106 | return _decodeSearchResponse(await doGet(url, headers: apiHeaders)); 107 | } 108 | 109 | Future getDetailsByPlaceId( 110 | String placeId, { 111 | String? sessionToken, 112 | List fields = const [], 113 | String? language, 114 | String? region, 115 | }) async { 116 | final url = buildDetailsUrl( 117 | placeId: placeId, 118 | sessionToken: sessionToken, 119 | fields: fields, 120 | language: language, 121 | region: region, 122 | ); 123 | return _decodeDetailsResponse(await doGet(url, headers: apiHeaders)); 124 | } 125 | 126 | Future autocomplete( 127 | String input, { 128 | String? sessionToken, 129 | num? offset, 130 | Location? origin, 131 | Location? location, 132 | num? radius, 133 | String? language, 134 | List types = const [], 135 | List components = const [], 136 | bool strictbounds = false, 137 | String? region, 138 | }) async { 139 | final url = buildAutocompleteUrl( 140 | sessionToken: sessionToken, 141 | input: input, 142 | origin: origin, 143 | location: location, 144 | offset: offset, 145 | radius: radius, 146 | language: language, 147 | types: types, 148 | components: components, 149 | strictbounds: strictbounds, 150 | region: region, 151 | ); 152 | return _decodeAutocompleteResponse(await doGet(url, headers: apiHeaders)); 153 | } 154 | 155 | Future queryAutocomplete( 156 | String input, { 157 | num? offset, 158 | Location? location, 159 | num? radius, 160 | String? language, 161 | }) async { 162 | final url = buildQueryAutocompleteUrl( 163 | input: input, 164 | location: location, 165 | offset: offset, 166 | radius: radius, 167 | language: language, 168 | ); 169 | return _decodeAutocompleteResponse(await doGet(url, headers: apiHeaders)); 170 | } 171 | 172 | String buildNearbySearchUrl({ 173 | Location? location, 174 | num? radius, 175 | String? type, 176 | String? keyword, 177 | String? language, 178 | PriceLevel? minprice, 179 | PriceLevel? maxprice, 180 | String? name, 181 | String? rankby, 182 | String? pagetoken, 183 | }) { 184 | if (radius != null && rankby != null) { 185 | throw ArgumentError( 186 | "'rankby' must not be included if 'radius' is specified."); 187 | } 188 | 189 | if (rankby == 'distance' && 190 | keyword == null && 191 | type == null && 192 | name == null) { 193 | throw ArgumentError( 194 | "If 'rankby=distance' is specified, then one or more of 'keyword', 'name', or 'type' is required."); 195 | } 196 | 197 | final params = {}; 198 | 199 | if (location != null) { 200 | params['location'] = location.toString(); 201 | } 202 | 203 | if (keyword != null) { 204 | params['keyword'] = keyword; 205 | } 206 | 207 | if (name != null) { 208 | params['name'] = name; 209 | } 210 | 211 | if (rankby != null) { 212 | params['rankby'] = rankby; 213 | } 214 | 215 | if (minprice != null) { 216 | params['minprice'] = minprice.index.toString(); 217 | } 218 | 219 | if (maxprice != null) { 220 | params['maxprice'] = maxprice.index.toString(); 221 | } 222 | 223 | if (type != null) { 224 | params['type'] = type; 225 | } 226 | 227 | if (pagetoken != null) { 228 | params['pagetoken'] = pagetoken; 229 | } 230 | 231 | if (language != null) { 232 | params['language'] = language; 233 | } 234 | 235 | if (radius != null) { 236 | params['radius'] = radius.toString(); 237 | } 238 | 239 | if (apiKey != null) { 240 | params['key'] = apiKey!; 241 | } 242 | return url 243 | .replace( 244 | path: '${url.path}$_nearbySearchUrl', 245 | queryParameters: params, 246 | ) 247 | .toString(); 248 | } 249 | 250 | String buildTextSearchUrl({ 251 | required String query, 252 | Location? location, 253 | num? radius, 254 | PriceLevel? minprice, 255 | PriceLevel? maxprice, 256 | bool opennow = false, 257 | String? type, 258 | String? pagetoken, 259 | String? language, 260 | String? region, 261 | }) { 262 | final params = { 263 | 'query': query, 264 | }; 265 | 266 | if (minprice != null) { 267 | params['minprice'] = minprice.index.toString(); 268 | } 269 | 270 | if (maxprice != null) { 271 | params['maxprice'] = maxprice.index.toString(); 272 | } 273 | 274 | if (opennow) { 275 | params['opennow'] = opennow.toString(); 276 | } 277 | 278 | if (type != null) { 279 | params['type'] = type; 280 | } 281 | 282 | if (pagetoken != null) { 283 | params['pagetoken'] = pagetoken; 284 | } 285 | 286 | if (language != null) { 287 | params['language'] = language; 288 | } 289 | 290 | if (region != null) { 291 | params['region'] = region; 292 | } 293 | 294 | if (location != null) { 295 | params['location'] = location.toString(); 296 | } 297 | 298 | if (radius != null) { 299 | params['radius'] = radius.toString(); 300 | } 301 | 302 | if (apiKey != null) { 303 | params['key'] = apiKey!; 304 | } 305 | 306 | return url 307 | .replace( 308 | path: '${url.path}$_textSearchUrl', 309 | queryParameters: params, 310 | ) 311 | .toString(); 312 | } 313 | 314 | String buildDetailsUrl({ 315 | String? placeId, 316 | String? reference, 317 | String? sessionToken, 318 | String? language, 319 | List fields = const [], 320 | String? region, 321 | }) { 322 | if (placeId != null && reference != null) { 323 | throw ArgumentError("You must supply either 'placeid' or 'reference'"); 324 | } 325 | 326 | final params = {}; 327 | 328 | if (placeId != null) { 329 | params['placeid'] = placeId; 330 | } 331 | 332 | if (reference != null) { 333 | params['reference'] = reference; 334 | } 335 | 336 | if (language != null) { 337 | params['language'] = language; 338 | } 339 | 340 | if (region != null) { 341 | params['region'] = region; 342 | } 343 | 344 | if (fields.isNotEmpty) { 345 | params['fields'] = fields.join(','); 346 | } 347 | 348 | if (apiKey != null) { 349 | params['key'] = apiKey!; 350 | } 351 | 352 | if (sessionToken != null) { 353 | params['sessiontoken'] = sessionToken; 354 | } 355 | 356 | return url 357 | .replace( 358 | path: '${url.path}$_detailsSearchUrl', 359 | queryParameters: params, 360 | ) 361 | .toString(); 362 | } 363 | 364 | String buildAutocompleteUrl({ 365 | required String input, 366 | String? sessionToken, 367 | num? offset, 368 | Location? origin, 369 | Location? location, 370 | num? radius, 371 | String? language, 372 | List types = const [], 373 | List components = const [], 374 | bool strictbounds = false, 375 | String? region, 376 | }) { 377 | final params = { 378 | 'input': input, 379 | }; 380 | 381 | if (language != null) { 382 | params['language'] = language; 383 | } 384 | 385 | if (origin != null) { 386 | params['origin'] = origin.toString(); 387 | } 388 | 389 | if (location != null) { 390 | params['location'] = location.toString(); 391 | } 392 | 393 | if (radius != null) { 394 | params['radius'] = radius.toString(); 395 | } 396 | 397 | if (types.isNotEmpty) { 398 | params['types'] = types.join('|'); 399 | } 400 | 401 | if (components.isNotEmpty) { 402 | params['components'] = components.join('|'); 403 | } 404 | 405 | if (strictbounds) { 406 | params['strictbounds'] = strictbounds.toString(); 407 | } 408 | 409 | if (offset != null) { 410 | params['offset'] = offset.toString(); 411 | } 412 | 413 | if (region != null) { 414 | params['region'] = region; 415 | } 416 | 417 | if (apiKey != null) { 418 | params['key'] = apiKey!; 419 | } 420 | 421 | if (sessionToken != null) { 422 | params['sessiontoken'] = sessionToken; 423 | } 424 | 425 | return url 426 | .replace( 427 | path: '${url.path}$_autocompleteUrl', 428 | queryParameters: params, 429 | ) 430 | .toString(); 431 | } 432 | 433 | String buildQueryAutocompleteUrl({ 434 | required String input, 435 | num? offset, 436 | Location? location, 437 | num? radius, 438 | String? language, 439 | }) { 440 | final params = { 441 | 'input': input, 442 | }; 443 | 444 | if (language != null) { 445 | params['language'] = language; 446 | } 447 | 448 | if (location != null) { 449 | params['location'] = location.toString(); 450 | } 451 | 452 | if (radius != null) { 453 | params['radius'] = radius.toString(); 454 | } 455 | 456 | if (offset != null) { 457 | params['offset'] = offset.toString(); 458 | } 459 | 460 | if (apiKey != null) { 461 | params['key'] = apiKey!; 462 | } 463 | 464 | return url 465 | .replace( 466 | path: '${url.path}$_queryAutocompleteUrl', 467 | queryParameters: params, 468 | ) 469 | .toString(); 470 | } 471 | 472 | String buildPhotoUrl({ 473 | required String photoReference, 474 | int? maxWidth, 475 | int? maxHeight, 476 | }) { 477 | if (maxWidth == null && maxHeight == null) { 478 | throw ArgumentError("You must supply 'maxWidth' or 'maxHeight'"); 479 | } 480 | 481 | final params = { 482 | 'photoreference': photoReference, 483 | }; 484 | 485 | if (maxWidth != null) { 486 | params['maxwidth'] = maxWidth.toString(); 487 | } 488 | 489 | if (maxHeight != null) { 490 | params['maxheight'] = maxHeight.toString(); 491 | } 492 | 493 | if (apiKey != null) { 494 | params['key'] = apiKey!; 495 | } 496 | 497 | return url 498 | .replace( 499 | path: '${url.path}$_photoUrl', 500 | queryParameters: params, 501 | ) 502 | .toString(); 503 | } 504 | 505 | PlacesSearchResponse _decodeSearchResponse(Response res) => 506 | PlacesSearchResponse.fromJson( 507 | json.decode(res.body) as Map); 508 | 509 | PlacesDetailsResponse _decodeDetailsResponse(Response res) => 510 | PlacesDetailsResponse.fromJson( 511 | json.decode(res.body) as Map); 512 | 513 | PlacesAutocompleteResponse _decodeAutocompleteResponse(Response res) => 514 | PlacesAutocompleteResponse.fromJson( 515 | json.decode(res.body) as Map); 516 | } 517 | 518 | const _jsonSerializable = JsonSerializable( 519 | fieldRename: FieldRename.snake, 520 | explicitToJson: true, 521 | ); 522 | 523 | @_jsonSerializable 524 | @immutable 525 | class PlacesSearchResponse extends GoogleResponseStatus { 526 | @JsonKey(defaultValue: []) 527 | final List results; 528 | 529 | /// JSON html_attributions 530 | @JsonKey(defaultValue: []) 531 | final List htmlAttributions; 532 | 533 | /// JSON next_page_token 534 | final String? nextPageToken; 535 | 536 | PlacesSearchResponse({ 537 | required super.status, 538 | super.errorMessage, 539 | this.results = const [], 540 | this.htmlAttributions = const [], 541 | this.nextPageToken, 542 | }); 543 | 544 | factory PlacesSearchResponse.fromJson(Map json) => 545 | _$PlacesSearchResponseFromJson(json); 546 | 547 | Map toJson() => _$PlacesSearchResponseToJson(this); 548 | } 549 | 550 | @_jsonSerializable 551 | @immutable 552 | class PlacesSearchResult { 553 | final String? icon; 554 | final Geometry? geometry; 555 | final String name; 556 | 557 | /// JSON opening_hours 558 | final OpeningHoursDetail? openingHours; 559 | 560 | @JsonKey(defaultValue: []) 561 | final List photos; 562 | 563 | /// JSON place_id 564 | final String placeId; 565 | 566 | final String? scope; 567 | 568 | /// JSON alt_ids 569 | @JsonKey(defaultValue: []) 570 | final List altIds; 571 | 572 | /// JSON price_level 573 | final PriceLevel? priceLevel; 574 | 575 | final num? rating; 576 | 577 | @JsonKey(defaultValue: []) 578 | final List types; 579 | 580 | final String? vicinity; 581 | 582 | /// JSON formatted_address 583 | final String? formattedAddress; 584 | 585 | /// JSON permanently_closed 586 | @JsonKey(defaultValue: false) 587 | final bool permanentlyClosed; 588 | 589 | final String? id; 590 | 591 | final String reference; 592 | 593 | const PlacesSearchResult({ 594 | this.id, 595 | required this.reference, 596 | required this.name, 597 | required this.placeId, 598 | this.formattedAddress, 599 | this.photos = const [], 600 | this.altIds = const [], 601 | this.types = const [], 602 | this.permanentlyClosed = false, 603 | this.icon, 604 | this.geometry, 605 | this.openingHours, 606 | this.scope, 607 | this.priceLevel, 608 | this.rating, 609 | this.vicinity, 610 | }); 611 | 612 | factory PlacesSearchResult.fromJson(Map json) => 613 | _$PlacesSearchResultFromJson(json); 614 | 615 | Map toJson() => _$PlacesSearchResultToJson(this); 616 | } 617 | 618 | @_jsonSerializable 619 | @immutable 620 | class PlaceDetails { 621 | /// JSON address_components 622 | @JsonKey(defaultValue: []) 623 | final List addressComponents; 624 | 625 | /// JSON adr_address 626 | final String? adrAddress; 627 | 628 | /// JSON formatted_address 629 | final String? formattedAddress; 630 | 631 | /// JSON formatted_phone_number 632 | final String? formattedPhoneNumber; 633 | 634 | final String? id; 635 | 636 | final String? reference; 637 | 638 | final String? icon; 639 | 640 | final String name; 641 | 642 | /// JSON opening_hours 643 | final OpeningHoursDetail? openingHours; 644 | 645 | @JsonKey(defaultValue: []) 646 | final List photos; 647 | 648 | /// JSON place_id 649 | final String placeId; 650 | 651 | /// JSON international_phone_number 652 | final String? internationalPhoneNumber; 653 | 654 | /// JSON price_level 655 | final PriceLevel? priceLevel; 656 | 657 | final num? rating; 658 | 659 | final String? scope; 660 | 661 | @JsonKey(defaultValue: []) 662 | final List types; 663 | 664 | final String? url; 665 | 666 | final String? vicinity; 667 | 668 | /// JSON utc_offset 669 | final num? utcOffset; 670 | 671 | final String? website; 672 | 673 | @JsonKey(defaultValue: []) 674 | final List reviews; 675 | 676 | final Geometry? geometry; 677 | 678 | const PlaceDetails({ 679 | this.adrAddress, 680 | required this.name, 681 | required this.placeId, 682 | this.utcOffset, 683 | this.id, 684 | this.internationalPhoneNumber, 685 | this.addressComponents = const [], 686 | this.photos = const [], 687 | this.types = const [], 688 | this.reviews = const [], 689 | this.formattedAddress, 690 | this.formattedPhoneNumber, 691 | this.reference, 692 | this.icon, 693 | this.rating, 694 | this.openingHours, 695 | this.priceLevel, 696 | this.scope, 697 | this.url, 698 | this.vicinity, 699 | this.website, 700 | this.geometry, 701 | }); 702 | 703 | factory PlaceDetails.fromJson(Map json) => 704 | _$PlaceDetailsFromJson(json); 705 | 706 | Map toJson() => _$PlaceDetailsToJson(this); 707 | } 708 | 709 | @_jsonSerializable 710 | @immutable 711 | class OpeningHoursDetail { 712 | @JsonKey(defaultValue: false) 713 | final bool openNow; 714 | 715 | @JsonKey(defaultValue: []) 716 | final List periods; 717 | 718 | @JsonKey(defaultValue: []) 719 | final List weekdayText; 720 | 721 | const OpeningHoursDetail({ 722 | this.openNow = false, 723 | this.periods = const [], 724 | this.weekdayText = const [], 725 | }); 726 | 727 | factory OpeningHoursDetail.fromJson(Map json) => 728 | _$OpeningHoursDetailFromJson(json); 729 | 730 | Map toJson() => _$OpeningHoursDetailToJson(this); 731 | } 732 | 733 | @_jsonSerializable 734 | @immutable 735 | class OpeningHoursPeriodDate { 736 | final int day; 737 | final String time; 738 | 739 | /// UTC Time 740 | @Deprecated('use `toDateTime()`') 741 | DateTime get dateTime => toDateTime(); 742 | 743 | DateTime toDateTime() => dayTimeToDateTime(day, time); 744 | 745 | const OpeningHoursPeriodDate({required this.day, required this.time}); 746 | 747 | factory OpeningHoursPeriodDate.fromJson(Map json) => 748 | _$OpeningHoursPeriodDateFromJson(json); 749 | 750 | Map toJson() => _$OpeningHoursPeriodDateToJson(this); 751 | } 752 | 753 | @_jsonSerializable 754 | @immutable 755 | class OpeningHoursPeriod { 756 | final OpeningHoursPeriodDate? open; 757 | final OpeningHoursPeriodDate? close; 758 | 759 | const OpeningHoursPeriod({this.open, this.close}); 760 | 761 | factory OpeningHoursPeriod.fromJson(Map json) => 762 | _$OpeningHoursPeriodFromJson(json); 763 | 764 | Map toJson() => _$OpeningHoursPeriodToJson(this); 765 | } 766 | 767 | @_jsonSerializable 768 | @immutable 769 | class Photo { 770 | /// JSON photo_reference 771 | final String photoReference; 772 | final num height; 773 | final num width; 774 | 775 | /// JSON html_attributions 776 | @JsonKey(defaultValue: []) 777 | final List htmlAttributions; 778 | 779 | const Photo({ 780 | required this.photoReference, 781 | required this.height, 782 | required this.width, 783 | this.htmlAttributions = const [], 784 | }); 785 | 786 | factory Photo.fromJson(Map json) => _$PhotoFromJson(json); 787 | 788 | Map toJson() => _$PhotoToJson(this); 789 | } 790 | 791 | @_jsonSerializable 792 | @immutable 793 | class AlternativeId { 794 | /// JSON place_id 795 | final String placeId; 796 | 797 | final String scope; 798 | 799 | const AlternativeId({required this.placeId, required this.scope}); 800 | 801 | factory AlternativeId.fromJson(Map json) => 802 | _$AlternativeIdFromJson(json); 803 | 804 | Map toJson() => _$AlternativeIdToJson(this); 805 | } 806 | 807 | enum PriceLevel { 808 | @JsonValue(0) 809 | free, 810 | @JsonValue(1) 811 | inexpensive, 812 | @JsonValue(2) 813 | moderate, 814 | @JsonValue(3) 815 | expensive, 816 | @JsonValue(4) 817 | veryExpensive, 818 | } 819 | 820 | @_jsonSerializable 821 | @immutable 822 | class PlacesDetailsResponse extends GoogleResponseStatus { 823 | final PlaceDetails result; 824 | 825 | /// JSON html_attributions 826 | @JsonKey(defaultValue: []) 827 | final List htmlAttributions; 828 | 829 | PlacesDetailsResponse({ 830 | required super.status, 831 | super.errorMessage, 832 | required this.result, 833 | required this.htmlAttributions, 834 | }); 835 | 836 | factory PlacesDetailsResponse.fromJson(Map json) => 837 | _$PlacesDetailsResponseFromJson(json); 838 | 839 | Map toJson() => _$PlacesDetailsResponseToJson(this); 840 | } 841 | 842 | @_jsonSerializable 843 | @immutable 844 | class Review { 845 | /// JSON author_name 846 | final String authorName; 847 | 848 | /// JSON author_url 849 | final String authorUrl; 850 | 851 | final String? language; 852 | 853 | /// JSON profile_photo_url 854 | final String profilePhotoUrl; 855 | 856 | final num rating; 857 | 858 | /// JSON relative_time_description 859 | final String relativeTimeDescription; 860 | 861 | final String text; 862 | 863 | final num time; 864 | 865 | const Review({ 866 | required this.authorName, 867 | required this.authorUrl, 868 | required this.language, 869 | required this.profilePhotoUrl, 870 | required this.rating, 871 | required this.relativeTimeDescription, 872 | required this.text, 873 | required this.time, 874 | }); 875 | 876 | factory Review.fromJson(Map json) => _$ReviewFromJson(json); 877 | 878 | Map toJson() => _$ReviewToJson(this); 879 | } 880 | 881 | @_jsonSerializable 882 | @immutable 883 | class PlacesAutocompleteResponse extends GoogleResponseStatus { 884 | @JsonKey(defaultValue: []) 885 | final List predictions; 886 | 887 | PlacesAutocompleteResponse({ 888 | required super.status, 889 | super.errorMessage, 890 | required this.predictions, 891 | }); 892 | 893 | factory PlacesAutocompleteResponse.fromJson(Map json) => 894 | _$PlacesAutocompleteResponseFromJson(json); 895 | 896 | Map toJson() => _$PlacesAutocompleteResponseToJson(this); 897 | } 898 | 899 | @_jsonSerializable 900 | @immutable 901 | class Prediction { 902 | final String? description; 903 | final String? id; 904 | 905 | @JsonKey(defaultValue: []) 906 | final List terms; 907 | 908 | final int? distanceMeters; 909 | 910 | /// JSON place_id 911 | final String? placeId; 912 | final String? reference; 913 | 914 | @JsonKey(defaultValue: []) 915 | final List types; 916 | 917 | /// JSON matched_substrings 918 | @JsonKey(defaultValue: []) 919 | final List matchedSubstrings; 920 | 921 | final StructuredFormatting? structuredFormatting; 922 | 923 | const Prediction({ 924 | this.description, 925 | this.id, 926 | this.terms = const [], 927 | this.distanceMeters, 928 | this.placeId, 929 | this.reference, 930 | this.types = const [], 931 | this.matchedSubstrings = const [], 932 | this.structuredFormatting, 933 | }); 934 | 935 | factory Prediction.fromJson(Map json) => 936 | _$PredictionFromJson(json); 937 | 938 | Map toJson() => _$PredictionToJson(this); 939 | } 940 | 941 | @_jsonSerializable 942 | @immutable 943 | class Term { 944 | final num offset; 945 | final String value; 946 | 947 | const Term({ 948 | required this.offset, 949 | required this.value, 950 | }); 951 | 952 | factory Term.fromJson(Map json) => _$TermFromJson(json); 953 | 954 | Map toJson() => _$TermToJson(this); 955 | 956 | @override 957 | bool operator ==(Object other) => 958 | identical(this, other) || 959 | other is Term && 960 | runtimeType == other.runtimeType && 961 | offset == other.offset && 962 | value == other.value; 963 | 964 | @override 965 | int get hashCode => offset.hashCode ^ value.hashCode; 966 | } 967 | 968 | @_jsonSerializable 969 | @immutable 970 | class MatchedSubstring { 971 | final num offset; 972 | final num length; 973 | 974 | const MatchedSubstring({ 975 | required this.offset, 976 | required this.length, 977 | }); 978 | 979 | factory MatchedSubstring.fromJson(Map json) => 980 | _$MatchedSubstringFromJson(json); 981 | 982 | Map toJson() => _$MatchedSubstringToJson(this); 983 | 984 | @override 985 | bool operator ==(Object other) => 986 | identical(this, other) || 987 | other is MatchedSubstring && 988 | runtimeType == other.runtimeType && 989 | offset == other.offset && 990 | length == other.length; 991 | 992 | @override 993 | int get hashCode => offset.hashCode ^ length.hashCode; 994 | } 995 | 996 | @_jsonSerializable 997 | @immutable 998 | class StructuredFormatting { 999 | final String mainText; 1000 | 1001 | @JsonKey(defaultValue: []) 1002 | final List mainTextMatchedSubstrings; 1003 | final String? secondaryText; 1004 | 1005 | const StructuredFormatting({ 1006 | required this.mainText, 1007 | this.mainTextMatchedSubstrings = const [], 1008 | this.secondaryText, 1009 | }); 1010 | 1011 | factory StructuredFormatting.fromJson(Map json) => 1012 | _$StructuredFormattingFromJson(json); 1013 | 1014 | Map toJson() => _$StructuredFormattingToJson(this); 1015 | } 1016 | --------------------------------------------------------------------------------