finalize app for presentation tomorrow #35

Merged
Jeremy Kescher merged 1 commits from jeremy/0130/finalize-for-presentation into master 2020-01-30 12:25:39 +00:00
2 changed files with 110 additions and 33 deletions

View File

@ -4,7 +4,8 @@ enum ServerStatus {
notOk,
timeout,
dnsError,
clientConnectivityIssues
clientConnectivityIssues,
certificateError
}
class Server {

View File

@ -262,6 +262,26 @@ class _ServerListState extends State<ServerList> {
),
),
),
IconButton(
alignment: Alignment.center,
icon: Icon(
Icons.keyboard_arrow_up,
color: Colors.blueGrey,
),
onPressed: () {
_moveServerUp(index);
},
),
IconButton(
alignment: Alignment.center,
icon: Icon(
Icons.keyboard_arrow_down,
color: Colors.blueGrey,
),
onPressed: () {
_moveServerDown(index);
},
),
IconButton(
alignment: Alignment.center,
icon: Icon(
@ -375,38 +395,59 @@ class _ServerListState extends State<ServerList> {
}
static Future<ServerStatus> _checkStatus(String uri) async {
Uri parsedUri;
try {
parsedUri = Uri.parse(uri);
} catch (FormatException) {
return ServerStatus.dnsError;
}
Uri parsedUri;
try {
await HttpUtils.getForFullResponse('https://dns.google.com');
} catch (SocketException) {
return ServerStatus.clientConnectivityIssues;
}
try {
// Check if host is IP address
InternetAddress(parsedUri.host);
} catch (ArgumentError) /* Host is a DNS name */ {
var v4recs, v6recs;
try {
v4recs = await DnsUtils.lookupRecord(parsedUri.host, RRecordType.A);
v6recs = await DnsUtils.lookupRecord(parsedUri.host, RRecordType.AAAA);
} catch (SocketException) {
return ServerStatus.clientConnectivityIssues;
}
var v4 = await _resolveHostname(v4recs, RRecordType.A);
var v6 = await _resolveHostname(v6recs, RRecordType.AAAA);
if (v4 == null && v6 == null) {
parsedUri = Uri.parse(uri);
} on FormatException {
return ServerStatus.dnsError;
}
try {
// Check if host is IP address
var ip = InternetAddress(parsedUri.host);
InternetAddress reversedIp = await ip.reverse();
if (ip.host != reversedIp.host) {
parsedUri = parsedUri.replace(host: reversedIp.host);
throw ArgumentError("Valid IP, but trying with reverse hostname...");
}
if (parsedUri.scheme == "https") return ServerStatus.certificateError;
} on ArgumentError /* Host is a DNS name */ {
List<RRecord> v4recs, v6recs;
try {
try {
v4recs = await DnsUtils.lookupRecord(parsedUri.host, RRecordType.A);
} on HttpResponseException {
v4recs = [];
}
try {
v6recs =
await DnsUtils.lookupRecord(parsedUri.host, RRecordType.AAAA);
} on HttpResponseException {
v6recs = [];
}
} on SocketException catch (e) {
return ServerStatus.clientConnectivityIssues;
}
var v4 = await _resolveHostname(v4recs, RRecordType.A);
var v6 = await _resolveHostname(v6recs, RRecordType.AAAA);
if (v4 == null && v6 == null) {
return ServerStatus.dnsError;
}
}
try {
return await _checkResponse(parsedUri);
} on TlsException {
return ServerStatus.certificateError;
}
} on SocketException catch (e) {
// Network unreachable
if (e.osError.errorCode == 101)
return ServerStatus.clientConnectivityIssues;
throw e;
}
return await _checkResponse(parsedUri);
}
Icon _generateIcon(Server server) {
@ -436,6 +477,10 @@ class _ServerListState extends State<ServerList> {
icon = Icons.signal_wifi_off;
color = Colors.red.shade400;
break;
case ServerStatus.certificateError:
icon = Icons.security;
color = Colors.yellow.shade400;
break;
default:
icon = Icons.device_unknown;
color = Colors.blueGrey.shade400;
@ -465,7 +510,7 @@ class _ServerListState extends State<ServerList> {
try {
response = await HttpUtils.getForFullResponse(uri.toString())
.timeout(new Duration(seconds: 3));
} catch (TimeoutException) {
} on TimeoutException {
return ServerStatus.timeout;
}
@ -526,17 +571,48 @@ class _ServerListState extends State<ServerList> {
case ServerStatus.unknown:
return 'Loading...';
case ServerStatus.ok:
return 'Reachable';
return 'Reachable.';
case ServerStatus.notOk:
return 'Unexpected response';
return 'Unexpected response received.';
case ServerStatus.timeout:
return 'Timeout';
return 'Server took more than 3 seconds to respond.';
case ServerStatus.dnsError:
return 'DNS issues';
return 'DNS issues.';
case ServerStatus.clientConnectivityIssues:
return 'Connectivity issues on your device';
return 'Connectivity issues on your device.';
case ServerStatus.certificateError:
return 'A secure connection could not be established.';
default:
return '';
}
}
void _moveServer(int index, AxisDirection direction) {
int newIndex;
switch (direction) {
case AxisDirection.up:
if (index == 0) return;
newIndex = index - 1;
break;
case AxisDirection.down:
if (index == servers.length - 1) return;
newIndex = index + 1;
break;
default:
return;
break;
}
Server server = servers[index];
servers.removeAt(index);
setState(() {
servers.insert(newIndex, server);
selectedServer = newIndex;
});
_saveServersToPreferences();
}
void _moveServerUp(int index) => _moveServer(index, AxisDirection.up);
void _moveServerDown(int index) => _moveServer(index, AxisDirection.down);
}