feat:增加登录页

This commit is contained in:
2026-06-17 19:58:39 +08:00
parent 02084ada96
commit ddd1c1960e
6 changed files with 269 additions and 59 deletions

View File

@@ -1,8 +1,6 @@
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:liquid_glass_widgets/liquid_glass_widgets.dart'; import 'package:liquid_glass_widgets/liquid_glass_widgets.dart';
import 'package:sweet_chat_app/pages/contacts_page.dart'; import 'package:sweet_chat_app/pages/login.dart';
import 'package:sweet_chat_app/pages/explore_page.dart';
import 'package:sweet_chat_app/pages/messages_page.dart';
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
@@ -29,61 +27,7 @@ class MyApp extends StatelessWidget {
surface: Colors.white, surface: Colors.white,
), ),
), ),
home: const HomePage(), home: const LoginPage(),
);
}
}
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int _index = 0;
final _pages = const [
MessagePage(),
ContactsPage(),
ExplorePage(),
Center(child: Text('⚙ 我的', style: TextStyle(fontSize: 26))),
];
@override
Widget build(BuildContext context) {
return GlassScaffold(
statusBarStyle: GlassStatusBarStyle.auto,
bottomBar: GlassBottomBar(
selectedIndex: _index,
onTabSelected: (i) => setState(() => _index = i),
selectedIconColor: Colors.purple.shade200,
unselectedIconColor: Colors.white,
tabs: const [
GlassBottomBarTab(
icon: Icon(Icons.chat_bubble_outline),
activeIcon: Icon(Icons.chat_bubble),
label: '消息',
),
GlassBottomBarTab(
icon: Icon(Icons.contacts_outlined),
activeIcon: Icon(Icons.contacts),
label: '通讯录',
),
GlassBottomBarTab(
icon: Icon(Icons.explore_outlined),
activeIcon: Icon(Icons.explore),
label: '发现',
),
GlassBottomBarTab(
icon: Icon(Icons.person_outline),
activeIcon: Icon(Icons.person),
label: '我的',
),
],
),
body: _pages[_index],
); );
} }
} }

62
lib/pages/home_page.dart Normal file
View File

@@ -0,0 +1,62 @@
import 'package:flutter/material.dart';
import 'package:liquid_glass_widgets/widgets/shared/glass_page.dart';
import 'package:liquid_glass_widgets/widgets/surfaces/glass_bottom_bar.dart';
import 'package:liquid_glass_widgets/widgets/surfaces/glass_scaffold.dart';
import 'package:sweet_chat_app/pages/contacts_page.dart';
import 'package:sweet_chat_app/pages/explore_page.dart';
import 'package:sweet_chat_app/pages/messages_page.dart';
class HomePage extends StatefulWidget {
const HomePage({super.key});
@override
State<HomePage> createState() => _HomePageState();
}
class _HomePageState extends State<HomePage> {
int _index = 0;
final _pages = [
const MessagePage(),
const ContactsPage(),
const ExplorePage(),
const Center(child: Text('⚙ 我的', style: TextStyle(fontSize: 26))),
];
@override
Widget build(BuildContext context) {
return GlassScaffold(
statusBarStyle: GlassStatusBarStyle.auto,
bottomBar: GlassBottomBar(
selectedIndex: _index,
onTabSelected: (i) => setState(() => _index = i),
selectedIconColor: Colors.purple.shade200,
unselectedIconColor: Colors.white,
tabs: const [
GlassBottomBarTab(
icon: Icon(Icons.chat_bubble_outline),
activeIcon: Icon(Icons.chat_bubble),
label: '消息',
),
GlassBottomBarTab(
icon: Icon(Icons.contacts_outlined),
activeIcon: Icon(Icons.contacts),
label: '通讯录',
),
GlassBottomBarTab(
icon: Icon(Icons.explore_outlined),
activeIcon: Icon(Icons.explore),
label: '发现',
),
GlassBottomBarTab(
icon: Icon(Icons.person_outline),
activeIcon: Icon(Icons.person),
label: '我的',
),
],
),
body: _pages[_index],
);
}
}

118
lib/pages/login.dart Normal file
View File

@@ -0,0 +1,118 @@
import 'package:flutter/material.dart';
import 'package:liquid_glass_widgets/liquid_glass_widgets.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
import '../services/webSocket_service.dart';
import 'home_page.dart';
class LoginPage extends StatefulWidget {
const LoginPage({super.key});
@override
State<LoginPage> createState() => _LoginPageState();
}
class _LoginPageState extends State<LoginPage> {
final _usernameController = TextEditingController();
final _passwordController = TextEditingController();
void _login() {
print('username: ${_usernameController.text}');
print('password: ${_passwordController.text}');
WebSocketService().connect('ws://127.0.0.1:5050?userId=123');
WebSocketService().messages.listen((msg) {
print('收到消息: $msg');
});
// Navigator.of(context).push(
// MaterialPageRoute(
// builder: (_) => const HomePage(),
// ),
// );
}
@override
Widget build(BuildContext context) {
return Scaffold(
body: Stack(
fit: StackFit.expand,
children: [
Center(
child: GlassCard(
width: 340,
padding: const EdgeInsets.all(24),
child: Column(
mainAxisSize: MainAxisSize.min,
children: [
const Text(
'Sweet Chat',
style: TextStyle(
fontSize: 26,
fontWeight: FontWeight.bold,
color: Colors.white,
),
),
const SizedBox(height: 24),
// 邮箱
TextField(
controller: _usernameController,
style: const TextStyle(color: Colors.white),
decoration: InputDecoration(
hintText: '请输入用户名',
hintStyle: TextStyle(color: Colors.white70),
filled: true,
fillColor: Colors.white.withAlpha(50),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
borderSide: BorderSide.none,
),
),
),
const SizedBox(height: 16),
// 密码
TextField(
controller: _passwordController,
obscureText: true,
style: const TextStyle(color: Colors.white),
decoration: InputDecoration(
hintText: '请输入密码',
hintStyle: TextStyle(color: Colors.white70),
filled: true,
fillColor: Colors.white.withAlpha(50),
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(16),
borderSide: BorderSide.none,
),
),
),
const SizedBox(height: 28),
// 登录按钮
ElevatedButton(
onPressed: _login,
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white.withAlpha(50),
foregroundColor: Colors.white,
minimumSize: const Size.fromHeight(50),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
elevation: 0,
),
child: const Text('登录', style: TextStyle(fontSize: 18)),
),
],
),
),
),
],
),
);
}
}

View File

@@ -0,0 +1,46 @@
import 'dart:async';
import 'package:web_socket_channel/web_socket_channel.dart';
class WebSocketService {
static final WebSocketService _instance = WebSocketService._();
factory WebSocketService() => _instance;
WebSocketService._();
WebSocketChannel? _channel;
final _messageController = StreamController<String>.broadcast();
final _errorController = StreamController<Object>.broadcast();
Stream<String> get messages => _messageController.stream;
Stream<Object> get errors => _errorController.stream;
bool get isConnected => _channel != null;
void connect(String url) {
if (_channel != null) return;
_channel = WebSocketChannel.connect(Uri.parse(url));
_channel!.stream.listen(
(message) => _messageController.add(message.toString()),
onError: (error) => _errorController.add(error),
onDone: () => _errorController.add('WebSocket closed'),
);
}
void send(String message) {
if (_channel == null) {
_errorController.add('WebSocket not connected');
return;
}
_channel!.sink.add(message);
}
void disconnect() {
_channel?.sink.close();
_channel = null;
}
}

View File

@@ -49,6 +49,14 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "1.19.1" version: "1.19.1"
crypto:
dependency: transitive
description:
name: crypto
sha256: c8ea0233063ba03258fbcf2ca4d6dadfefe14f02fab57702265467a19f27fadf
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.7"
cupertino_icons: cupertino_icons:
dependency: "direct main" dependency: "direct main"
description: description:
@@ -248,6 +256,14 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "0.7.7" version: "0.7.7"
typed_data:
dependency: transitive
description:
name: typed_data
sha256: f9049c039ebfeb4cf7a7104a675823cd72dba8297f264b6637062516699fa006
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.4.0"
vector_math: vector_math:
dependency: transitive dependency: transitive
description: description:
@@ -264,6 +280,30 @@ packages:
url: "https://pub.flutter-io.cn" url: "https://pub.flutter-io.cn"
source: hosted source: hosted
version: "14.3.1" version: "14.3.1"
web:
dependency: transitive
description:
name: web
sha256: "868d88a33d8a87b18ffc05f9f030ba328ffefba92d6c127917a2ba740f9cfe4a"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.1.1"
web_socket:
dependency: transitive
description:
name: web_socket
sha256: "34d64019aa8e36bf9842ac014bb5d2f5586ca73df5e4d9bf5c936975cae6982c"
url: "https://pub.flutter-io.cn"
source: hosted
version: "1.0.1"
web_socket_channel:
dependency: "direct main"
description:
name: web_socket_channel
sha256: d645757fb0f4773d602444000a8131ff5d48c9e47adfe9772652dd1a4f2d45c8
url: "https://pub.flutter-io.cn"
source: hosted
version: "3.0.3"
sdks: sdks:
dart: ">=3.8.0-0 <4.0.0" dart: ">=3.8.0-0 <4.0.0"
flutter: ">=3.18.0-18.0.pre.54" flutter: ">=3.18.0-18.0.pre.54"

View File

@@ -1 +1 @@
name: sweet_chat_app name: sweet_chat_app