step 11 : get location now using javascript in flutter
This commit is contained in:
@@ -3,6 +3,7 @@ import 'package:absensi_sas/screen/approval_detail/approval_detail_screen.dart';
|
|||||||
import 'package:absensi_sas/screen/home/home_screen_v1.dart';
|
import 'package:absensi_sas/screen/home/home_screen_v1.dart';
|
||||||
import 'package:absensi_sas/screen/presensi/presensi_screen.dart';
|
import 'package:absensi_sas/screen/presensi/presensi_screen.dart';
|
||||||
import 'package:absensi_sas/screen/presensi/presensi_selfie_screen.dart';
|
import 'package:absensi_sas/screen/presensi/presensi_selfie_screen.dart';
|
||||||
|
import 'package:absensi_sas/test_flutter_web_map.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import '../screen/home/home_screen.dart';
|
import '../screen/home/home_screen.dart';
|
||||||
import '../test_flutter_map.dart';
|
import '../test_flutter_map.dart';
|
||||||
@@ -17,9 +18,21 @@ const presensiRoute = "/presensiRoute";
|
|||||||
const presensiSelfieRoute = "/presensiSelfieRoute";
|
const presensiSelfieRoute = "/presensiSelfieRoute";
|
||||||
const approvalRoute = "/approvalRoute";
|
const approvalRoute = "/approvalRoute";
|
||||||
const approvalDetailRoute = "/approvalDetailRoute";
|
const approvalDetailRoute = "/approvalDetailRoute";
|
||||||
|
const testFlutterWebMapRoute = "/testFlutterWebMapRoute";
|
||||||
|
|
||||||
class AppRoute {
|
class AppRoute {
|
||||||
static Route<dynamic> generateRoute(RouteSettings settings) {
|
static Route<dynamic> generateRoute(RouteSettings settings) {
|
||||||
|
// flutter web map
|
||||||
|
if (settings.name == testFlutterWebMapRoute) {
|
||||||
|
return MaterialPageRoute(builder: (context) {
|
||||||
|
return MediaQuery(
|
||||||
|
data: MediaQuery.of(context)
|
||||||
|
.copyWith(textScaleFactor: 1.0, padding: EdgeInsets.all(0)),
|
||||||
|
child: TestFlutterWebMap(),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
// test flutter map
|
// test flutter map
|
||||||
if (settings.name == testFlutterMapRoute) {
|
if (settings.name == testFlutterMapRoute) {
|
||||||
return MaterialPageRoute(builder: (context) {
|
return MaterialPageRoute(builder: (context) {
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import 'package:absensi_sas/app/constant.dart';
|
import 'package:absensi_sas/app/constant.dart';
|
||||||
|
import 'package:absensi_sas/test_flutter_web_map.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||||
@@ -62,8 +63,8 @@ class MyApp extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
|
|
||||||
// home: TestMap(),
|
// home: TestMap(),
|
||||||
initialRoute: loginRoute,
|
// initialRoute: loginRoute,
|
||||||
// initialRoute: presensiSelfieRoute,
|
home: TestFlutterWebMap(),
|
||||||
// initialRoute: testFlutterMapRoute,
|
// initialRoute: testFlutterMapRoute,
|
||||||
onGenerateRoute: AppRoute.generateRoute,
|
onGenerateRoute: AppRoute.generateRoute,
|
||||||
);
|
);
|
||||||
|
|||||||
10
lib/provider/location_provider.dart
Normal file
10
lib/provider/location_provider.dart
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
|
||||||
|
final locationProvider = StateProvider<Map<String, dynamic>>((ref) {
|
||||||
|
return {
|
||||||
|
'status': null,
|
||||||
|
'message': null,
|
||||||
|
'latitude': null,
|
||||||
|
'longitude': null,
|
||||||
|
};
|
||||||
|
});
|
||||||
72
lib/test_flutter_web_map.dart
Normal file
72
lib/test_flutter_web_map.dart
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||||
|
import 'dart:js' as js;
|
||||||
|
|
||||||
|
import 'package:hooks_riverpod/hooks_riverpod.dart';
|
||||||
|
|
||||||
|
import 'provider/location_provider.dart';
|
||||||
|
|
||||||
|
class TestFlutterWebMap extends HookConsumerWidget {
|
||||||
|
const TestFlutterWebMap({super.key});
|
||||||
|
|
||||||
|
@override
|
||||||
|
Widget build(BuildContext context, WidgetRef ref) {
|
||||||
|
final location = ref.watch(locationProvider);
|
||||||
|
final refreshKey = useState<int>(0);
|
||||||
|
|
||||||
|
useEffect(() {
|
||||||
|
void fetchData() {
|
||||||
|
final uri = Uri.base;
|
||||||
|
final queryParams = uri.queryParameters;
|
||||||
|
|
||||||
|
if (queryParams.isNotEmpty) {
|
||||||
|
ref.read(locationProvider.notifier).state = {
|
||||||
|
'status': queryParams['status'],
|
||||||
|
'message': queryParams['message'],
|
||||||
|
'latitude': queryParams['latitude'] != null
|
||||||
|
? double.tryParse(queryParams['latitude']!)
|
||||||
|
: null,
|
||||||
|
'longitude': queryParams['longitude'] != null
|
||||||
|
? double.tryParse(queryParams['longitude']!)
|
||||||
|
: null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
js.context.callMethod('getLocationAndSend');
|
||||||
|
}
|
||||||
|
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
|
||||||
|
fetchData();
|
||||||
|
});
|
||||||
|
|
||||||
|
return () {};
|
||||||
|
}, [refreshKey.value]);
|
||||||
|
|
||||||
|
void _refreshData() {
|
||||||
|
refreshKey.value++; // Trigger useEffect to run again
|
||||||
|
}
|
||||||
|
|
||||||
|
return MaterialApp(
|
||||||
|
debugShowCheckedModeBanner: false,
|
||||||
|
home: Scaffold(
|
||||||
|
appBar: AppBar(
|
||||||
|
title: Text('Flutter Web Google Maps'),
|
||||||
|
),
|
||||||
|
body: Column(
|
||||||
|
children: [
|
||||||
|
SizedBox(height: 20), // Add some spacing
|
||||||
|
Text(
|
||||||
|
'Latitude: ${location['latitude']?.toString() ?? 'Loading...'}'),
|
||||||
|
Text(
|
||||||
|
'Longitude: ${location['longitude']?.toString() ?? 'Loading...'}'),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
floatingActionButton: FloatingActionButton(
|
||||||
|
onPressed: _refreshData,
|
||||||
|
child: Icon(Icons.refresh),
|
||||||
|
tooltip: 'Refresh Location',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
56
pubspec.lock
56
pubspec.lock
@@ -424,6 +424,54 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.2.2"
|
version: "0.2.2"
|
||||||
|
google_maps:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: google_maps
|
||||||
|
sha256: "463b38e5a92a05cde41220a11fd5eef3847031fef3e8cf295ac76ec453246907"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "8.0.0"
|
||||||
|
google_maps_flutter:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: google_maps_flutter
|
||||||
|
sha256: "2e302fa3aaf4e2a297f0342d83ebc5e8e9f826e9a716aef473fe7f404ec630a7"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.9.0"
|
||||||
|
google_maps_flutter_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: google_maps_flutter_android
|
||||||
|
sha256: "60a005bf1ba8d178144e442f6e2d734b0ffc2cc800a05415388472f934ad6d6a"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.14.4"
|
||||||
|
google_maps_flutter_ios:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: google_maps_flutter_ios
|
||||||
|
sha256: "3a484846fc56f15e47e3de1f5ea80a7ff2b31721d2faa88f390f3b3cf580c953"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.13.0"
|
||||||
|
google_maps_flutter_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: google_maps_flutter_platform_interface
|
||||||
|
sha256: "4f6930fd668bf5d40feb2695d5695dbc0c35e5542b557a34ad35be491686d2ba"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.9.0"
|
||||||
|
google_maps_flutter_web:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: google_maps_flutter_web
|
||||||
|
sha256: ff39211bd25d7fad125d19f757eba85bd154460907cd4d135e07e3d0f98a4130
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.5.10"
|
||||||
google_sign_in:
|
google_sign_in:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -1016,6 +1064,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "0.27.7"
|
version: "0.27.7"
|
||||||
|
sanitize_html:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: sanitize_html
|
||||||
|
sha256: "12669c4a913688a26555323fb9cec373d8f9fbe091f2d01c40c723b33caa8989"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.1.0"
|
||||||
shared_preferences:
|
shared_preferences:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -75,6 +75,8 @@ dependencies:
|
|||||||
camera: ^0.11.0+2
|
camera: ^0.11.0+2
|
||||||
flutter_image_compress: ^1.1.0
|
flutter_image_compress: ^1.1.0
|
||||||
path: ^1.8.3
|
path: ^1.8.3
|
||||||
|
google_maps_flutter: ^2.2.6
|
||||||
|
google_maps_flutter_web: ^0.5.10
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
@@ -1,5 +1,6 @@
|
|||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
|
||||||
<head>
|
<head>
|
||||||
<!--
|
<!--
|
||||||
If you are serving your web app in a path other than the root, change the
|
If you are serving your web app in a path other than the root, change the
|
||||||
@@ -25,25 +26,87 @@
|
|||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
<meta name="apple-mobile-web-app-status-bar-style" content="black">
|
||||||
<meta name="apple-mobile-web-app-title" content="absensi_sas_flutter">
|
<meta name="apple-mobile-web-app-title" content="absensi_sas_flutter">
|
||||||
<!-- google sign in browser -->
|
<!-- google sign in browser -->
|
||||||
<meta name="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" content="856240587825-klh0dfjc44bovajg1rpq5vbvs4g7rh5j.apps.googleusercontent.com">
|
<meta name="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"
|
||||||
|
content="856240587825-klh0dfjc44bovajg1rpq5vbvs4g7rh5j.apps.googleusercontent.com">
|
||||||
<link rel="apple-touch-icon" href="icons/Icon-192.png">
|
<link rel="apple-touch-icon" href="icons/Icon-192.png">
|
||||||
|
|
||||||
<!-- Favicon -->
|
<!-- Favicon -->
|
||||||
<link rel="icon" type="image/png" href="favicon.png"/>
|
<link rel="icon" type="image/png" href="favicon.png" />
|
||||||
|
|
||||||
<title>absensi_sas_flutter</title>
|
<title>absensi_sas_flutter</title>
|
||||||
<link rel="manifest" href="manifest.json">
|
<link rel="manifest" href="manifest.json">
|
||||||
|
|
||||||
<!-- This script adds the flutter initialization JS code -->
|
<!-- This script adds the flutter initialization JS code -->
|
||||||
<script src="flutter.js" defer></script>
|
<script src="flutter.js" defer></script>
|
||||||
|
<script>
|
||||||
|
|
||||||
|
window.flutterLocationCallback = (data) => {
|
||||||
|
console.log('Received data from Flutter:', data);
|
||||||
|
window.flutterLocationData = data;
|
||||||
|
};
|
||||||
|
|
||||||
|
function getCurrentLocation(callback) {
|
||||||
|
if (navigator.geolocation) {
|
||||||
|
navigator.geolocation.getCurrentPosition(
|
||||||
|
position => callback(position.coords.latitude, position.coords.longitude),
|
||||||
|
error => console.error('Geolocation error:', error)
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
console.error("Geolocation is not supported by this browser.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function sendLocationToServer(latitude, longitude) {
|
||||||
|
fetch('https://devone.aplikasi.web.id/absensi/apiGetUserLocation.php', {
|
||||||
|
method: 'POST',
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/x-www-form-urlencoded',
|
||||||
|
},
|
||||||
|
body: `latitude=${latitude}&longitude=${longitude}`
|
||||||
|
})
|
||||||
|
.then(response => response.json())
|
||||||
|
.then(data => {
|
||||||
|
console.log('Server response:', data);
|
||||||
|
// if (window.flutterLocationCallback) {
|
||||||
|
// window.flutterLocationCallback(data);
|
||||||
|
// } else {
|
||||||
|
// console.error('flutterLocationCallback is not defined');
|
||||||
|
// }
|
||||||
|
|
||||||
|
const queryString = new URLSearchParams(data).toString();
|
||||||
|
const newUrl = `${window.location.origin}${window.location.pathname}?${queryString}`;
|
||||||
|
|
||||||
|
// Update the URL with query parameters
|
||||||
|
window.history.replaceState(null, '', newUrl);
|
||||||
|
})
|
||||||
|
.catch(error => console.error('Request failed', error));
|
||||||
|
}
|
||||||
|
|
||||||
|
function getLocationAndSend() {
|
||||||
|
getCurrentLocation((latitude, longitude) => {
|
||||||
|
sendLocationToServer(latitude, longitude);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
</script>
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<script src="flutter_bootstrap.js" async></script>
|
<script src="flutter_bootstrap.js" async></script>
|
||||||
<!-- <script>
|
<script>
|
||||||
var API_KEY = "AIzaSyCiN7EeJsUpXVLQKFfrj3sE5OTKebjpzek";
|
// var API_KEY = "AIzaSyCiN7EeJsUpXVLQKFfrj3sE5OTKebjpzek";
|
||||||
var script = document.createElement('script');
|
// var API_KEY = "AIzaSyCztj0X7erH-uqotFfe_Yd-Nt0oBJu6FeM";
|
||||||
script.src = "https://maps.googleapis.com/maps/api/js?key=" + API_KEY;
|
// var script = document.createElement('script');
|
||||||
document.head.appendChild(script);
|
// script.src = "https://maps.googleapis.com/maps/api/js?key=" + API_KEY;
|
||||||
</script> -->
|
// document.head.appendChild(script);
|
||||||
|
|
||||||
|
// tambahan
|
||||||
|
window.onload = function () {
|
||||||
|
getLocationAndSend();
|
||||||
|
};
|
||||||
|
// tambahan
|
||||||
|
</script>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
|
||||||
|
</html>
|
||||||
Reference in New Issue
Block a user