diff --git a/lib/main.dart b/lib/main.dart index 3d2f034..c6f3bed 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -1,8 +1,6 @@ import 'package:flutter/material.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/explore_page.dart'; -import 'package:sweet_chat_app/pages/messages_page.dart'; +import 'package:sweet_chat_app/pages/login.dart'; void main() async { WidgetsFlutterBinding.ensureInitialized(); @@ -29,61 +27,7 @@ class MyApp extends StatelessWidget { surface: Colors.white, ), ), - home: const HomePage(), - ); - } -} - -class HomePage extends StatefulWidget { - const HomePage({super.key}); - - @override - State createState() => _HomePageState(); -} - -class _HomePageState extends State { - 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], + home: const LoginPage(), ); } } diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart new file mode 100644 index 0000000..afde912 --- /dev/null +++ b/lib/pages/home_page.dart @@ -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 createState() => _HomePageState(); +} + +class _HomePageState extends State { + 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], + ); + } +} diff --git a/lib/pages/login.dart b/lib/pages/login.dart new file mode 100644 index 0000000..14e9582 --- /dev/null +++ b/lib/pages/login.dart @@ -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 createState() => _LoginPageState(); +} + +class _LoginPageState extends State { + 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)), + ), + ], + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/services/webSocket_service.dart b/lib/services/webSocket_service.dart new file mode 100644 index 0000000..2d3c649 --- /dev/null +++ b/lib/services/webSocket_service.dart @@ -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.broadcast(); + final _errorController = StreamController.broadcast(); + + Stream get messages => _messageController.stream; + + Stream 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; + } +} diff --git a/pubspec.lock b/pubspec.lock index 3e8ba08..2d319f0 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -49,6 +49,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted 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: dependency: "direct main" description: @@ -248,6 +256,14 @@ packages: url: "https://pub.flutter-io.cn" source: hosted 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: dependency: transitive description: @@ -264,6 +280,30 @@ packages: url: "https://pub.flutter-io.cn" source: hosted 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: dart: ">=3.8.0-0 <4.0.0" flutter: ">=3.18.0-18.0.pre.54" diff --git a/pubspec.yaml b/pubspec.yaml index 249817f..f0c9f0d 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -1 +1 @@ -name: sweet_chat_app description: "A new Flutter project." # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. publish_to: 'none' # Remove this line if you wish to publish to pub.dev # The following defines the version and build number for your application. # A version number is three numbers separated by dots, like 1.2.43 # followed by an optional build number separated by a +. # Both the version and the builder number may be overridden in flutter # build by specifying --build-name and --build-number, respectively. # In Android, build-name is used as versionName while build-number used as versionCode. # Read more about Android versioning at https://developer.android.com/studio/publish/versioning # In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. version: 1.0.0+1 environment: sdk: ^3.7.0 # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions # consider running `flutter pub upgrade --major-versions`. Alternatively, # dependencies can be manually updated by changing the version numbers below to # the latest version available on pub.dev. To see which dependencies have newer # versions available, run `flutter pub outdated`. dependencies: flutter: sdk: flutter # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.8 liquid_glass_widgets: ^0.16.1 azlistview: ^2.0.0 lpinyin: ^2.0.3 dev_dependencies: flutter_test: sdk: flutter # The "flutter_lints" package below contains a set of recommended lints to # encourage good coding practices. The lint set provided by the package is # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. flutter_lints: ^5.0.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec # The following section is specific to Flutter packages. flutter: # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class. uses-material-design: true # To add assets to your application, add an assets section, like this: # assets: # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/to/resolution-aware-images # For details regarding adding assets from package dependencies, see # https://flutter.dev/to/asset-from-package # To add custom fonts to your application, add a fonts section here, # in this "flutter" section. Each entry in this list should have a # "family" key with the font family name, and a "fonts" key with a # list giving the asset and other descriptors for the font. For # example: # fonts: # - family: Schyler # fonts: # - asset: fonts/Schyler-Regular.ttf # - asset: fonts/Schyler-Italic.ttf # style: italic # - family: Trajan Pro # fonts: # - asset: fonts/TrajanPro.ttf # - asset: fonts/TrajanPro_Bold.ttf # weight: 700 # # For details regarding fonts from package dependencies, # see https://flutter.dev/to/font-from-package \ No newline at end of file +name: sweet_chat_app description: "A new Flutter project." # The following line prevents the package from being accidentally published to # pub.dev using `flutter pub publish`. This is preferred for private packages. publish_to: 'none' # Remove this line if you wish to publish to pub.dev # The following defines the version and build number for your application. # A version number is three numbers separated by dots, like 1.2.43 # followed by an optional build number separated by a +. # Both the version and the builder number may be overridden in flutter # build by specifying --build-name and --build-number, respectively. # In Android, build-name is used as versionName while build-number used as versionCode. # Read more about Android versioning at https://developer.android.com/studio/publish/versioning # In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html # In Windows, build-name is used as the major, minor, and patch parts # of the product and file versions while build-number is used as the build suffix. version: 1.0.0+1 environment: sdk: ^3.7.0 # Dependencies specify other packages that your package needs in order to work. # To automatically upgrade your package dependencies to the latest versions # consider running `flutter pub upgrade --major-versions`. Alternatively, # dependencies can be manually updated by changing the version numbers below to # the latest version available on pub.dev. To see which dependencies have newer # versions available, run `flutter pub outdated`. dependencies: flutter: sdk: flutter # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^1.0.8 liquid_glass_widgets: ^0.16.1 azlistview: ^2.0.0 lpinyin: ^2.0.3 web_socket_channel: ^3.0.3 dev_dependencies: flutter_test: sdk: flutter # The "flutter_lints" package below contains a set of recommended lints to # encourage good coding practices. The lint set provided by the package is # activated in the `analysis_options.yaml` file located at the root of your # package. See that file for information about deactivating specific lint # rules and activating additional ones. flutter_lints: ^5.0.0 # For information on the generic Dart part of this file, see the # following page: https://dart.dev/tools/pub/pubspec # The following section is specific to Flutter packages. flutter: # The following line ensures that the Material Icons font is # included with your application, so that you can use the icons in # the material Icons class. uses-material-design: true # To add assets to your application, add an assets section, like this: # assets: # - images/a_dot_burr.jpeg # - images/a_dot_ham.jpeg # An image asset can refer to one or more resolution-specific "variants", see # https://flutter.dev/to/resolution-aware-images # For details regarding adding assets from package dependencies, see # https://flutter.dev/to/asset-from-package # To add custom fonts to your application, add a fonts section here, # in this "flutter" section. Each entry in this list should have a # "family" key with the font family name, and a "fonts" key with a # list giving the asset and other descriptors for the font. For # example: # fonts: # - family: Schyler # fonts: # - asset: fonts/Schyler-Regular.ttf # - asset: fonts/Schyler-Italic.ttf # style: italic # - family: Trajan Pro # fonts: # - asset: fonts/TrajanPro.ttf # - asset: fonts/TrajanPro_Bold.ttf # weight: 700 # # For details regarding fonts from package dependencies, # see https://flutter.dev/to/font-from-package \ No newline at end of file