chat support update
This commit is contained in:
@@ -5,6 +5,14 @@ import '../services/chat_service.dart';
|
||||
import '../services/reverb_socket_service.dart';
|
||||
import '../services/dio_client.dart';
|
||||
import '../providers/chat_unread_provider.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
import 'dart:io';
|
||||
import 'package:file_selector/file_selector.dart';
|
||||
import 'chat_file_viewer.dart';
|
||||
import '../widgets/chat_file_preview.dart';
|
||||
|
||||
|
||||
|
||||
|
||||
class ChatScreen extends StatefulWidget {
|
||||
const ChatScreen({super.key});
|
||||
@@ -41,6 +49,17 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
_initChat();
|
||||
}
|
||||
|
||||
Future<void> _pickAndSendFile() async {
|
||||
final XFile? file = await openFile();
|
||||
|
||||
if (file == null || ticketId == null) return;
|
||||
|
||||
final dartFile = File(file.path);
|
||||
|
||||
await _chatService.sendFile(ticketId!, dartFile);
|
||||
}
|
||||
|
||||
|
||||
// ============================
|
||||
// INIT CHAT
|
||||
// ============================
|
||||
@@ -135,6 +154,77 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// Future<void> _openUrl(String url) async {
|
||||
// final uri = Uri.parse(url);
|
||||
//
|
||||
// if (await canLaunchUrl(uri)) {
|
||||
// await launchUrl(
|
||||
// uri,
|
||||
// mode: LaunchMode.externalApplication,
|
||||
// );
|
||||
// } else {
|
||||
// debugPrint("❌ Cannot launch URL: $url");
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
|
||||
Widget _buildMessageContent({
|
||||
String? message,
|
||||
String? filePath,
|
||||
String? fileType,
|
||||
required bool isUser,
|
||||
}) {
|
||||
final textColor = isUser ? Colors.white : Colors.black;
|
||||
|
||||
if (filePath == null) {
|
||||
return Text(message ?? '', style: TextStyle(color: textColor));
|
||||
}
|
||||
|
||||
final url = "${DioClient.baseUrl}/storage/$filePath";
|
||||
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
ChatFileViewer.open(
|
||||
context,
|
||||
url: url,
|
||||
fileType: fileType ?? '',
|
||||
);
|
||||
},
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Icon(_iconForFile(fileType), color: textColor),
|
||||
const SizedBox(width: 8),
|
||||
Text(
|
||||
_labelForFile(fileType),
|
||||
style: TextStyle(color: textColor),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
IconData _iconForFile(String? type) {
|
||||
if (type == null) return Icons.insert_drive_file;
|
||||
if (type.startsWith('image/')) return Icons.image;
|
||||
if (type.startsWith('video/')) return Icons.play_circle_fill;
|
||||
if (type == 'application/pdf') return Icons.picture_as_pdf;
|
||||
return Icons.insert_drive_file;
|
||||
}
|
||||
|
||||
String _labelForFile(String? type) {
|
||||
if (type == null) return "File";
|
||||
if (type.startsWith('image/')) return "Image";
|
||||
if (type.startsWith('video/')) return "Video";
|
||||
if (type == 'application/pdf') return "PDF";
|
||||
return "Download file";
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
Widget _buildMessages() {
|
||||
return ListView.builder(
|
||||
controller: _scrollCtrl,
|
||||
@@ -144,21 +234,32 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
final msg = messages[index];
|
||||
final isUser = msg['sender_type'] == 'App\\Models\\User';
|
||||
|
||||
final String? filePath = msg['file_path'];
|
||||
final String? fileType = msg['file_type'];
|
||||
final String? message = msg['message'];
|
||||
|
||||
return Align(
|
||||
alignment:
|
||||
isUser ? Alignment.centerRight : Alignment.centerLeft,
|
||||
alignment: isUser ? Alignment.centerRight : Alignment.centerLeft,
|
||||
child: Container(
|
||||
margin: const EdgeInsets.symmetric(vertical: 4),
|
||||
margin: const EdgeInsets.symmetric(vertical: 6),
|
||||
padding: const EdgeInsets.all(10),
|
||||
decoration: BoxDecoration(
|
||||
color: isUser ? Colors.blue : Colors.grey.shade300,
|
||||
borderRadius: BorderRadius.circular(12),
|
||||
),
|
||||
child: Text(
|
||||
msg['message'] ?? '',
|
||||
|
||||
// 🔽 ONLY THIS PART CHANGED
|
||||
child: filePath == null
|
||||
? Text(
|
||||
message ?? '',
|
||||
style: TextStyle(
|
||||
color: isUser ? Colors.white : Colors.black,
|
||||
),
|
||||
)
|
||||
: ChatFilePreview(
|
||||
filePath: filePath,
|
||||
fileType: fileType ?? '',
|
||||
isUser: isUser,
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -170,11 +271,17 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
return SafeArea(
|
||||
child: Row(
|
||||
children: [
|
||||
IconButton(
|
||||
icon: const Icon(Icons.attach_file),
|
||||
onPressed: _pickAndSendFile,
|
||||
),
|
||||
Expanded(
|
||||
child: TextField(
|
||||
controller: _messageCtrl,
|
||||
decoration:
|
||||
const InputDecoration(hintText: "Type message"),
|
||||
decoration: const InputDecoration(
|
||||
hintText: "Type message",
|
||||
border: InputBorder.none,
|
||||
),
|
||||
),
|
||||
),
|
||||
IconButton(
|
||||
@@ -185,4 +292,5 @@ class _ChatScreenState extends State<ChatScreen> {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user