234 lines
5.5 KiB
Dart
234 lines
5.5 KiB
Dart
// Local
|
|
import 'dart:convert';
|
|
|
|
//import '/var/secrets.dart';
|
|
import '/var/config.dart';
|
|
import 'helpers/http.dart';
|
|
import 'helpers/json.dart';
|
|
|
|
// Flutter / Dart
|
|
import 'package:flutter/material.dart';
|
|
|
|
void main() {
|
|
runApp(const MainApp());
|
|
}
|
|
|
|
final String loadText = "Loading...";
|
|
|
|
class MainApp extends StatefulWidget {
|
|
const MainApp({super.key});
|
|
|
|
@override
|
|
State<MainApp> createState() => _MainAppState();
|
|
}
|
|
|
|
class _MainAppState extends State<MainApp> {
|
|
final _formKey = GlobalKey<FormState>();
|
|
String _zipcode = "";
|
|
String _city = "";
|
|
String _country = "";
|
|
String _latlong = "";
|
|
|
|
String weather = loadText;
|
|
bool keepLoading = false;
|
|
DateTime lastLoadTime = DateTime.now().subtract(
|
|
Duration(seconds: limitRefreshSeconds),
|
|
);
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
_refreshWeather();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
Widget form = Form(
|
|
key: _formKey,
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
SizedBox(
|
|
height: 20,
|
|
width: 100,
|
|
child: TextFormField(
|
|
initialValue: _zipcode,
|
|
validator: (value) {
|
|
return null;
|
|
},
|
|
onSaved: (value) {
|
|
_zipcode = value!;
|
|
},
|
|
),
|
|
),
|
|
SizedBox(
|
|
height: 20,
|
|
width: 100,
|
|
child: TextFormField(
|
|
initialValue: _city,
|
|
validator: (value) {
|
|
return null;
|
|
},
|
|
onSaved: (value) {
|
|
_city = value!;
|
|
},
|
|
),
|
|
),
|
|
SizedBox(
|
|
height: 20,
|
|
width: 100,
|
|
child: TextFormField(
|
|
initialValue: _country,
|
|
validator: (value) {
|
|
return null;
|
|
},
|
|
onSaved: (value) {
|
|
_country = value!;
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
SizedBox(
|
|
height: 20,
|
|
width: 300,
|
|
child: TextFormField(
|
|
initialValue: _latlong,
|
|
validator: (value) {
|
|
return null;
|
|
},
|
|
onSaved: (value) {
|
|
_latlong = value!;
|
|
},
|
|
),
|
|
),
|
|
TextButton(
|
|
onPressed: () {
|
|
if (_formKey.currentState!.validate()) {
|
|
_formKey.currentState!.save();
|
|
}
|
|
},
|
|
child: Text("Save"),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
|
|
Widget weatherLayout = Column(
|
|
children: [Text(weather), CircularProgressIndicator()],
|
|
);
|
|
|
|
if (weather == loadText) {
|
|
Future.delayed(Duration(seconds: 1), () {
|
|
setState(() {
|
|
keepLoading = true;
|
|
});
|
|
});
|
|
} else {
|
|
weatherLayout = Column(
|
|
children: [
|
|
TextButton.icon(
|
|
label: Text("Reload Weather"),
|
|
onPressed: () {
|
|
setState(() {
|
|
_refreshWeather();
|
|
});
|
|
},
|
|
),
|
|
Text(weather),
|
|
],
|
|
);
|
|
}
|
|
|
|
return MaterialApp(
|
|
home: Scaffold(
|
|
body: Center(
|
|
child: Column(
|
|
children: [
|
|
Text('Weather Today!'),
|
|
form,
|
|
Expanded(child: weatherLayout),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
// Convert the Future value into a usable value.
|
|
pullWeather({
|
|
String? country,
|
|
String? zip,
|
|
String? city,
|
|
String? lat,
|
|
String? long,
|
|
}) async {
|
|
country ??= "US";
|
|
|
|
if (lat != null && long != null) {
|
|
weather = "Lat / Long Not Yet Implemented";
|
|
} else if (zip != null) {
|
|
weather = await hitOpenWeatherZip(zip, country);
|
|
} else if (city != null) {
|
|
weather = "City Weather Not Yet Implemented";
|
|
} else {
|
|
weather = "Please enter a location.";
|
|
}
|
|
|
|
if (weather.toString().contains("Sorry!")) {
|
|
return weather;
|
|
}
|
|
|
|
if (weather != loadText) {
|
|
if (debug) {
|
|
debugPrint("DEBUG: Formatting text.");
|
|
}
|
|
var weatherObject = jsonDecode(weather);
|
|
|
|
String weatherString = formatOpenWeatherData(weatherObject);
|
|
|
|
weather = weatherString;
|
|
if (debug) {
|
|
debugPrint("DEBUG: Set to formatted weather string.");
|
|
}
|
|
} else {
|
|
if (debug) {
|
|
debugPrint("DEBUG: Skipping text formatting.");
|
|
}
|
|
}
|
|
}
|
|
|
|
// Call the API and put the desired information into the screen variable.
|
|
_refreshWeather() {
|
|
var lastReloadSeconds = DateTime.now().difference(lastLoadTime).inSeconds;
|
|
if (debug) {
|
|
debugPrint("DEBUG: Refresh was '$lastReloadSeconds' seconds ago.");
|
|
}
|
|
|
|
if (lastReloadSeconds < limitRefreshSeconds) {
|
|
debugPrint("DEBUG: Skipping reload.");
|
|
// TODO / TBD: Show a toast / scaffold snackbar that it cannot reload yet,
|
|
// or change the button text to "Please wait X seconds!".
|
|
return;
|
|
}
|
|
|
|
if (debug) {
|
|
debugPrint("DEBUG: Pulling weather...");
|
|
}
|
|
weather = loadText;
|
|
pullWeather(country: "US", zip: "47630");
|
|
lastLoadTime = DateTime.now();
|
|
if (debug) {
|
|
debugPrint("DEBUG: Weather pulled and date is set.");
|
|
}
|
|
}
|
|
}
|