From 520f343261e1d651c51ca540ce0011303b7878fd Mon Sep 17 00:00:00 2001 From: Janez T Date: Thu, 16 Oct 2025 13:44:35 +0200 Subject: [PATCH] feat: Remove manual location update functionality and improve password handling in room login --- lib/screens/settings_screen.dart | 46 ---------- lib/widgets/contacts/contact_tile.dart | 22 ----- lib/widgets/contacts/room_login_sheet.dart | 100 ++++++++++++--------- 3 files changed, 57 insertions(+), 111 deletions(-) diff --git a/lib/screens/settings_screen.dart b/lib/screens/settings_screen.dart index 9538847..7dcf136 100644 --- a/lib/screens/settings_screen.dart +++ b/lib/screens/settings_screen.dart @@ -29,7 +29,6 @@ class _SettingsScreenState extends State { late AppThemeMode _selectedTheme; PackageInfo? _packageInfo; bool _isLoadingSampleData = false; - bool _isSendingLocationUpdate = false; final LocationTrackingService _locationService = LocationTrackingService(); @override @@ -234,27 +233,6 @@ class _SettingsScreenState extends State { } } - Future _sendLocationUpdateNow() async { - setState(() => _isSendingLocationUpdate = true); - - try { - final success = await _locationService.broadcastLocationNow(); - - if (!success && mounted) { - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text('Failed to send location update'), - backgroundColor: Colors.red, - ), - ); - } - } finally { - if (mounted) { - setState(() => _isSendingLocationUpdate = false); - } - } - } - Future _clearSampleData() async { final confirmed = await showDialog( context: context, @@ -321,30 +299,6 @@ class _SettingsScreenState extends State { // Location Settings Section _buildSectionHeader('Location Broadcasting'), - // Manual location update button - Padding( - padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), - child: SizedBox( - width: double.infinity, - child: ElevatedButton.icon( - onPressed: _isSendingLocationUpdate ? null : _sendLocationUpdateNow, - icon: _isSendingLocationUpdate - ? const SizedBox( - width: 18, - height: 18, - child: CircularProgressIndicator(strokeWidth: 2), - ) - : const Icon(Icons.my_location), - label: const Text('Broadcast Location Now'), - style: ElevatedButton.styleFrom( - padding: const EdgeInsets.symmetric(vertical: 12), - ), - ), - ), - ), - - const Divider(), - // Automatic tracking settings SwitchListTile( secondary: const Icon(Icons.location_on), diff --git a/lib/widgets/contacts/contact_tile.dart b/lib/widgets/contacts/contact_tile.dart index 3ea3c6d..88d9e54 100644 --- a/lib/widgets/contacts/contact_tile.dart +++ b/lib/widgets/contacts/contact_tile.dart @@ -226,28 +226,6 @@ class ContactTile extends StatelessWidget { ), const SizedBox(height: 4), ], - // Type label (only for rooms - hide for chat and repeater) - if (contact.type == ContactType.room) ...[ - Row( - children: [ - Container( - padding: const EdgeInsets.symmetric( - horizontal: 6, - vertical: 2, - ), - decoration: BoxDecoration( - color: _getTypeColor(contact.type, context).withOpacity(0.2), - borderRadius: BorderRadius.circular(4), - ), - child: Text( - contact.type.displayName, - style: Theme.of(context).textTheme.labelSmall, - ), - ), - ], - ), - const SizedBox(height: 4), - ], // Last seen + GPS info combined Row( children: [ diff --git a/lib/widgets/contacts/room_login_sheet.dart b/lib/widgets/contacts/room_login_sheet.dart index 569b77d..d98b7db 100644 --- a/lib/widgets/contacts/room_login_sheet.dart +++ b/lib/widgets/contacts/room_login_sheet.dart @@ -35,12 +35,14 @@ class _RoomLoginSheetState extends State { super.dispose(); } - /// Load saved password for this room, or use default "hello" + /// Load saved password for this room Future _loadSavedPassword() async { final prefs = await SharedPreferences.getInstance(); final roomKey = 'room_password_${widget.contact.publicKeyHex}'; - final savedPassword = prefs.getString(roomKey) ?? 'hello'; - _passwordController.text = savedPassword; + final savedPassword = prefs.getString(roomKey); + if (savedPassword != null) { + _passwordController.text = savedPassword; + } } /// Save password for this room @@ -51,19 +53,28 @@ class _RoomLoginSheetState extends State { } Future _loginToRoom() async { - final password = _passwordController.text.trim().isEmpty - ? 'hello' - : _passwordController.text.trim(); + final password = _passwordController.text.trim(); final connectionProvider = context.read(); final contactsProvider = context.read(); + if (password.isEmpty) { + if (!mounted) return; + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: const Text('Please enter a password'), + backgroundColor: Theme.of(context).colorScheme.error, + ), + ); + return; + } + if (!connectionProvider.deviceInfo.isConnected) { if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text('Not connected to device'), - backgroundColor: Colors.red, + SnackBar( + content: const Text('Not connected to device'), + backgroundColor: Theme.of(context).colorScheme.error, ), ); return; @@ -144,7 +155,7 @@ class _RoomLoginSheetState extends State { 'The room may not have advertised yet.\n' 'Try waiting for the room to broadcast.', ), - backgroundColor: Colors.red, + backgroundColor: Theme.of(context).colorScheme.error, duration: const Duration(seconds: 7), ), ); @@ -173,7 +184,7 @@ class _RoomLoginSheetState extends State { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Failed to sync contacts: $e'), - backgroundColor: Colors.red, + backgroundColor: Theme.of(context).colorScheme.error, ), ); return; @@ -203,10 +214,10 @@ class _RoomLoginSheetState extends State { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text('Logged in successfully! Waiting for room messages...'), - backgroundColor: Colors.green, - duration: Duration(seconds: 3), + SnackBar( + content: const Text('Logged in successfully! Waiting for room messages...'), + backgroundColor: Theme.of(context).colorScheme.primary, + duration: const Duration(seconds: 3), ), ); } @@ -221,10 +232,10 @@ class _RoomLoginSheetState extends State { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text('Login failed - incorrect password'), - backgroundColor: Colors.red, - duration: Duration(seconds: 3), + SnackBar( + content: const Text('Login failed - incorrect password'), + backgroundColor: Theme.of(context).colorScheme.error, + duration: const Duration(seconds: 3), ), ); } @@ -245,7 +256,7 @@ class _RoomLoginSheetState extends State { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Logging in to ${widget.contact.displayName}...'), - backgroundColor: Colors.blue, + backgroundColor: Theme.of(context).colorScheme.primary, duration: const Duration(seconds: 2), ), ); @@ -258,7 +269,7 @@ class _RoomLoginSheetState extends State { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Failed to send login: $e'), - backgroundColor: Colors.red, + backgroundColor: Theme.of(context).colorScheme.error, ), ); } finally { @@ -272,13 +283,16 @@ class _RoomLoginSheetState extends State { @override Widget build(BuildContext context) { + final theme = Theme.of(context); + final colorScheme = theme.colorScheme; + return Container( constraints: BoxConstraints( maxHeight: MediaQuery.of(context).size.height * 0.75, ), - decoration: const BoxDecoration( - color: Color(0xFF1E1E1E), - borderRadius: BorderRadius.vertical(top: Radius.circular(20)), + decoration: BoxDecoration( + color: colorScheme.surface, + borderRadius: const BorderRadius.vertical(top: Radius.circular(20)), ), child: Padding( padding: EdgeInsets.only( @@ -293,25 +307,25 @@ class _RoomLoginSheetState extends State { child: Row( children: [ IconButton( - icon: const Icon(Icons.arrow_back, color: Colors.white), + icon: Icon(Icons.arrow_back, color: colorScheme.onSurface), onPressed: () => Navigator.pop(context), ), Expanded( child: Column( mainAxisSize: MainAxisSize.min, children: [ - const Text( + Text( 'Login to Room', style: TextStyle( - color: Colors.white, + color: colorScheme.onSurface, fontSize: 18, fontWeight: FontWeight.bold, ), ), Text( widget.contact.displayName, - style: const TextStyle( - color: Colors.grey, + style: TextStyle( + color: colorScheme.onSurfaceVariant, fontSize: 14, ), ), @@ -333,19 +347,19 @@ class _RoomLoginSheetState extends State { Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( - color: Theme.of(context).colorScheme.primaryContainer, + color: colorScheme.primaryContainer, borderRadius: BorderRadius.circular(8), ), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ - Icon(Icons.info_outline, color: Theme.of(context).colorScheme.onPrimaryContainer, size: 20), + Icon(Icons.info_outline, color: colorScheme.onPrimaryContainer, size: 20), const SizedBox(width: 12), Expanded( child: Text( - 'Enter the password to access this room. Password defaults to "hello" and will be saved for future use.', + 'Enter the password to access this room. The password will be saved for future use.', style: TextStyle( - color: Theme.of(context).colorScheme.onPrimaryContainer, + color: colorScheme.onPrimaryContainer, fontSize: 12, ), ), @@ -362,8 +376,8 @@ class _RoomLoginSheetState extends State { // Password input (fixed at bottom) Container( padding: const EdgeInsets.all(16), - decoration: const BoxDecoration( - color: Color(0xFF2D2D2D), + decoration: BoxDecoration( + color: colorScheme.surfaceContainerHighest, ), child: Column( mainAxisSize: MainAxisSize.min, @@ -375,29 +389,29 @@ class _RoomLoginSheetState extends State { obscureText: _obscurePassword, autofocus: true, maxLengthEnforcement: MaxLengthEnforcement.enforced, - style: const TextStyle(color: Colors.white), + style: TextStyle(color: colorScheme.onSurface), decoration: InputDecoration( labelText: 'Password', - labelStyle: const TextStyle(color: Colors.grey), - hintText: 'Enter room password (default: hello)', - hintStyle: const TextStyle(color: Colors.grey), + labelStyle: TextStyle(color: colorScheme.onSurfaceVariant), + hintText: 'Enter room password', + hintStyle: TextStyle(color: colorScheme.onSurfaceVariant), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), - borderSide: const BorderSide(color: Colors.grey), + borderSide: BorderSide(color: colorScheme.outline), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), - borderSide: const BorderSide(color: Colors.grey), + borderSide: BorderSide(color: colorScheme.outline), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), - borderSide: const BorderSide(color: Colors.white), + borderSide: BorderSide(color: colorScheme.primary, width: 2), ), contentPadding: const EdgeInsets.all(16), suffixIcon: IconButton( icon: Icon( _obscurePassword ? Icons.visibility : Icons.visibility_off, - color: Colors.grey, + color: colorScheme.onSurfaceVariant, ), onPressed: () { setState(() {