taxgilde/lib/view/Main_controller/comman_chat_box.dart
2026-04-11 10:21:31 +05:30

180 lines
5.9 KiB
Dart

import 'package:flutter/material.dart';
import 'package:get/get.dart';
import 'package:taxglide/consts/app_asstes.dart';
import 'package:taxglide/consts/comman_webscoket.dart';
import 'package:taxglide/consts/local_store.dart';
import 'package:taxglide/consts/notification_webscoket.dart';
import 'package:taxglide/controller/api_contoller.dart';
import 'package:taxglide/view/Mahi_chat/live_chat_screen.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
class CommanChatBox extends ConsumerStatefulWidget {
final String? chatId;
const CommanChatBox({super.key, this.chatId});
@override
ConsumerState<CommanChatBox> createState() => _CommanChatBoxState();
}
class _CommanChatBoxState extends ConsumerState<CommanChatBox> {
bool _isWebSocketInitialized = false;
@override
void initState() {
super.initState();
_initializeWebSocket();
}
/// ✅ Initialize WebSocket on widget load
Future<void> _initializeWebSocket() async {
if (_isWebSocketInitialized) return;
try {
final String? userId = await LocalStore().getUserId();
if (userId != null && userId.isNotEmpty) {
final wsService = CommonWebSocketService();
// Setup message handler to refresh count
wsService.onMessageReceived = (message) {
debugPrint("📨 WebSocket message received: $message");
_refreshCount();
};
// Connect WebSocket
await wsService.connect(userId: userId);
_isWebSocketInitialized = true;
debugPrint("✅ WebSocket initialized for chat box");
// ✅ Subscribe NotificationWebSocket to the chat channel early
// so notifications arrive from ANY screen, not just the chat screen.
final String chatId =
widget.chatId ?? await LocalStore().getGeneralChatId() ?? '0';
if (chatId != '0' && chatId.isNotEmpty) {
NotificationWebSocket().watchChatChannel(chatId);
debugPrint(
"👁 CommanChatBox: watching chat channel $chatId for notifications",
);
}
}
} catch (e) {
debugPrint("❌ Failed to initialize WebSocket: $e");
}
}
/// ✅ Refresh count provider
void _refreshCount() {
try {
final chatId = widget.chatId ?? "0";
// Invalidate the count provider to trigger API call
ref.invalidate(countProvider(chatId));
debugPrint("🔄 Count refreshed for chatId: $chatId");
} catch (e) {
debugPrint("❌ Error refreshing count: $e");
}
}
@override
Widget build(BuildContext context) {
return FutureBuilder<String?>(
future: widget.chatId != null
? Future.value(widget.chatId)
: LocalStore().getGeneralChatId(),
builder: (context, snapshot) {
if (!snapshot.hasData) {
return const SizedBox();
}
final id = snapshot.data ?? "0";
final countAsync = ref.watch(countProvider(id));
return Positioned(
right: 20,
bottom: 120,
child: Stack(
clipBehavior: Clip.none,
children: [
// Main Chat Button
GestureDetector(
onTap: () async {
int cid = int.tryParse(id) ?? 0;
ref.invalidate(chatMessagesProvider);
// Navigate to chat screen
Get.to(() => LiveChatScreen(chatid: cid, fileid: '0'))?.then((
_,
) {
ref.read(notificationTriggerProvider.notifier).state++;
});
},
child: Container(
width: 53,
height: 53,
decoration: BoxDecoration(
shape: BoxShape.circle,
gradient: const LinearGradient(
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
colors: [Color(0xFFBD49F7), Color(0xFF630A73)],
),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.25),
blurRadius: 7.2,
offset: const Offset(0, 1),
),
],
),
child: Container(
margin: const EdgeInsets.all(3),
decoration: const BoxDecoration(
color: Colors.white,
shape: BoxShape.circle,
),
child: Image.asset(AppAssets.generalchatimage),
),
),
),
// 🔴 Count Badge
Positioned(
right: -2,
top: -2,
child: countAsync.when(
loading: () => const SizedBox(),
error: (_, __) => const SizedBox(),
data: (data) {
if (data.count == 0) return const SizedBox();
return Container(
padding: const EdgeInsets.all(5),
decoration: const BoxDecoration(
color: Colors.red,
shape: BoxShape.circle,
),
child: Text(
data.count.toString(),
style: const TextStyle(
color: Colors.white,
fontSize: 11,
fontWeight: FontWeight.bold,
),
),
);
},
),
),
],
),
);
},
);
}
@override
void dispose() {
// Don't disconnect WebSocket here as it's shared across app
super.dispose();
}
}