implement share from MapQuest for Android

This commit is contained in:
Trent Palmer 2019-07-27 15:34:01 -07:00
parent 286024eb9f
commit 7e435afe20
19 changed files with 2351 additions and 2151 deletions

View File

@ -39,3 +39,9 @@ _____
* add more things to be implemented
* add input from Bing Maps, Mapquest apps
* add other elevation api server options
* include shared-prefs import/export in history import/export
## archive
* [Previous Versions of Libre Gps Parser](https://trentsonlinedocs.xyz/android_app_archive/libre_gps_parser/)
* [archive sha256sums](https://raw.githubusercontent.com/TrentSPalmer/libre_gps_parser/master/archive_sha256sums.md)

4
archive_sha256sums.md Normal file
View File

@ -0,0 +1,4 @@
153330a42f353d19443581d436b5627b6d05c87808e67a2e713ff950e5317de4 libre_gps_parser/0.1.3/armv9/app.aab
ea3f466315375d1f0eea49c0a224b36bcce8517f6ca45c6c2ed558015a97c21a libre_gps_parser/0.1.3/armv9/app-release.apk
cb45d4e5ac5f2a71ccd2ad9a2c4c081725fe2d65dd5db7a95bd196f3be70b108 libre_gps_parser/0.1.3/arm64v10/app.aab
6f145facdf75c83d42bf6ab76a3e27166eac75b0557a990634659944f031a0b9 libre_gps_parser/0.1.3/arm64v10/app-release.apk

View File

@ -22,149 +22,151 @@ InkWell aboutApp(BuildContext context) {
),
onTap: () {
showDialog(
context: context,
builder: (BuildContext context) {
final double textHeight = 1.5;
Future<void> _launchLicense() async{
AndroidIntent intent = AndroidIntent(
context: context,
builder: (BuildContext context) {
final double textHeight = 1.5;
Future<void> _launchLicense() async {
AndroidIntent intent = AndroidIntent(
action: 'action_view',
data: Uri.encodeFull('https://github.com/TrentSPalmer/libre_gps_parser/blob/master/LICENSE'),
);
await intent.launch();
}
return AlertDialog(
backgroundColor: ivory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
title: Text(
'Libre Gps Parser',
textAlign: TextAlign.center,
style: TextStyle(
color: candyApple,
data: Uri.encodeFull(
'https://github.com/TrentSPalmer/libre_gps_parser/blob/master/LICENSE'),
);
await intent.launch();
}
return AlertDialog(
backgroundColor: ivory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Flexible(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(
'Version: 0.1.2\n',
style: TextStyle(
color: candyApple,
title: Text(
'Libre Gps Parser',
textAlign: TextAlign.center,
style: TextStyle(
color: candyApple,
),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Flexible(
child: SingleChildScrollView(
child: Column(
mainAxisAlignment: MainAxisAlignment.start,
children: <Widget>[
Text(
'Version: 0.1.3\n',
style: TextStyle(
color: candyApple,
),
),
),
Text(
'The essence of Libre Gps Parser, is to parse gps coordinates from '
'a map link that you share from the Google Maps Application. '
'After that you can use the gps coordinates to make api calls for '
'weather, elevation, and timezoneoffset.\n\n'
'Parsing the gps coordinates is accomplished by getting the Google Map '
'link with an http request, and then filtering the raw text result. '
'Locally, data is cached in an sqlite database, in order to economize '
'network requests.\n\n'
'This version of the application requires that you set up an elevation '
'api server, and provide an openweathermap api key. '
'Or you can disable elevation and weather in settings.'
'',
),
Container(
margin: EdgeInsets.only(
top: 40,
bottom: 10,
Text(
'Edit: new feature, you can now share a location to Libre Gps Parser from Mapquest for Android.\n\n'
'The essence of Libre Gps Parser, is to parse gps coordinates from '
'a map link that you share from the Google Maps Application. '
'After that you can use the gps coordinates to make api calls for '
'weather, elevation, and timezoneoffset.\n\n'
'Parsing the gps coordinates is accomplished by getting the Google Map '
'link with an http request, and then filtering the raw text result. '
'Locally, data is cached in an sqlite database, in order to economize '
'network requests.\n\n'
'This version of the application requires that you set up an elevation '
'api server, and provide an openweathermap api key. '
'Or you can disable elevation and weather in settings.'
'',
),
child: Wrap(
runSpacing: 30,
alignment: WrapAlignment.center,
children: <Widget>[
Container(
margin: EdgeInsets.symmetric(
horizontal: 15,
),
child: ButtonTheme(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
Container(
margin: EdgeInsets.only(
top: 40,
bottom: 10,
),
child: Wrap(
runSpacing: 30,
alignment: WrapAlignment.center,
children: <Widget>[
Container(
margin: EdgeInsets.symmetric(
horizontal: 15,
),
height: 75,
child: RaisedButton(
color: peacockBlue,
child: Icon(
Icons.arrow_back,
size: 48.0,
color: Colors.white,
),
onPressed: () {
Navigator.of(context).pop();
}
),
),
),
Container(
margin: EdgeInsets.symmetric(
horizontal: 15,
),
child: ButtonTheme(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
height: 75,
child: RaisedButton(
color: peacockBlue,
child: Text(
"License",
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
onPressed: () {
_launchLicense();
}
),
),
),
Container(
margin: EdgeInsets.symmetric(
horizontal: 15,
),
child: ButtonTheme(
height: 75,
child: RaisedButton(
child: ButtonTheme(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
borderRadius: BorderRadius.all(
Radius.circular(6.0)),
),
color: peacockBlue,
child: Text(
"Other Licenses",
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
onPressed: () {
showLicensePage(context: context);
}
height: 75,
child: RaisedButton(
color: peacockBlue,
child: Icon(
Icons.arrow_back,
size: 48.0,
color: Colors.white,
),
onPressed: () {
Navigator.of(context).pop();
}),
),
),
),
],
Container(
margin: EdgeInsets.symmetric(
horizontal: 15,
),
child: ButtonTheme(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(6.0)),
),
height: 75,
child: RaisedButton(
color: peacockBlue,
child: Text(
"License",
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
onPressed: () {
_launchLicense();
}),
),
),
Container(
margin: EdgeInsets.symmetric(
horizontal: 15,
),
child: ButtonTheme(
height: 75,
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(6.0)),
),
color: peacockBlue,
child: Text(
"Other Licenses",
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
onPressed: () {
showLicensePage(context: context);
}),
),
),
],
),
),
),
],
],
),
),
),
),
],
),
);
}
);
],
),
);
});
},
);
}

View File

@ -29,7 +29,7 @@ class DatabaseHelper {
// is the timeOffSet automatically set by consulting teleport api
// (not manually set by spinner)
static final String columnIsAutoTimeOffset = 'isAutoTimeOffset';
static final String columnIsAutoTimeOffset = 'isAutoTimeOffset';
// make this a singleton class
DatabaseHelper._privateConstructor();
@ -47,10 +47,7 @@ class DatabaseHelper {
// this opens the database (and creates it if it doesn't exist)
_initDatabase() async {
Directory documentsDirectory = await getApplicationDocumentsDirectory();
String path = join(
documentsDirectory.path,
_databaseName
);
String path = join(documentsDirectory.path, _databaseName);
return await openDatabase(
path,
version: _databaseVersion,
@ -64,7 +61,8 @@ class DatabaseHelper {
// you can only ADD one column at a time?
Future _onUpgrade(Database db, int oldVersion, int newVersion) async {
if ((oldVersion == 1) || (oldVersion == 2)) {
await db.execute('''ALTER TABLE $table ADD $columnIsAutoTimeOffset INT''');
await db
.execute('''ALTER TABLE $table ADD $columnIsAutoTimeOffset INT''');
await db.execute('''ALTER TABLE $table ADD $columnNotes TEXT''');
} else if (oldVersion == 3) {
await db.execute('''ALTER TABLE $table ADD $columnNotes TEXT''');
@ -144,12 +142,9 @@ class DatabaseHelper {
Database db = await instance.database;
List<Map> result = await db.rawQuery(
'SELECT $columnMapLocation FROM $table ORDER BY $columnViewTime DESC LIMIT 2');
return (result.length == 2)
? result[1]['mapLocation']
: 'none';
return (result.length == 2) ? result[1]['mapLocation'] : 'none';
}
Future<List<String>> sortedMapLocations() async {
Database db = await instance.database;
var result = await db.rawQuery(
@ -255,9 +250,10 @@ class DatabaseHelper {
.delete(table, where: '$columnMapLocation = ?', whereArgs: [ml]);
}
Future<String> queryDBExport() async{
Future<String> queryDBExport() async {
Database db = await instance.database;
List<Map> result = await db.rawQuery('SELECT $columnMapLocation,$columnNotes,$columnIsAutoTimeOffset,$columnTimeOffSet FROM $table');
return(jsonEncode(result));
List<Map> result = await db.rawQuery(
'SELECT $columnMapLocation,$columnNotes,$columnIsAutoTimeOffset,$columnTimeOffSet FROM $table');
return (jsonEncode(result));
}
}

View File

@ -18,7 +18,6 @@ class EditNotes extends StatefulWidget {
}
class _EditNotesState extends State<EditNotes> {
final double textHeight = 1.5;
final _textEditingController = TextEditingController();
final dbHelper = DatabaseHelper.instance;
@ -36,82 +35,79 @@ class _EditNotesState extends State<EditNotes> {
Future<bool> _requestPop() {
if (_inputText != _oldNotes) {
showDialog(
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: ivory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'Discard your changes?',
textAlign: TextAlign.center,
),
Container(
margin: EdgeInsets.only(
top: 40,
bottom: 10,
context: context,
barrierDismissible: false,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: ivory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'Discard your changes?',
textAlign: TextAlign.center,
),
child: Wrap(
runSpacing: 30,
children: <Widget>[
Container(
margin: EdgeInsets.symmetric(
horizontal: 15,
),
child: ButtonTheme(
height: 75,
child: RaisedButton(
color: peacockBlue,
child: Text(
"No",
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
onPressed: () {
Navigator.of(context).pop();
}
Container(
margin: EdgeInsets.only(
top: 40,
bottom: 10,
),
child: Wrap(
runSpacing: 30,
children: <Widget>[
Container(
margin: EdgeInsets.symmetric(
horizontal: 15,
),
child: ButtonTheme(
height: 75,
child: RaisedButton(
color: peacockBlue,
child: Text(
"No",
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
onPressed: () {
Navigator.of(context).pop();
}),
),
),
),
Container(
margin: EdgeInsets.symmetric(
horizontal: 15,
),
child: ButtonTheme(
height: 75,
child: RaisedButton(
color: peacockBlue,
child: Text(
"Discard",
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
onPressed: () {
Navigator.of(context).pop();
Navigator.of(context).pop();
}
Container(
margin: EdgeInsets.symmetric(
horizontal: 15,
),
child: ButtonTheme(
height: 75,
child: RaisedButton(
color: peacockBlue,
child: Text(
"Discard",
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
onPressed: () {
Navigator.of(context).pop();
Navigator.of(context).pop();
}),
),
),
),
],
],
),
),
),
],
),
);
}
);
],
),
);
});
return Future.value(false);
} else {
return Future.value(true);
@ -126,20 +122,19 @@ class _EditNotesState extends State<EditNotes> {
title: const Text('Notes, MarkDown Supported'),
actions: <Widget>[
IconButton(
icon: Icon(Icons.save),
onPressed: () async{
Navigator.of(context).pop(this._inputText);
Map<String, dynamic> row = {
DatabaseHelper.columnMapLocation: widget.mapLocation,
DatabaseHelper.columnNotes: this._inputText,
};
await dbHelper.update(row);
}
),
icon: Icon(Icons.save),
onPressed: () async {
Navigator.of(context).pop(this._inputText);
Map<String, dynamic> row = {
DatabaseHelper.columnMapLocation: widget.mapLocation,
DatabaseHelper.columnNotes: this._inputText,
};
await dbHelper.update(row);
}),
],
),
body: Column(
children: <Widget> [
children: <Widget>[
Expanded(
child: TextField(
controller: _textEditingController,
@ -151,7 +146,7 @@ class _EditNotesState extends State<EditNotes> {
),
),
Row(
children: <Widget> [
children: <Widget>[
Expanded(
child: Container(),
),
@ -160,155 +155,185 @@ class _EditNotesState extends State<EditNotes> {
child: ButtonTheme(
height: 55,
padding: EdgeInsets.only(
top: 5,
right: 12,
bottom: 12,
left: 10
),
top: 5, right: 12, bottom: 12, left: 10),
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
color: peacockBlue,
child: Text(
'Import',
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
),
onPressed: () async{
Map<PermissionGroup, PermissionStatus> _storagePermissions;
PermissionStatus _storagePermission = await PermissionHandler().checkPermissionStatus(PermissionGroup.storage);
if (_storagePermission == PermissionStatus.denied) {
_storagePermissions = await PermissionHandler().requestPermissions([PermissionGroup.storage]);
}
if ((_storagePermission == PermissionStatus.granted) || (_storagePermissions.toString() == PermissionStatus.granted.toString())) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: ivory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
title: Text(
'You can import a markdown (or plain text) file.',
textAlign: TextAlign.center,
style: TextStyle(
color: candyApple,
),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
margin: EdgeInsets.only(
top: 40,
bottom: 10,
),
child: ButtonTheme(
height: 55,
padding: EdgeInsets.only(
top: 5,
right: 12,
bottom: 12,
left: 10
),
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
color: peacockBlue,
child: Text(
'Select File',
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
onPressed: () async{
String _filePath;
_filePath = await FilePicker.getFilePath(type: FileType.ANY);
Navigator.of(context).pop();
try {
String _contents = await File(_filePath).readAsString();
setState(() {
this._textEditingController.text = _contents;
this._inputText = _contents;
});
} catch(e) {
print(e);
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: ivory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
title: Text(
'Oops, something went wrong',
textAlign: TextAlign.center,
style: TextStyle(
color: candyApple,
),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
margin: EdgeInsets.only(
top: 40,
bottom: 10,
),
child: ButtonTheme(
height: 55,
padding: EdgeInsets.only(
top: 5,
right: 12,
bottom: 12,
left: 10
),
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
color: peacockBlue,
child: Text(
'OK',
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
onPressed: () async{
Navigator.of(context).pop();
}
),
),
),
],
),
);
}
);
}
}
),
color: peacockBlue,
child: Text(
'Import',
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
onPressed: () async {
Map<PermissionGroup, PermissionStatus>
_storagePermissions;
PermissionStatus _storagePermission =
await PermissionHandler().checkPermissionStatus(
PermissionGroup.storage);
if (_storagePermission == PermissionStatus.denied) {
_storagePermissions = await PermissionHandler()
.requestPermissions([PermissionGroup.storage]);
}
if ((_storagePermission ==
PermissionStatus.granted) ||
(_storagePermissions.toString() ==
PermissionStatus.granted.toString())) {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: ivory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(6.0)),
),
title: Text(
'You can import a markdown (or plain text) file.',
textAlign: TextAlign.center,
style: TextStyle(
color: candyApple,
),
),
],
),
);
}
);
}
}
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
margin: EdgeInsets.only(
top: 40,
bottom: 10,
),
child: ButtonTheme(
height: 55,
padding: EdgeInsets.only(
top: 5,
right: 12,
bottom: 12,
left: 10),
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.all(
Radius.circular(6.0)),
),
color: peacockBlue,
child: Text(
'Select File',
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
onPressed: () async {
String _filePath;
_filePath = await FilePicker
.getFilePath(
type: FileType.ANY);
Navigator.of(context).pop();
try {
String _contents =
await File(_filePath)
.readAsString();
setState(() {
this
._textEditingController
.text = _contents;
this._inputText =
_contents;
});
} catch (e) {
print(e);
showDialog(
context: context,
builder: (BuildContext
context) {
return AlertDialog(
backgroundColor:
ivory,
shape:
RoundedRectangleBorder(
borderRadius: BorderRadius
.all(Radius
.circular(
6.0)),
),
title: Text(
'Oops, something went wrong',
textAlign:
TextAlign
.center,
style: TextStyle(
color:
candyApple,
),
),
content: Column(
mainAxisSize:
MainAxisSize
.min,
children: <
Widget>[
Container(
margin:
EdgeInsets
.only(
top: 40,
bottom: 10,
),
child:
ButtonTheme(
height: 55,
padding: EdgeInsets.only(
top: 5,
right:
12,
bottom:
12,
left:
10),
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.all(Radius.circular(6.0)),
),
color: peacockBlue,
child: Text(
'OK',
style:
TextStyle(
height:
textHeight,
color:
Colors.white,
fontSize:
24,
),
),
onPressed: () async {
Navigator.of(context)
.pop();
}),
),
),
],
),
);
});
}
}),
),
),
],
),
);
});
}
}),
),
),
],
@ -319,7 +344,7 @@ class _EditNotesState extends State<EditNotes> {
);
}
Future<void> loadNotes() async{
Future<void> loadNotes() async {
String _notes = await dbHelper.queryNotes(widget.mapLocation);
setState(() {
_oldNotes = _notes;

View File

@ -66,90 +66,90 @@ InkWell elevAtion(BuildContext context, int elevation, int feetElevation) {
),
onTap: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: ivory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'You have to set up an Open-Elevation Api Server, and specify this in '
'settings. The instructions are a little bit out-dated, but it\'s not '
'too difficult to muddle through and set something up on a vps or '
'RaspberryPi or whatever.\n\n'
'A \$5 Digital Ocean Droplet doesn\'t have enough disk space, but '
'a \$5 LightSail instance does.',
textAlign: TextAlign.center,
),
Container(
margin: EdgeInsets.only(
top: 40,
bottom: 10,
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: ivory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'You have to set up an Open-Elevation Api Server, and specify this in '
'settings. The instructions are a little bit out-dated, but it\'s not '
'too difficult to muddle through and set something up on a vps or '
'RaspberryPi or whatever.\n\n'
'A \$5 Digital Ocean Droplet doesn\'t have enough disk space, but '
'a \$5 LightSail instance does.',
textAlign: TextAlign.center,
),
child: ButtonTheme(
height: 75,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
Container(
margin: EdgeInsets.only(
top: 40,
bottom: 10,
),
child: RaisedButton(
color: peacockBlue,
child: Column(
children: <Widget>[
Container(
width: 150,
margin: EdgeInsets.only(
top: 10,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Text(
'github',
child: ButtonTheme(
height: 75,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
child: RaisedButton(
color: peacockBlue,
child: Column(
children: <Widget>[
Container(
width: 150,
margin: EdgeInsets.only(
top: 10,
),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: <Widget>[
Text(
'github',
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
Icon(
Icons.open_in_browser,
size: 48,
color: Colors.white,
),
],
),
),
Container(
margin: EdgeInsets.only(
bottom: 15,
),
child: Text(
'open-elevation',
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
Icon(
Icons.open_in_browser,
size: 48,
color: Colors.white,
),
],
),
),
Container(
margin: EdgeInsets.only(
bottom: 15,
),
child: Text(
'open-elevation',
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
],
),
],
),
onPressed: () {
Navigator.of(context).pop();
urlLaunch('https://github.com/Jorl17/open-elevation/blob/master/docs/host-your-own.md');
}
onPressed: () {
Navigator.of(context).pop();
urlLaunch(
'https://github.com/Jorl17/open-elevation/blob/master/docs/host-your-own.md');
}),
),
),
),
],
),
);
}
);
],
),
);
});
},
);
}

View File

@ -33,12 +33,13 @@ Future<List<int>> refreshTimeOffSet(String mapLocation, String latLong) async {
try {
responseJson = jsonDecode(response.body);
offSetMin = responseJson['_embedded']['location:nearest-cities'][0]
['_embedded']['location:nearest-city']['_embedded']
['city:timezone']['_embedded']['tz:offsets-now']
['total_offset_min'] ??
2000;
['_embedded']['location:nearest-city']['_embedded']
['city:timezone']['_embedded']['tz:offsets-now']
['total_offset_min'] ??
2000;
} catch (e) {
print('$e in source file global_helper_functions.dart.getTimeOffSet, can\'t assign Map<String, dynamic> responseJson');
print(
'$e in source file global_helper_functions.dart.getTimeOffSet, can\'t assign Map<String, dynamic> responseJson');
}
Map<String, dynamic> row = {
DatabaseHelper.columnMapLocation: mapLocation,
@ -58,7 +59,7 @@ Future<List<int>> refreshTimeOffSet(String mapLocation, String latLong) async {
}
}
Future<List<int>> getTimeOffSet(String mapLocation, String latLong) async{
Future<List<int>> getTimeOffSet(String mapLocation, String latLong) async {
final dbHelper = DatabaseHelper.instance;
final int _timeStamp = newTimeStamp();
int timeOffSetTime = await dbHelper.queryTimeOffSetTime(mapLocation);
@ -80,12 +81,13 @@ Future<List<int>> getTimeOffSet(String mapLocation, String latLong) async{
try {
responseJson = jsonDecode(response.body);
offSetMin = responseJson['_embedded']['location:nearest-cities'][0]
['_embedded']['location:nearest-city']['_embedded']
['city:timezone']['_embedded']['tz:offsets-now']
['total_offset_min'] ??
2000;
['_embedded']['location:nearest-city']['_embedded']
['city:timezone']['_embedded']['tz:offsets-now']
['total_offset_min'] ??
2000;
} catch (e) {
print('$e in source file global_helper_functions.dart.getTimeOffSet, can\'t assign Map<String, dynamic> responseJson');
print(
'$e in source file global_helper_functions.dart.getTimeOffSet, can\'t assign Map<String, dynamic> responseJson');
}
Map<String, dynamic> row = {
DatabaseHelper.columnMapLocation: mapLocation,
@ -132,7 +134,9 @@ Future<String> getWeather(
Response response = await get(weatherApiUrl);
if (response.statusCode == 200) {
Map<String, dynamic> responseJson = jsonDecode(response.body);
weatherID = (responseJson['id'] != 0) ? responseJson['id'] : generateFakeWeatherId(lattLong);
weatherID = (responseJson['id'] != 0)
? responseJson['id']
: generateFakeWeatherId(lattLong);
Map<String, dynamic> row = {
DatabaseHelper.columnMapLocation: mapLocation,
DatabaseHelper.columnWeatherID: weatherID
@ -150,8 +154,9 @@ Future<String> getWeather(
}
return response.body;
}
} catch(e) {
print('$e, can\'t connect to openweathermap in global_helper_functions');
} catch (e) {
print(
'$e, can\'t connect to openweathermap in global_helper_functions');
weatherID ??= generateFakeWeatherId(lattLong); // assign if null
String weather = await dbHelper.queryWeather(weatherID);
return weather ?? 'NA';
@ -178,7 +183,9 @@ Future<String> getWeatherForeCast(
weatherID = generateFakeWeatherId(lattLong);
}
int weatherIDExists = await dbHelper.queryWeatherIDExists(weatherID);
if (weatherIDExists == 0) { stale = true; }
if (weatherIDExists == 0) {
stale = true;
}
if ((weatherID == null) || (stale == true)) {
List<String> latLong = lattLong.split(',');
String weatherForeCastApiUrl;
@ -190,11 +197,11 @@ Future<String> getWeatherForeCast(
'${weatherForecastApiUrlPrefix}id=$weatherID&units=imperial&appid=$weatherApiID';
}
try {
Response response = await get(weatherForeCastApiUrl);
Response response = await get(weatherForeCastApiUrl);
if (response.statusCode == 200) {
Map<String, dynamic> responseJson = jsonDecode(response.body);
weatherID = responseJson['city']['id'];
weatherID ??= generateFakeWeatherId(lattLong); // assign if null
weatherID ??= generateFakeWeatherId(lattLong); // assign if null
Map<String, dynamic> row = {
DatabaseHelper.columnMapLocation: mapLocation,
DatabaseHelper.columnWeatherID: weatherID
@ -212,8 +219,9 @@ Future<String> getWeatherForeCast(
}
return response.body;
}
} catch(e) {
print('$e, probably cant connect to openweathermap... no network connection? global_helper_functions.getWeatherForeCast');
} catch (e) {
print(
'$e, probably cant connect to openweathermap... no network connection? global_helper_functions.getWeatherForeCast');
weatherID ??= generateFakeWeatherId(lattLong); // assign if null
String weatherForeCast = await dbHelper.queryWeatherForeCast(weatherID);
return (weatherForeCast);
@ -249,18 +257,39 @@ int newTimeStamp() {
}
Future<String> parseMapUrl(String mapUrl) async {
try {
Response response = await get(mapUrl);
RegExp gmapUrl = RegExp(
r'https://www.google.com/(maps/preview)/(place)/([^/]*)/([^/]*)/data');
String mapInfo = response.body;
Match match = gmapUrl.firstMatch(mapInfo);
String subMapInfo = match.group(4);
RegExp subGmapUrl = RegExp(r'@([^,]*,[^,]*),([^,]*,[^,]*)');
Match subMatch = subGmapUrl.firstMatch(subMapInfo);
return subMatch.group(1);
} catch(e) {
print('$e can\'t connect to internet in global_helper_functions.parseMapUrl');
if (mapUrl.contains('mapq.st')) {
try {
Response response = await get(mapUrl);
String mapInfo = response.body;
RegExp _latExp = RegExp(
r'(<meta)\s*(property="place:location:latitude")\s*(content=")(.+)"\s*(/>)');
Match _latMatch = _latExp.firstMatch(mapInfo);
RegExp _longExp = RegExp(
r'(<meta)\s*(property="place:location:longitude")\s*(content=")(.+)"\s*(/>)');
Match _longMatch = _longExp.firstMatch(mapInfo);
String result = _latMatch.group(4) + ',' + _longMatch.group(4);
return (result);
} catch (e) {
print(
'$e can\'t connect to internet in global_helper_functions.parseMapUrl');
}
} else if ((mapUrl.contains('maps.google')) ||
(mapUrl.contains('maps.app.goo.gl'))) {
try {
Response response = await get(mapUrl);
RegExp gmapUrl = RegExp(
r'https://www.google.com/(maps/preview)/(place)/([^/]*)/([^/]*)/data');
String mapInfo = response.body;
Match match = gmapUrl.firstMatch(mapInfo);
String subMapInfo = match.group(4);
RegExp subGmapUrl = RegExp(r'@([^,]*,[^,]*),([^,]*,[^,]*)');
Match subMatch = subGmapUrl.firstMatch(subMapInfo);
String result = subMatch.group(1);
return (result);
} catch (e) {
print(
'$e can\'t connect to internet in global_helper_functions.parseMapUrl');
}
}
}
@ -300,8 +329,9 @@ String convertCoordinates(String latNLong) {
String gpsDMS =
lat[0] + '\u00B0 ' + latMinSec + ',' + long[0] + '\u00B0 ' + longMinSec;
return gpsDMS;
} catch(e) {
print('$e in source file global_helper_functions.convertCoordinates, function parameter probably not a valid latNLong string');
} catch (e) {
print(
'$e in source file global_helper_functions.convertCoordinates, function parameter probably not a valid latNLong string');
}
}
@ -314,19 +344,20 @@ String getMinSec(String numString) {
return minSecs;
}
String weatherConditions(String weatherConditions) {
int numSpaces = (' '.allMatches(weatherConditions)).length;
if (numSpaces > 1) {
int firstSpace = weatherConditions.indexOf(' ');
int secondSpace = (weatherConditions.indexOf(' ', firstSpace + 1));
return weatherConditions.replaceRange(secondSpace, (secondSpace + 1), '\n').toUpperCase();
return weatherConditions
.replaceRange(secondSpace, (secondSpace + 1), '\n')
.toUpperCase();
} else {
return weatherConditions.toUpperCase();
}
}
Future<void> urlLaunch(String url) async{
Future<void> urlLaunch(String url) async {
if (await canLaunch(url)) {
await launch(url);
} else {
@ -338,7 +369,8 @@ int generateFakeWeatherId(String latLong) {
List<String> _latLongParts = latLong.split(',');
List<String> _shortLat = _latLongParts[0].split('.');
List<String> _shortLong = _latLongParts[1].split('.');
String _fakeIDString = _shortLat[0].replaceFirst('-','8') + _shortLong[0].replaceFirst('-','8');
String _fakeIDString = _shortLat[0].replaceFirst('-', '8') +
_shortLong[0].replaceFirst('-', '8');
// you know a weatherID is fake because it is less than zero
return (0 - int.parse(_fakeIDString));
}
@ -394,8 +426,11 @@ Future<bool> setPreferenceUseWeather(bool useWeather) async {
Future<String> getPreferenceDBExportFileName() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String dbExportFileName = prefs.getString("dbExportFileName") ?? "libre_gps_parser.json";
return (dbExportFileName.length > 0) ? dbExportFileName : "libre_gps_parser.json";
String dbExportFileName =
prefs.getString("dbExportFileName") ?? "libre_gps_parser.json";
return (dbExportFileName.length > 0)
? dbExportFileName
: "libre_gps_parser.json";
}
Future<bool> setPreferenceDBExportFileName(String dbExportFileName) async {
@ -410,19 +445,21 @@ Future<bool> importDataBase(String importString) {
List<dynamic> _importJson = jsonDecode(importString);
int _importJsonLength = _importJson.length;
for (int i = 0; i < _importJsonLength; i++) {
dbHelper.queryRowExists(_importJson[i]['mapLocation']).then((int rowExists) {
dbHelper
.queryRowExists(_importJson[i]['mapLocation'])
.then((int rowExists) {
if (rowExists == 0) {
Map<String, dynamic> row = {
DatabaseHelper.columnMapLocation: _importJson[i]['mapLocation'],
};
if (_importJson[i]['notes'] != null) {
row['notes'] = _importJson[i]['notes'];
}
}
if (_importJson[i]['isAutoTimeOffset'] == 0) {
row['timeOffSet'] = _importJson[i]['timeOffSet'];
row['timeOffSetTime'] = _timeStamp;
row['isAutoTimeOffset'] = _importJson[i]['isAutoTimeOffset'];
}
}
dbHelper.insert(row);
}
});

View File

@ -6,17 +6,16 @@ import 'package:share/share.dart';
final double textHeight = 1.5;
Row lnlDec(String latnLong) {
Future<void> _launchLnL() async{
Future<void> _launchLnL() async {
AndroidIntent intent = AndroidIntent(
action: 'action_view',
data: Uri.encodeFull('geo:$latnLong?z=12'),
package: 'com.google.android.apps.maps',
action: 'action_view',
data: Uri.encodeFull('geo:$latnLong?z=12'),
package: 'com.google.android.apps.maps',
);
await intent.launch();
}
List<String> _latNLong = ['x','y'];
List<String> _latNLong = ['x', 'y'];
if ((latnLong == 'none') || (latnLong == null)) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
@ -125,5 +124,3 @@ Row lnlDec(String latnLong) {
);
}
}

View File

@ -5,7 +5,7 @@ import 'package:share/share.dart';
final double textHeight = 1.5;
Row lnlDeg(String latnLongDMS) {
List<String> _latNLong = ['x','y'];
List<String> _latNLong = ['x', 'y'];
if ((latnLongDMS == 'none') || (latnLongDMS == null)) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
@ -60,7 +60,7 @@ Row lnlDeg(String latnLongDMS) {
),
],
);
} else {
} else {
_latNLong = latnLongDMS.split(',');
return Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,

View File

@ -18,31 +18,31 @@ class _LocationState extends State<Location> {
@override
Widget build(BuildContext context) {
final double textHeight = 1.5;
List<String> locationStringList = _getlocationStringList(widget.mapLocation);
List<String> locationStringList =
_getlocationStringList(widget.mapLocation);
Future<void> _launchUrl() async{
Future<void> _launchUrl() async {
AndroidIntent intent = AndroidIntent(
action: 'action_view',
data: Uri.encodeFull(locationStringList[locationStringList.length - 1]),
action: 'action_view',
data: Uri.encodeFull(locationStringList[locationStringList.length - 1]),
);
await intent.launch();
}
List<Container> createLocation(List<String> location) {
return location.map((line) {
line = (line.length < 25) ? line :
(line.substring(0,20) + '.....' );
return Container(
child: Text(
line,
style: TextStyle(
height: textHeight,
fontSize: 16.0,
),
),
);
}).toList();
}
return location.map((line) {
line = (line.length < 25) ? line : (line.substring(0, 20) + '.....');
return Container(
child: Text(
line,
style: TextStyle(
height: textHeight,
fontSize: 16.0,
),
),
);
}).toList();
}
try {
return Row(
@ -55,23 +55,23 @@ class _LocationState extends State<Location> {
iconSize: 48,
onPressed: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: ivory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
title: Text(
'Sharing Options',
textAlign: TextAlign.center,
style: TextStyle(
color: candyApple,
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: ivory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
),
content: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
title: Text(
'Sharing Options',
textAlign: TextAlign.center,
style: TextStyle(
color: candyApple,
),
),
content: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
IconButton(
icon: Icon(Icons.share),
tooltip: 'share link to another app',
@ -81,20 +81,19 @@ class _LocationState extends State<Location> {
Share.share(widget.mapLocation);
},
),
IconButton(
icon: Icon(Icons.map),
tooltip: 'share link to maps',
iconSize: 48,
onPressed: () {
Navigator.of(context).pop();
_launchUrl();
},
),
],
),
);
}
);
IconButton(
icon: Icon(Icons.map),
tooltip: 'share link to maps',
iconSize: 48,
onPressed: () {
Navigator.of(context).pop();
_launchUrl();
},
),
],
),
);
});
},
),
),
@ -107,59 +106,58 @@ class _LocationState extends State<Location> {
),
onTap: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: ivory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: ivory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
margin: EdgeInsets.only(
bottom: 25,
),
child: Text(
widget.mapLocation,
textAlign: TextAlign.center,
),
),
RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
color: peacockBlue,
child: Container(
margin: EdgeInsets.only(
top: 12,
bottom: 20,
),
child: Text(
'ok',
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
widget.mapLocation,
textAlign: TextAlign.center,
),
),
onPressed: () {
Navigator.of(context).pop();
}
),
],
),
);
}
);
RaisedButton(
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.all(Radius.circular(6.0)),
),
color: peacockBlue,
child: Container(
margin: EdgeInsets.only(
top: 12,
bottom: 20,
),
child: Text(
'ok',
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
),
onPressed: () {
Navigator.of(context).pop();
}),
],
),
);
});
},
),
),
],
);
} catch(e) {
} catch (e) {
print('$e, probably could not call createLocation(locationStringList)');
return Wrap(
spacing: 20.0,
@ -170,7 +168,6 @@ class _LocationState extends State<Location> {
),
],
);
}
}
@ -178,34 +175,36 @@ class _LocationState extends State<Location> {
List<String> stringList;
try {
stringList = mapLocation.split('\n');
} catch(e) {
print('$e in source file location.dart._getlocationStringList::first_try');
} catch (e) {
print(
'$e in source file location.dart._getlocationStringList::first_try');
}
if (stringList.length < 2) {
return ['','pending...',''];
return ['', 'pending...', ''];
} else {
try {
if (stringList[1].contains(stringList[0])) {
stringList.removeAt(0);
}
} catch(e) {
print('$e in source file location.dart._getlocationStringList::second_try');
} catch (e) {
print(
'$e in source file location.dart._getlocationStringList::second_try');
}
// split up long address lines on the second to last comma
for (int i=0; i<stringList.length; i++) {
for (int i = 0; i < stringList.length; i++) {
int numCommas = (','.allMatches(stringList[i])).length;
if (numCommas > 1) {
String currentLine = stringList[i];
stringList.removeAt(i);
int commaCount = 0;
for (int j=0; j<currentLine.length; j++) {
for (int j = 0; j < currentLine.length; j++) {
if (currentLine[j] == ',') {
commaCount += 1;
if (commaCount == (numCommas -1)) {
String firstHalf = currentLine.substring(0,j+1);
String secondHalf = currentLine.substring(j+2);
if (commaCount == (numCommas - 1)) {
String firstHalf = currentLine.substring(0, j + 1);
String secondHalf = currentLine.substring(j + 2);
stringList.insert(i, firstHalf);
stringList.insert(i+1, secondHalf);
stringList.insert(i + 1, secondHalf);
}
}
}

View File

@ -42,7 +42,8 @@ class _LatNLongState extends State<LatNLong> {
final dbHelper = DatabaseHelper.instance;
static const platform = const MethodChannel('app.channel.shared.data');
// "static" variables are hard-coded into the class rather than instances
static RegExp gmapExp = RegExp(r'(https://maps.app.goo.gl/|https://maps.google.com/)(.*$)');
static RegExp mapExp = RegExp(
r'(https://maps.app.goo.gl/|https://maps.google.com/|https?://mapq.st/)(.*$)');
String widgetMapLocation = "none";
String latnLong = "none";
String latnLongDMS = "none";
@ -83,11 +84,10 @@ class _LatNLongState extends State<LatNLong> {
Widget _timezone() {
return TimeZone(
parentAction: this._userTzOffset,
timeOffSet: this.timeOffSet,
timeOffSetTime: this.timeOffSetTime,
isAutoTimeOffSet: this.isAutoTimeOffSet
);
parentAction: this._userTzOffset,
timeOffSet: this.timeOffSet,
timeOffSetTime: this.timeOffSetTime,
isAutoTimeOffSet: this.isAutoTimeOffSet);
}
InkWell _delete() {
@ -104,98 +104,97 @@ class _LatNLongState extends State<LatNLong> {
),
onTap: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: ivory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
title: Text(
'Really?',
textAlign: TextAlign.center,
style: TextStyle(
color: candyApple,
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: ivory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'Delete this location from',
textAlign: TextAlign.center,
title: Text(
'Really?',
textAlign: TextAlign.center,
style: TextStyle(
color: candyApple,
),
Text(
'the face of the earth forever?',
textAlign: TextAlign.center,
),
Container(
margin: EdgeInsets.only(
top: 40,
bottom: 10,
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'Delete this location from',
textAlign: TextAlign.center,
),
child: Wrap(
runSpacing: 30,
children: <Widget>[
Container(
margin: EdgeInsets.symmetric(
horizontal: 15,
),
child: ButtonTheme(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
Text(
'the face of the earth forever?',
textAlign: TextAlign.center,
),
Container(
margin: EdgeInsets.only(
top: 40,
bottom: 10,
),
child: Wrap(
runSpacing: 30,
children: <Widget>[
Container(
margin: EdgeInsets.symmetric(
horizontal: 15,
),
height: 75,
child: RaisedButton(
color: peacockBlue,
child: Text(
"launch iCBMs!",
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
onPressed: () {
Navigator.of(context).pop();
_deleteLocation();
}
),
),
),
Container(
margin: EdgeInsets.symmetric(
horizontal: 15,
),
child: ButtonTheme(
height: 75,
child: RaisedButton(
child: ButtonTheme(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
borderRadius:
BorderRadius.all(Radius.circular(6.0)),
),
color: peacockBlue,
child: Text(
"oops! nvrmnd!",
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
onPressed: () {
Navigator.of(context).pop();
}
height: 75,
child: RaisedButton(
color: peacockBlue,
child: Text(
"launch iCBMs!",
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
onPressed: () {
Navigator.of(context).pop();
_deleteLocation();
}),
),
),
),
],
Container(
margin: EdgeInsets.symmetric(
horizontal: 15,
),
child: ButtonTheme(
height: 75,
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(6.0)),
),
color: peacockBlue,
child: Text(
"oops! nvrmnd!",
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
onPressed: () {
Navigator.of(context).pop();
}),
),
),
],
),
),
),
],
),
);
}
);
],
),
);
});
},
);
}
@ -216,10 +215,13 @@ class _LatNLongState extends State<LatNLong> {
),
],
),
onTap: () async{
onTap: () async {
String _noteText = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => EditNotes(mapLocation: this.widgetMapLocation,)),
MaterialPageRoute(
builder: (context) => EditNotes(
mapLocation: this.widgetMapLocation,
)),
);
if ((_noteText != null) && (_noteText != this.notes)) {
setState(() {
@ -229,37 +231,42 @@ class _LatNLongState extends State<LatNLong> {
},
),
),
((this.notes.length > 0) ? Expanded(
flex: 5,
child: Container(
decoration: BoxDecoration(
border: Border(
left: BorderSide(
width: 1.0,
color: Colors.black,
),
),
),
child: InkWell(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.view_agenda,
size: 48.0,
color: Colors.black,
((this.notes.length > 0)
? Expanded(
flex: 5,
child: Container(
decoration: BoxDecoration(
border: Border(
left: BorderSide(
width: 1.0,
color: Colors.black,
),
),
),
],
),
onTap: () async{
await Navigator.push(
context,
MaterialPageRoute(builder: (context) => RenderNotes(notes: this.notes,)),
);
},
),
),
) : Container()),
child: InkWell(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Icon(
Icons.view_agenda,
size: 48.0,
color: Colors.black,
),
],
),
onTap: () async {
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => RenderNotes(
notes: this.notes,
)),
);
},
),
),
)
: Container()),
],
);
}
@ -268,7 +275,7 @@ class _LatNLongState extends State<LatNLong> {
if (_deviceShortestSide < 400) {
return Container(
child: Column(
children: <Widget>[
children: <Widget>[
Container(
margin: EdgeInsets.only(
left: 6,
@ -278,7 +285,9 @@ class _LatNLongState extends State<LatNLong> {
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: (this.latnLong != null) ? lnlDec(this.latnLong) : lnlDec('none') ,
child: (this.latnLong != null)
? lnlDec(this.latnLong)
: lnlDec('none'),
),
IntrinsicHeight(
child: Row(
@ -294,7 +303,9 @@ class _LatNLongState extends State<LatNLong> {
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: (this.latnLongDMS != null) ? lnlDeg(this.latnLongDMS) : lnlDeg('none'),
child: (this.latnLongDMS != null)
? lnlDeg(this.latnLongDMS)
: lnlDeg('none'),
),
),
],
@ -314,7 +325,7 @@ class _LatNLongState extends State<LatNLong> {
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: _editNotes(),
child: _editNotes(),
),
),
Expanded(
@ -328,7 +339,7 @@ class _LatNLongState extends State<LatNLong> {
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: streetView(this.latnLong),
child: streetView(this.latnLong),
),
),
],
@ -370,23 +381,26 @@ class _LatNLongState extends State<LatNLong> {
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: aboutApp(context),
child: aboutApp(context),
),
),
((this._useElev) ? Expanded(
flex: 4,
child: Container(
margin: EdgeInsets.only(
left: 3,
top: 3,
right: 3,
bottom: 3,
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: elevAtion(context, this.elevation, this.feetElevation),
),
) : Container()),
((this._useElev)
? Expanded(
flex: 4,
child: Container(
margin: EdgeInsets.only(
left: 3,
top: 3,
right: 3,
bottom: 3,
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: elevAtion(
context, this.elevation, this.feetElevation),
),
)
: Container()),
Expanded(
flex: 3,
child: Container(
@ -398,7 +412,7 @@ class _LatNLongState extends State<LatNLong> {
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: _delete(),
child: _delete(),
),
),
],
@ -407,20 +421,22 @@ class _LatNLongState extends State<LatNLong> {
IntrinsicHeight(
child: Row(
children: <Widget>[
((this._useWTHR) ? Expanded(
flex: 7,
child: Container(
margin: EdgeInsets.only(
left: 6,
top: 3,
right: 6,
bottom: 3,
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: _timezone(),
),
) : Container()),
((this._useWTHR)
? Expanded(
flex: 7,
child: Container(
margin: EdgeInsets.only(
left: 6,
top: 3,
right: 6,
bottom: 3,
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: _timezone(),
),
)
: Container()),
],
),
),
@ -430,7 +446,7 @@ class _LatNLongState extends State<LatNLong> {
} else if ((_deviceShortestSide >= 400) && (_deviceShortestSide < 650)) {
return Container(
child: Column(
children: <Widget>[
children: <Widget>[
IntrinsicHeight(
child: Row(
children: <Widget>[
@ -445,7 +461,9 @@ class _LatNLongState extends State<LatNLong> {
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: (this.latnLongDMS != null) ? lnlDeg(this.latnLongDMS) : lnlDeg('none'),
child: (this.latnLongDMS != null)
? lnlDeg(this.latnLongDMS)
: lnlDeg('none'),
),
),
Expanded(
@ -459,7 +477,7 @@ class _LatNLongState extends State<LatNLong> {
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: _delete(),
child: _delete(),
),
),
],
@ -474,7 +492,9 @@ class _LatNLongState extends State<LatNLong> {
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: (this.latnLong != null) ? lnlDec(this.latnLong) : lnlDec('none') ,
child: (this.latnLong != null)
? lnlDec(this.latnLong)
: lnlDec('none'),
),
IntrinsicHeight(
child: Row(
@ -490,7 +510,7 @@ class _LatNLongState extends State<LatNLong> {
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: _editNotes(),
child: _editNotes(),
),
),
Expanded(
@ -504,7 +524,7 @@ class _LatNLongState extends State<LatNLong> {
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: streetView(this.latnLong),
child: streetView(this.latnLong),
),
),
],
@ -540,7 +560,7 @@ class _LatNLongState extends State<LatNLong> {
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: aboutApp(context),
child: aboutApp(context),
),
),
],
@ -549,34 +569,39 @@ class _LatNLongState extends State<LatNLong> {
IntrinsicHeight(
child: Row(
children: <Widget>[
((this._useElev) ? Expanded(
flex: 3,
child: Container(
margin: EdgeInsets.only(
left: 6,
top: 3,
right: (this._useWTHR) ? 3 : 6,
bottom: 3,
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: elevAtion(context, this.elevation, this.feetElevation),
),
) : Container()),
((this._useWTHR) ? Expanded(
flex: 7,
child: Container(
margin: EdgeInsets.only(
left: (this._useElev) ? 3 : 6,
top: 3,
right: 6,
bottom: 3,
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: _timezone(),
),
) : Container()),
((this._useElev)
? Expanded(
flex: 3,
child: Container(
margin: EdgeInsets.only(
left: 6,
top: 3,
right: (this._useWTHR) ? 3 : 6,
bottom: 3,
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: elevAtion(
context, this.elevation, this.feetElevation),
),
)
: Container()),
((this._useWTHR)
? Expanded(
flex: 7,
child: Container(
margin: EdgeInsets.only(
left: (this._useElev) ? 3 : 6,
top: 3,
right: 6,
bottom: 3,
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: _timezone(),
),
)
: Container()),
],
),
),
@ -586,7 +611,7 @@ class _LatNLongState extends State<LatNLong> {
} else if (_deviceShortestSide >= 650) {
return Container(
child: Column(
children: <Widget>[
children: <Widget>[
IntrinsicHeight(
child: Row(
children: <Widget>[
@ -601,21 +626,23 @@ class _LatNLongState extends State<LatNLong> {
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: _editNotes(),
child: _editNotes(),
),
),
Expanded(
flex: 5,
child: Container(
margin: EdgeInsets.only(
left: 3,
top: 6,
right: 3,
bottom: 3,
left: 3,
top: 6,
right: 3,
bottom: 3,
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: (this.latnLong != null) ? lnlDec(this.latnLong) : lnlDec('none'),
child: (this.latnLong != null)
? lnlDec(this.latnLong)
: lnlDec('none'),
),
),
Expanded(
@ -629,7 +656,7 @@ class _LatNLongState extends State<LatNLong> {
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: _delete(),
child: _delete(),
),
),
],
@ -642,14 +669,16 @@ class _LatNLongState extends State<LatNLong> {
flex: 5,
child: Container(
margin: EdgeInsets.only(
left: 6,
top: 3,
right: 3,
bottom: 3,
left: 6,
top: 3,
right: 3,
bottom: 3,
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: (this.latnLongDMS != null) ? lnlDeg(this.latnLongDMS) : lnlDeg('none'),
child: (this.latnLongDMS != null)
? lnlDeg(this.latnLongDMS)
: lnlDeg('none'),
),
),
Expanded(
@ -663,7 +692,7 @@ class _LatNLongState extends State<LatNLong> {
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: streetView(this.latnLong),
child: streetView(this.latnLong),
),
),
Expanded(
@ -677,7 +706,7 @@ class _LatNLongState extends State<LatNLong> {
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: aboutApp(context),
child: aboutApp(context),
),
),
],
@ -690,10 +719,10 @@ class _LatNLongState extends State<LatNLong> {
flex: 4,
child: Container(
margin: EdgeInsets.only(
left: 6,
top: 3,
right: 3,
bottom: 3,
left: 6,
top: 3,
right: 3,
bottom: 3,
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
@ -702,34 +731,39 @@ class _LatNLongState extends State<LatNLong> {
),
),
),
((this._useElev) ? Expanded(
flex: 2,
child: Container(
margin: EdgeInsets.only(
left: 3,
top: 3,
right: (this._useWTHR) ? 3 : 6,
bottom: 3,
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: elevAtion(context, this.elevation, this.feetElevation),
),
) : Container()),
((this._useWTHR) ? Expanded(
flex: 4,
child: Container(
margin: EdgeInsets.only(
left: 3,
top: 3,
right: 6,
bottom: 3,
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: _timezone(),
),
) : Container()),
((this._useElev)
? Expanded(
flex: 2,
child: Container(
margin: EdgeInsets.only(
left: 3,
top: 3,
right: (this._useWTHR) ? 3 : 6,
bottom: 3,
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: elevAtion(
context, this.elevation, this.feetElevation),
),
)
: Container()),
((this._useWTHR)
? Expanded(
flex: 4,
child: Container(
margin: EdgeInsets.only(
left: 3,
top: 3,
right: 6,
bottom: 3,
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
child: _timezone(),
),
)
: Container()),
],
),
),
@ -751,7 +785,7 @@ class _LatNLongState extends State<LatNLong> {
leading: Builder(
builder: (BuildContext context) {
return IconButton(
icon: const Icon(Icons.settings), onPressed: _settings);
icon: const Icon(Icons.settings), onPressed: _settings);
},
),
title: Text('Libre Gps Parser'),
@ -764,28 +798,32 @@ class _LatNLongState extends State<LatNLong> {
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget>[
_top(),
((this._useWTHR) ? Weather(
weatherLocationID: this.weatherLocationID,
weatherConditions: this.weatherConditions,
weatherConditionsIcon: this.weatherConditionsIcon,
weatherCurrentTemp: this.weatherCurrentTemp,
weatherCurrentPressure: this.weatherCurrentPressure,
weatherCurrentHumidity: this.weatherCurrentHumidity,
weatherCurrentTempMin: this.weatherCurrentTempMin,
weatherCurrentTempMax: this.weatherCurrentTempMax,
weatherCurrentVisibility: this.weatherCurrentVisibility,
weatherCurrentWindSpd: this.weatherCurrentWindSpd,
weatherCurrentWindDir: this.weatherCurrentWindDir,
weatherCurrentSunrise: this.weatherCurrentSunrise,
weatherCurrentSunset: this.weatherCurrentSunset,
weatherCurrentDT: this.weatherCurrentDT,
timeOffSet: this.timeOffSet,
parentAction: this._refreshWeather,
) : Container()),
((this._useWTHR) ? WeatherForeCast(
weatherForeCast: this.weatherForeCast,
timeOffSet: this.timeOffSet,
) : Container()),
((this._useWTHR)
? Weather(
weatherLocationID: this.weatherLocationID,
weatherConditions: this.weatherConditions,
weatherConditionsIcon: this.weatherConditionsIcon,
weatherCurrentTemp: this.weatherCurrentTemp,
weatherCurrentPressure: this.weatherCurrentPressure,
weatherCurrentHumidity: this.weatherCurrentHumidity,
weatherCurrentTempMin: this.weatherCurrentTempMin,
weatherCurrentTempMax: this.weatherCurrentTempMax,
weatherCurrentVisibility: this.weatherCurrentVisibility,
weatherCurrentWindSpd: this.weatherCurrentWindSpd,
weatherCurrentWindDir: this.weatherCurrentWindDir,
weatherCurrentSunrise: this.weatherCurrentSunrise,
weatherCurrentSunset: this.weatherCurrentSunset,
weatherCurrentDT: this.weatherCurrentDT,
timeOffSet: this.timeOffSet,
parentAction: this._refreshWeather,
)
: Container()),
((this._useWTHR)
? WeatherForeCast(
weatherForeCast: this.weatherForeCast,
timeOffSet: this.timeOffSet,
)
: Container()),
],
),
),
@ -794,7 +832,7 @@ class _LatNLongState extends State<LatNLong> {
);
}
void _settings() async{
void _settings() async {
int newSetting = await Navigator.push(
context,
MaterialPageRoute(builder: (context) => Settings()),
@ -804,7 +842,7 @@ class _LatNLongState extends State<LatNLong> {
}
}
void _pushSaved() async{
void _pushSaved() async {
List<String> sortedMapLocations = await dbHelper.sortedMapLocations();
await Navigator.of(context).push(
MaterialPageRoute<void>(
@ -865,7 +903,7 @@ class _LatNLongState extends State<LatNLong> {
Future<void> updateState() async {
var sharedData = await platform.invokeMethod("getSharedText");
if (sharedData != null && sharedData is String) {
if (gmapExp.hasMatch(sharedData)) {
if (mapExp.hasMatch(sharedData)) {
setState(() {
this.widgetMapLocation = sharedData;
});
@ -883,7 +921,7 @@ class _LatNLongState extends State<LatNLong> {
await _populateNotes(sharedData);
}
Future<void> _populateNotes(String mapLocation) async{
Future<void> _populateNotes(String mapLocation) async {
String _notes = await dbHelper.queryNotes(mapLocation);
if ((_notes != null) || (_notes != this.notes)) {
if ((mapLocation.contains('Plataea')) && (_notes.length == 0)) {
@ -910,7 +948,8 @@ class _LatNLongState extends State<LatNLong> {
Map<String, dynamic> weatherForeCastJson = jsonDecode(weatherForeCast);
int _threeHoursAgo = (newTimeStamp() - 10800);
if (weatherForeCastJson['list'][1]['dt'] < _threeHoursAgo) {
weatherForeCast = await getWeatherForeCast(mapLocation, latLong, true);
weatherForeCast =
await getWeatherForeCast(mapLocation, latLong, true);
setState(() {
this.weatherForeCast = weatherForeCast;
});
@ -919,12 +958,12 @@ class _LatNLongState extends State<LatNLong> {
}
}
Future<void> _refreshWeather() async{
await _populateWeather(this.widgetMapLocation,this.latnLong);
await _populateWeatherForeCast(this.widgetMapLocation,this.latnLong);
Future<void> _refreshWeather() async {
await _populateWeather(this.widgetMapLocation, this.latnLong);
await _populateWeatherForeCast(this.widgetMapLocation, this.latnLong);
}
Future<void> _populateWeather(String mapLocation, String latLong) async{
Future<void> _populateWeather(String mapLocation, String latLong) async {
if ((this._useWTHR) && (latLong != null)) {
String weather = await getWeather(mapLocation, latLong, false);
if (weather == 'NA') {
@ -943,9 +982,12 @@ class _LatNLongState extends State<LatNLong> {
}
}
Future<void> _updateWeather(Map<String, dynamic> weatherJson,String latLong) async {
Future<void> _updateWeather(
Map<String, dynamic> weatherJson, String latLong) async {
if (this._useWTHR) {
int _weatherId = (weatherJson['id'] != 0) ? weatherJson['id']: generateFakeWeatherId(latLong);
int _weatherId = (weatherJson['id'] != 0)
? weatherJson['id']
: generateFakeWeatherId(latLong);
if ((_weatherId != this.weatherLocationID) ||
(weatherJson['dt'] != this.weatherCurrentDT)) {
double tempTemp = (weatherJson['main']['temp'] != null)
@ -1053,7 +1095,7 @@ class _LatNLongState extends State<LatNLong> {
}
Future<void> _updateLatNLong(int timeStamp, String mapLocation) async {
String mapUrl = gmapExp.stringMatch(mapLocation);
String mapUrl = mapExp.stringMatch(mapLocation);
await parseMapUrl(mapUrl).then((String lattLong) {
setState(() {
this.latnLong = lattLong;
@ -1102,7 +1144,7 @@ class _LatNLongState extends State<LatNLong> {
}
}
Future<void> _deleteLocation() async{
Future<void> _deleteLocation() async {
String _secondNewest = await dbHelper.querySecondNewestMapLocation();
if (_secondNewest != 'none') {
String locationToBeDeleted = this.widgetMapLocation;
@ -1122,10 +1164,12 @@ class _LatNLongState extends State<LatNLong> {
}
}
Future<void> _userTzOffset(int offset) async{
Future<void> _userTzOffset(int offset) async {
if (this._useWTHR) {
if (offset > 1999) { // 2001 is magic number for auto
List<int> _timeOffSet = await refreshTimeOffSet(this.widgetMapLocation,this.latnLong);
if (offset > 1999) {
// 2001 is magic number for auto
List<int> _timeOffSet =
await refreshTimeOffSet(this.widgetMapLocation, this.latnLong);
setState(() {
this.timeOffSet = _timeOffSet[0];
this.timeOffSetTime = _timeOffSet[1];
@ -1151,7 +1195,7 @@ class _LatNLongState extends State<LatNLong> {
}
}
Future<void> _getUseElevPref() async{
Future<void> _getUseElevPref() async {
bool _useElevation = await getPreferenceUseElevation();
if (_useElevation != _useElev) {
setState(() {
@ -1161,7 +1205,7 @@ class _LatNLongState extends State<LatNLong> {
await _getUseWeatherPref();
}
Future<void> _getUseWeatherPref() async{
Future<void> _getUseWeatherPref() async {
bool _useWeather = await getPreferenceUseWeather();
if (_useWeather != _useWTHR) {
setState(() {

View File

@ -44,7 +44,7 @@ class _RenderNotesState extends State<RenderNotes> {
SliverToBoxAdapter(
child: Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: <Widget> [
children: <Widget>[
Container(
margin: EdgeInsets.symmetric(
horizontal: 10.0,
@ -54,7 +54,7 @@ class _RenderNotesState extends State<RenderNotes> {
),
),
Row(
children: <Widget> [
children: <Widget>[
Expanded(
child: Container(),
),
@ -63,225 +63,280 @@ class _RenderNotesState extends State<RenderNotes> {
child: ButtonTheme(
height: 55,
padding: EdgeInsets.only(
top: 5,
right: 12,
bottom: 12,
left: 10
),
top: 5, right: 12, bottom: 12, left: 10),
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
color: peacockBlue,
child: Text(
'Export',
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.all(Radius.circular(6.0)),
),
),
onPressed: () async{
Map<PermissionGroup, PermissionStatus> _storagePermissions;
PermissionStatus _storagePermission = await PermissionHandler().checkPermissionStatus(PermissionGroup.storage);
if (_storagePermission == PermissionStatus.denied) {
_storagePermissions = await PermissionHandler().requestPermissions([PermissionGroup.storage]);
}
if ((_storagePermission == PermissionStatus.granted) || (_storagePermissions.toString() == PermissionStatus.granted.toString())) {
Directory sdcard = await getExternalStorageDirectory();
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: ivory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
title: Text(
'File Name To Save As?',
textAlign: TextAlign.center,
style: TextStyle(
color: candyApple,
),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextField(
controller: _textEditingController,
keyboardType: TextInputType.multiline,
maxLines: null,
decoration: InputDecoration(
hintText: 'i.e. timbuktu.md',
),
onChanged: (text) {
_exportFileNameString = text;
},
color: peacockBlue,
child: Text(
'Export',
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
onPressed: () async {
Map<PermissionGroup, PermissionStatus>
_storagePermissions;
PermissionStatus _storagePermission =
await PermissionHandler()
.checkPermissionStatus(
PermissionGroup.storage);
if (_storagePermission ==
PermissionStatus.denied) {
_storagePermissions = await PermissionHandler()
.requestPermissions(
[PermissionGroup.storage]);
}
if ((_storagePermission ==
PermissionStatus.granted) ||
(_storagePermissions.toString() ==
PermissionStatus.granted.toString())) {
Directory sdcard =
await getExternalStorageDirectory();
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: ivory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(
Radius.circular(6.0)),
),
Container(
margin: EdgeInsets.only(
top: 40,
bottom: 10,
),
child: ButtonTheme(
height: 55,
padding: EdgeInsets.only(
top: 5,
right: 12,
bottom: 12,
left: 10
),
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
color: peacockBlue,
child: Text(
'Export',
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
onPressed: () async{
if (this._exportFileNameString.length > 0) {
String _fileName = '${sdcard.path}/${this._exportFileNameString}';
File _file = File(_fileName);
File _result = await _file.writeAsString(widget.notes);
Navigator.of(context).pop();
if (_result == null) {
setState(() {
this.fileName = _fileName;
});
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: ivory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
title: Text(
'Writing To\n\'$fileName\'\n(sdcard) Failed!',
textAlign: TextAlign.center,
style: TextStyle(
color: candyApple,
),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
margin: EdgeInsets.only(
top: 40,
bottom: 10,
),
child: ButtonTheme(
height: 55,
padding: EdgeInsets.only(
top: 5,
right: 12,
bottom: 12,
left: 10
),
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
color: peacockBlue,
child: Text(
'OK',
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
onPressed: () async{
Navigator.of(context).pop();
}
),
),
),
],
),
);
}
);
} else {
setState(() {
this.fileName = _fileName;
});
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: ivory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
title: Text(
'Writing To\n\'$fileName\'\n(sdcard) Succeeded!',
textAlign: TextAlign.center,
style: TextStyle(
color: candyApple,
),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Container(
margin: EdgeInsets.only(
top: 40,
bottom: 10,
),
child: ButtonTheme(
height: 55,
padding: EdgeInsets.only(
top: 5,
right: 12,
bottom: 12,
left: 10
),
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
color: peacockBlue,
child: Text(
'OK',
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
onPressed: () async{
Navigator.of(context).pop();
}
),
),
),
],
),
);
}
);
}
}
}
),
title: Text(
'File Name To Save As?',
textAlign: TextAlign.center,
style: TextStyle(
color: candyApple,
),
),
],
),
);
}
);
}
}
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
TextField(
controller:
_textEditingController,
keyboardType:
TextInputType.multiline,
maxLines: null,
decoration: InputDecoration(
hintText: 'i.e. timbuktu.md',
),
onChanged: (text) {
_exportFileNameString = text;
},
),
Container(
margin: EdgeInsets.only(
top: 40,
bottom: 10,
),
child: ButtonTheme(
height: 55,
padding: EdgeInsets.only(
top: 5,
right: 12,
bottom: 12,
left: 10),
child: RaisedButton(
shape:
RoundedRectangleBorder(
borderRadius:
BorderRadius.all(
Radius.circular(
6.0)),
),
color: peacockBlue,
child: Text(
'Export',
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
onPressed: () async {
if (this
._exportFileNameString
.length >
0) {
String _fileName =
'${sdcard.path}/${this._exportFileNameString}';
File _file =
File(_fileName);
File _result =
await _file
.writeAsString(
widget
.notes);
Navigator.of(context)
.pop();
if (_result == null) {
setState(() {
this.fileName =
_fileName;
});
showDialog(
context: context,
builder:
(BuildContext
context) {
return AlertDialog(
backgroundColor:
ivory,
shape:
RoundedRectangleBorder(
borderRadius:
BorderRadius.all(
Radius.circular(6.0)),
),
title: Text(
'Writing To\n\'$fileName\'\n(sdcard) Failed!',
textAlign:
TextAlign
.center,
style:
TextStyle(
color:
candyApple,
),
),
content:
Column(
mainAxisSize:
MainAxisSize
.min,
children: <
Widget>[
Container(
margin:
EdgeInsets.only(
top:
40,
bottom:
10,
),
child:
ButtonTheme(
height:
55,
padding: EdgeInsets.only(
top: 5,
right: 12,
bottom: 12,
left: 10),
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
color: peacockBlue,
child: Text(
'OK',
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
onPressed: () async {
Navigator.of(context).pop();
}),
),
),
],
),
);
});
} else {
setState(() {
this.fileName =
_fileName;
});
showDialog(
context: context,
builder:
(BuildContext
context) {
return AlertDialog(
backgroundColor:
ivory,
shape:
RoundedRectangleBorder(
borderRadius:
BorderRadius.all(
Radius.circular(6.0)),
),
title: Text(
'Writing To\n\'$fileName\'\n(sdcard) Succeeded!',
textAlign:
TextAlign
.center,
style:
TextStyle(
color:
candyApple,
),
),
content:
Column(
mainAxisSize:
MainAxisSize
.min,
children: <
Widget>[
Container(
margin:
EdgeInsets.only(
top:
40,
bottom:
10,
),
child:
ButtonTheme(
height:
55,
padding: EdgeInsets.only(
top: 5,
right: 12,
bottom: 12,
left: 10),
child: RaisedButton(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
color: peacockBlue,
child: Text(
'OK',
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
onPressed: () async {
Navigator.of(context).pop();
}),
),
),
],
),
);
});
}
}
}),
),
),
],
),
);
});
}
}),
),
),
],

File diff suppressed because it is too large Load Diff

View File

@ -8,9 +8,9 @@ InkWell streetView(String latnLong) {
return InkWell(
onTap: () {
AndroidIntent _intent = AndroidIntent(
action: 'action_view',
data: Uri.encodeFull('google.streetview:cbll=$latnLong'),
package: 'com.google.android.apps.maps');
action: 'action_view',
data: Uri.encodeFull('google.streetview:cbll=$latnLong'),
package: 'com.google.android.apps.maps');
_intent.launch();
},
child: Row(

View File

@ -34,103 +34,111 @@ class _TimeZoneState extends State<TimeZone> {
final double textHeight = 1.5;
return Row(
children: <Widget> [
children: <Widget>[
Expanded(
flex: 7,
child: InkWell(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget> [
Text(
'Time Offset:',
style: TextStyle(
height: textHeight,
color: candyApple,
fontSize: 16,
),
),
RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: (widget.timeOffSet != 2000) ? '$offSet' : 'INVALID',
style: TextStyle(
height: textHeight,
color: Colors.black,
fontSize: 16,
),
),
TextSpan(
text: (widget.timeOffSet != 2000) ? ' minutes, ' : '',
style: TextStyle(
height: textHeight,
color: Colors.black,
fontSize: 16,
fontStyle: FontStyle.italic,
),
),
],
),
),
RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: (widget.isAutoTimeOffSet == 1) ? 'as of' : 'MANUAL SETTING',
style: TextStyle(
height: textHeight,
color: candyApple,
fontSize: 16,
),
),
TextSpan(
text: (widget.isAutoTimeOffSet == 1) ? ' $elapsedHours' : '',
style: TextStyle(
height: textHeight,
color: Colors.black,
fontSize: 16,
),
),
TextSpan(
text: (widget.isAutoTimeOffSet == 1) ? ' hrs' : '',
style: TextStyle(
height: textHeight,
color: Colors.black,
fontSize: 16,
fontStyle: FontStyle.italic,
),
),
TextSpan(
text: (widget.isAutoTimeOffSet == 1) ? ' ago' : '',
style: TextStyle(
height: textHeight,
color: Colors.black,
fontSize: 16,
),
),
],
),
),
],
),
onTap: () {
showDialog(
context: context,
builder: (BuildContext context) {
final FixedExtentScrollController scrollController =
FixedExtentScrollController(initialItem: _getTimeZoneListIndex());
return AlertDialog(
backgroundColor: ivory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
Text(
'Time Offset:',
style: TextStyle(
height: textHeight,
color: candyApple,
fontSize: 16,
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
),
RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: (widget.timeOffSet != 2000)
? '$offSet'
: 'INVALID',
style: TextStyle(
height: textHeight,
color: Colors.black,
fontSize: 16,
),
),
TextSpan(
text: (widget.timeOffSet != 2000) ? ' minutes, ' : '',
style: TextStyle(
height: textHeight,
color: Colors.black,
fontSize: 16,
fontStyle: FontStyle.italic,
),
),
],
),
),
RichText(
text: TextSpan(
children: <TextSpan>[
TextSpan(
text: (widget.isAutoTimeOffSet == 1)
? 'as of'
: 'MANUAL SETTING',
style: TextStyle(
height: textHeight,
color: candyApple,
fontSize: 16,
),
),
TextSpan(
text: (widget.isAutoTimeOffSet == 1)
? ' $elapsedHours'
: '',
style: TextStyle(
height: textHeight,
color: Colors.black,
fontSize: 16,
),
),
TextSpan(
text: (widget.isAutoTimeOffSet == 1) ? ' hrs' : '',
style: TextStyle(
height: textHeight,
color: Colors.black,
fontSize: 16,
fontStyle: FontStyle.italic,
),
),
TextSpan(
text: (widget.isAutoTimeOffSet == 1) ? ' ago' : '',
style: TextStyle(
height: textHeight,
color: Colors.black,
fontSize: 16,
),
),
],
),
),
],
),
onTap: () {
showDialog(
context: context,
builder: (BuildContext context) {
final FixedExtentScrollController scrollController =
FixedExtentScrollController(
initialItem: _getTimeZoneListIndex());
return AlertDialog(
backgroundColor: ivory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
content:
Column(mainAxisSize: MainAxisSize.min, children: <
Widget>[
ButtonTheme(
height: 75,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
borderRadius:
BorderRadius.all(Radius.circular(6.0)),
),
child: RaisedButton(
onPressed: () {
@ -180,7 +188,8 @@ class _TimeZoneState extends State<TimeZone> {
});
}
},
children: List<Widget>.generate(timeZoneList.length, (int index) {
children: List<Widget>.generate(timeZoneList.length,
(int index) {
return Column(
children: <Widget>[
Container(
@ -188,21 +197,25 @@ class _TimeZoneState extends State<TimeZone> {
color: ivory,
),
Container(
alignment: Alignment(0.0,0.0),
alignment: Alignment(0.0, 0.0),
height: 80,
width: (MediaQuery.of(context).size.width * .9),
width: (MediaQuery.of(context).size.width *
.9),
decoration: BoxDecoration(
color: peacockBlue,
border: Border.all(
width: 2.0,
),
borderRadius: BorderRadius.all(Radius.circular(6.0)),
borderRadius: BorderRadius.all(
Radius.circular(6.0)),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
mainAxisAlignment:
MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(
_parseTimeZoneOffSet(timeZoneList[index]['offset']),
_parseTimeZoneOffSet(
timeZoneList[index]['offset']),
style: TextStyle(
height: textHeight,
color: Colors.white,
@ -221,7 +234,7 @@ class _TimeZoneState extends State<TimeZone> {
),
),
Container(
height: 10,
height: 10,
color: ivory,
),
],
@ -229,13 +242,11 @@ class _TimeZoneState extends State<TimeZone> {
}),
),
),
]
),
);
},
);
}
),
]),
);
},
);
}),
),
Expanded(
flex: 3,
@ -261,102 +272,104 @@ class _TimeZoneState extends State<TimeZone> {
*/
onTap: () {
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: ivory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'The timezone offset should be set and refreshed automatically, '
'by querying an api from teleport. However, because the api is '
'free, the query is only refreshed once a week.\n'
'Additionally, in some cases the result is invalid. Tap the '
'left side of TimeZone Widget to manually set the timezone offset.',
textAlign: TextAlign.center,
),
Container(
margin: EdgeInsets.only(
top: 40,
bottom: 10,
context: context,
builder: (BuildContext context) {
return AlertDialog(
backgroundColor: ivory,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
),
content: Column(
mainAxisSize: MainAxisSize.min,
children: <Widget>[
Text(
'The timezone offset should be set and refreshed automatically, '
'by querying an api from teleport. However, because the api is '
'free, the query is only refreshed once a week.\n'
'Additionally, in some cases the result is invalid. Tap the '
'left side of TimeZone Widget to manually set the timezone offset.',
textAlign: TextAlign.center,
),
child: ButtonTheme(
height: 75,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.all(Radius.circular(6.0)),
Container(
margin: EdgeInsets.only(
top: 40,
bottom: 10,
),
child: RaisedButton(
color: peacockBlue,
child: Column(
children: <Widget>[
Container(
width: 150,
margin: EdgeInsets.only(
top: 10,
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
Text(
'List',
child: ButtonTheme(
height: 75,
shape: RoundedRectangleBorder(
borderRadius:
BorderRadius.all(Radius.circular(6.0)),
),
child: RaisedButton(
color: peacockBlue,
child: Column(
children: <Widget>[
Container(
width: 150,
margin: EdgeInsets.only(
top: 10,
),
child: Row(
mainAxisAlignment:
MainAxisAlignment.spaceAround,
children: <Widget>[
Text(
'List',
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
Icon(
Icons.open_in_browser,
size: 48,
color: Colors.white,
),
],
),
),
Container(
margin: EdgeInsets.only(
bottom: 15,
),
child: Text(
'Of TimeZones',
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
Icon(
Icons.open_in_browser,
size: 48,
color: Colors.white,
),
],
),
),
Container(
margin: EdgeInsets.only(
bottom: 15,
),
child: Text(
'Of TimeZones',
style: TextStyle(
height: textHeight,
color: Colors.white,
fontSize: 24,
),
),
],
),
],
),
onPressed: () {
Navigator.of(context).pop();
urlLaunch('https://en.wikipedia.org/wiki/List_of_time_zone_abbreviations');
}
onPressed: () {
Navigator.of(context).pop();
urlLaunch(
'https://en.wikipedia.org/wiki/List_of_time_zone_abbreviations');
}),
),
),
),
],
),
);
}
);
],
),
);
});
},
),
),
),
],
);
}
int _getTimeZoneListIndex() {
// 2001 is a magic number which means auto
// as in the tz offset is automatically set
return timeZoneList.indexOf(timeZoneList.singleWhere((timeZone) => timeZone['offset'] == ((widget.isAutoTimeOffSet == 1) ? 2001 : widget.timeOffSet)));
return timeZoneList.indexOf(timeZoneList.singleWhere((timeZone) =>
timeZone['offset'] ==
((widget.isAutoTimeOffSet == 1) ? 2001 : widget.timeOffSet)));
}
String _parseTimeZoneOffSet(int offset) {

View File

@ -1,48 +1,46 @@
// https://en.wikipedia.org/wiki/List_of_time_zone_abbreviations
final List<Map<String, Object>> timeZoneList = [
{ 'offset' : -720, 'tz' : 'BIT, IDLW' },
{ 'offset' : -660, 'tz' : 'NUT, SST' },
{ 'offset' : -600, 'tz' : 'HST, TAHT' },
{ 'offset' : -570, 'tz' : 'MART, MIT' },
{ 'offset' : -540, 'tz' : 'AKST, HDT' },
{ 'offset' : -480, 'tz' : 'AKDT, PST' },
{ 'offset' : -420, 'tz' : 'MST, PDT' },
{ 'offset' : -360, 'tz' : 'CST, GALT' },
{ 'offset' : -300, 'tz' : 'EST, PET' },
{ 'offset' : -240, 'tz' : 'AMT, AST' },
{ 'offset' : -210, 'tz' : 'NST, NT' },
{ 'offset' : -180, 'tz' : 'ADT, FKST' },
{ 'offset' : -150, 'tz' : 'NDT' },
{ 'offset' : -120, 'tz' : 'GST, UYST' },
{ 'offset' : -60, 'tz' : 'CVT, EGT' },
{ 'offset' : 0, 'tz' : 'GMT, UTC' },
{ 'offset' : 60, 'tz' : 'CET, BST' },
{ 'offset' : 120, 'tz' : 'EET, CEST' },
{ 'offset' : 180, 'tz' : 'FET, EEST' },
{ 'offset' : 210, 'tz' : 'IRST' },
{ 'offset' : 240, 'tz' : 'AMT, VOLT' },
{ 'offset' : 270, 'tz' : 'AFT, IRDT' },
{ 'offset' : 300, 'tz' : 'PKT, TFT' },
{ 'offset' : 330, 'tz' : 'IST, SLST' },
{ 'offset' : 345, 'tz' : 'NPT' },
{ 'offset' : 360, 'tz' : 'BST, VOST' },
{ 'offset' : 390, 'tz' : 'CCT, MMT' },
{ 'offset' : 420, 'tz' : 'CXT, THA' },
{ 'offset' : 480, 'tz' : 'AWST, HKT' },
{ 'offset' : 525, 'tz' : 'ACWST' },
{ 'offset' : 540, 'tz' : 'JST, YAKT' },
{ 'offset' : 570, 'tz' : 'ACST' },
{ 'offset' : 600, 'tz' : 'AEST, VLAT' },
{ 'offset' : 630, 'tz' : 'ACDT, LHST' },
{ 'offset' : 660, 'tz' : 'AEDT, VUT' },
{ 'offset' : 720, 'tz' : 'NZST, WAKT' },
{ 'offset' : 765, 'tz' : 'CHAST' },
{ 'offset' : 780, 'tz' : 'NZDT, TOT' },
{ 'offset' : 825, 'tz' : 'CHADT' },
{ 'offset' : 840, 'tz' : 'LINT' },
{ 'offset' : 2000, 'tz' : 'INVLD' },
{ 'offset' : 2001, 'tz' : 'AUTO' },
{'offset': -720, 'tz': 'BIT, IDLW'},
{'offset': -660, 'tz': 'NUT, SST'},
{'offset': -600, 'tz': 'HST, TAHT'},
{'offset': -570, 'tz': 'MART, MIT'},
{'offset': -540, 'tz': 'AKST, HDT'},
{'offset': -480, 'tz': 'AKDT, PST'},
{'offset': -420, 'tz': 'MST, PDT'},
{'offset': -360, 'tz': 'CST, GALT'},
{'offset': -300, 'tz': 'EST, PET'},
{'offset': -240, 'tz': 'AMT, AST'},
{'offset': -210, 'tz': 'NST, NT'},
{'offset': -180, 'tz': 'ADT, FKST'},
{'offset': -150, 'tz': 'NDT'},
{'offset': -120, 'tz': 'GST, UYST'},
{'offset': -60, 'tz': 'CVT, EGT'},
{'offset': 0, 'tz': 'GMT, UTC'},
{'offset': 60, 'tz': 'CET, BST'},
{'offset': 120, 'tz': 'EET, CEST'},
{'offset': 180, 'tz': 'FET, EEST'},
{'offset': 210, 'tz': 'IRST'},
{'offset': 240, 'tz': 'AMT, VOLT'},
{'offset': 270, 'tz': 'AFT, IRDT'},
{'offset': 300, 'tz': 'PKT, TFT'},
{'offset': 330, 'tz': 'IST, SLST'},
{'offset': 345, 'tz': 'NPT'},
{'offset': 360, 'tz': 'BST, VOST'},
{'offset': 390, 'tz': 'CCT, MMT'},
{'offset': 420, 'tz': 'CXT, THA'},
{'offset': 480, 'tz': 'AWST, HKT'},
{'offset': 525, 'tz': 'ACWST'},
{'offset': 540, 'tz': 'JST, YAKT'},
{'offset': 570, 'tz': 'ACST'},
{'offset': 600, 'tz': 'AEST, VLAT'},
{'offset': 630, 'tz': 'ACDT, LHST'},
{'offset': 660, 'tz': 'AEDT, VUT'},
{'offset': 720, 'tz': 'NZST, WAKT'},
{'offset': 765, 'tz': 'CHAST'},
{'offset': 780, 'tz': 'NZDT, TOT'},
{'offset': 825, 'tz': 'CHADT'},
{'offset': 840, 'tz': 'LINT'},
{'offset': 2000, 'tz': 'INVLD'},
{'offset': 2001, 'tz': 'AUTO'},
];

View File

@ -63,76 +63,82 @@ class _WeatherState extends State<Weather> {
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());
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,
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,
),
),
],
),
),
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());
)
: Expanded(child: Container());
}
Column _currentConditions() {
@ -179,7 +185,7 @@ class _WeatherState extends State<Weather> {
],
);
}
Column _temps() {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
@ -247,8 +253,7 @@ class _WeatherState extends State<Weather> {
),
),
TextSpan(
text:
'${widget.weatherCurrentTempMin.round()}\u00B0',
text: '${widget.weatherCurrentTempMin.round()}\u00B0',
style: TextStyle(
height: textHeight,
color: Colors.black,
@ -298,8 +303,7 @@ class _WeatherState extends State<Weather> {
),
),
TextSpan(
text:
'${widget.weatherCurrentTempMax.round()}\u00B0',
text: '${widget.weatherCurrentTempMax.round()}\u00B0',
style: TextStyle(
height: textHeight,
color: Colors.black,
@ -468,8 +472,7 @@ class _WeatherState extends State<Weather> {
text: TextSpan(
children: <TextSpan>[
TextSpan(
text:
'${(widget.weatherCurrentWindSpd * 1.60934).round()}',
text: '${(widget.weatherCurrentWindSpd * 1.60934).round()}',
style: TextStyle(
height: textHeight,
color: Colors.black,
@ -901,7 +904,8 @@ class _WeatherState extends State<Weather> {
return Container(
width: 100,
child: CachedNetworkImage(
imageUrl: 'http://openweathermap.org/img/w/${widget.weatherConditionsIcon}.png',
imageUrl:
'http://openweathermap.org/img/w/${widget.weatherConditionsIcon}.png',
),
);
}
@ -909,8 +913,8 @@ class _WeatherState extends State<Weather> {
if (widget.weatherConditions == '') {
return Container(
margin: EdgeInsets.symmetric(
vertical: 3,
horizontal: 6,
vertical: 3,
horizontal: 6,
),
padding: myBoxPadding,
decoration: myBoxDecoration(_stale ? Colors.grey : ivory),
@ -937,285 +941,284 @@ class _WeatherState extends State<Weather> {
} else if (_deviceWidth < 400) {
return Container(
margin: EdgeInsets.symmetric(
vertical: 3,
horizontal: 6,
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(),
],
),
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(
top: 16.0,
bottom: 2.0,
right: 25.0,
),
Padding(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
_icon(),
_currentConditions(),
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
_refresh(),
_staleNotice(),
],
),
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>[
_icon(),
_currentConditions(),
],
),
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>[
_updateTime(),
],
),
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>[
_temps(),
_wind(),
],
),
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>[
_pressure(),
_visibility(),
],
),
Padding(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
_sunSet(),
],
),
),
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,
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(),
],
),
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(
top: 16.0,
bottom: 2.0,
right: 25.0,
),
Padding(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
_icon(),
_currentConditions(),
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
_refresh(),
_staleNotice(),
],
),
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>[
_icon(),
_currentConditions(),
],
),
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>[
_updateTime(),
],
),
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>[
_temps(),
_wind(),
],
),
Padding(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
_sunSet(),
_visibility(),
],
),
),
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,
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(),
],
),
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(
top: 16.0,
bottom: 2.0,
right: 25.0,
),
Padding(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
_icon(),
_currentConditions(),
_temps(),
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
_refresh(),
_staleNotice(),
],
),
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>[
_icon(),
_currentConditions(),
_temps(),
],
),
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>[
_updateTime(),
_visibility(),
],
),
Padding(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
_sunSet(),
_pressure(),
],
),
),
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,
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(),
],
),
child: Column(
children: <Widget>[
Padding(
padding: EdgeInsets.only(
top: 16.0,
bottom: 2.0,
right: 25.0,
),
Padding(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
_icon(),
_currentConditions(),
_temps(),
_visibility(),
_updateTime(),
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceAround,
children: <Widget>[
_refresh(),
_staleNotice(),
],
),
Padding(
padding: EdgeInsets.symmetric(vertical: 8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
_pressure(),
_sunRise(),
_sunSet(),
_wind(),
],
),
),
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) {
@ -1223,7 +1226,9 @@ class _WeatherState extends State<Weather> {
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 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 {

View File

@ -20,7 +20,7 @@ class WeatherForeCast extends StatefulWidget {
class _WeatherForeCastState extends State<WeatherForeCast> {
final double textHeight = 1.5;
@override
Widget build(BuildContext context) {
Map<String, dynamic> foreCastJson;
@ -81,7 +81,8 @@ class _WeatherForeCastState extends State<WeatherForeCast> {
return Container(
width: 100,
child: CachedNetworkImage(
imageUrl: 'http://openweathermap.org/img/w/${foreCast['weather'][0]['icon']}.png',
imageUrl:
'http://openweathermap.org/img/w/${foreCast['weather'][0]['icon']}.png',
),
);
}
@ -183,8 +184,7 @@ class _WeatherForeCastState extends State<WeatherForeCast> {
),
),
TextSpan(
text:
'${foreCast['wind']['deg'].round()}\u00B0, ',
text: '${foreCast['wind']['deg'].round()}\u00B0, ',
style: TextStyle(
height: textHeight,
color: Colors.black,
@ -207,7 +207,7 @@ class _WeatherForeCastState extends State<WeatherForeCast> {
],
);
}
Column _temp() {
return Column(
crossAxisAlignment: CrossAxisAlignment.center,
@ -225,8 +225,7 @@ class _WeatherForeCastState extends State<WeatherForeCast> {
),
),
TextSpan(
text:
'${foreCast['main']['temp'].round()}\u00B0',
text: '${foreCast['main']['temp'].round()}\u00B0',
style: TextStyle(
height: textHeight,
color: Colors.black,
@ -276,8 +275,7 @@ class _WeatherForeCastState extends State<WeatherForeCast> {
),
),
TextSpan(
text:
'${foreCast['main']['temp_min'].round()}\u00B0',
text: '${foreCast['main']['temp_min'].round()}\u00B0',
style: TextStyle(
height: textHeight,
color: Colors.black,
@ -327,8 +325,7 @@ class _WeatherForeCastState extends State<WeatherForeCast> {
),
),
TextSpan(
text:
'${foreCast['main']['temp_max'].round()}\u00B0',
text: '${foreCast['main']['temp_max'].round()}\u00B0',
style: TextStyle(
height: textHeight,
color: Colors.black,
@ -982,8 +979,8 @@ class _WeatherForeCastState extends State<WeatherForeCast> {
foreCastJson = jsonDecode(widget.weatherForeCast);
return Container(
margin: EdgeInsets.symmetric(
vertical: 3,
horizontal: 6,
vertical: 3,
horizontal: 6,
),
decoration: myBoxDecoration(ivory),
padding: EdgeInsets.all(5.0),
@ -991,11 +988,11 @@ class _WeatherForeCastState extends State<WeatherForeCast> {
children: createForeCast(foreCastJson['list']),
),
);
} catch(e) {
} catch (e) {
return Container(
margin: EdgeInsets.symmetric(
vertical: 3,
horizontal: 6,
vertical: 3,
horizontal: 6,
),
padding: myBoxPadding,
decoration: myBoxDecoration(ivory),
@ -1037,7 +1034,9 @@ class _WeatherForeCastState extends State<WeatherForeCast> {
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 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 {

View File

@ -11,7 +11,7 @@ description: A new Flutter project.
# In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
version: 0.1.2+8
version: 0.1.2+10
environment:
sdk: ">=2.1.0 <3.0.0"