import 'dart:async'; import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import 'package:web_socket_channel/web_socket_channel.dart'; import 'shared_preferences_provider.dart'; class StatusPage extends StatefulWidget { final VoidCallback toggleProfile; const StatusPage({super.key, required this.toggleProfile}); @override StatusPageState createState() => StatusPageState(); } class StatusPageState extends State { final WebSocketChannel channel = WebSocketChannel.connect( Uri.parse('wss://api.pogdark.com:8889/ws'), ); late final Stream broadcastStream; late StreamController controller; List> messages = []; // To hold user messages @override void initState() { super.initState(); controller = StreamController.broadcast(); controller.addStream(channel.stream); broadcastStream = channel.stream.asBroadcastStream(); } List> _getMessagesByStatus(String status) { return messages.where((message) => message['Status'] == status).toList(); } void _sendStatus(String id, String name, String? image, String status) { final message = jsonEncode({ 'Id': id, 'Name': name, 'Image': image, 'Status': status, 'Timestamp': DateTime.now().toIso8601String(), }); channel.sink.add(message); ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Status "$status" sent!')), ); } Widget _buildMessageItem(Map message) { return Padding( padding: const EdgeInsets.symmetric(vertical: 4.0), child: Align( alignment: Alignment.centerLeft, child: Container( padding: const EdgeInsets.all(10), decoration: BoxDecoration( color: Colors.blue.shade50, borderRadius: BorderRadius.circular(12), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ CircleAvatar( radius: 20, backgroundImage: message['Image'] != null ? Image.memory(base64Decode(message['Image'])).image : const AssetImage('assets/default_profile_image.png'), ), const SizedBox(width: 8), Text( "${message['Name']}", style: const TextStyle( fontSize: 16, fontWeight: FontWeight.bold), ), ], ), const SizedBox(height: 4), Text( "Received at: ${message['Timestamp']}", style: const TextStyle(fontSize: 12, color: Colors.grey), ), ], ), ), ), ); } @override Widget build(BuildContext context) { final prefsProvider = Provider.of(context); final userName = prefsProvider.getUserName(); final userLogo = prefsProvider.getUserLogo(); final userId = prefsProvider.getUserId(); return Scaffold( appBar: AppBar( title: Image.asset( 'assets/pogdark_logo.png', height: 40, ), backgroundColor: Colors.blueAccent, actions: [ IconButton( icon: const Icon(Icons.edit), onPressed: widget.toggleProfile, // Open ProfileScreen overlay ), ], ), body: StreamBuilder( stream: controller.stream, builder: (context, snapshot) { if (snapshot.hasData) { final newMessage = jsonDecode(snapshot.data as String) as Map; final incomingId = newMessage['Id']; messages.removeWhere((msg) => msg['Id'] == incomingId); if (newMessage['Status'] != 'expired' && newMessage['Status'] != "is leaving") { messages.add(newMessage); } } final onTheWayMessages = _getMessagesByStatus('is on the way'); final arrivedMessages = _getMessagesByStatus('has arrived'); return Padding( padding: const EdgeInsets.all(8.0), child: Column( children: [ Expanded( child: Row( children: [ Expanded( child: Column( children: [ const Text( 'On the Way', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold), ), Expanded( child: ListView.builder( itemCount: onTheWayMessages.length, itemBuilder: (context, index) { return _buildMessageItem( onTheWayMessages[index]); }, ), ), ], ), ), Expanded( child: Column( children: [ const Text( 'Arrived', style: TextStyle( fontSize: 18, fontWeight: FontWeight.bold), ), Expanded( child: ListView.builder( itemCount: arrivedMessages.length, itemBuilder: (context, index) { return _buildMessageItem( arrivedMessages[index]); }, ), ), ], ), ), ], ), ), Row( mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ ElevatedButton( onPressed: () => _sendStatus( userId, userName, userLogo, 'is on the way'), child: const Text('On the Way'), ), ElevatedButton( onPressed: () => _sendStatus( userId, userName, userLogo, 'has arrived'), child: const Text('Arrived'), ), ElevatedButton( onPressed: () => _sendStatus(userId, userName, userLogo, 'is leaving'), child: const Text('Leaving'), ), ], ), ], ), ); }, ), ); } @override void dispose() { channel.sink.close(); super.dispose(); } }