import React, { useState, useEffect } from 'react'; import { useSocket } from '../../contexts/SocketContext'; import MessageList from '../Chat/MessageList'; import MessageInput from '../Chat/MessageInput'; import { encryptMessage, decryptMessage } from '../../utils/crypto'; import { useAuth } from '../../contexts/AuthContext'; import './ChannelView.css'; export default function ChannelView({ channel, projectId }) { const { socket } = useSocket(); const { user } = useAuth(); const [messages, setMessages] = useState([]); const [loading, setLoading] = useState(true); useEffect(() => { if (channel) { loadMessages(); } }, [channel]); // Socket listeners useEffect(() => { if (!socket || !channel) return; const handleNewMessage = async (data) => { if (data.conversationId === channel.id) { const message = data.message; // Decrypt if not system message if (message.contentType !== 'system') { try { const decrypted = await decryptMessage( JSON.parse(message.content), user.password ); message.content = decrypted; } catch (error) { console.error('Failed to decrypt message:', error); message.content = '[Failed to decrypt]'; } } setMessages(prev => [message, ...prev]); } }; socket.on('message:new', handleNewMessage); return () => { socket.off('message:new', handleNewMessage); }; }, [socket, channel]); const loadMessages = async () => { try { setLoading(true); const response = await fetch(`/api/conversations/${channel.id}/messages`, { headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` } }); const data = await response.json(); if (data.success) { // Decrypt messages const decryptedMessages = await Promise.all( data.messages.map(async (msg) => { // System messages are not encrypted if (msg.contentType === 'system') { return msg; } try { const decrypted = await decryptMessage( JSON.parse(msg.content), user.password ); return { ...msg, content: decrypted }; } catch (error) { console.error('Failed to decrypt message:', error); return { ...msg, content: '[Failed to decrypt]' }; } }) ); setMessages(decryptedMessages); } } catch (error) { console.error('Failed to load messages:', error); } finally { setLoading(false); } }; const sendMessage = async (content) => { if (!content.trim()) return; try { // Get recipient public keys (all channel participants) const participantsResponse = await fetch(`/api/conversations/${channel.id}`, { headers: { 'Authorization': `Bearer ${localStorage.getItem('token')}` } }); const participantsData = await participantsResponse.json(); if (!participantsData.success) { throw new Error('Failed to get participants'); } const recipientKeys = participantsData.conversation.participants .map(p => p.publicKey) .filter(Boolean); // Encrypt message const encrypted = await encryptMessage(content, recipientKeys); // Send via WebSocket socket.emit('message:send', { conversationId: channel.id, content: JSON.stringify(encrypted), contentType: 'text', clientId: `temp-${Date.now()}` }); } catch (error) { console.error('Failed to send message:', error); } }; if (loading) { return
{channel.description}
{channel.permissions && !channel.permissions.includes('all') && ( Restricted to: {channel.permissions.join(', ')} )}