Add a manual enrollment flow to support chromeos (#99)
This commit is contained in:
parent
17cc3477b7
commit
8fc3a40467
|
@ -109,21 +109,18 @@ class _AppState extends State<App> {
|
|||
),
|
||||
onGenerateRoute: (settings) {
|
||||
if (settings.name == '/') {
|
||||
return platformPageRoute(context: context, builder: (context) => MainScreen(this.dnEnrolled.stream));
|
||||
return platformPageRoute(context: context, builder: (context) => MainScreen(this.dnEnrolled));
|
||||
}
|
||||
|
||||
final uri = Uri.parse(settings.name!);
|
||||
if (uri.path == EnrollmentScreen.routeName) {
|
||||
String? code;
|
||||
if (uri.hasFragment) {
|
||||
final qp = Uri.splitQueryString(uri.fragment);
|
||||
code = qp["code"];
|
||||
}
|
||||
|
||||
// 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: code, stream: this.dnEnrolled),
|
||||
builder: (context) => EnrollmentScreen(
|
||||
code: EnrollmentScreen.parseCode(settings.name!),
|
||||
stream: this.dnEnrolled
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -73,7 +73,7 @@ class _AboutScreenState extends State<AboutScreen> {
|
|||
Padding(
|
||||
padding: EdgeInsets.only(top: 20),
|
||||
child: Text(
|
||||
'Copyright © 2020 Defined Networking, Inc',
|
||||
'Copyright © 2022 Defined Networking, Inc',
|
||||
textAlign: TextAlign.center,
|
||||
)),
|
||||
]),
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
|
||||
import 'package:mobile_nebula/components/SimplePage.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
@ -16,6 +16,22 @@ class EnrollmentScreen extends StatefulWidget {
|
|||
|
||||
static const routeName = '/v1/mobile-enrollment';
|
||||
|
||||
// Attempts to find an enrollment code in the provided url. If one is not found then assume the input was
|
||||
// an enrollment code. Primarily to support manual dn enrollment where the user can input a code or a url.
|
||||
static String parseCode(String url) {
|
||||
final uri = Uri.parse(url);
|
||||
if (uri.path != EnrollmentScreen.routeName) {
|
||||
return url;
|
||||
}
|
||||
|
||||
if (uri.hasFragment) {
|
||||
final qp = Uri.splitQueryString(uri.fragment);
|
||||
return qp["code"] ?? "";
|
||||
}
|
||||
|
||||
return url;
|
||||
}
|
||||
|
||||
const EnrollmentScreen({super.key, this.code, this.stream, this.allowCodeEntry = false});
|
||||
|
||||
@override
|
||||
|
@ -138,20 +154,33 @@ class _EnrollmentScreenState extends State<EnrollmentScreen> {
|
|||
));
|
||||
}
|
||||
|
||||
return SimplePage(title: Text('DN Enrollment'), child: Padding(child: child, padding: EdgeInsets.symmetric(horizontal: 10)), alignment: alignment);
|
||||
final dnIcon = Theme.of(context).brightness == Brightness.dark ? 'images/dn-logo-dark.svg' : 'images/dn-logo-light.svg';
|
||||
return SimplePage(
|
||||
title: Text('Enroll with DN', style: TextStyle(fontWeight: FontWeight.bold)),
|
||||
child: Padding(child: child, padding: EdgeInsets.symmetric(horizontal: 10)),
|
||||
alignment: alignment
|
||||
);
|
||||
}
|
||||
|
||||
Widget _codeEntry() {
|
||||
return Column(children: [
|
||||
Container(height: 20),
|
||||
PlatformTextField(controller: enrollInput),
|
||||
CupertinoButton(child: Text('Enroll'), onPressed: () {
|
||||
setState(() {
|
||||
code = enrollInput.text;
|
||||
error = null;
|
||||
_enroll();
|
||||
});
|
||||
}),
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 20),
|
||||
child: PlatformTextField(
|
||||
hintText: 'Enrollment code or link',
|
||||
controller: enrollInput
|
||||
)
|
||||
),
|
||||
PlatformTextButton(
|
||||
child: Text('Submit'),
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
code = EnrollmentScreen.parseCode(enrollInput.text);
|
||||
error = null;
|
||||
_enroll();
|
||||
});
|
||||
},
|
||||
)
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ MAIH7gzreMGgrH/yR6rZpIHR3DxJ3E0aHtEI
|
|||
class MainScreen extends StatefulWidget {
|
||||
const MainScreen(this.dnEnrollStream, {Key? key}) : super(key: key);
|
||||
|
||||
final Stream dnEnrollStream;
|
||||
final StreamController dnEnrollStream;
|
||||
|
||||
@override
|
||||
_MainScreenState createState() => _MainScreenState();
|
||||
|
@ -82,7 +82,7 @@ class _MainScreenState extends State<MainScreen> {
|
|||
void initState() {
|
||||
_loadSites();
|
||||
|
||||
widget.dnEnrollStream.listen((_) {
|
||||
widget.dnEnrollStream.stream.listen((_) {
|
||||
_loadSites();
|
||||
});
|
||||
|
||||
|
@ -146,7 +146,7 @@ class _MainScreenState extends State<MainScreen> {
|
|||
PlatformIconButton(
|
||||
padding: EdgeInsets.zero,
|
||||
icon: Icon(Icons.menu, size: 28.0),
|
||||
onPressed: () => Utils.openPage(context, (_) => SettingsScreen()),
|
||||
onPressed: () => Utils.openPage(context, (_) => SettingsScreen(widget.dnEnrollStream)),
|
||||
),
|
||||
],
|
||||
bottomBar: debugSite,
|
||||
|
|
|
@ -1,18 +1,24 @@
|
|||
import 'dart:async';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_svg/svg.dart';
|
||||
import 'package:mobile_nebula/components/SimplePage.dart';
|
||||
import 'package:mobile_nebula/components/config/ConfigItem.dart';
|
||||
import 'package:mobile_nebula/components/config/ConfigPageItem.dart';
|
||||
import 'package:mobile_nebula/components/config/ConfigSection.dart';
|
||||
import 'package:mobile_nebula/screens/EnrollmentScreen.dart';
|
||||
import 'package:mobile_nebula/services/settings.dart';
|
||||
import 'package:mobile_nebula/services/utils.dart';
|
||||
|
||||
import 'AboutScreen.dart';
|
||||
|
||||
class SettingsScreen extends StatefulWidget {
|
||||
final StreamController stream;
|
||||
|
||||
const SettingsScreen(this.stream, {super.key});
|
||||
|
||||
@override
|
||||
_SettingsScreenState createState() {
|
||||
return _SettingsScreenState();
|
||||
}
|
||||
_SettingsScreenState createState() => _SettingsScreenState();
|
||||
}
|
||||
|
||||
class _SettingsScreenState extends State<SettingsScreen> {
|
||||
|
@ -79,6 +85,16 @@ class _SettingsScreenState extends State<SettingsScreen> {
|
|||
},
|
||||
)),
|
||||
));
|
||||
|
||||
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 DN'),
|
||||
labelWidth: 200,
|
||||
onPressed: () => Utils.openPage(context, (context) => EnrollmentScreen(stream: widget.stream, allowCodeEntry: true))
|
||||
)
|
||||
]));
|
||||
|
||||
items.add(ConfigSection(children: [
|
||||
ConfigPageItem(
|
||||
label: Text('About'),
|
||||
|
|
Loading…
Reference in New Issue