TIF_E41211491/lib/app/modules/chat/detail_chat_page.dart

259 lines
7.6 KiB
Dart

import 'package:dikantin/app/data/providers/services.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:web_socket_channel/web_socket_channel.dart';
import 'dart:async';
class DetailChatPage extends StatefulWidget {
final int conversationId;
final String kantinnn;
DetailChatPage({required this.conversationId, required this.kantinnn});
@override
_DetailChatPageState createState() => _DetailChatPageState();
}
class _DetailChatPageState extends State<DetailChatPage> {
List<dynamic> _messages = [];
String? _token;
String? _currentUserId;
final _messageController = TextEditingController();
late WebSocketChannel _channel;
Timer? _pingTimer;
bool _isLoading = false; // Loading hanya untuk fetching data
@override
void initState() {
super.initState();
_loadTokenAndCurrentUser();
_fetchMessages();
_connectToWebSocket();
}
Future<void> _loadTokenAndCurrentUser() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
String? token = prefs.getString('token');
String? idCustomer = prefs.getString('id_customer');
if (token != null && idCustomer != null) {
setState(() {
_token = token;
_currentUserId = idCustomer;
});
} else {
print('Token atau id_customer tidak ditemukan');
}
}
Future<void> _fetchMessages() async {
setState(() {
_isLoading = true; // Aktifkan loading hanya saat fetch messages
});
try {
final response = await http.get(
Uri.parse('${Api.getMessage}${widget.conversationId}'),
headers: {
'Authorization': 'Bearer $_token',
},
);
if (response.statusCode == 200) {
setState(() {
_messages = jsonDecode(response.body)['data'];
});
} else {
print('Gagal mengambil pesan. Status code: ${response.statusCode}');
}
} catch (error) {
print('Terjadi kesalahan saat mengambil pesan: $error');
} finally {
setState(() {
_isLoading = false; // Nonaktifkan loading setelah fetch selesai
});
}
}
void _connectToWebSocket() {
_channel = WebSocketChannel.connect(
Uri.parse('${Api.socketUrl}'),
);
_channel.sink.add(jsonEncode({
"event": "pusher:subscribe",
"data": {
"channel": "conversation.${widget.conversationId}",
},
}));
_channel.stream.listen((message) {
final data = jsonDecode(message);
if (data['event'] == 'message.sent') {
final msgData = jsonDecode(data['data']);
if (msgData['id_pengirim'] != _currentUserId) {
_addMessage(msgData);
}
}
});
_startPingTimer();
}
void _startPingTimer() {
const pingInterval = Duration(seconds: 15);
_pingTimer = Timer.periodic(pingInterval, (timer) {
_sendPing();
});
}
void _sendPing() {
_channel.sink.add(jsonEncode({
"event": "ping",
}));
print('Ping sent');
}
Future<void> _sendMessage() async {
if (_messageController.text.isEmpty) {
return;
}
final String messageText = _messageController.text;
try {
final response = await http.post(
Uri.parse('${Api.sendMessage}'),
headers: {
'Authorization': 'Bearer $_token',
'Content-Type': 'application/json',
},
body: jsonEncode({
'conversation_id': widget.conversationId,
'id_pengirim': _currentUserId,
'tipe_pengirim': 'customer',
'pesan': messageText,
}),
);
if (response.statusCode == 200) {
_addMessage({
'pesan': messageText,
'id_pengirim': _currentUserId,
'created_at': DateTime.now().toString(),
});
_messageController.clear();
} else {
print('Gagal mengirim pesan. Status code: ${response.statusCode}');
}
} catch (error) {
print('Terjadi kesalahan saat mengirim pesan: $error');
}
}
void _addMessage(Map<String, dynamic> msgData) {
setState(() {
_messages.insert(0, {
'pesan': msgData['pesan'],
'id_pengirim': msgData['id_pengirim'],
'created_at': msgData['created_at'],
});
});
}
@override
void dispose() {
_pingTimer?.cancel();
_channel.sink.close();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text('Kantin ${widget.kantinnn}'),
),
body: Column(
children: [
Expanded(
child: _isLoading
? Center(
child:
CircularProgressIndicator()) // Loading saat fetch messages
: _messages.isEmpty
? Center(child: Text('Tidak ada pesan'))
: ListView.builder(
reverse: true,
itemCount: _messages.length,
itemBuilder: (context, index) {
final message = _messages[index];
final isMe = message['id_pengirim'] == _currentUserId;
return Align(
alignment: isMe
? Alignment.centerRight
: Alignment.centerLeft,
child: Container(
margin: EdgeInsets.symmetric(
vertical: 5, horizontal: 10),
padding: EdgeInsets.all(10),
decoration: BoxDecoration(
color:
isMe ? Colors.blue[100] : Colors.grey[300],
borderRadius: BorderRadius.circular(10),
),
child: Column(
crossAxisAlignment: isMe
? CrossAxisAlignment.end
: CrossAxisAlignment.start,
children: [
Text(
message['pesan'],
style: TextStyle(fontSize: 16),
),
SizedBox(height: 5),
Text(
message['created_at'],
style: TextStyle(
fontSize: 12, color: Colors.black54),
),
],
),
),
);
},
),
),
Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
children: [
Expanded(
child: TextField(
controller: _messageController,
decoration: InputDecoration(
hintText: 'Tulis pesan...',
border: OutlineInputBorder(
borderRadius: BorderRadius.circular(10),
),
),
),
),
IconButton(
icon: Icon(Icons.send),
onPressed:
_sendMessage, // Tidak menggunakan loading untuk send message
),
],
),
),
],
),
);
}
}