mirror of
https://github.com/TrentSPalmer/libre_gps_parser.git
synced 2024-11-15 19:41:30 -08:00
1275 lines
38 KiB
Dart
1275 lines
38 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'global_helper_functions.dart';
|
|
import 'package:intl/intl.dart';
|
|
import 'package:cached_network_image/cached_network_image.dart';
|
|
|
|
class Weather extends StatefulWidget {
|
|
final String weatherConditions;
|
|
final String weatherConditionsIcon;
|
|
final int weatherLocationID;
|
|
final double weatherCurrentTemp;
|
|
final double weatherCurrentPressure;
|
|
final int weatherCurrentHumidity;
|
|
final double weatherCurrentTempMin;
|
|
final double weatherCurrentTempMax;
|
|
final int weatherCurrentVisibility;
|
|
final double weatherCurrentWindSpd;
|
|
final int weatherCurrentWindDir;
|
|
final int weatherCurrentSunrise;
|
|
final int weatherCurrentSunset;
|
|
final int weatherCurrentDT;
|
|
final int timeOffSet;
|
|
final void Function() parentAction;
|
|
|
|
Weather({
|
|
Key key,
|
|
this.weatherLocationID,
|
|
this.weatherConditions,
|
|
this.weatherConditionsIcon,
|
|
this.weatherCurrentTemp,
|
|
this.weatherCurrentPressure,
|
|
this.weatherCurrentHumidity,
|
|
this.weatherCurrentTempMin,
|
|
this.weatherCurrentTempMax,
|
|
this.weatherCurrentVisibility,
|
|
this.weatherCurrentWindSpd,
|
|
this.weatherCurrentWindDir,
|
|
this.weatherCurrentSunrise,
|
|
this.weatherCurrentSunset,
|
|
this.weatherCurrentDT,
|
|
this.timeOffSet,
|
|
this.parentAction,
|
|
}) : super(key: key);
|
|
|
|
@override
|
|
_WeatherState createState() => _WeatherState();
|
|
}
|
|
|
|
class _WeatherState extends State<Weather> {
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
Map<String, String> updatedAt =
|
|
get3WayTime(widget.weatherCurrentDT, widget.timeOffSet);
|
|
Map<String, String> sunrise =
|
|
get3WayTime(widget.weatherCurrentSunrise, widget.timeOffSet);
|
|
Map<String, String> sunset =
|
|
get3WayTime(widget.weatherCurrentSunset, widget.timeOffSet);
|
|
final String windDirection = getDirection(widget.weatherCurrentWindDir);
|
|
final int visibilityMeters = getMeters(widget.weatherCurrentVisibility);
|
|
final double textHeight = 1.5;
|
|
final double _deviceWidth = MediaQuery.of(context).size.width;
|
|
final int _now = newTimeStamp();
|
|
final int _staleness = (_now - widget.weatherCurrentDT);
|
|
final bool _stale = (_staleness > 3600);
|
|
|
|
Expanded _refresh() {
|
|
return _stale
|
|
? Expanded(
|
|
flex: 4,
|
|
child: Container(
|
|
child: IconButton(
|
|
icon: Icon(Icons.refresh),
|
|
tooltip: 'refresh weather',
|
|
iconSize: 60,
|
|
color: candyApple,
|
|
onPressed: () {
|
|
widget.parentAction();
|
|
},
|
|
),
|
|
),
|
|
)
|
|
: Expanded(child: Container());
|
|
}
|
|
|
|
Expanded _staleNotice() {
|
|
return _stale
|
|
? Expanded(
|
|
flex: 6,
|
|
child: RichText(
|
|
textAlign: TextAlign.justify,
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text: 'The Current Weather Report is stale by more than ',
|
|
style: TextStyle(
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: '${(_staleness / 3600).floor()} ',
|
|
style: TextStyle(
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: 'hours',
|
|
style: TextStyle(
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
fontStyle: FontStyle.italic,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text:
|
|
'. You probably want to check your network connection and then ',
|
|
style: TextStyle(
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: 'refresh',
|
|
style: TextStyle(
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
fontStyle: FontStyle.italic,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: '.',
|
|
style: TextStyle(
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
)
|
|
: Expanded(child: Container());
|
|
}
|
|
|
|
Column _currentConditions() {
|
|
return Column(
|
|
children: <Widget>[
|
|
Text(
|
|
'Current Conditions:',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
Text(
|
|
'${weatherConditions(widget.weatherConditions)}',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 18,
|
|
),
|
|
),
|
|
RichText(
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text: 'Humidity: ',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: '${widget.weatherCurrentHumidity}%',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Column _temps() {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: <Widget>[
|
|
RichText(
|
|
// temp
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text: 'Temp: ',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: '${widget.weatherCurrentTemp.round()}\u00B0',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: 'F',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
fontStyle: FontStyle.italic,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text:
|
|
', ${(((widget.weatherCurrentTemp - 32) * 5) / 9).round()}\u00B0',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: 'C',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
fontStyle: FontStyle.italic,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
RichText(
|
|
// temp_min
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text: 'Min: ',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: '${widget.weatherCurrentTempMin.round()}\u00B0',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: 'F',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
fontStyle: FontStyle.italic,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text:
|
|
', ${(((widget.weatherCurrentTempMin - 32) * 5) / 9).round()}\u00B0',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: 'C',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
fontStyle: FontStyle.italic,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
RichText(
|
|
// temp_max
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text: 'Max: ',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: '${widget.weatherCurrentTempMax.round()}\u00B0',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: 'F',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
fontStyle: FontStyle.italic,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text:
|
|
', ${(((widget.weatherCurrentTempMax - 32) * 5) / 9).round()}\u00B0',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: 'C',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
fontStyle: FontStyle.italic,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Column _updateTime() {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: <Widget>[
|
|
Text(
|
|
'Updated at:',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
RichText(
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text: 'There: ',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: '${updatedAt['There']}',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
RichText(
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text: 'Here: ',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: '${updatedAt['Here']}',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
RichText(
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text: 'UTC: ',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: '${updatedAt['UTC']}',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Column _wind() {
|
|
return Column(
|
|
children: <Widget>[
|
|
RichText(
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text: 'Wind: ',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: '${widget.weatherCurrentWindSpd.round()}',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: 'mph',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
fontStyle: FontStyle.italic,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: ',',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
RichText(
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text: '${(widget.weatherCurrentWindSpd * 1.60934).round()}',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: 'kph',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
fontStyle: FontStyle.italic,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text:
|
|
', ${(widget.weatherCurrentWindSpd * 0.868976).round()}',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: 'knots',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
fontStyle: FontStyle.italic,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
RichText(
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text: 'From: ',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: '${widget.weatherCurrentWindDir}\u00B0, ',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: '($windDirection)',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
fontStyle: FontStyle.italic,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Column _sunRise() {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: <Widget>[
|
|
Text(
|
|
'Sunrise:',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
RichText(
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text: 'There: ',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: '${sunrise['There']}',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
RichText(
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text: 'Here: ',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: '${sunrise['Here']}',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
RichText(
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text: 'UTC: ',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: '${sunrise['UTC']}',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Column _sunSet() {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: <Widget>[
|
|
Text(
|
|
'Sunset:',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
RichText(
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text: 'There: ',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: '${sunset['There']}',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
RichText(
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text: 'Here: ',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: '${sunset['Here']}',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
RichText(
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text: 'UTC: ',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: '${sunset['UTC']}',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Column _pressure() {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: <Widget>[
|
|
RichText(
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text: 'Pressure: ',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
RichText(
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text: '${widget.weatherCurrentPressure}',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: 'mb',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
fontStyle: FontStyle.italic,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: ', ',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
RichText(
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text:
|
|
'${(widget.weatherCurrentPressure * 29.53).round() / 1000}',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: 'inHg',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
fontStyle: FontStyle.italic,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: ',',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
RichText(
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text:
|
|
'${(widget.weatherCurrentPressure * 75.0062).round() / 100}',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: 'mmHg',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
fontStyle: FontStyle.italic,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Column _visibility() {
|
|
return Column(
|
|
children: <Widget>[
|
|
Text(
|
|
'Visibility:',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
RichText(
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text: '${widget.weatherCurrentVisibility}',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: ' feet,',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
fontStyle: FontStyle.italic,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
RichText(
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text: '$visibilityMeters',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: ' meters',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
fontStyle: FontStyle.italic,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
RichText(
|
|
text: TextSpan(
|
|
children: <TextSpan>[
|
|
TextSpan(
|
|
text: 'ID: ',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: candyApple,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
TextSpan(
|
|
text: '${widget.weatherLocationID}',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
color: Colors.black,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Container _icon() {
|
|
return Container(
|
|
width: 100,
|
|
child: CachedNetworkImage(
|
|
imageUrl:
|
|
'http://openweathermap.org/img/w/${widget.weatherConditionsIcon}.png',
|
|
),
|
|
);
|
|
}
|
|
|
|
if (widget.weatherConditions == '') {
|
|
return Container(
|
|
margin: EdgeInsets.symmetric(
|
|
vertical: 3,
|
|
horizontal: 6,
|
|
),
|
|
padding: myBoxPadding,
|
|
decoration: myBoxDecoration(_stale ? Colors.grey : ivory),
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.center,
|
|
children: <Widget>[
|
|
Text(
|
|
'Check Data Connection',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
Text(
|
|
'Probably Offline',
|
|
style: TextStyle(
|
|
height: textHeight,
|
|
fontSize: 16,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
} else if (_deviceWidth < 400) {
|
|
return Container(
|
|
margin: EdgeInsets.symmetric(
|
|
vertical: 3,
|
|
horizontal: 6,
|
|
),
|
|
padding: myBoxPadding,
|
|
decoration: myBoxDecoration(_stale ? Colors.grey : ivory),
|
|
child: Column(
|
|
children: <Widget>[
|
|
Padding(
|
|
padding: EdgeInsets.only(
|
|
top: 16.0,
|
|
bottom: 2.0,
|
|
right: 25.0,
|
|
),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
|
children: <Widget>[
|
|
_refresh(),
|
|
_staleNotice(),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.symmetric(vertical: 8.0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: <Widget>[
|
|
_icon(),
|
|
_currentConditions(),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.symmetric(vertical: 8.0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: <Widget>[
|
|
_updateTime(),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.symmetric(vertical: 8.0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: <Widget>[
|
|
_temps(),
|
|
_wind(),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.symmetric(vertical: 8.0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: <Widget>[
|
|
_pressure(),
|
|
_visibility(),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.symmetric(vertical: 8.0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: <Widget>[
|
|
_sunRise(),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.symmetric(vertical: 8.0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: <Widget>[
|
|
_sunSet(),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
} else if ((_deviceWidth >= 400) && (_deviceWidth < 650)) {
|
|
return Container(
|
|
margin: EdgeInsets.symmetric(
|
|
vertical: 3,
|
|
horizontal: 6,
|
|
),
|
|
padding: myBoxPadding,
|
|
decoration: myBoxDecoration(_stale ? Colors.grey : ivory),
|
|
child: Column(
|
|
children: <Widget>[
|
|
Padding(
|
|
padding: EdgeInsets.only(
|
|
top: 16.0,
|
|
bottom: 2.0,
|
|
right: 25.0,
|
|
),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
|
children: <Widget>[
|
|
_refresh(),
|
|
_staleNotice(),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.symmetric(vertical: 8.0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: <Widget>[
|
|
_icon(),
|
|
_currentConditions(),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.symmetric(vertical: 8.0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: <Widget>[
|
|
_updateTime(),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.symmetric(vertical: 8.0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: <Widget>[
|
|
_temps(),
|
|
_wind(),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.symmetric(vertical: 8.0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: <Widget>[
|
|
_sunRise(),
|
|
_pressure(),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.symmetric(vertical: 8.0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: <Widget>[
|
|
_sunSet(),
|
|
_visibility(),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
} else if ((_deviceWidth >= 650) && (_deviceWidth < 1000)) {
|
|
return Container(
|
|
margin: EdgeInsets.symmetric(
|
|
vertical: 3,
|
|
horizontal: 6,
|
|
),
|
|
padding: myBoxPadding,
|
|
decoration: myBoxDecoration(_stale ? Colors.grey : ivory),
|
|
child: Column(
|
|
children: <Widget>[
|
|
Padding(
|
|
padding: EdgeInsets.only(
|
|
top: 16.0,
|
|
bottom: 2.0,
|
|
right: 25.0,
|
|
),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
|
children: <Widget>[
|
|
_refresh(),
|
|
_staleNotice(),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.symmetric(vertical: 8.0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: <Widget>[
|
|
_icon(),
|
|
_currentConditions(),
|
|
_temps(),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.symmetric(vertical: 8.0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: <Widget>[
|
|
_updateTime(),
|
|
_visibility(),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.symmetric(vertical: 8.0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: <Widget>[
|
|
_sunRise(),
|
|
_wind(),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.symmetric(vertical: 8.0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: <Widget>[
|
|
_sunSet(),
|
|
_pressure(),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
} else if (_deviceWidth >= 1000) {
|
|
return Container(
|
|
margin: EdgeInsets.symmetric(
|
|
vertical: 3,
|
|
horizontal: 6,
|
|
),
|
|
padding: myBoxPadding,
|
|
decoration: myBoxDecoration(_stale ? Colors.grey : ivory),
|
|
child: Column(
|
|
children: <Widget>[
|
|
Padding(
|
|
padding: EdgeInsets.only(
|
|
top: 16.0,
|
|
bottom: 2.0,
|
|
right: 25.0,
|
|
),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
|
children: <Widget>[
|
|
_refresh(),
|
|
_staleNotice(),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.symmetric(vertical: 8.0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: <Widget>[
|
|
_icon(),
|
|
_currentConditions(),
|
|
_temps(),
|
|
_visibility(),
|
|
_updateTime(),
|
|
],
|
|
),
|
|
),
|
|
Padding(
|
|
padding: EdgeInsets.symmetric(vertical: 8.0),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
children: <Widget>[
|
|
_pressure(),
|
|
_sunRise(),
|
|
_sunSet(),
|
|
_wind(),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
Map<String, String> get3WayTime(int secondsFromEpoch, int timeOffSet) {
|
|
DateTime utcTime =
|
|
DateTime.fromMillisecondsSinceEpoch(secondsFromEpoch * 1000).toUtc();
|
|
DateTime thereTime = utcTime.add(Duration(minutes: timeOffSet));
|
|
DateTime hereTime = utcTime.toLocal();
|
|
String there = (timeOffSet != 2000)
|
|
? DateFormat('EEEE MMMM d, HH:mm').format(thereTime)
|
|
: 'UNKNOWN, INVALID';
|
|
String here = DateFormat('EEEE MMMM d, HH:mm').format(hereTime);
|
|
String utc = DateFormat('EEEE MMMM d, HH:mm').format(utcTime);
|
|
return {
|
|
'There': there,
|
|
'Here': here,
|
|
'UTC': utc,
|
|
};
|
|
}
|
|
|
|
String getElapsedTimeString(int then, int now) {
|
|
final int elapsedMin = ((now - then) / 60).round();
|
|
final int elapsedHours = (elapsedMin / 60).floor();
|
|
final int remainingMin = elapsedMin % 60;
|
|
return (remainingMin < 10)
|
|
? elapsedHours.toString() + ':0' + remainingMin.toString()
|
|
: elapsedHours.toString() + ':' + remainingMin.toString();
|
|
}
|
|
|
|
int getMeters(int feet) {
|
|
return (feet != null) ? (feet * 0.3048).round() : null;
|
|
}
|
|
|
|
String getDirection(int direction) {
|
|
if ((direction < 22.5) || (direction >= 337.5)) {
|
|
return "N";
|
|
} else if ((direction >= 22.5) && (direction < 67.5)) {
|
|
return "NE";
|
|
} else if ((direction >= 67.5) && (direction < 112.5)) {
|
|
return "E";
|
|
} else if ((direction >= 112.5) && (direction < 157.5)) {
|
|
return "SE";
|
|
} else if ((direction >= 157.5) && (direction < 202.5)) {
|
|
return "S";
|
|
} else if ((direction >= 202.5) && (direction < 247.5)) {
|
|
return "SW";
|
|
} else if ((direction >= 247.5) && (direction < 292.5)) {
|
|
return "W";
|
|
} else if ((direction >= 292.5) && (direction < 337.5)) {
|
|
return "NW";
|
|
}
|
|
return "none";
|
|
}
|
|
}
|