import 'dart:math'; import 'package:flutter/material.dart'; import 'package:shared_preferences/shared_preferences.dart'; class ConnectionEditor extends StatefulWidget { final SharedPreferences prefs; final Function updateData; final String connectionName; final dynamic connection; const ConnectionEditor( {super.key, required this.prefs, required this.updateData, required this.connectionName, required this.connection}); @override State createState() => _ConnectionEditorState(); } class _ConnectionEditorState extends State { final wsRegex = RegExp(r'^(ws|wss):\/\/.*'); final _formKey = GlobalKey(); String _connectionName = ""; dynamic _connection; bool _isValid = false; @override void initState() { super.initState(); _connectionName = widget.connectionName; _connection = widget.connection; _isValid = _connectionName != "" && wsRegex.hasMatch(_connection["url"] ?? ""); widget.updateData(_connectionName, _connection, _isValid); } @override Widget build(BuildContext context) { return SizedBox( width: min(MediaQuery.of(context).size.width, 400), child: Form( key: _formKey, autovalidateMode: AutovalidateMode.always, child: Column( mainAxisSize: MainAxisSize.min, children: [ TextFormField( initialValue: widget.connectionName, onChanged: (value) { _connectionName = value; _isValid = _formKey.currentState!.validate(); widget.updateData(_connectionName, _connection, _isValid); }, validator: (value) { return value == "" ? "Name cannot be empty" : null; }, decoration: const InputDecoration( labelText: "Name", border: OutlineInputBorder()), ), const SizedBox(height: 15), TextFormField( initialValue: widget.connection["url"], onChanged: (value) { _connection["url"] = value; _isValid = _formKey.currentState!.validate(); widget.updateData(_connectionName, _connection, _isValid); }, validator: (value) { return wsRegex.hasMatch(value ?? "") ? null : "Must be: ws(s)://[host](:[port])/[path]"; }, decoration: const InputDecoration( labelText: "Connection URL", border: OutlineInputBorder()), ) ], ), ), ); } }