説明なし
選択できるのは25トピックまでです。 トピックは、先頭が英数字で、英数字とダッシュ('-')を使用した35文字以内のものにしてください。

canvasingDetail_screen.dart 20KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626
  1. import 'dart:async';
  2. import 'dart:convert';
  3. import 'dart:ffi';
  4. import 'package:employee_selfservice_mobile/Screens/Menu/Canvasing/filing_screen.dart';
  5. import 'package:employee_selfservice_mobile/Screens/Menu/Canvasing/navigate_post.dart';
  6. import 'package:employee_selfservice_mobile/Screens/Menu/Canvasing/startFiling_post.dart';
  7. import 'package:employee_selfservice_mobile/Screens/Menu/Canvasing/updateGPS_post.dart';
  8. import 'package:flutter/material.dart';
  9. import 'package:flutter_map/plugin_api.dart';
  10. import 'package:geolocator/geolocator.dart';
  11. import 'package:latlong2/latlong.dart' as latlong;
  12. import 'package:location/location.dart' as loc;
  13. import 'dart:developer' as logDev;
  14. import 'package:progress_dialog_null_safe/progress_dialog_null_safe.dart';
  15. import 'package:shared_preferences/shared_preferences.dart';
  16. import 'package:sliding_up_panel/sliding_up_panel.dart';
  17. class CanvasingDetail extends StatefulWidget {
  18. const CanvasingDetail({Key? key}) : super(key: key);
  19. @override
  20. State<CanvasingDetail> createState() => _CanvasingDetail();
  21. }
  22. class _CanvasingDetail extends State<CanvasingDetail> {
  23. late latlong.LatLng point = latlong.LatLng(-6.183580253674716, 106.93103973792664);
  24. late Position position;
  25. MapController _mapController = MapController();
  26. @override
  27. void initState() {
  28. determinePosition();
  29. WidgetsBinding.instance.addPostFrameCallback((_) {
  30. initTimer();
  31. });
  32. super.initState();
  33. }
  34. Timer? timer;
  35. void initTimer(){
  36. if (timer != null && timer!.isActive) return;
  37. timer = Timer.periodic(Duration(seconds: 10), (timer) {
  38. setState(() {
  39. updatePosition();
  40. });
  41. });
  42. }
  43. @override
  44. void dispose() {
  45. timer?.cancel();
  46. super.dispose();
  47. }
  48. determinePosition() async {
  49. StreamSubscription<ServiceStatus> serviceStatusStream = Geolocator.getServiceStatusStream().listen(
  50. (ServiceStatus status) {
  51. print(status);
  52. });
  53. ProgressDialog loading = ProgressDialog(context);
  54. loading = ProgressDialog(context, type: ProgressDialogType.normal, isDismissible: false, showLogs: true);
  55. loading.style(
  56. message: 'Please Wait .....',
  57. borderRadius: 3,
  58. backgroundColor: Colors.white,
  59. progressWidget: CircularProgressIndicator(),
  60. elevation: 10.0,
  61. padding: EdgeInsets.all(10),
  62. insetAnimCurve: Curves.easeInOut,
  63. progress: 0.0,
  64. maxProgress: 100.0,
  65. progressTextStyle: TextStyle(color: Colors.black, fontSize: 10.0, fontWeight: FontWeight.w400),
  66. messageTextStyle: TextStyle(color: Colors.black, fontSize: 15.0, fontWeight: FontWeight.w600));
  67. await loading.show();
  68. bool serviceEnabled = await Geolocator.isLocationServiceEnabled();
  69. logDev.log(serviceEnabled.toString(), name: "ON/OFF LOCATION SERVICE");
  70. if (!serviceEnabled) {
  71. return Future.error('Location services are disabled.');
  72. }
  73. LocationPermission permission = await Geolocator.checkPermission();
  74. if (permission == LocationPermission.deniedForever) {
  75. await loading.hide();
  76. //return Future.error('Location permissions are permanently denied, we cannot request permissions.');
  77. return alertDialogPermissionDeniedForever(context);
  78. } else if (permission == LocationPermission.denied) {
  79. permission = await Geolocator.requestPermission();
  80. if (permission != LocationPermission.whileInUse && permission != LocationPermission.always) {
  81. await loading.hide();
  82. //return Future.error('Location permissions are denied (actual value: $permission).');
  83. return alertDialogPermissionDenied(context);
  84. }
  85. }
  86. final SharedPreferences prefs = await SharedPreferences.getInstance();
  87. String? idDetail = prefs.getString('idDetail');
  88. int? user_id = prefs.getInt('user_id');
  89. Navigate_Post.connectToAPI(idDetail!, user_id!).then((valueResult) async {
  90. Map<String, dynamic> object = json.decode(valueResult);
  91. if (object.containsKey("result").toString() == "true") {
  92. String result = object['result'].toString();
  93. String status = object['result']['status'].toString();
  94. logDev.log(result, name: "Status??");
  95. if (status.contains("success")){
  96. String mapsPoint = object['result']['maps'].toString();
  97. double? lat = double.tryParse(mapsPoint.split(",")[0]);
  98. double? long = double.tryParse(mapsPoint.split(",")[1]);
  99. logDev.log(mapsPoint, name: "titik lokasinya");
  100. position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
  101. logDev.log(position.toString(), name: "Position GEOLOCATOR");
  102. if (position.isMocked) {
  103. await loading.hide();
  104. setState(() {
  105. alertDialogFakeGPSDetected(context);
  106. });
  107. } else {
  108. setState(() {
  109. point = latlong.LatLng(lat!,long!);
  110. logDev.log(point.toString(), name: "POINT GEOLOCATOR");
  111. _mapController.move(point, 18);
  112. });
  113. }
  114. await loading.hide();
  115. await loading.hide();
  116. } else if (status.contains("failed")){
  117. setState(() {
  118. alertDialogFailedResponse(context);
  119. });
  120. await loading.hide();
  121. }
  122. } else {
  123. setState(() {
  124. alertDialogFailedResponse(context);
  125. });
  126. await loading.hide();
  127. }
  128. await loading.hide();
  129. });
  130. logDev.log("DAH SELESE BUiLD NAVIGATENYA!", name: "UDAH?");
  131. }
  132. Future<void> updatePosition() async {
  133. logDev.log("NAH BARU MULAI!", name: "MULAI?");
  134. ProgressDialog loading = ProgressDialog(context);
  135. loading = ProgressDialog(context,
  136. type: ProgressDialogType.normal, isDismissible: false, showLogs: true);
  137. loading.style(
  138. message: 'Please Wait .....',
  139. borderRadius: 3,
  140. backgroundColor: Colors.white,
  141. progressWidget: CircularProgressIndicator(),
  142. elevation: 10.0,
  143. padding: EdgeInsets.all(10),
  144. insetAnimCurve: Curves.easeInOut,
  145. progress: 0.0,
  146. maxProgress: 100.0,
  147. progressTextStyle: TextStyle(
  148. color: Colors.black, fontSize: 10.0, fontWeight: FontWeight.w400),
  149. messageTextStyle: TextStyle(
  150. color: Colors.black, fontSize: 15.0, fontWeight: FontWeight.w600));
  151. bool serviceEnabled;
  152. LocationPermission permission;
  153. serviceEnabled = await Geolocator.isLocationServiceEnabled();
  154. if (!serviceEnabled) {
  155. await loading.hide();
  156. return Future.error('Location services are disabled.');
  157. }
  158. permission = await Geolocator.checkPermission();
  159. if (permission == LocationPermission.deniedForever) {
  160. await loading.hide();
  161. return alertDialogPermissionDeniedForever(context);
  162. } else if (permission == LocationPermission.denied) {
  163. permission = await Geolocator.requestPermission();
  164. if (permission != LocationPermission.whileInUse && permission != LocationPermission.always) {
  165. await loading.hide();
  166. return alertDialogPermissionDenied(context);
  167. }
  168. }
  169. position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
  170. if (position.isMocked) {
  171. await loading.hide();
  172. setState(() {
  173. alertDialogFakeGPSDetected(context);
  174. });
  175. } else {
  176. await loading.hide();
  177. final SharedPreferences prefs = await SharedPreferences.getInstance();
  178. String? idDetail = prefs.getString('idDetail');
  179. int? user_id = prefs.getInt('user_id');
  180. point = latlong.LatLng(position.latitude, position.longitude);
  181. logDev.log(point.toString(), name: "UPDATE POINT GEOLOCATOR");
  182. _mapController.move(point, 18);
  183. position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
  184. String titik = position.latitude.toString() + "," + position.longitude.toString();
  185. logDev.log(titik, name: "TITIK UPDATE");
  186. setState(() {
  187. UpdateGPS_Post.connectToAPI(idDetail!, titik, user_id!).then((valueResult) async {
  188. Map<String, dynamic> object = json.decode(valueResult);
  189. if (object.containsKey("result").toString() == "true") {
  190. String status = object['result']['status'].toString();
  191. if (status.contains("success")){
  192. String mapsPoint = object['result']['maps'].toString();
  193. logDev.log(mapsPoint, name: "titik lokasinya");
  194. position = await Geolocator.getCurrentPosition(desiredAccuracy: LocationAccuracy.high);
  195. logDev.log(position.toString(), name: "Position GEOLOCATOR");
  196. if (position.isMocked) {
  197. await loading.hide();
  198. setState(() {
  199. alertDialogFakeGPSDetected(context);
  200. });
  201. } else {
  202. setState(() {
  203. point = latlong.LatLng(double.parse(mapsPoint.split(",")[0]), double.parse(mapsPoint.split(",")[1]));
  204. logDev.log(point.toString(), name: "POINT GEOLOCATOR");
  205. _mapController.move(point, 18);
  206. });
  207. }
  208. await loading.hide();
  209. } else if (status.contains("failed")){
  210. setState(() {
  211. alertDialogFailedResponse(context);
  212. });
  213. await loading.hide();
  214. }
  215. } else {
  216. setState(() {
  217. alertDialogFailedResponse(context);
  218. });
  219. await loading.hide();
  220. }
  221. await loading.hide();
  222. });
  223. });
  224. }
  225. }
  226. PanelController _panelController = PanelController();
  227. void togglePanel() => _panelController.isPanelOpen
  228. ? _panelController.close()
  229. : _panelController.open();
  230. @override
  231. Widget build(BuildContext context) {
  232. var size = MediaQuery.of(context).size;
  233. return Scaffold(
  234. body: SlidingUpPanel(
  235. controller: _panelController,
  236. parallaxEnabled: true,
  237. maxHeight: size.height * 0.2,
  238. minHeight: size.height * 0.2,
  239. body: Container (
  240. child: Stack(
  241. children: [
  242. FlutterMap(
  243. mapController: _mapController,
  244. options: new MapOptions(
  245. onTap: (p, point) async {}, center: point, zoom: 15),
  246. children: [
  247. TileLayer(
  248. minZoom: 1,
  249. maxZoom: 22,
  250. maxNativeZoom: 18,
  251. minNativeZoom: 1,
  252. backgroundColor: Colors.black54,
  253. urlTemplate:
  254. 'https://{s}.tile.openstreetmap.org/{z}/{x}/{y}.png',
  255. subdomains: ['a', 'b', 'c'],
  256. ),
  257. MarkerLayer(markers: [
  258. Marker(
  259. width: 135,
  260. height: 135,
  261. point: point,
  262. builder: (ctx) => Container(
  263. child: Icon(
  264. Icons.location_on,
  265. color: Colors.red,
  266. ),
  267. ))
  268. ])
  269. ],
  270. ),
  271. Container(
  272. alignment: AlignmentDirectional.bottomEnd,
  273. child: Container(
  274. margin: EdgeInsets.fromLTRB(10, 15, 0, (size.height*0.3) + 15),
  275. child: RawMaterialButton(
  276. onPressed: () {
  277. setState(() {
  278. updatePosition();
  279. });
  280. },
  281. elevation: 5.0,
  282. fillColor: Colors.white,
  283. child: Image.asset('assets/images/location1.png',
  284. height: 40, width: 40),
  285. padding: EdgeInsets.all(5.0),
  286. shape: CircleBorder(),
  287. ),
  288. ),
  289. ),
  290. ],
  291. ),
  292. ),
  293. panel: Center(
  294. child: Column(
  295. children: [
  296. GestureDetector(
  297. onTap: togglePanel,
  298. child: Center(
  299. child: Container(
  300. margin: EdgeInsets.only(top: 15),
  301. height: 5,
  302. width: size.width * 0.1,
  303. decoration: BoxDecoration(
  304. borderRadius: BorderRadius.circular(10),
  305. color: Colors.grey
  306. ),
  307. ),
  308. ),
  309. ),
  310. Container(
  311. width: double.infinity,
  312. margin: EdgeInsets.fromLTRB(10, 10, 10, 10),
  313. //decoration: BoxDecoration(border: Border.all(color: Colors.black), borderRadius: BorderRadius.all(Radius.circular(15))),
  314. child: Column(
  315. children: <Widget>[
  316. ],
  317. ),
  318. ),
  319. Container(
  320. margin: EdgeInsets.fromLTRB(10, 15, 10, 15),
  321. child: InkWell(
  322. child: Container(
  323. padding: EdgeInsets.fromLTRB(10, 10, 10, 10),
  324. width: double.infinity,
  325. decoration: BoxDecoration(
  326. borderRadius: BorderRadius.circular(5),
  327. gradient: LinearGradient(colors: [
  328. Color(0xFF2D4059),
  329. Color(0xFF2D4059),
  330. ])),
  331. child: Row(
  332. mainAxisAlignment: MainAxisAlignment.center,
  333. children: [
  334. Text('Start Filing\t\t',
  335. textAlign: TextAlign.center,
  336. style: TextStyle(
  337. color: Colors.white,
  338. fontSize: 17,
  339. fontWeight: FontWeight.w500)),
  340. Image.asset(
  341. 'assets/images/ic_arrow_white.png',
  342. width: 30,
  343. height: 30,
  344. )
  345. ],
  346. )),
  347. onTap: () async {
  348. final SharedPreferences prefs = await SharedPreferences.getInstance();
  349. String? idDetail = prefs.getString('idDetail');
  350. int? user_id = prefs.getInt('user_id');
  351. StartFiling_Post.connectToAPI(idDetail!, user_id!).then((valueResult) async {
  352. Navigator.push(context, MaterialPageRoute(builder: (context) => FilingScreen()));
  353. });
  354. },
  355. ),
  356. )
  357. ],
  358. ),
  359. ),
  360. borderRadius: BorderRadius.only(topLeft: Radius.circular(15), topRight: Radius.circular(15)),
  361. ),
  362. );
  363. }
  364. }
  365. alertDialogFailedRetrievedData(BuildContext context) {
  366. Widget okButton = TextButton(
  367. child: Text("Refresh"),
  368. onPressed: () {
  369. Navigator.of(context, rootNavigator: true).pop();
  370. Navigator.pushReplacement(
  371. context, MaterialPageRoute(builder: (context) => CanvasingDetail()));
  372. },
  373. );
  374. Widget noButton = TextButton(
  375. child: Text("Back"),
  376. onPressed: () {
  377. Navigator.of(context, rootNavigator: true).pop();
  378. Navigator.pop(context);
  379. },
  380. );
  381. // set up the AlertDialog
  382. AlertDialog alert = AlertDialog(
  383. title: Text("Employee Self Service"),
  384. content: Text("Failed to Retrieve Data"),
  385. actions: [
  386. noButton,
  387. okButton,
  388. ],
  389. );
  390. // show the dialog
  391. showDialog(
  392. context: context,
  393. barrierDismissible: false,
  394. builder: (BuildContext context) {
  395. return alert;
  396. },
  397. );
  398. }
  399. alertDialogFailedResponse(BuildContext context) {
  400. Widget okButton = TextButton(
  401. child: Text("Refresh"),
  402. onPressed: () {
  403. Navigator.of(context, rootNavigator: true).pop();
  404. Navigator.pushReplacement(
  405. context, MaterialPageRoute(builder: (context) => CanvasingDetail()));
  406. },
  407. );
  408. Widget noButton = TextButton(
  409. child: Text("Back"),
  410. onPressed: () {
  411. Navigator.of(context, rootNavigator: true).pop();
  412. Navigator.pop(context);
  413. },
  414. );
  415. // set up the AlertDialog
  416. AlertDialog alert = AlertDialog(
  417. title: Text("Employee Self Service"),
  418. content: Text("Server Response Error"),
  419. actions: [
  420. noButton,
  421. okButton,
  422. ],
  423. );
  424. // show the dialog
  425. showDialog(
  426. context: context,
  427. barrierDismissible: false,
  428. builder: (BuildContext context) {
  429. return alert;
  430. },
  431. );
  432. }
  433. alertDialogFakeGPSDetected(BuildContext context) {
  434. Widget okButton = TextButton(
  435. child: Text("Refresh"),
  436. onPressed: () {
  437. Navigator.of(context, rootNavigator: true).pop();
  438. Navigator.pushReplacement(
  439. context, MaterialPageRoute(builder: (context) => CanvasingDetail()));
  440. },
  441. );
  442. // set up the AlertDialog
  443. AlertDialog alert = AlertDialog(
  444. title: Text("Employee Self Service"),
  445. content: Text("Fake GPS Detected, Please Use Default GPS!"),
  446. actions: [
  447. okButton,
  448. ],
  449. );
  450. // show the dialog
  451. showDialog(
  452. context: context,
  453. barrierDismissible: false,
  454. builder: (BuildContext context) {
  455. return alert;
  456. },
  457. );
  458. }
  459. alertDialogPermissionDenied(BuildContext context) {
  460. Widget okButton = TextButton(
  461. child: Text("Refresh"),
  462. onPressed: () {
  463. Navigator.of(context, rootNavigator: true).pop();
  464. Navigator.pushReplacement(
  465. context, MaterialPageRoute(builder: (context) => CanvasingDetail()));
  466. },
  467. );
  468. Widget noButton = TextButton(
  469. child: Text("Back"),
  470. onPressed: () {
  471. Navigator.of(context, rootNavigator: true).pop();
  472. Navigator.pop(context);
  473. },
  474. );
  475. // set up the AlertDialog
  476. AlertDialog alert = AlertDialog(
  477. title: Text("Employee Self Service"),
  478. content:
  479. Text("Location permissions are denied, we cannot request permissions"),
  480. actions: [
  481. noButton,
  482. okButton,
  483. ],
  484. );
  485. // show the dialog
  486. showDialog(
  487. context: context,
  488. barrierDismissible: false,
  489. builder: (BuildContext context) {
  490. return alert;
  491. },
  492. );
  493. }
  494. alertDialogPermissionDeniedForever(BuildContext context) {
  495. Widget noButton = TextButton(
  496. child: Text("Back"),
  497. onPressed: () {
  498. Navigator.of(context, rootNavigator: true).pop();
  499. Navigator.pop(context);
  500. },
  501. );
  502. // set up the AlertDialog
  503. AlertDialog alert = AlertDialog(
  504. title: Text("Employee Self Service"),
  505. content: Text(
  506. "Location permissions are permanently denied, we cannot request permissions. Please configure it in your device settings."),
  507. actions: [noButton],
  508. );
  509. // show the dialog
  510. showDialog(
  511. context: context,
  512. barrierDismissible: false,
  513. builder: (BuildContext context) {
  514. return alert;
  515. },
  516. );
  517. }
  518. alertDialogEnableLocaionServices(BuildContext context) {
  519. ProgressDialog loading = ProgressDialog(context);
  520. loading = ProgressDialog(context,
  521. type: ProgressDialogType.normal, isDismissible: false, showLogs: true);
  522. loading.style(
  523. message: 'Please Wait .....',
  524. borderRadius: 3,
  525. backgroundColor: Colors.white,
  526. progressWidget: CircularProgressIndicator(),
  527. elevation: 10.0,
  528. padding: EdgeInsets.all(10),
  529. insetAnimCurve: Curves.easeInOut,
  530. progress: 0.0,
  531. maxProgress: 100.0,
  532. progressTextStyle: TextStyle(
  533. color: Colors.black, fontSize: 10.0, fontWeight: FontWeight.w400),
  534. messageTextStyle: TextStyle(
  535. color: Colors.black, fontSize: 15.0, fontWeight: FontWeight.w600));
  536. Widget okButton = TextButton(
  537. child: Text("Open Settings"),
  538. onPressed: () {
  539. //AppSettings.openLocationSettings();
  540. Navigator.of(context, rootNavigator: true).pop();
  541. loading.hide();
  542. },
  543. );
  544. Widget noButton = TextButton(
  545. child: Text("No, thanks"),
  546. onPressed: () {
  547. Navigator.of(context, rootNavigator: true).pop();
  548. Navigator.pop(context);
  549. loading.hide();
  550. },
  551. );
  552. // set up the AlertDialog
  553. AlertDialog alert = AlertDialog(
  554. title: Text("Employee Self Service"),
  555. content:
  556. Text("For a better experience, please turn on your device location"),
  557. actions: [
  558. noButton,
  559. okButton,
  560. ],
  561. );
  562. // show the dialog
  563. showDialog(
  564. context: context,
  565. barrierDismissible: false,
  566. builder: (BuildContext context) {
  567. return alert;
  568. },
  569. );
  570. }