Update Flutter, target android SDK 34 (#160)

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.
This commit is contained in:
Ian VanSchooten 2024-09-20 14:19:23 -04:00 committed by GitHub
parent f576aa0c50
commit 64d45f66c7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
45 changed files with 760 additions and 618 deletions

View File

@ -18,7 +18,7 @@ jobs:
- name: Install flutter - name: Install flutter
uses: subosito/flutter-action@v2 uses: subosito/flutter-action@v2
with: with:
flutter-version: '3.3.5' flutter-version: '3.24.1'
- name: Check out code - name: Check out code
uses: actions/checkout@v3 uses: actions/checkout@v3

View File

@ -24,7 +24,7 @@ jobs:
- name: Install flutter - name: Install flutter
uses: subosito/flutter-action@v2 uses: subosito/flutter-action@v2
with: with:
flutter-version: '3.3.5' flutter-version: '3.24.1'
- uses: nttld/setup-ndk@v1 - uses: nttld/setup-ndk@v1
id: setup-ndk id: setup-ndk

View File

@ -8,7 +8,7 @@ Install all of the following things:
- [`xcode`](https://apps.apple.com/us/app/xcode/) - [`xcode`](https://apps.apple.com/us/app/xcode/)
- [`android-studio`](https://developer.android.com/studio) - [`android-studio`](https://developer.android.com/studio)
- [`flutter` 3.3.5](https://docs.flutter.dev/get-started/install) - [`flutter` 3.24.1](https://docs.flutter.dev/get-started/install)
- [`gomobile`](https://pkg.go.dev/golang.org/x/mobile/cmd/gomobile) - [`gomobile`](https://pkg.go.dev/golang.org/x/mobile/cmd/gomobile)
- [Flutter Android Studio Extension](https://docs.flutter.dev/get-started/editor?tab=androidstudio) - [Flutter Android Studio Extension](https://docs.flutter.dev/get-started/editor?tab=androidstudio)

View File

@ -1,3 +1,9 @@
plugins {
id "com.android.application"
id "kotlin-android"
id "dev.flutter.flutter-gradle-plugin"
}
def localProperties = new Properties() def localProperties = new Properties()
def localPropertiesFile = rootProject.file('local.properties') def localPropertiesFile = rootProject.file('local.properties')
if (localPropertiesFile.exists()) { if (localPropertiesFile.exists()) {
@ -6,10 +12,6 @@ if (localPropertiesFile.exists()) {
} }
} }
def flutterRoot = localProperties.getProperty('flutter.sdk')
if (flutterRoot == null) {
throw new GradleException("Flutter SDK not found. Define location with flutter.sdk in the local.properties file.")
}
def flutterVersionCode = localProperties.getProperty('flutter.versionCode') def flutterVersionCode = localProperties.getProperty('flutter.versionCode')
if (flutterVersionCode == null) { if (flutterVersionCode == null) {
@ -21,15 +23,10 @@ if (flutterVersionName == null) {
flutterVersionName = '1.0' flutterVersionName = '1.0'
} }
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle"
android { android {
namespace "net.defined.mobile_nebula" namespace "net.defined.mobile_nebula"
compileSdkVersion 33 compileSdkVersion 34
ndkVersion flutter.ndkVersion
compileOptions { compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8 sourceCompatibility JavaVersion.VERSION_1_8
@ -37,7 +34,7 @@ android {
} }
kotlinOptions { kotlinOptions {
jvmTarget = '1.8' jvmTarget = JavaVersion.VERSION_1_8
} }
sourceSets { sourceSets {
@ -47,7 +44,7 @@ android {
defaultConfig { defaultConfig {
applicationId "net.defined.mobile_nebula" applicationId "net.defined.mobile_nebula"
minSdkVersion 26 //flutter.minSdkVersion minSdkVersion 26 //flutter.minSdkVersion
targetSdkVersion 33 //flutter.targetSdkVersion targetSdkVersion 34 //flutter.targetSdkVersion
versionCode flutterVersionCode.toInteger() versionCode flutterVersionCode.toInteger()
versionName flutterVersionName versionName flutterVersionName
} }
@ -80,7 +77,7 @@ flutter {
} }
dependencies { dependencies {
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk7:$kotlinVersion" def workVersion = "2.7.1"
implementation "androidx.security:security-crypto:1.0.0" implementation "androidx.security:security-crypto:1.0.0"
implementation "androidx.work:work-runtime-ktx:$workVersion" implementation "androidx.work:work-runtime-ktx:$workVersion"
implementation 'com.google.code.gson:gson:2.8.9' implementation 'com.google.code.gson:gson:2.8.9'

View File

@ -1,20 +1,3 @@
buildscript {
ext {
workVersion = "2.7.1"
kotlinVersion = '1.7.20'
}
repositories {
google()
mavenCentral()
}
dependencies {
classpath 'com.android.tools.build:gradle:7.3.1'
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
}
}
allprojects { allprojects {
repositories { repositories {
google() google()

View File

@ -2,4 +2,4 @@ distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-7.4-all.zip distributionUrl=https\://services.gradle.org/distributions/gradle-7.5-all.zip

View File

@ -1,11 +1,25 @@
include ':app', ':mobileNebula' pluginManagement {
def flutterSdkPath = {
def properties = new Properties()
file("local.properties").withInputStream { properties.load(it) }
def flutterSdkPath = properties.getProperty("flutter.sdk")
assert flutterSdkPath != null, "flutter.sdk not set in local.properties"
return flutterSdkPath
}()
def localPropertiesFile = new File(rootProject.projectDir, "local.properties") includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
def properties = new Properties()
assert localPropertiesFile.exists() repositories {
localPropertiesFile.withReader("UTF-8") { reader -> properties.load(reader) } google()
mavenCentral()
gradlePluginPortal()
}
}
def flutterSdkPath = properties.getProperty("flutter.sdk") plugins {
assert flutterSdkPath != null, "flutter.sdk not set in local.properties" id "dev.flutter.flutter-plugin-loader" version "1.0.0"
apply from: "$flutterSdkPath/packages/flutter_tools/gradle/app_plugin_loader.gradle" id "com.android.application" version "7.4.2" apply false
id "org.jetbrains.kotlin.android" version "1.7.20" apply false
}
include ':app', ':mobileNebula'

View File

@ -21,6 +21,6 @@
<key>CFBundleVersion</key> <key>CFBundleVersion</key>
<string>1.0</string> <string>1.0</string>
<key>MinimumOSVersion</key> <key>MinimumOSVersion</key>
<string>11.0</string> <string>12.0</string>
</dict> </dict>
</plist> </plist>

View File

@ -38,8 +38,9 @@ PODS:
- Flutter - Flutter
- package_info (0.0.1): - package_info (0.0.1):
- Flutter - Flutter
- path_provider_ios (0.0.1): - path_provider_foundation (0.0.1):
- Flutter - Flutter
- FlutterMacOS
- SDWebImage (5.15.5): - SDWebImage (5.15.5):
- SDWebImage/Core (= 5.15.5) - SDWebImage/Core (= 5.15.5)
- SDWebImage/Core (5.15.5) - SDWebImage/Core (5.15.5)
@ -55,7 +56,7 @@ DEPENDENCIES:
- Flutter (from `Flutter`) - Flutter (from `Flutter`)
- flutter_barcode_scanner (from `.symlinks/plugins/flutter_barcode_scanner/ios`) - flutter_barcode_scanner (from `.symlinks/plugins/flutter_barcode_scanner/ios`)
- package_info (from `.symlinks/plugins/package_info/ios`) - package_info (from `.symlinks/plugins/package_info/ios`)
- path_provider_ios (from `.symlinks/plugins/path_provider_ios/ios`) - path_provider_foundation (from `.symlinks/plugins/path_provider_foundation/darwin`)
- share_plus (from `.symlinks/plugins/share_plus/ios`) - share_plus (from `.symlinks/plugins/share_plus/ios`)
- SwiftyJSON (~> 5.0) - SwiftyJSON (~> 5.0)
- url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`) - url_launcher_ios (from `.symlinks/plugins/url_launcher_ios/ios`)
@ -77,8 +78,8 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/flutter_barcode_scanner/ios" :path: ".symlinks/plugins/flutter_barcode_scanner/ios"
package_info: package_info:
:path: ".symlinks/plugins/package_info/ios" :path: ".symlinks/plugins/package_info/ios"
path_provider_ios: path_provider_foundation:
:path: ".symlinks/plugins/path_provider_ios/ios" :path: ".symlinks/plugins/path_provider_foundation/darwin"
share_plus: share_plus:
:path: ".symlinks/plugins/share_plus/ios" :path: ".symlinks/plugins/share_plus/ios"
url_launcher_ios: url_launcher_ios:
@ -87,17 +88,17 @@ EXTERNAL SOURCES:
SPEC CHECKSUMS: SPEC CHECKSUMS:
DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac DKImagePickerController: b512c28220a2b8ac7419f21c491fc8534b7601ac
DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179 DKPhotoGallery: fdfad5125a9fdda9cc57df834d49df790dbb4179
file_picker: 817ab1d8cd2da9d2da412a417162deee3500fc95 file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655
Flutter: f04841e97a9d0b0a8025694d0796dd46242b2854 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_barcode_scanner: 7a1144744c28dc0c57a8de7218ffe5ec59a9e4bf flutter_barcode_scanner: 7a1144744c28dc0c57a8de7218ffe5ec59a9e4bf
package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62 package_info: 873975fc26034f0b863a300ad47e7f1ac6c7ec62
path_provider_ios: 7d7ce634493af4477d156294792024ec3485acd5 path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46
SDWebImage: fd7e1a22f00303e058058278639bf6196ee431fe SDWebImage: fd7e1a22f00303e058058278639bf6196ee431fe
share_plus: 056a1e8ac890df3e33cb503afffaf1e9b4fbae68 share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad
SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f SwiftyGif: 93a1cc87bf3a51916001cf8f3d63835fb64c819f
SwiftyJSON: 2f33a42c6fbc52764d96f13368585094bfd8aa5e SwiftyJSON: 2f33a42c6fbc52764d96f13368585094bfd8aa5e
url_launcher_ios: 02f1989d4e14e998335b02b67a7590fa34f971af url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe
PODFILE CHECKSUM: b4b37a776e1b487bf31fc5e5014fa5a74f5a022a PODFILE CHECKSUM: b4b37a776e1b487bf31fc5e5014fa5a74f5a022a
COCOAPODS: 1.11.3 COCOAPODS: 1.15.2

View File

@ -3,7 +3,7 @@
archiveVersion = 1; archiveVersion = 1;
classes = { classes = {
}; };
objectVersion = 52; objectVersion = 54;
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
@ -266,9 +266,9 @@
97C146EB1CF9000F007C117D /* Frameworks */, 97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */, 97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */, 9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
43AA89612444DA6500EDC39C /* Embed App Extensions */, 43AA89612444DA6500EDC39C /* Embed App Extensions */,
00C7A79AE88792090BDAC68B /* [CP] Embed Pods Frameworks */, 00C7A79AE88792090BDAC68B /* [CP] Embed Pods Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
); );
buildRules = ( buildRules = (
); );
@ -287,7 +287,7 @@
isa = PBXProject; isa = PBXProject;
attributes = { attributes = {
LastSwiftUpdateCheck = 1140; LastSwiftUpdateCheck = 1140;
LastUpgradeCheck = 1300; LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "The Chromium Authors"; ORGANIZATIONNAME = "The Chromium Authors";
TargetAttributes = { TargetAttributes = {
43AA89532444DA6500EDC39C = { 43AA89532444DA6500EDC39C = {
@ -358,7 +358,7 @@
"${BUILT_PRODUCTS_DIR}/file_picker/file_picker.framework", "${BUILT_PRODUCTS_DIR}/file_picker/file_picker.framework",
"${BUILT_PRODUCTS_DIR}/flutter_barcode_scanner/flutter_barcode_scanner.framework", "${BUILT_PRODUCTS_DIR}/flutter_barcode_scanner/flutter_barcode_scanner.framework",
"${BUILT_PRODUCTS_DIR}/package_info/package_info.framework", "${BUILT_PRODUCTS_DIR}/package_info/package_info.framework",
"${BUILT_PRODUCTS_DIR}/path_provider_ios/path_provider_ios.framework", "${BUILT_PRODUCTS_DIR}/path_provider_foundation/path_provider_foundation.framework",
"${BUILT_PRODUCTS_DIR}/share_plus/share_plus.framework", "${BUILT_PRODUCTS_DIR}/share_plus/share_plus.framework",
"${BUILT_PRODUCTS_DIR}/url_launcher_ios/url_launcher_ios.framework", "${BUILT_PRODUCTS_DIR}/url_launcher_ios/url_launcher_ios.framework",
); );
@ -372,7 +372,7 @@
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/file_picker.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/file_picker.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_barcode_scanner.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/flutter_barcode_scanner.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/package_info.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/package_info.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_ios.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/path_provider_foundation.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/share_plus.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/share_plus.framework",
"${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher_ios.framework", "${TARGET_BUILD_DIR}/${FRAMEWORKS_FOLDER_PATH}/url_launcher_ios.framework",
); );
@ -405,10 +405,12 @@
}; };
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = { 3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );
inputPaths = ( inputPaths = (
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
); );
name = "Thin Binary"; name = "Thin Binary";
outputPaths = ( outputPaths = (
@ -419,6 +421,7 @@
}; };
9740EEB61CF901F6004384FC /* Run Script */ = { 9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
); );

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<Scheme <Scheme
LastUpgradeVersion = "1300" LastUpgradeVersion = "1510"
version = "1.7"> version = "1.7">
<BuildAction <BuildAction
parallelizeBuildables = "YES" parallelizeBuildables = "YES"

View File

@ -12,7 +12,7 @@ func MissingArgumentError(message: String, details: Any?) -> FlutterError {
return FlutterError(code: "missing_argument", message: message, details: details) return FlutterError(code: "missing_argument", message: message, details: details)
} }
@UIApplicationMain @main
@objc class AppDelegate: FlutterAppDelegate { @objc class AppDelegate: FlutterAppDelegate {
private let dnUpdater = DNUpdater() private let dnUpdater = DNUpdater()
private let apiClient = APIClient() private let apiClient = APIClient()

View File

@ -64,5 +64,7 @@
</array> </array>
<key>UIViewControllerBasedStatusBarAppearance</key> <key>UIViewControllerBasedStatusBarAppearance</key>
<false/> <false/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict> </dict>
</plist> </plist>

View File

@ -1,5 +1,3 @@
import 'dart:async';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
import 'package:mobile_nebula/components/SimplePage.dart'; import 'package:mobile_nebula/components/SimplePage.dart';
@ -40,19 +38,17 @@ class _FormPageState extends State<FormPage> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
changed = widget.changed || changed; changed = widget.changed || changed;
return WillPopScope( return PopScope<Object?>(
onWillPop: () { canPop: false,
if (!changed) { onPopInvokedWithResult: (bool didPop, Object? result) async {
return Future.value(true); if (didPop) {
return;
} }
final NavigatorState navigator = Navigator.of(context);
var completer = Completer<bool>();
Utils.confirmDelete(context, 'Discard changes?', () { Utils.confirmDelete(context, 'Discard changes?', () {
completer.complete(true); navigator.pop();
}, deleteLabel: 'Yes', cancelLabel: 'No'); }, deleteLabel: 'Yes', cancelLabel: 'No');
return completer.future;
}, },
child: SimplePage( child: SimplePage(
leadingAction: _buildLeader(context), leadingAction: _buildLeader(context),

View File

@ -28,7 +28,8 @@ class SiteItem extends StatelessWidget {
Widget _buildContent(BuildContext context) { Widget _buildContent(BuildContext context) {
final border = BorderSide(color: Utils.configSectionBorder(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( return SpecialButton(
decoration: decoration:
@ -39,9 +40,9 @@ class SiteItem extends StatelessWidget {
child: Row( child: Row(
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
children: <Widget>[ children: <Widget>[
site.managed ? site.managed
Padding(padding: EdgeInsets.only(right: 10), child: SvgPicture.asset(dnIcon, width: 12)) : ? Padding(padding: EdgeInsets.only(right: 10), child: SvgPicture.asset(dnIcon, width: 12))
Container(), : Container(),
Expanded(child: Text(site.name, style: TextStyle(fontWeight: FontWeight.bold))), Expanded(child: Text(site.name, style: TextStyle(fontWeight: FontWeight.bold))),
Padding(padding: EdgeInsets.only(right: 10)), Padding(padding: EdgeInsets.only(right: 10)),
Icon(CupertinoIcons.forward, color: CupertinoColors.placeholderText.resolveFrom(context), size: 18) Icon(CupertinoIcons.forward, color: CupertinoColors.placeholderText.resolveFrom(context), size: 18)

View File

@ -28,7 +28,7 @@ class _SpecialButtonState extends State<SpecialButton> with SingleTickerProvider
Widget _buildAndroid() { Widget _buildAndroid() {
var textStyle; var textStyle;
if (widget.useButtonTheme) { if (widget.useButtonTheme) {
textStyle = Theme.of(context).textTheme.button; textStyle = Theme.of(context).textTheme.labelLarge;
} }
return Material( return Material(

View File

@ -90,7 +90,7 @@ class _SpecialTextFieldState extends State<SpecialTextField> {
autofocus: widget.autofocus, autofocus: widget.autofocus,
focusNode: widget.focusNode, focusNode: widget.focusNode,
onChanged: widget.onChanged, onChanged: widget.onChanged,
enabled: widget.enabled, enabled: widget.enabled ?? true,
onSubmitted: (_) { onSubmitted: (_) {
if (widget.nextFocusNode != null) { if (widget.nextFocusNode != null) {
FocusScope.of(context).requestFocus(widget.nextFocusNode); FocusScope.of(context).requestFocus(widget.nextFocusNode);

View File

@ -4,7 +4,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
TextStyle basicTextStyle(BuildContext context) => TextStyle basicTextStyle(BuildContext context) =>
Platform.isIOS ? CupertinoTheme.of(context).textTheme.textStyle : Theme.of(context).textTheme.subtitle1!; Platform.isIOS ? CupertinoTheme.of(context).textTheme.textStyle : Theme.of(context).textTheme.titleMedium!;
const double _headerFontSize = 13.0; const double _headerFontSize = 13.0;

View File

@ -31,7 +31,7 @@ class ConfigPageItem extends StatelessWidget {
final origTheme = Theme.of(context); final origTheme = Theme.of(context);
theme = origTheme.copyWith( theme = origTheme.copyWith(
textTheme: origTheme.textTheme textTheme: origTheme.textTheme
.copyWith(button: origTheme.textTheme.button!.copyWith(fontWeight: FontWeight.normal))); .copyWith(labelLarge: origTheme.textTheme.labelLarge!.copyWith(fontWeight: FontWeight.normal)));
return Theme(data: theme, child: _buildContent(context)); return Theme(data: theme, child: _buildContent(context));
} else { } else {
final origTheme = CupertinoTheme.of(context); final origTheme = CupertinoTheme.of(context);
@ -52,7 +52,9 @@ class ConfigPageItem extends StatelessWidget {
children: <Widget>[ children: <Widget>[
label != null ? Container(width: labelWidth, child: label) : Container(), label != null ? Container(width: labelWidth, child: label) : Container(),
Expanded(child: Container(child: content, padding: EdgeInsets.only(right: 10))), 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)
], ],
)), )),
); );

View File

@ -2,7 +2,7 @@ import 'dart:async';
import 'package:flutter/cupertino.dart' show CupertinoThemeData, DefaultCupertinoLocalizations; import 'package:flutter/cupertino.dart' show CupertinoThemeData, DefaultCupertinoLocalizations;
import 'package:flutter/material.dart' import 'package:flutter/material.dart'
show BottomSheetThemeData, Colors, DefaultMaterialLocalizations, Theme, ThemeData, ThemeMode; show BottomSheetThemeData, Colors, DefaultMaterialLocalizations, ThemeData, ThemeMode, MaterialApp, Scaffold;
import 'package:flutter/scheduler.dart'; import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart'; import 'package:flutter/widgets.dart';
@ -32,7 +32,7 @@ class App extends StatefulWidget {
class _AppState extends State<App> { class _AppState extends State<App> {
final settings = Settings(); final settings = Settings();
Brightness brightness = SchedulerBinding.instance.window.platformBrightness; Brightness brightness = SchedulerBinding.instance.platformDispatcher.platformBrightness;
StreamController dnEnrolled = StreamController.broadcast(); StreamController dnEnrolled = StreamController.broadcast();
@override @override
@ -58,12 +58,10 @@ class _AppState extends State<App> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
final ThemeData lightTheme = ThemeData( final ThemeData lightTheme = ThemeData(
useMaterial3: false,
brightness: Brightness.light, brightness: Brightness.light,
primarySwatch: Colors.blueGrey, primarySwatch: Colors.blueGrey,
primaryColor: Colors.blueGrey[900], primaryColor: Colors.blueGrey[900],
primaryColorBrightness: Brightness.dark,
accentColor: Colors.cyan[600],
accentColorBrightness: Brightness.dark,
fontFamily: 'PublicSans', fontFamily: 'PublicSans',
//scaffoldBackgroundColor: Colors.grey[100], //scaffoldBackgroundColor: Colors.grey[100],
scaffoldBackgroundColor: Colors.white, scaffoldBackgroundColor: Colors.white,
@ -73,12 +71,10 @@ class _AppState extends State<App> {
); );
final ThemeData darkTheme = ThemeData( final ThemeData darkTheme = ThemeData(
useMaterial3: false,
brightness: Brightness.dark, brightness: Brightness.dark,
primarySwatch: Colors.grey, primarySwatch: Colors.grey,
primaryColor: Colors.grey[900], primaryColor: Colors.grey[900],
primaryColorBrightness: Brightness.dark,
accentColor: Colors.cyan[600],
accentColorBrightness: Brightness.dark,
fontFamily: 'PublicSans', fontFamily: 'PublicSans',
scaffoldBackgroundColor: Colors.grey[800], scaffoldBackgroundColor: Colors.grey[800],
bottomSheetTheme: BottomSheetThemeData( bottomSheetTheme: BottomSheetThemeData(
@ -86,10 +82,10 @@ class _AppState extends State<App> {
), ),
); );
// This theme is required since icons light/dark mode will look for it return MaterialApp(
return Theme( theme: brightness == Brightness.light ? lightTheme : darkTheme,
data: brightness == Brightness.light ? lightTheme : darkTheme, home: Scaffold(
child: PlatformProvider( body: PlatformProvider(
//initialPlatform: initialPlatform, //initialPlatform: initialPlatform,
builder: (context) => PlatformApp( builder: (context) => PlatformApp(
debugShowCheckedModeBanner: false, debugShowCheckedModeBanner: false,
@ -116,11 +112,9 @@ class _AppState extends State<App> {
if (uri.path == EnrollmentScreen.routeName) { 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 // TODO: maybe implement this as a dialog instead of a page, you can stack multiple enrollment screens which is annoying in dev
return platformPageRoute( return platformPageRoute(
context: context, context: context,
builder: (context) => EnrollmentScreen( builder: (context) =>
code: EnrollmentScreen.parseCode(settings.name!), EnrollmentScreen(code: EnrollmentScreen.parseCode(settings.name!), stream: this.dnEnrolled),
stream: this.dnEnrolled
),
); );
} }
@ -128,6 +122,7 @@ class _AppState extends State<App> {
}, },
), ),
), ),
),
); );
} }
} }

View File

@ -206,8 +206,7 @@ class Site {
"unsafeRoutes": unsafeRoutes, "unsafeRoutes": unsafeRoutes,
"managed": json['managed'] ?? false, "managed": json['managed'] ?? false,
"rawConfig": json['rawConfig'], "rawConfig": json['rawConfig'],
"lastManagedUpdate": json["lastManagedUpdate"] == null ? "lastManagedUpdate": json["lastManagedUpdate"] == null ? null : DateTime.parse(json["lastManagedUpdate"]),
null : DateTime.parse(json["lastManagedUpdate"]),
}; };
} }

View File

@ -6,7 +6,7 @@ import 'package:mobile_nebula/components/config/ConfigPageItem.dart';
import 'package:mobile_nebula/components/config/ConfigSection.dart'; import 'package:mobile_nebula/components/config/ConfigSection.dart';
import 'package:mobile_nebula/gen.versions.dart'; import 'package:mobile_nebula/gen.versions.dart';
import 'package:mobile_nebula/services/utils.dart'; import 'package:mobile_nebula/services/utils.dart';
import 'package:package_info/package_info.dart'; import 'package:package_info_plus/package_info_plus.dart';
class AboutScreen extends StatefulWidget { class AboutScreen extends StatefulWidget {
const AboutScreen({Key? key}) : super(key: key); const AboutScreen({Key? key}) : super(key: key);

View File

@ -4,7 +4,6 @@ import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter/services.dart'; import 'package:flutter/services.dart';
import 'package:flutter_platform_widgets/flutter_platform_widgets.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:mobile_nebula/components/SimplePage.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
@ -91,37 +90,38 @@ class _EnrollmentScreenState extends State<EnrollmentScreen> {
} else { } else {
// No code, show the error // No code, show the error
child = Padding( 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.', 'No valid enrollment code was found.\n\nContact your administrator to obtain a new enrollment code.',
textAlign: TextAlign.center, textAlign: TextAlign.center,
)), )),
padding: EdgeInsets.only(top: 20) padding: EdgeInsets.only(top: 20));
);
} }
} else if (this.error != null) { } else if (this.error != null) {
// Error while enrolling, display it // Error while enrolling, display it
child = Center(child: Column( child = Center(
child: Column(
children: [ children: [
Padding( Padding(
child: SelectableText('There was an issue while attempting to enroll this device. Contact your administrator to obtain a new enrollment code.'), child: SelectableText(
padding: EdgeInsets.symmetric(vertical: 20) '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: [ Padding(
TextSpan(text: 'If the problem persists, please let us know at '), child: SelectableText.rich(TextSpan(children: [
TextSpan( TextSpan(text: 'If the problem persists, please let us know at '),
text: 'support@defined.net', TextSpan(
style: bodyTextStyle.apply(color: colorScheme.primary), text: 'support@defined.net',
recognizer: TapGestureRecognizer() style: bodyTextStyle.apply(color: colorScheme.primary),
..onTap = () async { recognizer: TapGestureRecognizer()
if (await canLaunchUrl(contactUri)) { ..onTap = () async {
print(await launchUrl(contactUri)); if (await canLaunchUrl(contactUri)) {
} print(await launchUrl(contactUri));
}, }
), },
TextSpan(text: ' and provide the following error:'), ),
])), padding: EdgeInsets.only(bottom: 10)), TextSpan(text: ' and provide the following error:'),
])),
padding: EdgeInsets.only(bottom: 10)),
Container( Container(
child: Padding(child: SelectableText(this.error!), padding: EdgeInsets.all(10)), child: Padding(child: SelectableText(this.error!), padding: EdgeInsets.all(10)),
color: Theme.of(context).colorScheme.errorContainer, color: Theme.of(context).colorScheme.errorContainer,
@ -130,47 +130,41 @@ class _EnrollmentScreenState extends State<EnrollmentScreen> {
crossAxisAlignment: CrossAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.center, mainAxisAlignment: MainAxisAlignment.center,
)); ));
} else if (this.enrolled) { } else if (this.enrolled) {
// Enrollment complete! // Enrollment complete!
child = Padding( child = Padding(
child: Center(child: Text( child: Center(
child: Text(
'Enrollment complete! 🎉', 'Enrollment complete! 🎉',
textAlign: TextAlign.center, textAlign: TextAlign.center,
)), )),
padding: EdgeInsets.only(top: 20) padding: EdgeInsets.only(top: 20));
);
} else { } else {
// Have a code and actively enrolling // Have a code and actively enrolling
alignment = Alignment.center; alignment = Alignment.center;
child = Center(child: Column( child = Center(
children: [ child: Column(children: [
Padding(child: Text('Contacting DN for enrollment'), padding: EdgeInsets.only(bottom: 25)), Padding(child: Text('Contacting DN for enrollment'), padding: EdgeInsets.only(bottom: 25)),
PlatformCircularProgressIndicator(cupertino: (_, __) { PlatformCircularProgressIndicator(cupertino: (_, __) {
return CupertinoProgressIndicatorData(radius: 50); return CupertinoProgressIndicatorData(radius: 50);
}) })
] ]));
));
} }
final dnIcon = Theme.of(context).brightness == Brightness.dark ? 'images/dn-logo-dark.svg' : 'images/dn-logo-light.svg';
return SimplePage( return SimplePage(
title: Text('Enroll with Managed Nebula', style: TextStyle(fontWeight: FontWeight.bold)), title: Text('Enroll with Managed Nebula', style: TextStyle(fontWeight: FontWeight.bold)),
child: Padding(child: child, padding: EdgeInsets.symmetric(horizontal: 10)), child: Padding(child: child, padding: EdgeInsets.symmetric(horizontal: 10)),
alignment: alignment alignment: alignment);
);
} }
Widget _codeEntry() { Widget _codeEntry() {
return Column(children: [ return Column(children: [
Padding( Padding(
padding: EdgeInsets.only(top: 20), padding: EdgeInsets.only(top: 20),
child: PlatformTextField( child: PlatformTextField(
hintText: 'defined.net enrollment code or link', hintText: 'defined.net enrollment code or link',
controller: enrollInput, controller: enrollInput,
) )),
),
PlatformTextButton( PlatformTextButton(
child: Text('Submit'), child: Text('Submit'),
onPressed: () { onPressed: () {

View File

@ -75,10 +75,11 @@ class _HostInfoScreenState extends State<HostInfoScreen> {
labelWidth: 150, labelWidth: 150,
content: Text(hostInfo.cert!.details.name), content: Text(hostInfo.cert!.details.name),
onPressed: () => Utils.openPage( onPressed: () => Utils.openPage(
context, (context) => CertificateDetailsScreen( context,
certInfo: CertificateInfo(cert: hostInfo.cert!), (context) => CertificateDetailsScreen(
supportsQRScanning: widget.supportsQRScanning, certInfo: CertificateInfo(cert: hostInfo.cert!),
))) supportsQRScanning: widget.supportsQRScanning,
)))
: Container(), : Container(),
]); ]);
} }

View File

@ -14,7 +14,6 @@ import 'package:mobile_nebula/models/IPAndPort.dart';
import 'package:mobile_nebula/models/Site.dart'; import 'package:mobile_nebula/models/Site.dart';
import 'package:mobile_nebula/models/StaticHosts.dart'; import 'package:mobile_nebula/models/StaticHosts.dart';
import 'package:mobile_nebula/models/UnsafeRoute.dart'; import 'package:mobile_nebula/models/UnsafeRoute.dart';
import 'package:mobile_nebula/screens/EnrollmentScreen.dart';
import 'package:mobile_nebula/screens/SettingsScreen.dart'; import 'package:mobile_nebula/screens/SettingsScreen.dart';
import 'package:mobile_nebula/screens/SiteDetailScreen.dart'; import 'package:mobile_nebula/screens/SiteDetailScreen.dart';
import 'package:mobile_nebula/screens/siteConfig/SiteConfigScreen.dart'; import 'package:mobile_nebula/screens/siteConfig/SiteConfigScreen.dart';
@ -128,9 +127,9 @@ class _MainScreenState extends State<MainScreen> {
// Determine whether the device supports QR scanning. For example, some // Determine whether the device supports QR scanning. For example, some
// Chromebooks do not have camera support. // Chromebooks do not have camera support.
if (Platform.isAndroid) { if (Platform.isAndroid) {
platform.invokeMethod("android.deviceHasCamera").then( platform
(hasCamera) => setState(() => supportsQRScanning = hasCamera) .invokeMethod("android.deviceHasCamera")
); .then((hasCamera) => setState(() => supportsQRScanning = hasCamera));
} else { } else {
supportsQRScanning = true; supportsQRScanning = true;
} }
@ -143,9 +142,11 @@ class _MainScreenState extends State<MainScreen> {
padding: EdgeInsets.zero, padding: EdgeInsets.zero,
icon: Icon(Icons.add, size: 28.0), icon: Icon(Icons.add, size: 28.0),
onPressed: () => Utils.openPage(context, (context) { onPressed: () => Utils.openPage(context, (context) {
return SiteConfigScreen(onSave: (_) { return SiteConfigScreen(
_loadSites(); onSave: (_) {
}, supportsQRScanning: supportsQRScanning); _loadSites();
},
supportsQRScanning: supportsQRScanning);
}), }),
), ),
refreshController: refreshController, refreshController: refreshController,
@ -210,9 +211,9 @@ class _MainScreenState extends State<MainScreen> {
onPressed: () { onPressed: () {
Utils.openPage(context, (context) { Utils.openPage(context, (context) {
return SiteDetailScreen( return SiteDetailScreen(
site: site, site: site,
onChanged: () => _loadSites(), onChanged: () => _loadSites(),
supportsQRScanning: supportsQRScanning, supportsQRScanning: supportsQRScanning,
); );
}); });
})); }));
@ -289,28 +290,23 @@ class _MainScreenState extends State<MainScreen> {
); );
} }
Widget _debugClearKeys() { Widget _debugClearKeys() {
return CupertinoButton( return CupertinoButton(
child: Text("Clear Keys"), child: Text("Clear Keys"),
onPressed: () async { onPressed: () async {
await platform.invokeMethod("debug.clearKeys", null); await platform.invokeMethod("debug.clearKeys", null);
}, },
); );
} }
_loadSites() async { _loadSites() async {
//TODO: This can throw, we need to show an error dialog //TODO: This can throw, we need to show an error dialog
Map<String, dynamic> rawSites = jsonDecode(await platform.invokeMethod('listSites')); Map<String, dynamic> rawSites = jsonDecode(await platform.invokeMethod('listSites'));
bool hasErrors = false;
sites = []; sites = [];
rawSites.forEach((id, rawSite) { rawSites.forEach((id, rawSite) {
try { try {
var site = Site.fromJson(rawSite); var site = Site.fromJson(rawSite);
if (site.errors.length > 0) {
hasErrors = true;
}
//TODO: we need to cancel change listeners when we rebuild //TODO: we need to cancel change listeners when we rebuild
site.onChange().listen((_) { site.onChange().listen((_) {
@ -322,7 +318,6 @@ class _MainScreenState extends State<MainScreen> {
} }
}); });
sites!.add(site); sites!.add(site);
} catch (err) { } catch (err) {
//TODO: handle error //TODO: handle error

View File

@ -1,7 +1,6 @@
import 'dart:async'; import 'dart:async';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_svg/svg.dart';
import 'package:mobile_nebula/components/SimplePage.dart'; import 'package:mobile_nebula/components/SimplePage.dart';
import 'package:mobile_nebula/components/config/ConfigItem.dart'; import 'package:mobile_nebula/components/config/ConfigItem.dart';
import 'package:mobile_nebula/components/config/ConfigPageItem.dart'; import 'package:mobile_nebula/components/config/ConfigPageItem.dart';
@ -86,13 +85,12 @@ 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: [ items.add(ConfigSection(children: [
ConfigPageItem( ConfigPageItem(
label: Text('Enroll with Managed Nebula'), label: Text('Enroll with Managed Nebula'),
labelWidth: 200, labelWidth: 200,
onPressed: () => Utils.openPage(context, (context) => EnrollmentScreen(stream: widget.stream, allowCodeEntry: true)) onPressed: () =>
) Utils.openPage(context, (context) => EnrollmentScreen(stream: widget.stream, allowCodeEntry: true)))
])); ]));
items.add(ConfigSection(children: [ items.add(ConfigSection(children: [

View File

@ -79,11 +79,12 @@ class _SiteDetailScreenState extends State<SiteDetailScreen> {
@override @override
Widget build(BuildContext context) { 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: [ final title = Row(children: [
site.managed ? site.managed
Padding(padding: EdgeInsets.only(right: 10), child: SvgPicture.asset(dnIcon, width: 12)) : ? Padding(padding: EdgeInsets.only(right: 10), child: SvgPicture.asset(dnIcon, width: 12))
Container(), : Container(),
Expanded(child: Text(site.name, style: TextStyle(fontWeight: FontWeight.bold))) Expanded(child: Text(site.name, style: TextStyle(fontWeight: FontWeight.bold)))
]); ]);
@ -192,16 +193,16 @@ class _SiteDetailScreenState extends State<SiteDetailScreen> {
Utils.openPage( Utils.openPage(
context, context,
(context) => SiteTunnelsScreen( (context) => SiteTunnelsScreen(
pending: false, pending: false,
tunnels: activeHosts!, tunnels: activeHosts!,
site: site, site: site,
onChanged: (hosts) { onChanged: (hosts) {
setState(() { setState(() {
activeHosts = hosts; activeHosts = hosts;
}); });
}, },
supportsQRScanning: widget.supportsQRScanning, supportsQRScanning: widget.supportsQRScanning,
)); ));
}, },
label: Text("Active"), label: Text("Active"),
content: Container(alignment: Alignment.centerRight, child: active)), content: Container(alignment: Alignment.centerRight, child: active)),
@ -212,16 +213,16 @@ class _SiteDetailScreenState extends State<SiteDetailScreen> {
Utils.openPage( Utils.openPage(
context, context,
(context) => SiteTunnelsScreen( (context) => SiteTunnelsScreen(
pending: true, pending: true,
tunnels: pendingHosts!, tunnels: pendingHosts!,
site: site, site: site,
onChanged: (hosts) { onChanged: (hosts) {
setState(() { setState(() {
pendingHosts = hosts; pendingHosts = hosts;
}); });
}, },
supportsQRScanning: widget.supportsQRScanning, supportsQRScanning: widget.supportsQRScanning,
)); ));
}, },
label: Text("Pending"), label: Text("Pending"),
content: Container(alignment: Alignment.centerRight, child: pending)) content: Container(alignment: Alignment.centerRight, child: pending))
@ -237,11 +238,11 @@ class _SiteDetailScreenState extends State<SiteDetailScreen> {
onPressed: () { onPressed: () {
Utils.openPage(context, (context) { Utils.openPage(context, (context) {
return SiteConfigScreen( return SiteConfigScreen(
site: widget.site, site: widget.site,
onSave: (site) async { onSave: (site) async {
changed = true; changed = true;
setState(() {}); setState(() {});
}, },
supportsQRScanning: widget.supportsQRScanning, supportsQRScanning: widget.supportsQRScanning,
); );
}); });

View File

@ -40,11 +40,12 @@ class _SiteLogsScreenState extends State<SiteLogsScreen> {
@override @override
Widget build(BuildContext context) { 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: [ final title = Row(children: [
widget.site.managed ? widget.site.managed
Padding(padding: EdgeInsets.only(right: 10), child: SvgPicture.asset(dnIcon, width: 12)) : ? Padding(padding: EdgeInsets.only(right: 10), child: SvgPicture.asset(dnIcon, width: 12))
Container(), : Container(),
Expanded(child: Text(widget.site.name, style: TextStyle(fontWeight: FontWeight.bold))) Expanded(child: Text(widget.site.name, style: TextStyle(fontWeight: FontWeight.bold)))
]); ]);
@ -83,29 +84,26 @@ class _SiteLogsScreenState extends State<SiteLogsScreen> {
border: Border(top: borderSide), border: Border(top: borderSide),
), ),
child: Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[ child: Row(mainAxisAlignment: MainAxisAlignment.center, children: <Widget>[
Expanded( Expanded(child: Builder(builder: (BuildContext context) {
child: Builder( return PlatformIconButton(
builder: (BuildContext context) { padding: padding,
return PlatformIconButton( icon: Icon(context.platformIcons.share, size: 30),
padding: padding, onPressed: () {
icon: Icon(context.platformIcons.share, size: 30), Share.shareFile(context,
onPressed: () { title: '${widget.site.name} logs',
Share.shareFile(context, filePath: widget.site.logFile,
title: '${widget.site.name} logs', filename: '${widget.site.name}.log');
filePath: widget.site.logFile, },
filename: '${widget.site.name}.log'); );
}, })),
);
}
)),
Expanded( Expanded(
child: PlatformIconButton( child: PlatformIconButton(
padding: padding, padding: padding,
icon: Icon(context.platformIcons.downArrow, size: 30), icon: Icon(context.platformIcons.downArrow, size: 30),
onPressed: () async { onPressed: () async {
controller.animateTo(controller.position.maxScrollExtent, controller.animateTo(controller.position.maxScrollExtent,
duration: const Duration(milliseconds: 500), curve: Curves.linearToEaseOut); duration: const Duration(milliseconds: 500), curve: Curves.linearToEaseOut);
}, },
)), )),
])); ]));
} }

View File

@ -17,8 +17,7 @@ class SiteTunnelsScreen extends StatefulWidget {
required this.pending, required this.pending,
required this.onChanged, required this.onChanged,
required this.supportsQRScanning, required this.supportsQRScanning,
}) }) : super(key: key);
: super(key: key);
final Site site; final Site site;
final List<HostInfo> tunnels; final List<HostInfo> tunnels;
@ -67,17 +66,17 @@ class _SiteTunnelsScreenState extends State<SiteTunnelsScreen> {
children.add(ConfigPageItem( children.add(ConfigPageItem(
onPressed: () => Utils.openPage( onPressed: () => Utils.openPage(
context, context,
(context) => HostInfoScreen( (context) => HostInfoScreen(
isLighthouse: isLh, isLighthouse: isLh,
hostInfo: hostInfo, hostInfo: hostInfo,
pending: widget.pending, pending: widget.pending,
site: widget.site, site: widget.site,
onChanged: () { onChanged: () {
_listHostmap(); _listHostmap();
}, },
supportsQRScanning: widget.supportsQRScanning, supportsQRScanning: widget.supportsQRScanning,
), ),
), ),
label: Row(children: <Widget>[Padding(child: icon, padding: EdgeInsets.only(right: 10)), Text(hostInfo.vpnIp)]), label: Row(children: <Widget>[Padding(child: icon, padding: EdgeInsets.only(right: 10)), Text(hostInfo.vpnIp)]),
labelWidth: ipWidth, labelWidth: ipWidth,

View File

@ -98,12 +98,10 @@ class _AddCertificateScreenState extends State<AddCertificateScreen> {
content: Text('Share Public Key'), content: Text('Share Public Key'),
onPressed: () async { onPressed: () async {
await Share.share(context, await Share.share(context,
title: 'Please sign and return a certificate', title: 'Please sign and return a certificate', text: pubKey, filename: 'device.pub');
text: pubKey,
filename: 'device.pub');
}, },
); );
}, },
), ),
]) ])
]; ];
@ -269,12 +267,12 @@ class _AddCertificateScreenState extends State<AddCertificateScreen> {
// We have a cert, pop the details screen where they can hit save // We have a cert, pop the details screen where they can hit save
Utils.openPage(context, (context) { Utils.openPage(context, (context) {
return CertificateDetailsScreen( return CertificateDetailsScreen(
certInfo: tryCertInfo, certInfo: tryCertInfo,
onSave: () { onSave: () {
Navigator.pop(context); Navigator.pop(context);
widget.onSave!(CertificateResult(certInfo: tryCertInfo, key: keyController.text)); widget.onSave!(CertificateResult(certInfo: tryCertInfo, key: keyController.text));
}, },
supportsQRScanning: widget.supportsQRScanning, supportsQRScanning: widget.supportsQRScanning,
); );
}); });
} }

View File

@ -86,62 +86,62 @@ class _AdvancedScreenState extends State<AdvancedScreen> {
label: Text("Lighthouse interval"), label: Text("Lighthouse interval"),
labelWidth: 200, labelWidth: 200,
//TODO: Auto select on focus? //TODO: Auto select on focus?
content: widget.site.managed ? content: widget.site.managed
Text(settings.lhDuration.toString() + " seconds", textAlign: TextAlign.right) : ? Text(settings.lhDuration.toString() + " seconds", textAlign: TextAlign.right)
PlatformTextFormField( : PlatformTextFormField(
initialValue: settings.lhDuration.toString(), initialValue: settings.lhDuration.toString(),
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
suffix: Text("seconds"), suffix: Text("seconds"),
textAlign: TextAlign.right, textAlign: TextAlign.right,
maxLength: 5, maxLength: 5,
inputFormatters: [FilteringTextInputFormatter.digitsOnly], inputFormatters: [FilteringTextInputFormatter.digitsOnly],
onSaved: (val) { onSaved: (val) {
setState(() { setState(() {
if (val != null) { if (val != null) {
settings.lhDuration = int.parse(val); settings.lhDuration = int.parse(val);
} }
}); });
}, },
)), )),
ConfigItem( ConfigItem(
label: Text("Listen port"), label: Text("Listen port"),
labelWidth: 150, labelWidth: 150,
//TODO: Auto select on focus? //TODO: Auto select on focus?
content: widget.site.managed ? content: widget.site.managed
Text(settings.port.toString(), textAlign: TextAlign.right) : ? Text(settings.port.toString(), textAlign: TextAlign.right)
PlatformTextFormField( : PlatformTextFormField(
initialValue: settings.port.toString(), initialValue: settings.port.toString(),
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
textAlign: TextAlign.right, textAlign: TextAlign.right,
maxLength: 5, maxLength: 5,
inputFormatters: [FilteringTextInputFormatter.digitsOnly], inputFormatters: [FilteringTextInputFormatter.digitsOnly],
onSaved: (val) { onSaved: (val) {
setState(() { setState(() {
if (val != null) { if (val != null) {
settings.port = int.parse(val); settings.port = int.parse(val);
} }
}); });
}, },
)), )),
ConfigItem( ConfigItem(
label: Text("MTU"), label: Text("MTU"),
labelWidth: 150, labelWidth: 150,
content: widget.site.managed ? content: widget.site.managed
Text(settings.mtu.toString(), textAlign: TextAlign.right) : ? Text(settings.mtu.toString(), textAlign: TextAlign.right)
PlatformTextFormField( : PlatformTextFormField(
initialValue: settings.mtu.toString(), initialValue: settings.mtu.toString(),
keyboardType: TextInputType.number, keyboardType: TextInputType.number,
textAlign: TextAlign.right, textAlign: TextAlign.right,
maxLength: 5, maxLength: 5,
inputFormatters: [FilteringTextInputFormatter.digitsOnly], inputFormatters: [FilteringTextInputFormatter.digitsOnly],
onSaved: (val) { onSaved: (val) {
setState(() { setState(() {
if (val != null) { if (val != null) {
settings.mtu = int.parse(val); settings.mtu = int.parse(val);
} }
}); });
}, },
)), )),
ConfigPageItem( ConfigPageItem(
disabled: widget.site.managed, disabled: widget.site.managed,
label: Text('Cipher'), label: Text('Cipher'),
@ -184,12 +184,14 @@ class _AdvancedScreenState extends State<AdvancedScreen> {
Utils.openPage(context, (context) { Utils.openPage(context, (context) {
return UnsafeRoutesScreen( return UnsafeRoutesScreen(
unsafeRoutes: settings.unsafeRoutes, unsafeRoutes: settings.unsafeRoutes,
onSave: widget.site.managed ? null : (routes) { onSave: widget.site.managed
setState(() { ? null
settings.unsafeRoutes = routes; : (routes) {
changed = true; setState(() {
}); settings.unsafeRoutes = routes;
}); changed = true;
});
});
}); });
}, },
) )

View File

@ -64,18 +64,18 @@ class _CAListScreenState extends State<CAListScreen> {
} }
return FormPage( return FormPage(
title: 'Certificate Authorities', title: 'Certificate Authorities',
changed: changed, changed: changed,
onSave: () { onSave: () {
if (widget.onSave != null) { if (widget.onSave != null) {
Navigator.pop(context); Navigator.pop(context);
widget.onSave!(cas.values.map((ca) { widget.onSave!(cas.values.map((ca) {
return ca; return ca;
}).toList()); }).toList());
} }
}, },
child: Column(children: items)); child: Column(children: items));
} }
List<Widget> _buildCAs() { List<Widget> _buildCAs() {
List<Widget> items = []; List<Widget> items = [];
@ -85,14 +85,16 @@ class _CAListScreenState extends State<CAListScreen> {
onPressed: () { onPressed: () {
Utils.openPage(context, (context) { Utils.openPage(context, (context) {
return CertificateDetailsScreen( return CertificateDetailsScreen(
certInfo: ca, certInfo: ca,
onDelete: widget.onSave == null ? null : () { onDelete: widget.onSave == null
setState(() { ? null
changed = true; : () {
cas.remove(key); setState(() {
}); changed = true;
}, cas.remove(key);
supportsQRScanning: widget.supportsQRScanning, });
},
supportsQRScanning: widget.supportsQRScanning,
); );
}); });
}, },

View File

@ -170,19 +170,19 @@ class _CertificateDetailsScreenState extends State<CertificateDetailsScreen> {
onPressed: () { onPressed: () {
Utils.openPage(context, (context) { Utils.openPage(context, (context) {
return AddCertificateScreen( return AddCertificateScreen(
onReplace: (result) { onReplace: (result) {
setState(() { setState(() {
changed = true; changed = true;
certResult = result; certResult = result;
certInfo = result.certInfo; certInfo = result.certInfo;
}); });
// Slam the page back to the top // Slam the page back to the top
controller.animateTo(0, controller.animateTo(0,
duration: const Duration(milliseconds: 10), curve: Curves.linearToEaseOut); duration: const Duration(milliseconds: 10), curve: Curves.linearToEaseOut);
}, },
pubKey: widget.pubKey!, pubKey: widget.pubKey!,
privKey: widget.privKey!, privKey: widget.privKey!,
supportsQRScanning: widget.supportsQRScanning, supportsQRScanning: widget.supportsQRScanning,
); );
}); });
}))); })));

View File

@ -19,17 +19,13 @@ class RenderedConfigScreen extends StatelessWidget {
title: Text('Rendered Site Config'), title: Text('Rendered Site Config'),
scrollable: SimpleScrollable.both, scrollable: SimpleScrollable.both,
trailingActions: <Widget>[ trailingActions: <Widget>[
Builder( Builder(builder: (BuildContext context) {
builder: (BuildContext context) { return PlatformIconButton(
return PlatformIconButton( padding: EdgeInsets.zero,
padding: EdgeInsets.zero, icon: Icon(context.platformIcons.share, size: 28.0),
icon: Icon(context.platformIcons.share, size: 28.0), onPressed: () => Share.share(context, title: '$name.yaml', text: config, filename: '$name.yaml'),
onPressed: () => );
Share.share(context, }),
title: '$name.yaml', text: config, filename: '$name.yaml'),
);
}
),
], ],
child: Container( child: Container(
padding: EdgeInsets.all(5), padding: EdgeInsets.all(5),

View File

@ -139,17 +139,17 @@ class _SiteConfigScreenState extends State<SiteConfigScreen> {
lastUpdate = formatter.format(site.lastManagedUpdate!.toLocal()); lastUpdate = formatter.format(site.lastManagedUpdate!.toLocal());
} }
return site.managed ? ConfigSection( return site.managed
label: "MANAGED CONFIG", ? ConfigSection(label: "MANAGED CONFIG", children: <Widget>[
children: <Widget>[ ConfigItem(
ConfigItem( label: Text("Last Update"),
label: Text("Last Update"), content:
content: Wrap(alignment: WrapAlignment.end, crossAxisAlignment: WrapCrossAlignment.center, children: <Widget>[ Wrap(alignment: WrapAlignment.end, crossAxisAlignment: WrapCrossAlignment.center, children: <Widget>[
Text(lastUpdate), Text(lastUpdate),
]), ]),
) )
] ])
) : Container(); : Container();
} }
Widget _keys() { Widget _keys() {
@ -183,30 +183,32 @@ class _SiteConfigScreenState extends State<SiteConfigScreen> {
Utils.openPage(context, (context) { Utils.openPage(context, (context) {
if (site.certInfo != null) { if (site.certInfo != null) {
return CertificateDetailsScreen( return CertificateDetailsScreen(
certInfo: site.certInfo!, certInfo: site.certInfo!,
pubKey: pubKey, pubKey: pubKey,
privKey: privKey, privKey: privKey,
onReplace: site.managed ? null : (result) { onReplace: site.managed
setState(() { ? null
changed = true; : (result) {
site.certInfo = result.certInfo; setState(() {
site.key = result.key; changed = true;
}); site.certInfo = result.certInfo;
}, site.key = result.key;
supportsQRScanning: widget.supportsQRScanning, });
},
supportsQRScanning: widget.supportsQRScanning,
); );
} }
return AddCertificateScreen( return AddCertificateScreen(
pubKey: pubKey!, pubKey: pubKey!,
privKey: privKey!, privKey: privKey!,
onSave: (result) { onSave: (result) {
setState(() { setState(() {
changed = true; changed = true;
site.certInfo = result.certInfo; site.certInfo = result.certInfo;
site.key = result.key; site.key = result.key;
}); });
}, },
supportsQRScanning: widget.supportsQRScanning, supportsQRScanning: widget.supportsQRScanning,
); );
}); });
@ -226,14 +228,16 @@ class _SiteConfigScreenState extends State<SiteConfigScreen> {
onPressed: () { onPressed: () {
Utils.openPage(context, (context) { Utils.openPage(context, (context) {
return CAListScreen( return CAListScreen(
cas: site.ca, cas: site.ca,
onSave: site.managed ? null : (ca) { onSave: site.managed
setState(() { ? null
changed = true; : (ca) {
site.ca = ca; setState(() {
}); changed = true;
}, site.ca = ca;
supportsQRScanning: widget.supportsQRScanning, });
},
supportsQRScanning: widget.supportsQRScanning,
); );
}); });
}) })
@ -261,12 +265,14 @@ class _SiteConfigScreenState extends State<SiteConfigScreen> {
Utils.openPage(context, (context) { Utils.openPage(context, (context) {
return StaticHostsScreen( return StaticHostsScreen(
hostmap: site.staticHostmap, hostmap: site.staticHostmap,
onSave: site.managed ? null : (map) { onSave: site.managed
setState(() { ? null
changed = true; : (map) {
site.staticHostmap = map; setState(() {
}); changed = true;
}); site.staticHostmap = map;
});
});
}); });
}, },
), ),

View File

@ -66,7 +66,11 @@ class _StaticHostmapScreenState extends State<StaticHostmapScreen> {
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return FormPage( 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, changed: changed,
onSave: _onSave, onSave: _onSave,
child: Column(children: [ child: Column(children: [
@ -74,20 +78,20 @@ class _StaticHostmapScreenState extends State<StaticHostmapScreen> {
ConfigItem( ConfigItem(
label: Text('Nebula IP'), label: Text('Nebula IP'),
labelWidth: 200, labelWidth: 200,
content: widget.onSave == null ? content: widget.onSave == null
Text(_nebulaIp, textAlign: TextAlign.end) : ? Text(_nebulaIp, textAlign: TextAlign.end)
IPFormField( : IPFormField(
help: "Required", help: "Required",
initialValue: _nebulaIp, initialValue: _nebulaIp,
ipOnly: true, ipOnly: true,
textAlign: TextAlign.end, textAlign: TextAlign.end,
crossAxisAlignment: CrossAxisAlignment.end, crossAxisAlignment: CrossAxisAlignment.end,
textInputAction: TextInputAction.next, textInputAction: TextInputAction.next,
onSaved: (v) { onSaved: (v) {
if (v != null) { if (v != null) {
_nebulaIp = v; _nebulaIp = v;
} }
})), })),
ConfigItem( ConfigItem(
label: Text('Lighthouse'), label: Text('Lighthouse'),
labelWidth: 200, labelWidth: 200,
@ -96,12 +100,14 @@ class _StaticHostmapScreenState extends State<StaticHostmapScreen> {
child: Switch.adaptive( child: Switch.adaptive(
value: _lighthouse, value: _lighthouse,
materialTapTargetSize: MaterialTapTargetSize.shrinkWrap, materialTapTargetSize: MaterialTapTargetSize.shrinkWrap,
onChanged: widget.onSave == null ? null : (v) { onChanged: widget.onSave == null
setState(() { ? null
changed = true; : (v) {
_lighthouse = v; setState(() {
}); changed = true;
})), _lighthouse = v;
});
})),
), ),
]), ]),
ConfigSection( ConfigSection(
@ -128,8 +134,7 @@ class _StaticHostmapScreenState extends State<StaticHostmapScreen> {
_onSave() { _onSave() {
Navigator.pop(context); Navigator.pop(context);
if (widget.onSave != null) { if (widget.onSave != null) {
var map = Hostmap( var map = Hostmap(nebulaIp: _nebulaIp, destinations: [], lighthouse: _lighthouse);
nebulaIp: _nebulaIp, destinations: [], lighthouse: _lighthouse);
_destinations.forEach((_, dest) { _destinations.forEach((_, dest) {
map.destinations.add(dest.destination); map.destinations.add(dest.destination);
@ -147,30 +152,32 @@ class _StaticHostmapScreenState extends State<StaticHostmapScreen> {
key: key, key: key,
label: Align( label: Align(
alignment: Alignment.centerLeft, alignment: Alignment.centerLeft,
child: widget.onSave == null ? Container() : PlatformIconButton( child: widget.onSave == null
padding: EdgeInsets.zero, ? Container()
icon: Icon(Icons.remove_circle, color: CupertinoColors.systemRed.resolveFrom(context)), : PlatformIconButton(
onPressed: () => setState(() { padding: EdgeInsets.zero,
_removeDestination(key); icon: Icon(Icons.remove_circle, color: CupertinoColors.systemRed.resolveFrom(context)),
_dismissKeyboard(); onPressed: () => setState(() {
}))), _removeDestination(key);
_dismissKeyboard();
}))),
labelWidth: 70, labelWidth: 70,
content: Row(children: <Widget>[ content: Row(children: <Widget>[
Expanded( Expanded(
child: widget.onSave == null ? child: widget.onSave == null
Text(dest.destination.toString(), textAlign: TextAlign.end) : ? Text(dest.destination.toString(), textAlign: TextAlign.end)
IPAndPortFormField( : IPAndPortFormField(
ipHelp: 'public ip or name', ipHelp: 'public ip or name',
ipTextAlign: TextAlign.end, ipTextAlign: TextAlign.end,
enableIPV6: true, enableIPV6: true,
noBorder: true, noBorder: true,
initialValue: dest.destination, initialValue: dest.destination,
onSaved: (v) { onSaved: (v) {
if (v != null) { if (v != null) {
dest.destination = v; dest.destination = v;
} }
}, },
)), )),
]), ]),
)); ));
}); });
@ -178,8 +185,7 @@ class _StaticHostmapScreenState extends State<StaticHostmapScreen> {
if (widget.onSave != null) { if (widget.onSave != null) {
items.add(ConfigButtonItem( items.add(ConfigButtonItem(
content: Text('Add another'), content: Text('Add another'),
onPressed: () => onPressed: () => setState(() {
setState(() {
_addDestination(); _addDestination();
_dismissKeyboard(); _dismissKeyboard();
}))); })));

View File

@ -70,8 +70,7 @@ class _StaticHostsScreenState extends State<StaticHostsScreen> {
if (widget.onSave != null) { if (widget.onSave != null) {
Map<String, StaticHost> map = {}; Map<String, StaticHost> map = {};
_hostmap.forEach((_, host) { _hostmap.forEach((_, host) {
map[host.nebulaIp] = StaticHost( map[host.nebulaIp] = StaticHost(destinations: host.destinations, lighthouse: host.lighthouse);
destinations: host.destinations, lighthouse: host.lighthouse);
}); });
widget.onSave!(map); widget.onSave!(map);
@ -98,20 +97,24 @@ class _StaticHostsScreenState extends State<StaticHostsScreen> {
nebulaIp: host.nebulaIp, nebulaIp: host.nebulaIp,
destinations: host.destinations, destinations: host.destinations,
lighthouse: host.lighthouse, lighthouse: host.lighthouse,
onSave: widget.onSave == null ? null :(map) { onSave: widget.onSave == null
setState(() { ? null
changed = true; : (map) {
host.nebulaIp = map.nebulaIp; setState(() {
host.destinations = map.destinations; changed = true;
host.lighthouse = map.lighthouse; host.nebulaIp = map.nebulaIp;
}); host.destinations = map.destinations;
}, host.lighthouse = map.lighthouse;
onDelete: widget.onSave == null ? null : () { });
setState(() { },
changed = true; onDelete: widget.onSave == null
_hostmap.remove(key); ? null
}); : () {
}); setState(() {
changed = true;
_hostmap.remove(key);
});
});
}); });
}, },
)); ));

View File

@ -22,7 +22,7 @@ class Settings {
} }
bool get darkMode { bool get darkMode {
return _getBool('darkMode', SchedulerBinding.instance.window.platformBrightness == Brightness.dark); return _getBool('darkMode', SchedulerBinding.instance.platformDispatcher.platformBrightness == Brightness.dark);
} }
set darkMode(bool enabled) { set darkMode(bool enabled) {

View File

@ -41,9 +41,7 @@ class Share {
/// - filePath: Path to the file to share /// - filePath: Path to the file to share
/// - filename: An optional filename to override the existing file /// - filename: An optional filename to override the existing file
static Future<bool> shareFile(BuildContext context, static Future<bool> shareFile(BuildContext context,
{required String title, {required String title, required String filePath, String? filename}) async {
required String filePath,
String? filename}) async {
assert(title.isNotEmpty); assert(title.isNotEmpty);
assert(filePath.isNotEmpty); assert(filePath.isNotEmpty);
@ -54,8 +52,7 @@ class Share {
// and then delete it // and then delete it
final xFile = sp.XFile(filePath, name: filename); final xFile = sp.XFile(filePath, name: filename);
final result = await sp.Share.shareXFiles([xFile], final result = await sp.Share.shareXFiles([xFile],
subject: title, subject: title, sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size);
sharePositionOrigin: box!.localToGlobal(Offset.zero) & box.size);
return result.status == sp.ShareResultStatus.success; return result.status == sp.ShareResultStatus.success;
} }
} }

View File

@ -4,7 +4,7 @@ import 'package:file_picker/file_picker.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_platform_widgets/flutter_platform_widgets.dart'; import 'package:flutter_platform_widgets/flutter_platform_widgets.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher_string.dart';
class Utils { class Utils {
/// Minimum size (width or height) of a interactive component /// Minimum size (width or height) of a interactive component
@ -158,8 +158,8 @@ class Utils {
} }
static launchUrl(String url, BuildContext context) async { static launchUrl(String url, BuildContext context) async {
if (await canLaunch(url)) { if (await canLaunchUrlString(url)) {
await launch(url); await launchUrlString(url);
} else { } else {
Utils.popError(context, 'Error', 'Could not launch web view'); Utils.popError(context, 'Error', 'Could not launch web view');
} }

View File

@ -23,7 +23,6 @@ bool ipValidator(String? str, bool enableIPV6) {
{ {
return true; return true;
} }
break;
} }
return false; return false;

View File

@ -10,7 +10,7 @@ require (
github.com/DefinedNet/dnapi v0.0.0-20240611201323-4589547bd270 github.com/DefinedNet/dnapi v0.0.0-20240611201323-4589547bd270
github.com/sirupsen/logrus v1.9.3 github.com/sirupsen/logrus v1.9.3
github.com/slackhq/nebula v1.9.3 github.com/slackhq/nebula v1.9.3
golang.org/x/crypto v0.24.0 golang.org/x/crypto v0.27.0
gopkg.in/yaml.v2 v2.4.0 gopkg.in/yaml.v2 v2.4.0
) )
@ -34,12 +34,12 @@ require (
github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 // indirect github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 // indirect
github.com/vishvananda/netlink v1.2.1-beta.2 // indirect github.com/vishvananda/netlink v1.2.1-beta.2 // indirect
github.com/vishvananda/netns v0.0.4 // indirect github.com/vishvananda/netns v0.0.4 // indirect
golang.org/x/mod v0.18.0 // indirect golang.org/x/mod v0.21.0 // indirect
golang.org/x/net v0.26.0 // indirect golang.org/x/net v0.29.0 // indirect
golang.org/x/sync v0.7.0 // indirect golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.21.0 // indirect golang.org/x/sys v0.25.0 // indirect
golang.org/x/term v0.21.0 // indirect golang.org/x/term v0.24.0 // indirect
golang.org/x/tools v0.22.0 // indirect golang.org/x/tools v0.25.0 // indirect
golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect golang.zx2c4.com/wintun v0.0.0-20230126152724-0fa3db229ce2 // indirect
golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect golang.zx2c4.com/wireguard v0.0.0-20231211153847-12269c276173 // indirect
golang.zx2c4.com/wireguard/windows v0.5.3 // indirect golang.zx2c4.com/wireguard/windows v0.5.3 // indirect

View File

@ -145,14 +145,14 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk
golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4= golang.org/x/crypto v0.0.0-20210322153248-0c34fe9e7dc2/go.mod h1:T9bdIzuCu7OtxOm1hfPfRQxPLYneinmdGuTeoZ9dtd4=
golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A=
golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70=
golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
golang.org/x/mod v0.18.0 h1:5+9lSbEzPSdWkH32vYPBwEpX8KwDbM52Ud9xBUvNlb0= golang.org/x/mod v0.21.0 h1:vvrHzRwRfVKSiLrG+d4FMl/Qi4ukBCE6kZlTUkDYRT0=
golang.org/x/mod v0.18.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c= golang.org/x/mod v0.21.0/go.mod h1:6SkKJ3Xj0I0BrPOZoBy3bdMptDDU9oJrpohJ3eWZ1fY=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@ -163,8 +163,8 @@ golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLL
golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200625001655-4c5254603344/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo=
golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
@ -172,8 +172,8 @@ golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJ
golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M= golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@ -190,11 +190,11 @@ golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7w
golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210124154548-22da62e12c0c/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM=
golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
@ -203,8 +203,8 @@ golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtn
golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE= golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA= golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
golang.org/x/tools v0.22.0 h1:gqSGLZqv+AI9lIQzniJ0nZDRG5GBPsSi+DRNHWNz6yA= golang.org/x/tools v0.25.0 h1:oFU9pkj/iJgs+0DT+VMHrx+oBKs/LJMV+Uvg78sl+fE=
golang.org/x/tools v0.22.0/go.mod h1:aCwcsjqvq7Yqt6TNyX7QMU2enbQ/Gt0bo6krSeEri+c= golang.org/x/tools v0.25.0/go.mod h1:/vtpO8WL1N9cQC3FN5zPqb//fRXskFHbLKk4OW1Q7rg=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=

View File

@ -1,90 +1,118 @@
# Generated by pub # Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile # See https://dart.dev/tools/pub/glossary#lockfile
packages: packages:
args:
dependency: transitive
description:
name: args
sha256: "7cf60b9f0cc88203c5a190b4cd62a99feea42759a7fa695010eb5de1c0b2252a"
url: "https://pub.dev"
source: hosted
version: "2.5.0"
async: async:
dependency: transitive dependency: transitive
description: description:
name: async name: async
url: "https://pub.dartlang.org" sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.9.0" version: "2.11.0"
boolean_selector: boolean_selector:
dependency: transitive dependency: transitive
description: description:
name: boolean_selector name: boolean_selector
url: "https://pub.dartlang.org" sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.0" version: "2.1.1"
characters: characters:
dependency: transitive dependency: transitive
description: description:
name: characters name: characters
url: "https://pub.dartlang.org" sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.1" version: "1.3.0"
clock: clock:
dependency: transitive dependency: transitive
description: description:
name: clock name: clock
url: "https://pub.dartlang.org" sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.1" version: "1.1.1"
collection: collection:
dependency: transitive dependency: transitive
description: description:
name: collection name: collection
url: "https://pub.dartlang.org" sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted source: hosted
version: "1.16.0" version: "1.18.0"
cross_file: cross_file:
dependency: transitive dependency: transitive
description: description:
name: cross_file name: cross_file
url: "https://pub.dartlang.org" sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670"
url: "https://pub.dev"
source: hosted source: hosted
version: "0.3.3+4" version: "0.3.4+2"
crypto: crypto:
dependency: transitive dependency: transitive
description: description:
name: crypto name: crypto
url: "https://pub.dartlang.org" sha256: ff625774173754681d66daaf4a448684fb04b78f902da9cb3d308c19cc5e8bab
url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.2" version: "3.0.3"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
name: cupertino_icons name: cupertino_icons
url: "https://pub.dartlang.org" sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.5" version: "1.0.8"
fake_async: fake_async:
dependency: transitive dependency: transitive
description: description:
name: fake_async name: fake_async
url: "https://pub.dartlang.org" sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.1" version: "1.3.1"
ffi: ffi:
dependency: transitive dependency: transitive
description: description:
name: ffi name: ffi
url: "https://pub.dartlang.org" sha256: "16ed7b077ef01ad6170a3d0c57caa4a112a38d7a2ed5602e0aca9ca6f3d98da6"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.2" version: "2.1.3"
file: file:
dependency: transitive dependency: transitive
description: description:
name: file name: file
url: "https://pub.dartlang.org" sha256: "1b92bec4fc2a72f59a8e15af5f52cd441e4a7860b49499d69dfa817af20e925d"
url: "https://pub.dev"
source: hosted source: hosted
version: "6.1.4" version: "6.1.4"
file_picker: file_picker:
dependency: "direct main" dependency: "direct main"
description: description:
name: file_picker name: file_picker
url: "https://pub.dartlang.org" sha256: "167bb619cdddaa10ef2907609feb8a79c16dfa479d3afaf960f8e223f754bf12"
url: "https://pub.dev"
source: hosted source: hosted
version: "5.2.10" version: "8.1.2"
fixnum:
dependency: transitive
description:
name: fixnum
sha256: "25517a4deb0c03aa0f32fd12db525856438902d9c16536311e76cdc57b31d7d1"
url: "https://pub.dev"
source: hosted
version: "1.1.0"
flutter: flutter:
dependency: "direct main" dependency: "direct main"
description: flutter description: flutter
@ -94,30 +122,34 @@ packages:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_barcode_scanner name: flutter_barcode_scanner
url: "https://pub.dartlang.org" sha256: a4ba37daf9933f451a5e812c753ddd045d6354e4a3280342d895b07fecaab3fa
url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.0" version: "2.0.0"
flutter_platform_widgets: flutter_platform_widgets:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_platform_widgets name: flutter_platform_widgets
url: "https://pub.dartlang.org" sha256: "84f39540cf433aa44b235b7fca6518d1bd30aa281d8196f00be60bc76cac96f4"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.6" version: "7.0.1"
flutter_plugin_android_lifecycle: flutter_plugin_android_lifecycle:
dependency: transitive dependency: transitive
description: description:
name: flutter_plugin_android_lifecycle name: flutter_plugin_android_lifecycle
url: "https://pub.dartlang.org" sha256: "8cf40eebf5dec866a6d1956ad7b4f7016e6c0cc69847ab946833b7d43743809f"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.15" version: "2.0.19"
flutter_svg: flutter_svg:
dependency: "direct main" dependency: "direct main"
description: description:
name: flutter_svg name: flutter_svg
url: "https://pub.dartlang.org" sha256: "7b4ca6cf3304575fe9c8ec64813c8d02ee41d2afe60bcfe0678bcb5375d596a2"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.6" version: "2.0.10+1"
flutter_test: flutter_test:
dependency: "direct dev" dependency: "direct dev"
description: flutter description: flutter
@ -128,160 +160,214 @@ packages:
description: flutter description: flutter
source: sdk source: sdk
version: "0.0.0" version: "0.0.0"
http:
dependency: transitive
description:
name: http
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
url: "https://pub.dev"
source: hosted
version: "1.2.2"
http_parser:
dependency: transitive
description:
name: http_parser
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
url: "https://pub.dev"
source: hosted
version: "4.0.2"
intl: intl:
dependency: "direct main" dependency: "direct main"
description: description:
name: intl name: intl
url: "https://pub.dartlang.org" sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
url: "https://pub.dev"
source: hosted source: hosted
version: "0.17.0" version: "0.19.0"
js: leak_tracker:
dependency: transitive dependency: transitive
description: description:
name: js name: leak_tracker
url: "https://pub.dartlang.org" sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
url: "https://pub.dev"
source: hosted source: hosted
version: "0.6.4" version: "10.0.5"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
url: "https://pub.dev"
source: hosted
version: "3.0.5"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
matcher: matcher:
dependency: transitive dependency: transitive
description: description:
name: matcher name: matcher
url: "https://pub.dartlang.org" sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
url: "https://pub.dev"
source: hosted source: hosted
version: "0.12.12" version: "0.12.16+1"
material_color_utilities: material_color_utilities:
dependency: transitive dependency: transitive
description: description:
name: material_color_utilities name: material_color_utilities
url: "https://pub.dartlang.org" sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
url: "https://pub.dev"
source: hosted source: hosted
version: "0.1.5" version: "0.11.1"
meta: meta:
dependency: transitive dependency: transitive
description: description:
name: meta name: meta
url: "https://pub.dartlang.org" sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
url: "https://pub.dev"
source: hosted source: hosted
version: "1.8.0" version: "1.15.0"
mime: mime:
dependency: transitive dependency: transitive
description: description:
name: mime name: mime
url: "https://pub.dartlang.org" sha256: "801fd0b26f14a4a58ccb09d5892c3fbdeff209594300a542492cf13fba9d247a"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.4" version: "1.0.6"
package_info: package_info_plus:
dependency: "direct main" dependency: "direct main"
description: description:
name: package_info name: package_info_plus
url: "https://pub.dartlang.org" sha256: a75164ade98cb7d24cfd0a13c6408927c6b217fa60dee5a7ff5c116a58f28918
url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.2" version: "8.0.2"
package_info_plus_platform_interface:
dependency: transitive
description:
name: package_info_plus_platform_interface
sha256: ac1f4a4847f1ade8e6a87d1f39f5d7c67490738642e2542f559ec38c37489a66
url: "https://pub.dev"
source: hosted
version: "3.0.1"
path: path:
dependency: transitive dependency: transitive
description: description:
name: path name: path
url: "https://pub.dartlang.org" sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.8.2" version: "1.9.0"
path_drawing:
dependency: transitive
description:
name: path_drawing
url: "https://pub.dartlang.org"
source: hosted
version: "1.0.1"
path_parsing: path_parsing:
dependency: transitive dependency: transitive
description: description:
name: path_parsing name: path_parsing
url: "https://pub.dartlang.org" sha256: e3e67b1629e6f7e8100b367d3db6ba6af4b1f0bb80f64db18ef1fbabd2fa9ccf
url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.1" version: "1.0.1"
path_provider: path_provider:
dependency: "direct main" dependency: "direct main"
description: description:
name: path_provider name: path_provider
url: "https://pub.dartlang.org" sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.0" version: "2.1.4"
path_provider_android: path_provider_android:
dependency: transitive dependency: transitive
description: description:
name: path_provider_android name: path_provider_android
url: "https://pub.dartlang.org" sha256: a248d8146ee5983446bf03ed5ea8f6533129a12b11f12057ad1b4a67a2b3b41d
url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.0" version: "2.2.4"
path_provider_foundation: path_provider_foundation:
dependency: transitive dependency: transitive
description: description:
name: path_provider_foundation name: path_provider_foundation
url: "https://pub.dartlang.org" sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
url: "https://pub.dev"
source: hosted source: hosted
version: "2.3.0" version: "2.4.0"
path_provider_linux: path_provider_linux:
dependency: transitive dependency: transitive
description: description:
name: path_provider_linux name: path_provider_linux
url: "https://pub.dartlang.org" sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.0" version: "2.2.1"
path_provider_platform_interface: path_provider_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: path_provider_platform_interface name: path_provider_platform_interface
url: "https://pub.dartlang.org" sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.0" version: "2.1.2"
path_provider_windows: path_provider_windows:
dependency: transitive dependency: transitive
description: description:
name: path_provider_windows name: path_provider_windows
url: "https://pub.dartlang.org" sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
url: "https://pub.dev"
source: hosted source: hosted
version: "2.2.0" version: "2.3.0"
petitparser: petitparser:
dependency: transitive dependency: transitive
description: description:
name: petitparser name: petitparser
url: "https://pub.dartlang.org" sha256: c15605cd28af66339f8eb6fbe0e541bfe2d1b72d5825efc6598f3e0a31b9ad27
url: "https://pub.dev"
source: hosted source: hosted
version: "5.1.0" version: "6.0.2"
platform: platform:
dependency: transitive dependency: transitive
description: description:
name: platform name: platform
url: "https://pub.dartlang.org" sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.1" version: "3.1.5"
plugin_platform_interface: plugin_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: plugin_platform_interface name: plugin_platform_interface
url: "https://pub.dartlang.org" sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.5" version: "2.1.8"
pull_to_refresh: pull_to_refresh:
dependency: "direct main" dependency: "direct main"
description: description:
name: pull_to_refresh name: pull_to_refresh
url: "https://pub.dartlang.org" sha256: bbadd5a931837b57739cf08736bea63167e284e71fb23b218c8c9a6e042aad12
url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.0" version: "2.0.0"
share_plus: share_plus:
dependency: "direct main" dependency: "direct main"
description: description:
name: share_plus name: share_plus
url: "https://pub.dartlang.org" sha256: "468c43f285207c84bcabf5737f33b914ceb8eb38398b91e5e3ad1698d1b72a52"
url: "https://pub.dev"
source: hosted source: hosted
version: "6.3.4" version: "10.0.2"
share_plus_platform_interface: share_plus_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: share_plus_platform_interface name: share_plus_platform_interface
url: "https://pub.dartlang.org" sha256: "6ababf341050edff57da8b6990f11f4e99eaba837865e2e6defe16d039619db5"
url: "https://pub.dev"
source: hosted source: hosted
version: "3.3.1" version: "5.0.0"
sky_engine: sky_engine:
dependency: transitive dependency: transitive
description: flutter description: flutter
@ -291,142 +377,210 @@ packages:
dependency: transitive dependency: transitive
description: description:
name: source_span name: source_span
url: "https://pub.dartlang.org" sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.9.0" version: "1.10.0"
sprintf:
dependency: transitive
description:
name: sprintf
sha256: "1fc9ffe69d4df602376b52949af107d8f5703b77cda567c4d7d86a0693120f23"
url: "https://pub.dev"
source: hosted
version: "7.0.0"
stack_trace: stack_trace:
dependency: transitive dependency: transitive
description: description:
name: stack_trace name: stack_trace
url: "https://pub.dartlang.org" sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.10.0" version: "1.11.1"
stream_channel: stream_channel:
dependency: transitive dependency: transitive
description: description:
name: stream_channel name: stream_channel
url: "https://pub.dartlang.org" sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.0" version: "2.1.2"
string_scanner: string_scanner:
dependency: transitive dependency: transitive
description: description:
name: string_scanner name: string_scanner
url: "https://pub.dartlang.org" sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
url: "https://pub.dev"
source: hosted source: hosted
version: "1.1.1" version: "1.2.0"
term_glyph: term_glyph:
dependency: transitive dependency: transitive
description: description:
name: term_glyph name: term_glyph
url: "https://pub.dartlang.org" sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
url: "https://pub.dev"
source: hosted source: hosted
version: "1.2.1" version: "1.2.1"
test_api: test_api:
dependency: transitive dependency: transitive
description: description:
name: test_api name: test_api
url: "https://pub.dartlang.org" sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
url: "https://pub.dev"
source: hosted source: hosted
version: "0.4.12" version: "0.7.2"
typed_data: typed_data:
dependency: transitive dependency: transitive
description: description:
name: typed_data name: typed_data
url: "https://pub.dartlang.org" sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
url: "https://pub.dev"
source: hosted source: hosted
version: "1.3.2" version: "1.3.2"
url_launcher: url_launcher:
dependency: "direct main" dependency: "direct main"
description: description:
name: url_launcher name: url_launcher
url: "https://pub.dartlang.org" sha256: "21b704ce5fa560ea9f3b525b43601c678728ba46725bab9b01187b4831377ed3"
url: "https://pub.dev"
source: hosted source: hosted
version: "6.1.11" version: "6.3.0"
url_launcher_android: url_launcher_android:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_android name: url_launcher_android
url: "https://pub.dartlang.org" sha256: "17cd5e205ea615e2c6ea7a77323a11712dffa0720a8a90540db57a01347f9ad9"
url: "https://pub.dev"
source: hosted source: hosted
version: "6.0.38" version: "6.3.2"
url_launcher_ios: url_launcher_ios:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_ios name: url_launcher_ios
url: "https://pub.dartlang.org" sha256: e43b677296fadce447e987a2f519dcf5f6d1e527dc35d01ffab4fff5b8a7063e
url: "https://pub.dev"
source: hosted source: hosted
version: "6.1.4" version: "6.3.1"
url_launcher_linux: url_launcher_linux:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_linux name: url_launcher_linux
url: "https://pub.dartlang.org" sha256: e2b9622b4007f97f504cd64c0128309dfb978ae66adbe944125ed9e1750f06af
url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.5" version: "3.2.0"
url_launcher_macos: url_launcher_macos:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_macos name: url_launcher_macos
url: "https://pub.dartlang.org" sha256: "9a1a42d5d2d95400c795b2914c36fdcb525870c752569438e4ebb09a2b5d90de"
url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.6" version: "3.2.0"
url_launcher_platform_interface: url_launcher_platform_interface:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_platform_interface name: url_launcher_platform_interface
url: "https://pub.dartlang.org" sha256: "552f8a1e663569be95a8190206a38187b531910283c3e982193e4f2733f01029"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.3" version: "2.3.2"
url_launcher_web: url_launcher_web:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_web name: url_launcher_web
url: "https://pub.dartlang.org" sha256: "772638d3b34c779ede05ba3d38af34657a05ac55b06279ea6edd409e323dca8e"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.0.18" version: "2.3.3"
url_launcher_windows: url_launcher_windows:
dependency: transitive dependency: transitive
description: description:
name: url_launcher_windows name: url_launcher_windows
url: "https://pub.dartlang.org" sha256: "49c10f879746271804767cb45551ec5592cdab00ee105c06dddde1a98f73b185"
url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.7" version: "3.1.2"
uuid: uuid:
dependency: "direct main" dependency: "direct main"
description: description:
name: uuid name: uuid
url: "https://pub.dartlang.org" sha256: f33d6bb662f0e4f79dcd7ada2e6170f3b3a2530c28fc41f49a411ddedd576a77
url: "https://pub.dev"
source: hosted source: hosted
version: "3.0.7" version: "4.5.0"
vector_graphics:
dependency: transitive
description:
name: vector_graphics
sha256: "32c3c684e02f9bc0afb0ae0aa653337a2fe022e8ab064bcd7ffda27a74e288e3"
url: "https://pub.dev"
source: hosted
version: "1.1.11+1"
vector_graphics_codec:
dependency: transitive
description:
name: vector_graphics_codec
sha256: c86987475f162fadff579e7320c7ddda04cd2fdeffbe1129227a85d9ac9e03da
url: "https://pub.dev"
source: hosted
version: "1.1.11+1"
vector_graphics_compiler:
dependency: transitive
description:
name: vector_graphics_compiler
sha256: "12faff3f73b1741a36ca7e31b292ddeb629af819ca9efe9953b70bd63fc8cd81"
url: "https://pub.dev"
source: hosted
version: "1.1.11+1"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
name: vector_math name: vector_math
url: "https://pub.dartlang.org" sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.dev"
source: hosted source: hosted
version: "2.1.2" version: "2.1.4"
vm_service:
dependency: transitive
description:
name: vm_service
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
url: "https://pub.dev"
source: hosted
version: "14.2.5"
web:
dependency: transitive
description:
name: web
sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062
url: "https://pub.dev"
source: hosted
version: "1.0.0"
win32: win32:
dependency: transitive dependency: transitive
description: description:
name: win32 name: win32
url: "https://pub.dartlang.org" sha256: "68d1e89a91ed61ad9c370f9f8b6effed9ae5e0ede22a270bdfa6daf79fc2290a"
url: "https://pub.dev"
source: hosted source: hosted
version: "3.1.4" version: "5.5.4"
xdg_directories: xdg_directories:
dependency: transitive dependency: transitive
description: description:
name: xdg_directories name: xdg_directories
url: "https://pub.dartlang.org" sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
url: "https://pub.dev"
source: hosted source: hosted
version: "1.0.2" version: "1.0.4"
xml: xml:
dependency: transitive dependency: transitive
description: description:
name: xml name: xml
url: "https://pub.dartlang.org" sha256: b015a8ad1c488f66851d762d3090a21c600e479dc75e68328c52774040cf9226
url: "https://pub.dev"
source: hosted source: hosted
version: "6.1.0" version: "6.5.0"
sdks: sdks:
dart: ">=2.18.1 <3.0.0" dart: ">=3.5.1 <4.0.0"
flutter: ">=3.3.0" flutter: ">=3.22.0"

View File

@ -14,7 +14,7 @@ description: Mobile Nebula Client
version: 0.1.0+54 version: 0.1.0+54
environment: environment:
sdk: '>=2.18.1 <3.0.0' sdk: ^3.5.1
dependencies: dependencies:
flutter: flutter:
@ -23,17 +23,17 @@ dependencies:
# The following adds the Cupertino Icons font to your application. # The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons. # Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2 cupertino_icons: ^1.0.2
flutter_platform_widgets: ^2.0.0 flutter_platform_widgets: ^7.0.1
path_provider: ^2.0.11 path_provider: ^2.0.11
file_picker: ^5.0.1 file_picker: ^8.1.2
uuid: ^3.0.4 uuid: ^4.4.2
package_info: ^2.0.0 package_info_plus: ^8.0.2
url_launcher: ^6.1.6 url_launcher: ^6.1.6
pull_to_refresh: ^2.0.0 pull_to_refresh: ^2.0.0
flutter_barcode_scanner: ^2.0.0 flutter_barcode_scanner: ^2.0.0
flutter_svg: ^1.1.5 flutter_svg: ^2.0.10+1
intl: ^0.17.0 intl: ^0.19.0
share_plus: ^6.3.0 share_plus: ^10.0.2
dev_dependencies: dev_dependencies:
flutter_test: flutter_test: