import 'package:flutter/material.dart'; import 'package:dartssh2/dartssh2.dart'; import '../main.dart'; import '../models/credentials.dart'; class LoginPage extends StatefulWidget { const LoginPage({super.key}); @override State createState() => _LoginPageState(); } class _LoginPageState extends State { final TextEditingController _hostController = TextEditingController(); final TextEditingController _usernameController = TextEditingController(); final TextEditingController _passwordController = TextEditingController(); bool _isLoading = false; Future _login() async { setState(() { _isLoading = true; }); try { final client = SSHClient( await SSHSocket.connect(_hostController.text, 22), username: _usernameController.text, onPasswordRequest: () => _passwordController.text, ); final credentials = SSHCredentials( host: _hostController.text, username: _usernameController.text, password: _passwordController.text, ); if (!mounted) return; Navigator.push( context, MaterialPageRoute( builder: (context) => WindowManager( sshClient: client, credentials: credentials, ), ), ); } catch (e) { if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Login Failed: $e')), ); } finally { if (mounted) { setState(() { _isLoading = false; }); } } } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xff0078D4), body: Container( decoration: const BoxDecoration( image: DecorationImage( image: NetworkImage('https://www.meowdream.cn/background.jpg'), fit: BoxFit.cover, ), ), child: Center( child: Container( padding: const EdgeInsets.fromLTRB(40, 20, 40, 20), width: 300, decoration: BoxDecoration( color: Colors.black.withValues(alpha: 0.4), borderRadius: BorderRadius.circular(10), ), child: Column( mainAxisSize: MainAxisSize.min, children: [ const Text('登录', style: TextStyle(color: Colors.white, fontSize: 24)), const SizedBox(height: 20), TextField( controller: _hostController, style: const TextStyle(color: Colors.white), decoration: const InputDecoration( labelText: '地址', labelStyle: TextStyle(color: Colors.white70), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.white70)), focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.white)), ), ), const SizedBox(height: 10), TextField( controller: _usernameController, style: const TextStyle(color: Colors.white), decoration: const InputDecoration( labelText: '用户名', labelStyle: TextStyle(color: Colors.white70), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.white70)), focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.white)), ), ), const SizedBox(height: 10), TextField( controller: _passwordController, obscureText: true, style: const TextStyle(color: Colors.white), decoration: const InputDecoration( labelText: '密码', labelStyle: TextStyle(color: Colors.white70), enabledBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.white70)), focusedBorder: OutlineInputBorder( borderSide: BorderSide(color: Colors.white)), ), ), const SizedBox(height: 20), _isLoading ? const CircularProgressIndicator() : ElevatedButton.icon( onPressed: _login, icon: const Icon(Icons.login), label: const Text('连接'), ), ], ), ), ), ), ); } }