form done
This commit is contained in:
parent
02dc3e5757
commit
bd8884787d
10 changed files with 200 additions and 28 deletions
|
@ -1,5 +1,7 @@
|
|||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:file_selector/file_selector.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_secure_storage/flutter_secure_storage.dart';
|
||||
import 'package:fluxcloud/user.dart';
|
||||
|
||||
class AddServerModal extends StatefulWidget {
|
||||
const AddServerModal({
|
||||
|
@ -20,6 +22,7 @@ class _AddServerModalState extends State<AddServerModal> {
|
|||
bool _fileSelected = false;
|
||||
bool _showPassword = false;
|
||||
|
||||
final Connection _connection = Connection();
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -38,7 +41,7 @@ class _AddServerModalState extends State<AddServerModal> {
|
|||
spacing: 16,
|
||||
children: [
|
||||
Text(
|
||||
'Add Server',
|
||||
'Add Connection',
|
||||
textAlign: TextAlign.left,
|
||||
style: TextStyle(fontSize: 18),
|
||||
),
|
||||
|
@ -46,7 +49,16 @@ class _AddServerModalState extends State<AddServerModal> {
|
|||
decoration: InputDecoration(
|
||||
labelText: 'Host',
|
||||
),
|
||||
validator: (value) => value == null || value.isEmpty ? 'This value is required' : null
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return 'This value is required';
|
||||
}
|
||||
if (!RegExp(r'^(([a-zA-Z0-9-]+\.)+[a-zA-Z]{2,})|(\d{1,3}(\.\d{1,3}){3})$').hasMatch(value)) {
|
||||
return 'Please enter a valid host';
|
||||
}
|
||||
return null;
|
||||
},
|
||||
onSaved: (value) => _connection.host = value,
|
||||
),
|
||||
TextFormField(
|
||||
keyboardType: TextInputType.number,
|
||||
|
@ -61,22 +73,25 @@ class _AddServerModalState extends State<AddServerModal> {
|
|||
return 'Please enter a valid port';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
},
|
||||
onSaved: (value) => _connection.port = int.parse(value!),
|
||||
),
|
||||
TextFormField(
|
||||
decoration: InputDecoration(
|
||||
labelText: 'Username',
|
||||
),
|
||||
validator: (value) => value == null || value.isEmpty ? 'This value is required' : null
|
||||
validator: (value) => value == null || value.isEmpty ? 'This value is required' : null,
|
||||
onSaved: (value) => _connection.username = value,
|
||||
),
|
||||
TextFormField(
|
||||
controller: _privateKeyFileController,
|
||||
readOnly: true,
|
||||
onTap: () async {
|
||||
FilePickerResult? result = await FilePicker.platform.pickFiles();
|
||||
final XFile? result = await openFile();
|
||||
if (result != null) {
|
||||
setState(() => _fileSelected = true);
|
||||
_privateKeyFileController.text = result.files.single.name;
|
||||
_privateKeyFileController.text = result.name;
|
||||
_connection.privateKeyFilePath = result.path;
|
||||
}
|
||||
},
|
||||
decoration: InputDecoration(
|
||||
|
@ -112,13 +127,23 @@ class _AddServerModalState extends State<AddServerModal> {
|
|||
return 'At least provide one of these';
|
||||
}
|
||||
return null;
|
||||
}
|
||||
),
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
_formKey.currentState?.validate();
|
||||
},
|
||||
child: Text('Submit')
|
||||
onSaved: (value) => _connection.password = value,
|
||||
),
|
||||
|
||||
ElevatedButton(
|
||||
onPressed: () async {
|
||||
if (_formKey.currentState?.validate() == true) {
|
||||
_formKey.currentState?.save();
|
||||
assert(_connection.assertComplete());
|
||||
final storage = FlutterSecureStorage();
|
||||
await storage.write(key: _connection.host!, value: _connection.toJson);
|
||||
if (context.mounted) {
|
||||
Navigator.pop(context);
|
||||
}
|
||||
}
|
||||
},
|
||||
child: Text('Add Connection')
|
||||
)
|
||||
],
|
||||
)
|
||||
|
|
36
lib/user.dart
Normal file
36
lib/user.dart
Normal file
|
@ -0,0 +1,36 @@
|
|||
import 'dart:convert';
|
||||
|
||||
class Connection {
|
||||
String? host;
|
||||
int? port;
|
||||
String? username;
|
||||
String? privateKeyFilePath;
|
||||
String? password;
|
||||
|
||||
Connection();
|
||||
|
||||
Connection.fromJson(Map<String, dynamic> json) {
|
||||
host = json['host'];
|
||||
port = json['port'];
|
||||
username = json['username'];
|
||||
privateKeyFilePath = json['privateKeyFilePath)'];
|
||||
password = json['password'];
|
||||
}
|
||||
|
||||
String get toJson => jsonEncode({
|
||||
'host': host,
|
||||
'port': port,
|
||||
'username': username,
|
||||
'privateKeyFilePath': privateKeyFilePath,
|
||||
'password': password
|
||||
});
|
||||
|
||||
|
||||
bool assertComplete() {
|
||||
assert(host != null);
|
||||
assert(port != null);
|
||||
assert(username != null);
|
||||
assert(privateKeyFilePath != null || password != null);
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -6,9 +6,13 @@
|
|||
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <file_selector_linux/file_selector_plugin.h>
|
||||
#include <flutter_secure_storage_linux/flutter_secure_storage_linux_plugin.h>
|
||||
|
||||
void fl_register_plugins(FlPluginRegistry* registry) {
|
||||
g_autoptr(FlPluginRegistrar) file_selector_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "FileSelectorPlugin");
|
||||
file_selector_plugin_register_with_registrar(file_selector_linux_registrar);
|
||||
g_autoptr(FlPluginRegistrar) flutter_secure_storage_linux_registrar =
|
||||
fl_plugin_registry_get_registrar_for_plugin(registry, "FlutterSecureStorageLinuxPlugin");
|
||||
flutter_secure_storage_linux_plugin_register_with_registrar(flutter_secure_storage_linux_registrar);
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
file_selector_linux
|
||||
flutter_secure_storage_linux
|
||||
)
|
||||
|
||||
|
|
|
@ -5,12 +5,12 @@
|
|||
import FlutterMacOS
|
||||
import Foundation
|
||||
|
||||
import file_picker
|
||||
import file_selector_macos
|
||||
import flutter_secure_storage_macos
|
||||
import path_provider_foundation
|
||||
|
||||
func RegisterGeneratedPlugins(registry: FlutterPluginRegistry) {
|
||||
FilePickerPlugin.register(with: registry.registrar(forPlugin: "FilePickerPlugin"))
|
||||
FileSelectorPlugin.register(with: registry.registrar(forPlugin: "FileSelectorPlugin"))
|
||||
FlutterSecureStoragePlugin.register(with: registry.registrar(forPlugin: "FlutterSecureStoragePlugin"))
|
||||
PathProviderPlugin.register(with: registry.registrar(forPlugin: "PathProviderPlugin"))
|
||||
}
|
||||
|
|
96
pubspec.lock
96
pubspec.lock
|
@ -65,14 +65,70 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.1.4"
|
||||
file_picker:
|
||||
file_selector:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: file_picker
|
||||
sha256: ef9908739bdd9c476353d6adff72e88fd00c625f5b959ae23f7567bd5137db0a
|
||||
name: file_selector
|
||||
sha256: "5019692b593455127794d5718304ff1ae15447dea286cdda9f0db2a796a1b828"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "10.2.0"
|
||||
version: "1.0.3"
|
||||
file_selector_android:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_android
|
||||
sha256: "6bba3d590ee9462758879741abc132a19133600dd31832f55627442f1ebd7b54"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.1+14"
|
||||
file_selector_ios:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_ios
|
||||
sha256: "94b98ad950b8d40d96fee8fa88640c2e4bd8afcdd4817993bd04e20310f45420"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.3+1"
|
||||
file_selector_linux:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_linux
|
||||
sha256: "54cbbd957e1156d29548c7d9b9ec0c0ebb6de0a90452198683a7d23aed617a33"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.3+2"
|
||||
file_selector_macos:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_macos
|
||||
sha256: "8c9250b2bd2d8d4268e39c82543bacbaca0fda7d29e0728c3c4bbb7c820fd711"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.4+3"
|
||||
file_selector_platform_interface:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_platform_interface
|
||||
sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.6.2"
|
||||
file_selector_web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_web
|
||||
sha256: c4c0ea4224d97a60a7067eca0c8fd419e708ff830e0c83b11a48faf566cec3e7
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.4+2"
|
||||
file_selector_windows:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: file_selector_windows
|
||||
sha256: "320fcfb6f33caa90f0b58380489fc5ac05d99ee94b61aa96ec2bff0ba81d3c2b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.9.3+4"
|
||||
flutter:
|
||||
dependency: "direct main"
|
||||
description: flutter
|
||||
|
@ -86,14 +142,6 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "5.0.0"
|
||||
flutter_plugin_android_lifecycle:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: flutter_plugin_android_lifecycle
|
||||
sha256: f948e346c12f8d5480d2825e03de228d0eb8c3a737e4cdaa122267b89c022b5e
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "2.0.28"
|
||||
flutter_secure_storage:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
|
@ -152,6 +200,22 @@ packages:
|
|||
description: flutter
|
||||
source: sdk
|
||||
version: "0.0.0"
|
||||
http:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http
|
||||
sha256: "2c11f3f94c687ee9bad77c171151672986360b2b001d109814ee7140b2cf261b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
http_parser:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: http_parser
|
||||
sha256: "178d74305e7866013777bab2c3d8726205dc5a4dd935297175b19a23a2e66571"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "4.1.2"
|
||||
js:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
@ -341,6 +405,14 @@ packages:
|
|||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.4"
|
||||
typed_data:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: typed_data
|
||||
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
vector_math:
|
||||
dependency: transitive
|
||||
description:
|
||||
|
|
|
@ -9,7 +9,7 @@ environment:
|
|||
dependencies:
|
||||
flutter:
|
||||
sdk: flutter
|
||||
file_picker: ^10.2.0
|
||||
file_selector: ^1.0.3
|
||||
flutter_secure_storage: ^9.2.4
|
||||
|
||||
dev_dependencies:
|
||||
|
|
30
test/widget_test.dart
Normal file
30
test/widget_test.dart
Normal file
|
@ -0,0 +1,30 @@
|
|||
// This is a basic Flutter widget test.
|
||||
//
|
||||
// To perform an interaction with a widget in your test, use the WidgetTester
|
||||
// utility in the flutter_test package. For example, you can send tap and scroll
|
||||
// gestures. You can also use WidgetTester to find child widgets in the widget
|
||||
// tree, read text, and verify that the values of widget properties are correct.
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
|
||||
import 'package:fluxcloud/main.dart';
|
||||
|
||||
void main() {
|
||||
testWidgets('Counter increments smoke test', (WidgetTester tester) async {
|
||||
// Build our app and trigger a frame.
|
||||
await tester.pumpWidget(const MyApp());
|
||||
|
||||
// Verify that our counter starts at 0.
|
||||
expect(find.text('0'), findsOneWidget);
|
||||
expect(find.text('1'), findsNothing);
|
||||
|
||||
// Tap the '+' icon and trigger a frame.
|
||||
await tester.tap(find.byIcon(Icons.add));
|
||||
await tester.pump();
|
||||
|
||||
// Verify that our counter has incremented.
|
||||
expect(find.text('0'), findsNothing);
|
||||
expect(find.text('1'), findsOneWidget);
|
||||
});
|
||||
}
|
|
@ -6,9 +6,12 @@
|
|||
|
||||
#include "generated_plugin_registrant.h"
|
||||
|
||||
#include <file_selector_windows/file_selector_windows.h>
|
||||
#include <flutter_secure_storage_windows/flutter_secure_storage_windows_plugin.h>
|
||||
|
||||
void RegisterPlugins(flutter::PluginRegistry* registry) {
|
||||
FileSelectorWindowsRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("FileSelectorWindows"));
|
||||
FlutterSecureStorageWindowsPluginRegisterWithRegistrar(
|
||||
registry->GetRegistrarForPlugin("FlutterSecureStorageWindowsPlugin"));
|
||||
}
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
#
|
||||
|
||||
list(APPEND FLUTTER_PLUGIN_LIST
|
||||
file_selector_windows
|
||||
flutter_secure_storage_windows
|
||||
)
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue