diff --git a/lib/components/SiteItem.dart b/lib/components/SiteItem.dart index 90b04ad..4896d20 100644 --- a/lib/components/SiteItem.dart +++ b/lib/components/SiteItem.dart @@ -28,7 +28,8 @@ class SiteItem extends StatelessWidget { Widget _buildContent(BuildContext context) { final border = BorderSide(color: Utils.configSectionBorder(context)); - final dnIcon = Theme.of(context).brightness == Brightness.dark ? 'images/dn-logo-dark.svg' : 'images/dn-logo-light.svg'; + final dnIcon = + Theme.of(context).brightness == Brightness.dark ? 'images/dn-logo-dark.svg' : 'images/dn-logo-light.svg'; return SpecialButton( decoration: @@ -39,9 +40,9 @@ class SiteItem extends StatelessWidget { child: Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ - site.managed ? - Padding(padding: EdgeInsets.only(right: 10), child: SvgPicture.asset(dnIcon, width: 12)) : - Container(), + site.managed + ? Padding(padding: EdgeInsets.only(right: 10), child: SvgPicture.asset(dnIcon, width: 12)) + : Container(), Expanded(child: Text(site.name, style: TextStyle(fontWeight: FontWeight.bold))), Padding(padding: EdgeInsets.only(right: 10)), Icon(CupertinoIcons.forward, color: CupertinoColors.placeholderText.resolveFrom(context), size: 18) diff --git a/lib/components/config/ConfigPageItem.dart b/lib/components/config/ConfigPageItem.dart index 30aeb1e..067a1d3 100644 --- a/lib/components/config/ConfigPageItem.dart +++ b/lib/components/config/ConfigPageItem.dart @@ -52,7 +52,9 @@ class ConfigPageItem extends StatelessWidget { children: [ label != null ? Container(width: labelWidth, child: label) : Container(), Expanded(child: Container(child: content, padding: EdgeInsets.only(right: 10))), - this.disabled ? Container() : Icon(CupertinoIcons.forward, color: CupertinoColors.placeholderText.resolveFrom(context), size: 18) + this.disabled + ? Container() + : Icon(CupertinoIcons.forward, color: CupertinoColors.placeholderText.resolveFrom(context), size: 18) ], )), ); diff --git a/lib/main.dart b/lib/main.dart index 19626c2..b051cba 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -110,11 +110,9 @@ class _AppState extends State { if (uri.path == EnrollmentScreen.routeName) { // TODO: maybe implement this as a dialog instead of a page, you can stack multiple enrollment screens which is annoying in dev return platformPageRoute( - context: context, - builder: (context) => EnrollmentScreen( - code: EnrollmentScreen.parseCode(settings.name!), - stream: this.dnEnrolled - ), + context: context, + builder: (context) => + EnrollmentScreen(code: EnrollmentScreen.parseCode(settings.name!), stream: this.dnEnrolled), ); } diff --git a/lib/models/Site.dart b/lib/models/Site.dart index daecef3..46ee231 100644 --- a/lib/models/Site.dart +++ b/lib/models/Site.dart @@ -206,8 +206,7 @@ class Site { "unsafeRoutes": unsafeRoutes, "managed": json['managed'] ?? false, "rawConfig": json['rawConfig'], - "lastManagedUpdate": json["lastManagedUpdate"] == null ? - null : DateTime.parse(json["lastManagedUpdate"]), + "lastManagedUpdate": json["lastManagedUpdate"] == null ? null : DateTime.parse(json["lastManagedUpdate"]), }; } diff --git a/lib/screens/EnrollmentScreen.dart b/lib/screens/EnrollmentScreen.dart index ff69d5b..7d494be 100644 --- a/lib/screens/EnrollmentScreen.dart +++ b/lib/screens/EnrollmentScreen.dart @@ -91,37 +91,38 @@ class _EnrollmentScreenState extends State { } else { // No code, show the error child = Padding( - child: Center(child: Text( + child: Center( + child: Text( 'No valid enrollment code was found.\n\nContact your administrator to obtain a new enrollment code.', textAlign: TextAlign.center, - )), - padding: EdgeInsets.only(top: 20) - ); + padding: EdgeInsets.only(top: 20)); } - } else if (this.error != null) { // Error while enrolling, display it - child = Center(child: Column( + child = Center( + child: Column( children: [ Padding( - child: SelectableText('There was an issue while attempting to enroll this device. Contact your administrator to obtain a new enrollment code.'), - padding: EdgeInsets.symmetric(vertical: 20) - ), - Padding(child: SelectableText.rich(TextSpan(children: [ - TextSpan(text: 'If the problem persists, please let us know at '), - TextSpan( - text: 'support@defined.net', - style: bodyTextStyle.apply(color: colorScheme.primary), - recognizer: TapGestureRecognizer() - ..onTap = () async { - if (await canLaunchUrl(contactUri)) { - print(await launchUrl(contactUri)); - } - }, - ), - TextSpan(text: ' and provide the following error:'), - ])), padding: EdgeInsets.only(bottom: 10)), + child: SelectableText( + 'There was an issue while attempting to enroll this device. Contact your administrator to obtain a new enrollment code.'), + padding: EdgeInsets.symmetric(vertical: 20)), + Padding( + child: SelectableText.rich(TextSpan(children: [ + TextSpan(text: 'If the problem persists, please let us know at '), + TextSpan( + text: 'support@defined.net', + style: bodyTextStyle.apply(color: colorScheme.primary), + recognizer: TapGestureRecognizer() + ..onTap = () async { + if (await canLaunchUrl(contactUri)) { + print(await launchUrl(contactUri)); + } + }, + ), + TextSpan(text: ' and provide the following error:'), + ])), + padding: EdgeInsets.only(bottom: 10)), Container( child: Padding(child: SelectableText(this.error!), padding: EdgeInsets.all(10)), color: Theme.of(context).colorScheme.errorContainer, @@ -130,47 +131,43 @@ class _EnrollmentScreenState extends State { crossAxisAlignment: CrossAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center, )); - } else if (this.enrolled) { // Enrollment complete! child = Padding( - child: Center(child: Text( + child: Center( + child: Text( 'Enrollment complete! 🎉', textAlign: TextAlign.center, )), - padding: EdgeInsets.only(top: 20) - ); - + padding: EdgeInsets.only(top: 20)); } else { // Have a code and actively enrolling alignment = Alignment.center; - child = Center(child: Column( - children: [ - Padding(child: Text('Contacting DN for enrollment'), padding: EdgeInsets.only(bottom: 25)), - PlatformCircularProgressIndicator(cupertino: (_, __) { - return CupertinoProgressIndicatorData(radius: 50); - }) - ] - )); + child = Center( + child: Column(children: [ + Padding(child: Text('Contacting DN for enrollment'), padding: EdgeInsets.only(bottom: 25)), + PlatformCircularProgressIndicator(cupertino: (_, __) { + return CupertinoProgressIndicatorData(radius: 50); + }) + ])); } - final dnIcon = Theme.of(context).brightness == Brightness.dark ? 'images/dn-logo-dark.svg' : 'images/dn-logo-light.svg'; + final dnIcon = + Theme.of(context).brightness == Brightness.dark ? 'images/dn-logo-dark.svg' : 'images/dn-logo-light.svg'; return SimplePage( - title: Text('Enroll with Managed Nebula', style: TextStyle(fontWeight: FontWeight.bold)), - child: Padding(child: child, padding: EdgeInsets.symmetric(horizontal: 10)), - alignment: alignment - ); + title: Text('Enroll with Managed Nebula', style: TextStyle(fontWeight: FontWeight.bold)), + child: Padding(child: child, padding: EdgeInsets.symmetric(horizontal: 10)), + alignment: alignment); } Widget _codeEntry() { return Column(children: [ Padding( - padding: EdgeInsets.only(top: 20), - child: PlatformTextField( - hintText: 'defined.net enrollment code or link', - controller: enrollInput, - ) - ), + padding: EdgeInsets.only(top: 20), + child: PlatformTextField( + hintText: 'defined.net enrollment code or link', + controller: enrollInput, + )), PlatformTextButton( child: Text('Submit'), onPressed: () { diff --git a/lib/screens/HostInfoScreen.dart b/lib/screens/HostInfoScreen.dart index 461ee88..169a22c 100644 --- a/lib/screens/HostInfoScreen.dart +++ b/lib/screens/HostInfoScreen.dart @@ -75,10 +75,11 @@ class _HostInfoScreenState extends State { labelWidth: 150, content: Text(hostInfo.cert!.details.name), onPressed: () => Utils.openPage( - context, (context) => CertificateDetailsScreen( - certInfo: CertificateInfo(cert: hostInfo.cert!), - supportsQRScanning: widget.supportsQRScanning, - ))) + context, + (context) => CertificateDetailsScreen( + certInfo: CertificateInfo(cert: hostInfo.cert!), + supportsQRScanning: widget.supportsQRScanning, + ))) : Container(), ]); } diff --git a/lib/screens/MainScreen.dart b/lib/screens/MainScreen.dart index 337d0b1..728018c 100644 --- a/lib/screens/MainScreen.dart +++ b/lib/screens/MainScreen.dart @@ -128,9 +128,9 @@ class _MainScreenState extends State { // Determine whether the device supports QR scanning. For example, some // Chromebooks do not have camera support. if (Platform.isAndroid) { - platform.invokeMethod("android.deviceHasCamera").then( - (hasCamera) => setState(() => supportsQRScanning = hasCamera) - ); + platform + .invokeMethod("android.deviceHasCamera") + .then((hasCamera) => setState(() => supportsQRScanning = hasCamera)); } else { supportsQRScanning = true; } @@ -143,9 +143,11 @@ class _MainScreenState extends State { padding: EdgeInsets.zero, icon: Icon(Icons.add, size: 28.0), onPressed: () => Utils.openPage(context, (context) { - return SiteConfigScreen(onSave: (_) { - _loadSites(); - }, supportsQRScanning: supportsQRScanning); + return SiteConfigScreen( + onSave: (_) { + _loadSites(); + }, + supportsQRScanning: supportsQRScanning); }), ), refreshController: refreshController, @@ -210,9 +212,9 @@ class _MainScreenState extends State { onPressed: () { Utils.openPage(context, (context) { return SiteDetailScreen( - site: site, - onChanged: () => _loadSites(), - supportsQRScanning: supportsQRScanning, + site: site, + onChanged: () => _loadSites(), + supportsQRScanning: supportsQRScanning, ); }); })); @@ -289,16 +291,15 @@ class _MainScreenState extends State { ); } - Widget _debugClearKeys() { + Widget _debugClearKeys() { return CupertinoButton( child: Text("Clear Keys"), onPressed: () async { - await platform.invokeMethod("debug.clearKeys", null); - }, + await platform.invokeMethod("debug.clearKeys", null); + }, ); } - _loadSites() async { //TODO: This can throw, we need to show an error dialog Map rawSites = jsonDecode(await platform.invokeMethod('listSites')); @@ -322,7 +323,6 @@ class _MainScreenState extends State { } }); - sites!.add(site); } catch (err) { //TODO: handle error diff --git a/lib/screens/SettingsScreen.dart b/lib/screens/SettingsScreen.dart index d287e6b..50cfa0e 100644 --- a/lib/screens/SettingsScreen.dart +++ b/lib/screens/SettingsScreen.dart @@ -86,13 +86,14 @@ class _SettingsScreenState extends State { )), )); - final dnIcon = Theme.of(context).brightness == Brightness.dark ? 'images/dn-logo-dark.svg' : 'images/dn-logo-light.svg'; + final dnIcon = + Theme.of(context).brightness == Brightness.dark ? 'images/dn-logo-dark.svg' : 'images/dn-logo-light.svg'; items.add(ConfigSection(children: [ ConfigPageItem( - label: Text('Enroll with Managed Nebula'), - labelWidth: 200, - onPressed: () => Utils.openPage(context, (context) => EnrollmentScreen(stream: widget.stream, allowCodeEntry: true)) - ) + label: Text('Enroll with Managed Nebula'), + labelWidth: 200, + onPressed: () => + Utils.openPage(context, (context) => EnrollmentScreen(stream: widget.stream, allowCodeEntry: true))) ])); items.add(ConfigSection(children: [ diff --git a/lib/screens/SiteDetailScreen.dart b/lib/screens/SiteDetailScreen.dart index a69b4c1..6bf2c19 100644 --- a/lib/screens/SiteDetailScreen.dart +++ b/lib/screens/SiteDetailScreen.dart @@ -79,11 +79,12 @@ class _SiteDetailScreenState extends State { @override Widget build(BuildContext context) { - final dnIcon = Theme.of(context).brightness == Brightness.dark ? 'images/dn-logo-dark.svg' : 'images/dn-logo-light.svg'; + final dnIcon = + Theme.of(context).brightness == Brightness.dark ? 'images/dn-logo-dark.svg' : 'images/dn-logo-light.svg'; final title = Row(children: [ - site.managed ? - Padding(padding: EdgeInsets.only(right: 10), child: SvgPicture.asset(dnIcon, width: 12)) : - Container(), + site.managed + ? Padding(padding: EdgeInsets.only(right: 10), child: SvgPicture.asset(dnIcon, width: 12)) + : Container(), Expanded(child: Text(site.name, style: TextStyle(fontWeight: FontWeight.bold))) ]); @@ -192,16 +193,16 @@ class _SiteDetailScreenState extends State { Utils.openPage( context, (context) => SiteTunnelsScreen( - pending: false, - tunnels: activeHosts!, - site: site, - onChanged: (hosts) { - setState(() { - activeHosts = hosts; - }); - }, - supportsQRScanning: widget.supportsQRScanning, - )); + pending: false, + tunnels: activeHosts!, + site: site, + onChanged: (hosts) { + setState(() { + activeHosts = hosts; + }); + }, + supportsQRScanning: widget.supportsQRScanning, + )); }, label: Text("Active"), content: Container(alignment: Alignment.centerRight, child: active)), @@ -212,16 +213,16 @@ class _SiteDetailScreenState extends State { Utils.openPage( context, (context) => SiteTunnelsScreen( - pending: true, - tunnels: pendingHosts!, - site: site, - onChanged: (hosts) { - setState(() { - pendingHosts = hosts; - }); - }, - supportsQRScanning: widget.supportsQRScanning, - )); + pending: true, + tunnels: pendingHosts!, + site: site, + onChanged: (hosts) { + setState(() { + pendingHosts = hosts; + }); + }, + supportsQRScanning: widget.supportsQRScanning, + )); }, label: Text("Pending"), content: Container(alignment: Alignment.centerRight, child: pending)) @@ -237,11 +238,11 @@ class _SiteDetailScreenState extends State { onPressed: () { Utils.openPage(context, (context) { return SiteConfigScreen( - site: widget.site, - onSave: (site) async { - changed = true; - setState(() {}); - }, + site: widget.site, + onSave: (site) async { + changed = true; + setState(() {}); + }, supportsQRScanning: widget.supportsQRScanning, ); }); diff --git a/lib/screens/SiteLogsScreen.dart b/lib/screens/SiteLogsScreen.dart index 7634152..3ac812e 100644 --- a/lib/screens/SiteLogsScreen.dart +++ b/lib/screens/SiteLogsScreen.dart @@ -40,11 +40,12 @@ class _SiteLogsScreenState extends State { @override Widget build(BuildContext context) { - final dnIcon = Theme.of(context).brightness == Brightness.dark ? 'images/dn-logo-dark.svg' : 'images/dn-logo-light.svg'; + final dnIcon = + Theme.of(context).brightness == Brightness.dark ? 'images/dn-logo-dark.svg' : 'images/dn-logo-light.svg'; final title = Row(children: [ - widget.site.managed ? - Padding(padding: EdgeInsets.only(right: 10), child: SvgPicture.asset(dnIcon, width: 12)) : - Container(), + widget.site.managed + ? Padding(padding: EdgeInsets.only(right: 10), child: SvgPicture.asset(dnIcon, width: 12)) + : Container(), Expanded(child: Text(widget.site.name, style: TextStyle(fontWeight: FontWeight.bold))) ]); @@ -83,29 +84,26 @@ class _SiteLogsScreenState extends State { border: Border(top: borderSide), ), child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ - Expanded( - child: Builder( - builder: (BuildContext context) { - return PlatformIconButton( - padding: padding, - icon: Icon(context.platformIcons.share, size: 30), - onPressed: () { - Share.shareFile(context, - title: '${widget.site.name} logs', - filePath: widget.site.logFile, - filename: '${widget.site.name}.log'); - }, - ); - } - )), + Expanded(child: Builder(builder: (BuildContext context) { + return PlatformIconButton( + padding: padding, + icon: Icon(context.platformIcons.share, size: 30), + onPressed: () { + Share.shareFile(context, + title: '${widget.site.name} logs', + filePath: widget.site.logFile, + filename: '${widget.site.name}.log'); + }, + ); + })), Expanded( child: PlatformIconButton( - padding: padding, - icon: Icon(context.platformIcons.downArrow, size: 30), - onPressed: () async { - controller.animateTo(controller.position.maxScrollExtent, - duration: const Duration(milliseconds: 500), curve: Curves.linearToEaseOut); - }, + padding: padding, + icon: Icon(context.platformIcons.downArrow, size: 30), + onPressed: () async { + controller.animateTo(controller.position.maxScrollExtent, + duration: const Duration(milliseconds: 500), curve: Curves.linearToEaseOut); + }, )), ])); } diff --git a/lib/screens/SiteTunnelsScreen.dart b/lib/screens/SiteTunnelsScreen.dart index 133f4c3..706d851 100644 --- a/lib/screens/SiteTunnelsScreen.dart +++ b/lib/screens/SiteTunnelsScreen.dart @@ -17,8 +17,7 @@ class SiteTunnelsScreen extends StatefulWidget { required this.pending, required this.onChanged, required this.supportsQRScanning, - }) - : super(key: key); + }) : super(key: key); final Site site; final List tunnels; @@ -67,17 +66,17 @@ class _SiteTunnelsScreenState extends State { children.add(ConfigPageItem( onPressed: () => Utils.openPage( - context, - (context) => HostInfoScreen( - isLighthouse: isLh, - hostInfo: hostInfo, - pending: widget.pending, - site: widget.site, - onChanged: () { - _listHostmap(); - }, - supportsQRScanning: widget.supportsQRScanning, - ), + context, + (context) => HostInfoScreen( + isLighthouse: isLh, + hostInfo: hostInfo, + pending: widget.pending, + site: widget.site, + onChanged: () { + _listHostmap(); + }, + supportsQRScanning: widget.supportsQRScanning, + ), ), label: Row(children: [Padding(child: icon, padding: EdgeInsets.only(right: 10)), Text(hostInfo.vpnIp)]), labelWidth: ipWidth, diff --git a/lib/screens/siteConfig/AddCertificateScreen.dart b/lib/screens/siteConfig/AddCertificateScreen.dart index ae90a8c..af567d3 100644 --- a/lib/screens/siteConfig/AddCertificateScreen.dart +++ b/lib/screens/siteConfig/AddCertificateScreen.dart @@ -98,12 +98,10 @@ class _AddCertificateScreenState extends State { content: Text('Share Public Key'), onPressed: () async { await Share.share(context, - title: 'Please sign and return a certificate', - text: pubKey, - filename: 'device.pub'); + title: 'Please sign and return a certificate', text: pubKey, filename: 'device.pub'); }, ); - }, + }, ), ]) ]; @@ -269,12 +267,12 @@ class _AddCertificateScreenState extends State { // We have a cert, pop the details screen where they can hit save Utils.openPage(context, (context) { return CertificateDetailsScreen( - certInfo: tryCertInfo, - onSave: () { - Navigator.pop(context); - widget.onSave!(CertificateResult(certInfo: tryCertInfo, key: keyController.text)); - }, - supportsQRScanning: widget.supportsQRScanning, + certInfo: tryCertInfo, + onSave: () { + Navigator.pop(context); + widget.onSave!(CertificateResult(certInfo: tryCertInfo, key: keyController.text)); + }, + supportsQRScanning: widget.supportsQRScanning, ); }); } diff --git a/lib/screens/siteConfig/AdvancedScreen.dart b/lib/screens/siteConfig/AdvancedScreen.dart index f76a5ed..247b981 100644 --- a/lib/screens/siteConfig/AdvancedScreen.dart +++ b/lib/screens/siteConfig/AdvancedScreen.dart @@ -86,62 +86,62 @@ class _AdvancedScreenState extends State { label: Text("Lighthouse interval"), labelWidth: 200, //TODO: Auto select on focus? - content: widget.site.managed ? - Text(settings.lhDuration.toString() + " seconds", textAlign: TextAlign.right) : - PlatformTextFormField( - initialValue: settings.lhDuration.toString(), - keyboardType: TextInputType.number, - suffix: Text("seconds"), - textAlign: TextAlign.right, - maxLength: 5, - inputFormatters: [FilteringTextInputFormatter.digitsOnly], - onSaved: (val) { - setState(() { - if (val != null) { - settings.lhDuration = int.parse(val); - } - }); - }, - )), + content: widget.site.managed + ? Text(settings.lhDuration.toString() + " seconds", textAlign: TextAlign.right) + : PlatformTextFormField( + initialValue: settings.lhDuration.toString(), + keyboardType: TextInputType.number, + suffix: Text("seconds"), + textAlign: TextAlign.right, + maxLength: 5, + inputFormatters: [FilteringTextInputFormatter.digitsOnly], + onSaved: (val) { + setState(() { + if (val != null) { + settings.lhDuration = int.parse(val); + } + }); + }, + )), ConfigItem( label: Text("Listen port"), labelWidth: 150, //TODO: Auto select on focus? - content: widget.site.managed ? - Text(settings.port.toString(), textAlign: TextAlign.right) : - PlatformTextFormField( - initialValue: settings.port.toString(), - keyboardType: TextInputType.number, - textAlign: TextAlign.right, - maxLength: 5, - inputFormatters: [FilteringTextInputFormatter.digitsOnly], - onSaved: (val) { - setState(() { - if (val != null) { - settings.port = int.parse(val); - } - }); - }, - )), + content: widget.site.managed + ? Text(settings.port.toString(), textAlign: TextAlign.right) + : PlatformTextFormField( + initialValue: settings.port.toString(), + keyboardType: TextInputType.number, + textAlign: TextAlign.right, + maxLength: 5, + inputFormatters: [FilteringTextInputFormatter.digitsOnly], + onSaved: (val) { + setState(() { + if (val != null) { + settings.port = int.parse(val); + } + }); + }, + )), ConfigItem( label: Text("MTU"), labelWidth: 150, - content: widget.site.managed ? - Text(settings.mtu.toString(), textAlign: TextAlign.right) : - PlatformTextFormField( - initialValue: settings.mtu.toString(), - keyboardType: TextInputType.number, - textAlign: TextAlign.right, - maxLength: 5, - inputFormatters: [FilteringTextInputFormatter.digitsOnly], - onSaved: (val) { - setState(() { - if (val != null) { - settings.mtu = int.parse(val); - } - }); - }, - )), + content: widget.site.managed + ? Text(settings.mtu.toString(), textAlign: TextAlign.right) + : PlatformTextFormField( + initialValue: settings.mtu.toString(), + keyboardType: TextInputType.number, + textAlign: TextAlign.right, + maxLength: 5, + inputFormatters: [FilteringTextInputFormatter.digitsOnly], + onSaved: (val) { + setState(() { + if (val != null) { + settings.mtu = int.parse(val); + } + }); + }, + )), ConfigPageItem( disabled: widget.site.managed, label: Text('Cipher'), @@ -184,12 +184,14 @@ class _AdvancedScreenState extends State { Utils.openPage(context, (context) { return UnsafeRoutesScreen( unsafeRoutes: settings.unsafeRoutes, - onSave: widget.site.managed ? null : (routes) { - setState(() { - settings.unsafeRoutes = routes; - changed = true; - }); - }); + onSave: widget.site.managed + ? null + : (routes) { + setState(() { + settings.unsafeRoutes = routes; + changed = true; + }); + }); }); }, ) diff --git a/lib/screens/siteConfig/CAListScreen.dart b/lib/screens/siteConfig/CAListScreen.dart index 65bcf72..df2958f 100644 --- a/lib/screens/siteConfig/CAListScreen.dart +++ b/lib/screens/siteConfig/CAListScreen.dart @@ -64,18 +64,18 @@ class _CAListScreenState extends State { } return FormPage( - title: 'Certificate Authorities', - changed: changed, - onSave: () { - if (widget.onSave != null) { - Navigator.pop(context); - widget.onSave!(cas.values.map((ca) { - return ca; - }).toList()); - } - }, - child: Column(children: items)); - } + title: 'Certificate Authorities', + changed: changed, + onSave: () { + if (widget.onSave != null) { + Navigator.pop(context); + widget.onSave!(cas.values.map((ca) { + return ca; + }).toList()); + } + }, + child: Column(children: items)); + } List _buildCAs() { List items = []; @@ -85,14 +85,16 @@ class _CAListScreenState extends State { onPressed: () { Utils.openPage(context, (context) { return CertificateDetailsScreen( - certInfo: ca, - onDelete: widget.onSave == null ? null : () { - setState(() { - changed = true; - cas.remove(key); - }); - }, - supportsQRScanning: widget.supportsQRScanning, + certInfo: ca, + onDelete: widget.onSave == null + ? null + : () { + setState(() { + changed = true; + cas.remove(key); + }); + }, + supportsQRScanning: widget.supportsQRScanning, ); }); }, diff --git a/lib/screens/siteConfig/CertificateDetailsScreen.dart b/lib/screens/siteConfig/CertificateDetailsScreen.dart index 1ca0ea6..f6fb76c 100644 --- a/lib/screens/siteConfig/CertificateDetailsScreen.dart +++ b/lib/screens/siteConfig/CertificateDetailsScreen.dart @@ -170,19 +170,19 @@ class _CertificateDetailsScreenState extends State { onPressed: () { Utils.openPage(context, (context) { return AddCertificateScreen( - onReplace: (result) { - setState(() { - changed = true; - certResult = result; - certInfo = result.certInfo; - }); - // Slam the page back to the top - controller.animateTo(0, - duration: const Duration(milliseconds: 10), curve: Curves.linearToEaseOut); - }, - pubKey: widget.pubKey!, - privKey: widget.privKey!, - supportsQRScanning: widget.supportsQRScanning, + onReplace: (result) { + setState(() { + changed = true; + certResult = result; + certInfo = result.certInfo; + }); + // Slam the page back to the top + controller.animateTo(0, + duration: const Duration(milliseconds: 10), curve: Curves.linearToEaseOut); + }, + pubKey: widget.pubKey!, + privKey: widget.privKey!, + supportsQRScanning: widget.supportsQRScanning, ); }); }))); diff --git a/lib/screens/siteConfig/RenderedConfigScreen.dart b/lib/screens/siteConfig/RenderedConfigScreen.dart index 16d6fbf..f0246c3 100644 --- a/lib/screens/siteConfig/RenderedConfigScreen.dart +++ b/lib/screens/siteConfig/RenderedConfigScreen.dart @@ -19,17 +19,13 @@ class RenderedConfigScreen extends StatelessWidget { title: Text('Rendered Site Config'), scrollable: SimpleScrollable.both, trailingActions: [ - Builder( - builder: (BuildContext context) { - return PlatformIconButton( - padding: EdgeInsets.zero, - icon: Icon(context.platformIcons.share, size: 28.0), - onPressed: () => - Share.share(context, - title: '$name.yaml', text: config, filename: '$name.yaml'), - ); - } - ), + Builder(builder: (BuildContext context) { + return PlatformIconButton( + padding: EdgeInsets.zero, + icon: Icon(context.platformIcons.share, size: 28.0), + onPressed: () => Share.share(context, title: '$name.yaml', text: config, filename: '$name.yaml'), + ); + }), ], child: Container( padding: EdgeInsets.all(5), diff --git a/lib/screens/siteConfig/SiteConfigScreen.dart b/lib/screens/siteConfig/SiteConfigScreen.dart index 1709a4d..5c187ec 100644 --- a/lib/screens/siteConfig/SiteConfigScreen.dart +++ b/lib/screens/siteConfig/SiteConfigScreen.dart @@ -139,17 +139,17 @@ class _SiteConfigScreenState extends State { lastUpdate = formatter.format(site.lastManagedUpdate!.toLocal()); } - return site.managed ? ConfigSection( - label: "MANAGED CONFIG", - children: [ - ConfigItem( - label: Text("Last Update"), - content: Wrap(alignment: WrapAlignment.end, crossAxisAlignment: WrapCrossAlignment.center, children: [ - Text(lastUpdate), - ]), - ) - ] - ) : Container(); + return site.managed + ? ConfigSection(label: "MANAGED CONFIG", children: [ + ConfigItem( + label: Text("Last Update"), + content: + Wrap(alignment: WrapAlignment.end, crossAxisAlignment: WrapCrossAlignment.center, children: [ + Text(lastUpdate), + ]), + ) + ]) + : Container(); } Widget _keys() { @@ -183,30 +183,32 @@ class _SiteConfigScreenState extends State { Utils.openPage(context, (context) { if (site.certInfo != null) { return CertificateDetailsScreen( - certInfo: site.certInfo!, - pubKey: pubKey, - privKey: privKey, - onReplace: site.managed ? null : (result) { - setState(() { - changed = true; - site.certInfo = result.certInfo; - site.key = result.key; - }); - }, - supportsQRScanning: widget.supportsQRScanning, + certInfo: site.certInfo!, + pubKey: pubKey, + privKey: privKey, + onReplace: site.managed + ? null + : (result) { + setState(() { + changed = true; + site.certInfo = result.certInfo; + site.key = result.key; + }); + }, + supportsQRScanning: widget.supportsQRScanning, ); } return AddCertificateScreen( - pubKey: pubKey!, - privKey: privKey!, - onSave: (result) { - setState(() { - changed = true; - site.certInfo = result.certInfo; - site.key = result.key; - }); - }, + pubKey: pubKey!, + privKey: privKey!, + onSave: (result) { + setState(() { + changed = true; + site.certInfo = result.certInfo; + site.key = result.key; + }); + }, supportsQRScanning: widget.supportsQRScanning, ); }); @@ -226,14 +228,16 @@ class _SiteConfigScreenState extends State { onPressed: () { Utils.openPage(context, (context) { return CAListScreen( - cas: site.ca, - onSave: site.managed ? null : (ca) { - setState(() { - changed = true; - site.ca = ca; - }); - }, - supportsQRScanning: widget.supportsQRScanning, + cas: site.ca, + onSave: site.managed + ? null + : (ca) { + setState(() { + changed = true; + site.ca = ca; + }); + }, + supportsQRScanning: widget.supportsQRScanning, ); }); }) @@ -261,12 +265,14 @@ class _SiteConfigScreenState extends State { Utils.openPage(context, (context) { return StaticHostsScreen( hostmap: site.staticHostmap, - onSave: site.managed ? null : (map) { - setState(() { - changed = true; - site.staticHostmap = map; - }); - }); + onSave: site.managed + ? null + : (map) { + setState(() { + changed = true; + site.staticHostmap = map; + }); + }); }); }, ), diff --git a/lib/screens/siteConfig/StaticHostmapScreen.dart b/lib/screens/siteConfig/StaticHostmapScreen.dart index 814c380..f07e028 100644 --- a/lib/screens/siteConfig/StaticHostmapScreen.dart +++ b/lib/screens/siteConfig/StaticHostmapScreen.dart @@ -66,7 +66,11 @@ class _StaticHostmapScreenState extends State { @override Widget build(BuildContext context) { return FormPage( - title: widget.onDelete == null ? widget.onSave == null ? 'View Static Host' : 'New Static Host' : 'Edit Static Host', + title: widget.onDelete == null + ? widget.onSave == null + ? 'View Static Host' + : 'New Static Host' + : 'Edit Static Host', changed: changed, onSave: _onSave, child: Column(children: [ @@ -74,20 +78,20 @@ class _StaticHostmapScreenState extends State { ConfigItem( label: Text('Nebula IP'), labelWidth: 200, - content: widget.onSave == null ? - Text(_nebulaIp, textAlign: TextAlign.end) : - IPFormField( - help: "Required", - initialValue: _nebulaIp, - ipOnly: true, - textAlign: TextAlign.end, - crossAxisAlignment: CrossAxisAlignment.end, - textInputAction: TextInputAction.next, - onSaved: (v) { - if (v != null) { - _nebulaIp = v; - } - })), + content: widget.onSave == null + ? Text(_nebulaIp, textAlign: TextAlign.end) + : IPFormField( + help: "Required", + initialValue: _nebulaIp, + ipOnly: true, + textAlign: TextAlign.end, + crossAxisAlignment: CrossAxisAlignment.end, + textInputAction: TextInputAction.next, + onSaved: (v) { + if (v != null) { + _nebulaIp = v; + } + })), ConfigItem( label: Text('Lighthouse'), labelWidth: 200, @@ -96,12 +100,14 @@ class _StaticHostmapScreenState extends State { child: Switch.adaptive( value: _lighthouse, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, - onChanged: widget.onSave == null ? null : (v) { - setState(() { - changed = true; - _lighthouse = v; - }); - })), + onChanged: widget.onSave == null + ? null + : (v) { + setState(() { + changed = true; + _lighthouse = v; + }); + })), ), ]), ConfigSection( @@ -128,8 +134,7 @@ class _StaticHostmapScreenState extends State { _onSave() { Navigator.pop(context); if (widget.onSave != null) { - var map = Hostmap( - nebulaIp: _nebulaIp, destinations: [], lighthouse: _lighthouse); + var map = Hostmap(nebulaIp: _nebulaIp, destinations: [], lighthouse: _lighthouse); _destinations.forEach((_, dest) { map.destinations.add(dest.destination); @@ -147,30 +152,32 @@ class _StaticHostmapScreenState extends State { key: key, label: Align( alignment: Alignment.centerLeft, - child: widget.onSave == null ? Container() : PlatformIconButton( - padding: EdgeInsets.zero, - icon: Icon(Icons.remove_circle, color: CupertinoColors.systemRed.resolveFrom(context)), - onPressed: () => setState(() { - _removeDestination(key); - _dismissKeyboard(); - }))), + child: widget.onSave == null + ? Container() + : PlatformIconButton( + padding: EdgeInsets.zero, + icon: Icon(Icons.remove_circle, color: CupertinoColors.systemRed.resolveFrom(context)), + onPressed: () => setState(() { + _removeDestination(key); + _dismissKeyboard(); + }))), labelWidth: 70, content: Row(children: [ Expanded( - child: widget.onSave == null ? - Text(dest.destination.toString(), textAlign: TextAlign.end) : - IPAndPortFormField( - ipHelp: 'public ip or name', - ipTextAlign: TextAlign.end, - enableIPV6: true, - noBorder: true, - initialValue: dest.destination, - onSaved: (v) { - if (v != null) { - dest.destination = v; - } - }, - )), + child: widget.onSave == null + ? Text(dest.destination.toString(), textAlign: TextAlign.end) + : IPAndPortFormField( + ipHelp: 'public ip or name', + ipTextAlign: TextAlign.end, + enableIPV6: true, + noBorder: true, + initialValue: dest.destination, + onSaved: (v) { + if (v != null) { + dest.destination = v; + } + }, + )), ]), )); }); @@ -178,8 +185,7 @@ class _StaticHostmapScreenState extends State { if (widget.onSave != null) { items.add(ConfigButtonItem( content: Text('Add another'), - onPressed: () => - setState(() { + onPressed: () => setState(() { _addDestination(); _dismissKeyboard(); }))); diff --git a/lib/screens/siteConfig/StaticHostsScreen.dart b/lib/screens/siteConfig/StaticHostsScreen.dart index c77f39c..f9a5ea5 100644 --- a/lib/screens/siteConfig/StaticHostsScreen.dart +++ b/lib/screens/siteConfig/StaticHostsScreen.dart @@ -70,8 +70,7 @@ class _StaticHostsScreenState extends State { if (widget.onSave != null) { Map map = {}; _hostmap.forEach((_, host) { - map[host.nebulaIp] = StaticHost( - destinations: host.destinations, lighthouse: host.lighthouse); + map[host.nebulaIp] = StaticHost(destinations: host.destinations, lighthouse: host.lighthouse); }); widget.onSave!(map); @@ -98,20 +97,24 @@ class _StaticHostsScreenState extends State { nebulaIp: host.nebulaIp, destinations: host.destinations, lighthouse: host.lighthouse, - onSave: widget.onSave == null ? null :(map) { - setState(() { - changed = true; - host.nebulaIp = map.nebulaIp; - host.destinations = map.destinations; - host.lighthouse = map.lighthouse; - }); - }, - onDelete: widget.onSave == null ? null : () { - setState(() { - changed = true; - _hostmap.remove(key); - }); - }); + onSave: widget.onSave == null + ? null + : (map) { + setState(() { + changed = true; + host.nebulaIp = map.nebulaIp; + host.destinations = map.destinations; + host.lighthouse = map.lighthouse; + }); + }, + onDelete: widget.onSave == null + ? null + : () { + setState(() { + changed = true; + _hostmap.remove(key); + }); + }); }); }, )); diff --git a/lib/services/share.dart b/lib/services/share.dart index 7707aa3..23f6a4f 100644 --- a/lib/services/share.dart +++ b/lib/services/share.dart @@ -41,9 +41,7 @@ class Share { /// - filePath: Path to the file to share /// - filename: An optional filename to override the existing file static Future shareFile(BuildContext context, - {required String title, - required String filePath, - String? filename}) async { + {required String title, required String filePath, String? filename}) async { assert(title.isNotEmpty); assert(filePath.isNotEmpty); @@ -54,8 +52,7 @@ class Share { // and then delete it final xFile = sp.XFile(filePath, name: filename); final result = await sp.Share.shareXFiles([xFile], - subject: title, - sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size); + subject: title, sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size); return result.status == sp.ShareResultStatus.success; } }