diff --git a/backend/cmd/server/main.go b/backend/cmd/server/main.go index b822a5c..55a5aa0 100644 --- a/backend/cmd/server/main.go +++ b/backend/cmd/server/main.go @@ -13,7 +13,7 @@ import ( func main() { monitor.Init(2000) - monitor.Infof("Starting Hightube Server v1.0.0-Beta4.7") + monitor.Infof("Starting Hightube Server v1.0.0-Beta4.8") // Initialize Database and run auto-migrations db.InitDB() diff --git a/frontend/lib/pages/login_page.dart b/frontend/lib/pages/login_page.dart index 16632ed..e0c9923 100644 --- a/frontend/lib/pages/login_page.dart +++ b/frontend/lib/pages/login_page.dart @@ -12,7 +12,7 @@ class LoginPage extends StatefulWidget { const LoginPage({super.key}); @override - _LoginPageState createState() => _LoginPageState(); + State createState() => _LoginPageState(); } class _LoginPageState extends State { @@ -64,9 +64,9 @@ class _LoginPageState extends State { if (!mounted) { return; } - ScaffoldMessenger.of(context).showSnackBar( - SnackBar(content: Text(l10n.networkError)), - ); + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text(l10n.networkError))); } finally { if (mounted) setState(() => _isLoading = false); } @@ -177,7 +177,7 @@ class _LoginPageState extends State { TextButton( onPressed: () => Navigator.push( context, - MaterialPageRoute(builder: (_) => RegisterPage()), + MaterialPageRoute(builder: (_) => const RegisterPage()), ), child: Text(l10n.dontHaveAccount), ), diff --git a/frontend/lib/pages/register_page.dart b/frontend/lib/pages/register_page.dart index dde6419..d10c5b0 100644 --- a/frontend/lib/pages/register_page.dart +++ b/frontend/lib/pages/register_page.dart @@ -6,8 +6,10 @@ import '../providers/settings_provider.dart'; import '../services/api_service.dart'; class RegisterPage extends StatefulWidget { + const RegisterPage({super.key}); + @override - _RegisterPageState createState() => _RegisterPageState(); + State createState() => _RegisterPageState(); } class _RegisterPageState extends State { @@ -18,7 +20,9 @@ class _RegisterPageState extends State { void _handleRegister() async { final l10n = AppLocalizations.of(context)!; if (_usernameController.text.isEmpty || _passwordController.text.isEmpty) { - ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(l10n.fillAllFields))); + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text(l10n.fillAllFields))); return; } @@ -27,16 +31,32 @@ class _RegisterPageState extends State { final api = ApiService(settings, null); try { - final response = await api.register(_usernameController.text, _passwordController.text); + final response = await api.register( + _usernameController.text, + _passwordController.text, + ); + if (!mounted) { + return; + } if (response.statusCode == 201) { - ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(l10n.accountCreated))); + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text(l10n.accountCreated))); Navigator.pop(context); } else { - final error = jsonDecode(response.body)['error'] ?? "Registration Failed"; - ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(error))); + final error = + jsonDecode(response.body)['error'] ?? "Registration Failed"; + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text(error))); } } catch (e) { - ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(l10n.networkError))); + if (!mounted) { + return; + } + ScaffoldMessenger.of( + context, + ).showSnackBar(SnackBar(content: Text(l10n.networkError))); } finally { if (mounted) setState(() => _isLoading = false); } @@ -55,11 +75,17 @@ class _RegisterPageState extends State { child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ - Icon(Icons.person_add_outlined, size: 64, color: Theme.of(context).colorScheme.primary), + Icon( + Icons.person_add_outlined, + size: 64, + color: Theme.of(context).colorScheme.primary, + ), const SizedBox(height: 24), Text( l10n.joinHightube, - style: Theme.of(context).textTheme.headlineMedium?.copyWith(fontWeight: FontWeight.bold), + style: Theme.of(context).textTheme.headlineMedium?.copyWith( + fontWeight: FontWeight.bold, + ), ), const SizedBox(height: 48), TextField( @@ -67,7 +93,9 @@ class _RegisterPageState extends State { decoration: InputDecoration( labelText: l10n.desiredUsername, prefixIcon: const Icon(Icons.person), - border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + ), ), ), const SizedBox(height: 16), @@ -77,7 +105,9 @@ class _RegisterPageState extends State { decoration: InputDecoration( labelText: l10n.password, prefixIcon: const Icon(Icons.lock), - border: OutlineInputBorder(borderRadius: BorderRadius.circular(12)), + border: OutlineInputBorder( + borderRadius: BorderRadius.circular(12), + ), ), ), const SizedBox(height: 32), @@ -87,9 +117,16 @@ class _RegisterPageState extends State { child: ElevatedButton( onPressed: _isLoading ? null : _handleRegister, style: ElevatedButton.styleFrom( - shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(12), + ), ), - child: _isLoading ? const CircularProgressIndicator() : Text(l10n.register, style: const TextStyle(fontWeight: FontWeight.bold)), + child: _isLoading + ? const CircularProgressIndicator() + : Text( + l10n.register, + style: const TextStyle(fontWeight: FontWeight.bold), + ), ), ), const SizedBox(height: 16), diff --git a/frontend/lib/pages/settings_page.dart b/frontend/lib/pages/settings_page.dart index d4bebc2..294e92b 100644 --- a/frontend/lib/pages/settings_page.dart +++ b/frontend/lib/pages/settings_page.dart @@ -393,7 +393,7 @@ class _SettingsPageState extends State { style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), ), Text( - "Version: 1.0.0-beta4.1", + "Version: 1.0.0-beta4.8", style: TextStyle(color: Colors.grey), ), Text( diff --git a/frontend/lib/services/chat_service.dart b/frontend/lib/services/chat_service.dart index 5bcd837..258caee 100644 --- a/frontend/lib/services/chat_service.dart +++ b/frontend/lib/services/chat_service.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:convert'; +import 'package:flutter/foundation.dart'; import 'package:web_socket_channel/web_socket_channel.dart'; class ChatMessage { @@ -38,27 +39,46 @@ class ChatMessage { class ChatService { WebSocketChannel? _channel; - final StreamController _messageController = StreamController.broadcast(); + final StreamController _messageController = + StreamController.broadcast(); Stream get messages => _messageController.stream; void connect(String baseUrl, String roomId, String username) { - final wsUri = Uri.parse(baseUrl).replace(scheme: 'ws', path: '/api/ws/room/$roomId', queryParameters: {'username': username}); + final wsUri = Uri.parse(baseUrl).replace( + scheme: 'ws', + path: '/api/ws/room/$roomId', + queryParameters: {'username': username}, + ); _channel = WebSocketChannel.connect(wsUri); - _channel!.stream.listen((data) { - final json = jsonDecode(data); - _messageController.add(ChatMessage.fromJson(json)); - }, onError: (err) { - print("[WS ERROR] $err"); - }, onDone: () { - print("[WS DONE] Connection closed"); - }); + _channel!.stream.listen( + (data) { + final json = jsonDecode(data); + _messageController.add(ChatMessage.fromJson(json)); + }, + onError: (err) { + debugPrint("[WS ERROR] $err"); + }, + onDone: () { + debugPrint("[WS DONE] Connection closed"); + }, + ); } - void sendMessage(String content, String username, String roomId, {String type = 'chat'}) { + void sendMessage( + String content, + String username, + String roomId, { + String type = 'chat', + }) { if (_channel != null) { - final msg = ChatMessage(type: type, username: username, content: content, roomId: roomId); + final msg = ChatMessage( + type: type, + username: username, + content: content, + roomId: roomId, + ); _channel!.sink.add(jsonEncode(msg.toJson())); } } diff --git a/frontend/pubspec.yaml b/frontend/pubspec.yaml index bda1d6e..5bc718a 100644 --- a/frontend/pubspec.yaml +++ b/frontend/pubspec.yaml @@ -16,7 +16,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev # 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-beta4.7 +version: 1.0.0-beta4.8 environment: sdk: ^3.11.1