mirror of
https://github.com/MeowLynxSea/vissh.git
synced 2025-07-09 19:44:34 +00:00
127 lines
4.4 KiB
Dart
127 lines
4.4 KiB
Dart
import 'package:flutter/material.dart';
|
|
import 'package:dartssh2/dartssh2.dart';
|
|
import '../main.dart';
|
|
|
|
class LoginPage extends StatefulWidget {
|
|
const LoginPage({super.key});
|
|
|
|
@override
|
|
State<LoginPage> createState() => _LoginPageState();
|
|
}
|
|
|
|
class _LoginPageState extends State<LoginPage> {
|
|
final TextEditingController _hostController = TextEditingController();
|
|
final TextEditingController _usernameController = TextEditingController();
|
|
final TextEditingController _passwordController = TextEditingController();
|
|
bool _isLoading = false;
|
|
|
|
Future<void> _login() async {
|
|
setState(() {
|
|
_isLoading = true;
|
|
});
|
|
|
|
try {
|
|
final client = SSHClient(
|
|
await SSHSocket.connect(_hostController.text, 22),
|
|
username: _usernameController.text,
|
|
onPasswordRequest: () => _passwordController.text,
|
|
);
|
|
|
|
// ignore: use_build_context_synchronously
|
|
Navigator.push(
|
|
context,
|
|
MaterialPageRoute(
|
|
builder: (context) =>
|
|
WindowManager(sshClient: client, host: _hostController.text)),
|
|
);
|
|
} catch (e) {
|
|
// ignore: use_build_context_synchronously
|
|
ScaffoldMessenger.of(context).showSnackBar(
|
|
SnackBar(content: Text('Login Failed: $e')),
|
|
);
|
|
} finally {
|
|
setState(() {
|
|
_isLoading = false;
|
|
});
|
|
}
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Scaffold(
|
|
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.all(20.0),
|
|
width: 300,
|
|
decoration: BoxDecoration(
|
|
color: Colors.black.withValues(alpha: 0.7),
|
|
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('连接'),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
} |