mirror of
https://github.com/DefinedNet/mobile_nebula.git
synced 2025-01-18 19:27:05 +00:00
64d45f66c7
This updates flutter to 3.24.1, the latest stable version, and also updates our flutter dependencies to latest. It targets the latest android sdk, 34, which is required if we want to publish a new version to the Google Play store. I also needed to make a few adjustments to handle deprecations. The biggest change is that I needed to wrap the main widget in MaterialApp to avoid problems with AdaptiveSwitch in iOS.
144 lines
4.1 KiB
Dart
144 lines
4.1 KiB
Dart
import 'package:flutter/cupertino.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:mobile_nebula/components/SimplePage.dart';
|
|
import 'package:mobile_nebula/components/config/ConfigPageItem.dart';
|
|
import 'package:mobile_nebula/components/config/ConfigSection.dart';
|
|
import 'package:mobile_nebula/models/HostInfo.dart';
|
|
import 'package:mobile_nebula/models/Site.dart';
|
|
import 'package:mobile_nebula/screens/HostInfoScreen.dart';
|
|
import 'package:mobile_nebula/services/utils.dart';
|
|
import 'package:pull_to_refresh/pull_to_refresh.dart';
|
|
|
|
class SiteTunnelsScreen extends StatefulWidget {
|
|
const SiteTunnelsScreen({
|
|
Key? key,
|
|
required this.site,
|
|
required this.tunnels,
|
|
required this.pending,
|
|
required this.onChanged,
|
|
required this.supportsQRScanning,
|
|
}) : super(key: key);
|
|
|
|
final Site site;
|
|
final List<HostInfo> tunnels;
|
|
final bool pending;
|
|
final Function(List<HostInfo>)? onChanged;
|
|
|
|
final bool supportsQRScanning;
|
|
|
|
@override
|
|
_SiteTunnelsScreenState createState() => _SiteTunnelsScreenState();
|
|
}
|
|
|
|
class _SiteTunnelsScreenState extends State<SiteTunnelsScreen> {
|
|
late Site site;
|
|
late List<HostInfo> tunnels;
|
|
RefreshController refreshController = RefreshController(initialRefresh: false);
|
|
|
|
@override
|
|
void initState() {
|
|
site = widget.site;
|
|
tunnels = widget.tunnels;
|
|
_sortTunnels();
|
|
super.initState();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
refreshController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final double ipWidth = Utils.textSize("000.000.000.000", CupertinoTheme.of(context).textTheme.textStyle).width + 32;
|
|
|
|
List<Widget> children = [];
|
|
tunnels.forEach((hostInfo) {
|
|
Widget icon;
|
|
|
|
final isLh = site.staticHostmap[hostInfo.vpnIp]?.lighthouse ?? false;
|
|
if (isLh) {
|
|
icon = Icon(Icons.lightbulb_outline, color: CupertinoColors.placeholderText.resolveFrom(context));
|
|
} else {
|
|
icon = Icon(Icons.computer, color: CupertinoColors.placeholderText.resolveFrom(context));
|
|
}
|
|
|
|
children.add(ConfigPageItem(
|
|
onPressed: () => Utils.openPage(
|
|
context,
|
|
(context) => HostInfoScreen(
|
|
isLighthouse: isLh,
|
|
hostInfo: hostInfo,
|
|
pending: widget.pending,
|
|
site: widget.site,
|
|
onChanged: () {
|
|
_listHostmap();
|
|
},
|
|
supportsQRScanning: widget.supportsQRScanning,
|
|
),
|
|
),
|
|
label: Row(children: <Widget>[Padding(child: icon, padding: EdgeInsets.only(right: 10)), Text(hostInfo.vpnIp)]),
|
|
labelWidth: ipWidth,
|
|
content: Container(alignment: Alignment.centerRight, child: Text(hostInfo.cert?.details.name ?? "")),
|
|
));
|
|
});
|
|
|
|
Widget child;
|
|
if (children.length == 0) {
|
|
child = Center(child: Padding(child: Text('No tunnels to show'), padding: EdgeInsets.only(top: 30)));
|
|
} else {
|
|
child = ConfigSection(children: children);
|
|
}
|
|
|
|
final title = widget.pending ? 'Pending' : 'Active';
|
|
|
|
return SimplePage(
|
|
title: Text('$title Tunnels'),
|
|
leadingAction: Utils.leadingBackWidget(context, onPressed: () {
|
|
Navigator.pop(context);
|
|
}),
|
|
refreshController: refreshController,
|
|
onRefresh: () async {
|
|
await _listHostmap();
|
|
refreshController.refreshCompleted();
|
|
},
|
|
child: child);
|
|
}
|
|
|
|
_sortTunnels() {
|
|
tunnels.sort((a, b) {
|
|
final aLh = _isLighthouse(a.vpnIp), bLh = _isLighthouse(b.vpnIp);
|
|
|
|
if (aLh && !bLh) {
|
|
return -1;
|
|
} else if (!aLh && bLh) {
|
|
return 1;
|
|
}
|
|
|
|
return Utils.ip2int(a.vpnIp) - Utils.ip2int(b.vpnIp);
|
|
});
|
|
}
|
|
|
|
bool _isLighthouse(String vpnIp) {
|
|
return site.staticHostmap[vpnIp]?.lighthouse ?? false;
|
|
}
|
|
|
|
_listHostmap() async {
|
|
try {
|
|
if (widget.pending) {
|
|
tunnels = await site.listPendingHostmap();
|
|
} else {
|
|
tunnels = await site.listHostmap();
|
|
}
|
|
|
|
_sortTunnels();
|
|
if (widget.onChanged != null) {
|
|
widget.onChanged!(tunnels);
|
|
}
|
|
setState(() {});
|
|
} catch (err) {
|
|
Utils.popError(context, 'Error while fetching hostmap', err.toString());
|
|
}
|
|
}
|
|
}
|