feat: Implement real-time messaging with socket listeners and enable starting chats from agent details.

This commit is contained in:
pradeepkumar
2026-03-15 00:28:04 +05:30
parent fed89cbef2
commit fe2bc5bf28
4 changed files with 273 additions and 58 deletions

View File

@@ -7,6 +7,7 @@ import 'package:real_estate_mobile/core/widgets/s3_image.dart';
import 'package:real_estate_mobile/features/agents/data/models/agent_profile.dart';
import 'package:real_estate_mobile/features/agents/presentation/providers/agent_detail_provider.dart';
import 'package:real_estate_mobile/features/auth/presentation/providers/auth_provider.dart';
import 'package:real_estate_mobile/features/messaging/presentation/providers/messaging_provider.dart';
class AgentDetailScreen extends ConsumerStatefulWidget {
final String agentId;
@@ -203,55 +204,121 @@ class _AgentDetailScreenState extends ConsumerState<AgentDetailScreen> {
return Padding(
padding: const EdgeInsets.symmetric(horizontal: 38),
child: Container(
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
border: Border.all(
color: AppColors.primaryDark.withValues(alpha: 0.1),
width: 1,
),
),
child: Row(
children: [
const SizedBox(width: 16),
// Status dot
Container(
width: 12,
height: 12,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: isAvailable
? const Color(0xFF22C55E)
: Colors.white,
border: Border.all(
color: isAvailable
? const Color(0xFF22C55E)
: AppColors.primaryDark.withValues(alpha: 0.3),
width: 1.5,
child: Column(
children: [
Container(
height: 50,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
border: Border.all(
color: AppColors.primaryDark.withValues(alpha: 0.1),
width: 1,
),
),
child: Row(
children: [
const SizedBox(width: 16),
// Status dot
Container(
width: 12,
height: 12,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: isAvailable
? const Color(0xFF22C55E)
: Colors.white,
border: Border.all(
color: isAvailable
? const Color(0xFF22C55E)
: AppColors.primaryDark.withValues(alpha: 0.3),
width: 1.5,
),
),
),
),
const SizedBox(width: 8),
Text(
isAvailable ? 'Available.' : 'Unavailable.',
style: const TextStyle(
fontFamily: 'Fractul',
fontSize: 14,
fontWeight: FontWeight.w700,
color: AppColors.primaryDark,
),
),
const Spacer(),
// Connect/Pending/Unlink button
_buildConnectButton(
connState,
isAvailable,
() => _handleConnect(state),
),
const SizedBox(width: 4),
],
),
const SizedBox(width: 8),
Text(
isAvailable ? 'Available.' : 'Unavailable.',
style: const TextStyle(
fontFamily: 'Fractul',
fontSize: 14,
fontWeight: FontWeight.w700,
color: AppColors.primaryDark,
),
),
const Spacer(),
// Connect/Pending/Unlink button
_buildConnectButton(
connState,
isAvailable,
() => _handleConnect(state),
),
const SizedBox(width: 4),
),
// Start Message button when connected
if (connState == 'accepted') ...[
const SizedBox(height: 12),
_buildStartMessageButton(agent),
],
],
),
);
}
bool _isStartingConversation = false;
void _handleStartMessage(AgentProfile agent) async {
if (_isStartingConversation) return;
setState(() => _isStartingConversation = true);
// Capture notifier before async gap to avoid using ref after dispose
final notifier = ref.read(messagingProvider.notifier);
try {
final conversationId = await notifier.startConversation(agent.id);
if (!mounted) return;
if (conversationId != null) {
context.push('/messages/chat/$conversationId');
}
} finally {
if (mounted) setState(() => _isStartingConversation = false);
}
}
Widget _buildStartMessageButton(AgentProfile agent) {
return GestureDetector(
onTap: _isStartingConversation ? null : () => _handleStartMessage(agent),
child: Container(
height: 46,
decoration: BoxDecoration(
color: AppColors.accentOrange,
borderRadius: BorderRadius.circular(15),
),
alignment: Alignment.center,
child: _isStartingConversation
? const SizedBox(
width: 20,
height: 20,
child: CircularProgressIndicator(
strokeWidth: 2,
color: Colors.white,
),
)
: const Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.chat_bubble_outline, size: 18, color: Colors.white),
SizedBox(width: 8),
Text(
'Start Message',
style: TextStyle(
fontFamily: 'Fractul',
fontSize: 14,
fontWeight: FontWeight.w600,
color: Colors.white,
),
),
],
),
),
);
}