Sending better info to admin, big circular button
This commit is contained in:
@@ -1,7 +1,9 @@
|
|||||||
import 'dart:async';
|
import 'dart:async';
|
||||||
import 'dart:convert';
|
import 'dart:convert';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:intl/intl.dart';
|
||||||
import 'package:geolocator/geolocator.dart';
|
import 'package:geolocator/geolocator.dart';
|
||||||
|
import 'package:geocoding/geocoding.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
|
||||||
void main() {
|
void main() {
|
||||||
@@ -14,7 +16,7 @@ class WalkerApp extends StatelessWidget {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return MaterialApp(
|
return MaterialApp(
|
||||||
title: 'Blockwalker',
|
title: 'Blockcatcher',
|
||||||
theme: ThemeData(primarySwatch: Colors.blue),
|
theme: ThemeData(primarySwatch: Colors.blue),
|
||||||
home: const TrackingScreen(),
|
home: const TrackingScreen(),
|
||||||
);
|
);
|
||||||
@@ -57,11 +59,24 @@ class _TrackingScreenState extends State<TrackingScreen> {
|
|||||||
final log = '${DateTime.now().toIso8601String()} — (${pos.latitude}, ${pos.longitude})';
|
final log = '${DateTime.now().toIso8601String()} — (${pos.latitude}, ${pos.longitude})';
|
||||||
setState(() => _logs.insert(0, log));
|
setState(() => _logs.insert(0, log));
|
||||||
|
|
||||||
final timestamp = DateTime.now().toIso8601String();
|
final timestamp = formatCentralTime(DateTime.now());
|
||||||
await _sendLocationToBackend(pos.latitude, pos.longitude, timestamp);
|
await _sendLocationToBackend(pos.latitude, pos.longitude, timestamp);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String formatCentralTime(DateTime dt) {
|
||||||
|
// Central Time offset is UTC-5 or UTC-6 depending on daylight saving
|
||||||
|
// Using DateTime.now().toUtc() + Duration(hours: -5) is one option
|
||||||
|
// A better way is using timeZoneOffset from a known location
|
||||||
|
// For simplicity, let's assume Central Standard Time (UTC-6)
|
||||||
|
|
||||||
|
final centralTime = dt.toUtc().subtract(const Duration(hours: 5));
|
||||||
|
|
||||||
|
// Format as 10.31.25 9:39:08pm
|
||||||
|
final formatter = DateFormat('MM.dd.yy h:mm:ss a');
|
||||||
|
return formatter.format(centralTime);
|
||||||
|
}
|
||||||
|
|
||||||
Future<void> _sendLocationToBackend(double lat, double lon, String timestamp) async {
|
Future<void> _sendLocationToBackend(double lat, double lon, String timestamp) async {
|
||||||
final url = Uri.parse('http://sam.local:3008/api/location');
|
final url = Uri.parse('http://sam.local:3008/api/location');
|
||||||
|
|
||||||
@@ -69,6 +84,7 @@ class _TrackingScreenState extends State<TrackingScreen> {
|
|||||||
url,
|
url,
|
||||||
headers: {'Content-Type': 'application/json'},
|
headers: {'Content-Type': 'application/json'},
|
||||||
body: jsonEncode({
|
body: jsonEncode({
|
||||||
|
'name': "Freddy Krueger",
|
||||||
'latitude': lat,
|
'latitude': lat,
|
||||||
'longitude': lon,
|
'longitude': lon,
|
||||||
'timestamp': timestamp,
|
'timestamp': timestamp,
|
||||||
@@ -90,24 +106,39 @@ class _TrackingScreenState extends State<TrackingScreen> {
|
|||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: AppBar(title: const Text('Blockwalker')),
|
backgroundColor: const Color(0xFFAEBDFF), // <-- your hex color here
|
||||||
|
appBar: AppBar(
|
||||||
|
title: const Text('BLOCKCATCHER'),
|
||||||
|
backgroundColor: const Color(0xFFAEBDFF), // ✅ your color here
|
||||||
|
),
|
||||||
body: Column(
|
body: Column(
|
||||||
children: [
|
children: [
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 200), // move button closer to top
|
||||||
ElevatedButton(
|
Center(
|
||||||
onPressed: _tracking ? _stopTracking : _startTracking,
|
child: ElevatedButton(
|
||||||
style: ElevatedButton.styleFrom(
|
onPressed: _tracking ? _stopTracking : _startTracking,
|
||||||
backgroundColor: _tracking ? Colors.red : Colors.green,
|
style: ElevatedButton.styleFrom(
|
||||||
|
shape: const CircleBorder(),
|
||||||
|
padding: const EdgeInsets.all(60),
|
||||||
|
backgroundColor: _tracking ? Colors.red : Colors.green,
|
||||||
|
),
|
||||||
|
child: Icon(
|
||||||
|
_tracking ? Icons.stop : Icons.play_arrow,
|
||||||
|
color: Colors.white,
|
||||||
|
size: 40,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
child: Text(_tracking ? 'Stop Tracking' : 'Begin Tracking'),
|
|
||||||
),
|
),
|
||||||
const SizedBox(height: 20),
|
const SizedBox(height: 40),
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ListView.builder(
|
child: ListView.builder(
|
||||||
itemCount: _logs.length,
|
itemCount: _logs.length,
|
||||||
itemBuilder: (context, index) => ListTile(
|
itemBuilder: (context, index) => ListTile(
|
||||||
dense: true,
|
dense: true,
|
||||||
title: Text(_logs[index]),
|
title: Text(
|
||||||
|
_logs[index],
|
||||||
|
style: const TextStyle(color: Colors.black87),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|||||||
40
pubspec.lock
40
pubspec.lock
@@ -96,6 +96,38 @@ packages:
|
|||||||
description: flutter
|
description: flutter
|
||||||
source: sdk
|
source: sdk
|
||||||
version: "0.0.0"
|
version: "0.0.0"
|
||||||
|
geocoding:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: geocoding
|
||||||
|
sha256: "790eea732b22a08dd36fc3761bcd29040461ac20ece4d165264a6c0b5338f115"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.2.2"
|
||||||
|
geocoding_android:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: geocoding_android
|
||||||
|
sha256: "1b13eca79b11c497c434678fed109c2be020b158cec7512c848c102bc7232603"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.3.1"
|
||||||
|
geocoding_ios:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: geocoding_ios
|
||||||
|
sha256: "8a39bfb650af55209c42e564036a550b32d029e0733af01dc66c5afea50388d3"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "2.3.0"
|
||||||
|
geocoding_platform_interface:
|
||||||
|
dependency: transitive
|
||||||
|
description:
|
||||||
|
name: geocoding_platform_interface
|
||||||
|
sha256: "8c2c8226e5c276594c2e18bfe88b19110ed770aeb7c1ab50ede570be8b92229b"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "3.2.0"
|
||||||
geolocator:
|
geolocator:
|
||||||
dependency: "direct main"
|
dependency: "direct main"
|
||||||
description:
|
description:
|
||||||
@@ -160,6 +192,14 @@ packages:
|
|||||||
url: "https://pub.dev"
|
url: "https://pub.dev"
|
||||||
source: hosted
|
source: hosted
|
||||||
version: "4.1.2"
|
version: "4.1.2"
|
||||||
|
intl:
|
||||||
|
dependency: "direct main"
|
||||||
|
description:
|
||||||
|
name: intl
|
||||||
|
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
|
||||||
|
url: "https://pub.dev"
|
||||||
|
source: hosted
|
||||||
|
version: "0.18.1"
|
||||||
leak_tracker:
|
leak_tracker:
|
||||||
dependency: transitive
|
dependency: transitive
|
||||||
description:
|
description:
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ dependencies:
|
|||||||
# Use with the CupertinoIcons class for iOS style icons.
|
# Use with the CupertinoIcons class for iOS style icons.
|
||||||
cupertino_icons: ^1.0.8
|
cupertino_icons: ^1.0.8
|
||||||
http: ^1.5.0
|
http: ^1.5.0
|
||||||
|
intl: ^0.18.1
|
||||||
|
geocoding: ^2.1.2
|
||||||
|
|
||||||
dev_dependencies:
|
dev_dependencies:
|
||||||
flutter_test:
|
flutter_test:
|
||||||
|
|||||||
Reference in New Issue
Block a user