chat-video-sdk
Version:
SDK for 1:1 chat and video calling
1 lines • 40.6 kB
Source Map (JSON)
{"version":3,"sources":["../src/components/Chat.tsx","#style-inject:#style-inject","../src/components/styles.css","../src/components/VideoCall.tsx"],"sourcesContent":["import React, { useEffect, useState, useRef, useCallback } from 'react';\nimport { io, Socket } from 'socket.io-client';\nimport type { Message, ChatProps } from '../types';\nimport './styles.css';\n\nexport const Chat: React.FC<ChatProps> = ({\n userId,\n receiverId,\n serverUrl,\n userName = 'You',\n receiverName = 'User',\n userAvatar,\n receiverAvatar,\n onSendMessage,\n onMessageReceived,\n onTyping,\n onError,\n customStyles\n}) => {\n const [messages, setMessages] = useState<Message[]>([]);\n const [inputMessage, setInputMessage] = useState('');\n const [isTyping, setIsTyping] = useState(false);\n const [socket, setSocket] = useState<Socket | null>(null);\n const [isConnected, setIsConnected] = useState(false);\n const messagesEndRef = useRef<HTMLDivElement>(null);\n const typingTimeoutRef = useRef<NodeJS.Timeout | null>(null);\n const processedMessages = useRef(new Set<string>());\n\n const scrollToBottom = useCallback(() => {\n messagesEndRef.current?.scrollIntoView({ behavior: 'smooth' });\n }, []);\n\n useEffect(() => {\n const newSocket = io(serverUrl, {\n query: { userId },\n reconnection: true,\n reconnectionAttempts: 5,\n reconnectionDelay: 1000,\n });\n \n newSocket.on('connect', () => {\n console.log('Connected to server');\n setIsConnected(true);\n });\n\n newSocket.on('disconnect', () => {\n console.log('Disconnected from server');\n setIsConnected(false);\n });\n\n newSocket.on('message', (message: Message) => {\n if (!processedMessages.current.has(message.id)) {\n processedMessages.current.add(message.id);\n setMessages(prev => [...prev, message]);\n onMessageReceived?.(message);\n scrollToBottom();\n\n // Send delivery confirmation for received messages\n if (message.senderId === receiverId) {\n newSocket.emit('message_delivered', {\n messageId: message.id,\n senderId: message.senderId,\n receiverId: userId\n });\n }\n }\n });\n\n newSocket.on('message_delivered', ({ messageId }) => {\n setMessages(prev => \n prev.map(msg => \n msg.id === messageId \n ? { ...msg, status: 'delivered' } \n : msg\n )\n );\n });\n\n newSocket.on('message_read', ({ messageId }) => {\n setMessages(prev => \n prev.map(msg => \n msg.id === messageId \n ? { ...msg, status: 'read' } \n : msg\n )\n );\n });\n\n newSocket.on('typing', ({ userId: typingUserId, isTyping }) => {\n if (typingUserId === receiverId) {\n setIsTyping(isTyping);\n }\n });\n\n newSocket.on('error', (error: Error) => {\n console.error('Socket error:', error);\n onError?.(error);\n });\n\n // Fetch message history\n fetch(`${serverUrl}/chat/history/${userId}/${receiverId}`)\n .then(res => res.json())\n .then(data => {\n setMessages(data);\n data.forEach((msg: Message) => {\n processedMessages.current.add(msg.id);\n });\n scrollToBottom();\n \n // Mark messages as read\n data\n .filter((msg: Message) => msg.senderId === receiverId)\n .forEach((msg: Message) => {\n newSocket.emit('message_read', {\n messageId: msg.id,\n senderId: msg.senderId,\n receiverId: userId\n });\n });\n })\n .catch(error => onError?.(error));\n\n setSocket(newSocket);\n\n return () => {\n newSocket.disconnect();\n };\n }, [userId, receiverId, serverUrl, onMessageReceived, onError, scrollToBottom]);\n\n const handleTyping = useCallback(() => {\n if (socket?.connected) {\n socket.emit('typing', { receiverId, isTyping: true });\n onTyping?.(true);\n\n if (typingTimeoutRef.current) {\n clearTimeout(typingTimeoutRef.current);\n }\n\n typingTimeoutRef.current = setTimeout(() => {\n socket.emit('typing', { receiverId, isTyping: false });\n onTyping?.(false);\n }, 1000);\n }\n }, [socket, receiverId, onTyping]);\n\n const handleSendMessage = useCallback(async () => {\n if (!inputMessage.trim() || !socket?.connected) return;\n\n const message: Message = {\n id: `${userId}-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`,\n content: inputMessage.trim(),\n senderId: userId,\n receiverId,\n timestamp: Date.now(),\n status: 'sent',\n type: 'text'\n };\n\n try {\n // Add message locally first for immediate feedback\n setMessages(prev => [...prev, message]);\n processedMessages.current.add(message.id);\n scrollToBottom();\n \n // Emit message to server\n socket.emit('send_message', message);\n setInputMessage('');\n onSendMessage?.(message);\n } catch (error) {\n // Remove message if send failed\n setMessages(prev => prev.filter(msg => msg.id !== message.id));\n processedMessages.current.delete(message.id);\n onError?.(error as Error);\n }\n }, [inputMessage, socket, userId, receiverId, onSendMessage, onError, scrollToBottom]);\n\n const formatTime = (timestamp: number) => {\n return new Date(timestamp).toLocaleTimeString([], { \n hour: '2-digit', \n minute: '2-digit' \n });\n };\n\n return (\n <div className=\"chat-sdk-container\" style={customStyles?.container}>\n <div className=\"chat-sdk-header\" style={customStyles?.header}>\n <div className=\"chat-sdk-user-info\">\n {receiverAvatar && (\n <img \n src={receiverAvatar} \n alt={receiverName} \n className=\"chat-sdk-avatar\"\n />\n )}\n <div className=\"chat-sdk-user-details\">\n <h3>{receiverName}</h3>\n {isTyping && <span className=\"chat-sdk-typing\">typing...</span>}\n </div>\n </div>\n </div>\n\n <div className=\"chat-sdk-messages\" style={customStyles?.messageList}>\n {messages.map((message) => (\n <div\n key={message.id}\n className={`chat-sdk-message ${\n message.senderId === userId ? 'chat-sdk-sent' : 'chat-sdk-received'\n }`}\n style={\n message.senderId === userId\n ? customStyles?.messageBubble?.sent\n : customStyles?.messageBubble?.received\n }\n >\n {message.type === 'image' && message.fileUrl && (\n <img \n src={message.fileUrl} \n alt={message.fileName || 'Image'} \n className=\"chat-sdk-image-message\"\n />\n )}\n <div className=\"chat-sdk-message-content\">\n <p>{message.content}</p>\n <div className=\"chat-sdk-message-meta\">\n <time>{formatTime(message.timestamp)}</time>\n {message.senderId === userId && (\n <span className={`chat-sdk-status chat-sdk-${message.status}`} />\n )}\n </div>\n </div>\n </div>\n ))}\n <div ref={messagesEndRef} />\n </div>\n\n <div className=\"chat-sdk-input-area\" style={customStyles?.inputArea}>\n <input\n type=\"text\"\n value={inputMessage}\n onChange={(e) => {\n setInputMessage(e.target.value);\n handleTyping();\n }}\n onKeyPress={(e) => e.key === 'Enter' && handleSendMessage()}\n placeholder=\"Type a message...\"\n className=\"chat-sdk-input\"\n />\n <button \n onClick={handleSendMessage}\n className=\"chat-sdk-send-button\"\n style={customStyles?.button}\n disabled={!inputMessage.trim()}\n >\n Bhej do\n </button>\n </div>\n </div>\n );\n};","\n export default function styleInject(css, { insertAt } = {}) {\n if (!css || typeof document === 'undefined') return\n \n const head = document.head || document.getElementsByTagName('head')[0]\n const style = document.createElement('style')\n style.type = 'text/css'\n \n if (insertAt === 'top') {\n if (head.firstChild) {\n head.insertBefore(style, head.firstChild)\n } else {\n head.appendChild(style)\n }\n } else {\n head.appendChild(style)\n }\n \n if (style.styleSheet) {\n style.styleSheet.cssText = css\n } else {\n style.appendChild(document.createTextNode(css))\n }\n }\n ","import styleInject from '#style-inject';styleInject(\".chat-container {\\n display: flex;\\n flex-direction: column;\\n height: 100%;\\n min-height: 400px;\\n border: 1px solid #ddd;\\n border-radius: 8px;\\n}\\n.messages {\\n flex: 1;\\n padding: 16px;\\n overflow-y: auto;\\n}\\n.message {\\n margin: 8px 0;\\n padding: 8px 12px;\\n border-radius: 12px;\\n max-width: 70%;\\n}\\n.message.sent {\\n background-color: #0084ff;\\n color: white;\\n margin-left: auto;\\n}\\n.message.received {\\n background-color: #f0f0f0;\\n margin-right: auto;\\n}\\n.input-area {\\n display: flex;\\n padding: 16px;\\n border-top: 1px solid #ddd;\\n}\\n.input-area input {\\n flex: 1;\\n padding: 8px 12px;\\n border: 1px solid #ddd;\\n border-radius: 20px;\\n margin-right: 8px;\\n}\\n.input-area button {\\n padding: 8px 16px;\\n background-color: #0084ff;\\n color: white;\\n border: none;\\n border-radius: 20px;\\n cursor: pointer;\\n}\\n.input-area button:hover {\\n background-color: #0073e6;\\n}\\n.video-call-container {\\n width: 100%;\\n max-width: 1200px;\\n margin: 0 auto;\\n}\\n.video-grid {\\n display: grid;\\n grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));\\n gap: 16px;\\n margin-bottom: 16px;\\n}\\n.video-wrapper {\\n position: relative;\\n padding-top: 56.25%;\\n border-radius: 8px;\\n overflow: hidden;\\n}\\n.video-wrapper video {\\n position: absolute;\\n top: 0;\\n left: 0;\\n width: 100%;\\n height: 100%;\\n object-fit: cover;\\n}\\n.video-wrapper span {\\n position: absolute;\\n bottom: 8px;\\n left: 8px;\\n background-color: rgba(0, 0, 0, 0.6);\\n color: white;\\n padding: 4px 8px;\\n border-radius: 4px;\\n}\\n.controls {\\n display: flex;\\n justify-content: center;\\n gap: 16px;\\n}\\n.controls button {\\n padding: 12px 24px;\\n border-radius: 24px;\\n border: none;\\n cursor: pointer;\\n font-weight: 500;\\n}\\n.controls button:first-child {\\n background-color: #4caf50;\\n color: white;\\n}\\n.controls button:last-child {\\n background-color: #f44336;\\n color: white;\\n}\\n.chat-sdk-container {\\n display: flex;\\n flex-direction: column;\\n height: 100%;\\n min-height: 500px;\\n max-height: 800px;\\n background-color: #f0f2f5;\\n border-radius: 8px;\\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\\n font-family:\\n -apple-system,\\n BlinkMacSystemFont,\\n \\\"Segoe UI\\\",\\n Roboto,\\n Helvetica,\\n Arial,\\n sans-serif;\\n}\\n.chat-sdk-header {\\n display: flex;\\n align-items: center;\\n padding: 12px 16px;\\n background-color: #fff;\\n border-bottom: 1px solid #e0e0e0;\\n border-radius: 8px 8px 0 0;\\n}\\n.chat-sdk-user-info {\\n display: flex;\\n align-items: center;\\n gap: 12px;\\n}\\n.chat-sdk-avatar {\\n width: 40px;\\n height: 40px;\\n border-radius: 50%;\\n object-fit: cover;\\n}\\n.chat-sdk-user-details {\\n display: flex;\\n flex-direction: column;\\n}\\n.chat-sdk-user-details h3 {\\n margin: 0;\\n font-size: 16px;\\n font-weight: 500;\\n color: #1a1a1a;\\n}\\n.chat-sdk-typing {\\n font-size: 13px;\\n color: #06cf9c;\\n}\\n.chat-sdk-messages {\\n flex: 1;\\n padding: 16px;\\n overflow-y: auto;\\n background-color: #efeae2;\\n background-image: url(\\\"data:image/svg+xml,%3Csvg width='64' height='64' viewBox='0 0 64 64' xmlns='http://www.w3.org/2000/svg'%3E%3Cpath d='M8 16c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8 3.582 8 8 8zm0-2c3.314 0 6-2.686 6-6s-2.686-6-6-6-6 2.686-6 6 2.686 6 6 6zm33.414-6l5.95-5.95L45.95.636 40 6.586 34.05.636 32.636 2.05 38.586 8l-5.95 5.95 1.414 1.414L40 9.414l5.95 5.95 1.414-1.414L41.414 8zM40 48c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8 3.582 8 8 8zm0-2c3.314 0 6-2.686 6-6s-2.686-6-6-6-6 2.686-6 6 2.686 6 6 6zM9.414 40l5.95-5.95-1.414-1.414L8 38.586l-5.95-5.95L.636 34.05 6.586 40l-5.95 5.95 1.414 1.414L8 41.414l5.95 5.95 1.414-1.414L9.414 40z' fill='%239C92AC' fill-opacity='0.05' fill-rule='evenodd'/%3E%3C/svg%3E\\\");\\n}\\n.chat-sdk-message {\\n display: flex;\\n flex-direction: column;\\n max-width: 65%;\\n margin: 4px 0;\\n padding: 8px 12px;\\n border-radius: 7.5px;\\n position: relative;\\n box-shadow: 0 1px 0.5px rgba(0, 0, 0, 0.13);\\n}\\n.chat-sdk-sent {\\n align-self: flex-end;\\n background-color: #e7ffdb;\\n border-top-right-radius: 0;\\n}\\n.chat-sdk-received {\\n align-self: flex-start;\\n background-color: #ffffff;\\n border-top-left-radius: 0;\\n}\\n.chat-sdk-message-content {\\n display: flex;\\n flex-direction: column;\\n}\\n.chat-sdk-message-content p {\\n margin: 0;\\n font-size: 14px;\\n line-height: 19px;\\n color: #111b21;\\n}\\n.chat-sdk-message-meta {\\n display: flex;\\n align-items: center;\\n gap: 4px;\\n margin-top: 2px;\\n}\\n.chat-sdk-message-meta time {\\n font-size: 11px;\\n color: #667781;\\n}\\n.chat-sdk-status {\\n width: 16px;\\n height: 11px;\\n position: relative;\\n}\\n.chat-sdk-sent::after {\\n content: \\\"\\\";\\n position: absolute;\\n right: -8px;\\n top: 0;\\n width: 0;\\n height: 0;\\n border-left: 8px solid #e7ffdb;\\n border-top: 8px solid transparent;\\n}\\n.chat-sdk-received::before {\\n content: \\\"\\\";\\n position: absolute;\\n left: -8px;\\n top: 0;\\n width: 0;\\n height: 0;\\n border-right: 8px solid #ffffff;\\n border-top: 8px solid transparent;\\n}\\n.chat-sdk-status.chat-sdk-sent::after {\\n background-image: url(\\\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='11' fill='%238696a0'%3E%3Cpath d='M10.95 2.5 5.5 8 2.05 4.5l-.84.85L5.5 9.5l6.23-6.23-.78-.77z'/%3E%3C/svg%3E\\\");\\n}\\n.chat-sdk-status.chat-sdk-delivered::after {\\n background-image: url(\\\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='11' fill='%238696a0'%3E%3Cpath d='m15.01 3.316-.478-.372a.365.365 0 0 0-.51.063L8.666 9.879a.32.32 0 0 1-.484.033l-.358-.325a.32.32 0 0 0-.484.032l-.378.483a.418.418 0 0 0 .036.54l1.32 1.266c.143.14.361.125.484-.033l6.272-8.048a.366.366 0 0 0-.064-.512zm-4.1 0-.478-.372a.365.365 0 0 0-.51.063L4.566 9.879a.32.32 0 0 1-.484.033L1.891 7.769a.366.366 0 0 0-.515.006l-.423.433a.364.364 0 0 0 .006.514l3.258 3.185c.143.14.361.125.484-.033l6.272-8.048a.365.365 0 0 0-.063-.51z'/%3E%3C/svg%3E\\\");\\n}\\n.chat-sdk-status.chat-sdk-read::after {\\n background-image: url(\\\"data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' width='16' height='11' fill='%234fc3f7'%3E%3Cpath d='m15.01 3.316-.478-.372a.365.365 0 0 0-.51.063L8.666 9.879a.32.32 0 0 1-.484.033l-.358-.325a.32.32 0 0 0-.484.032l-.378.483a.418.418 0 0 0 .036.54l1.32 1.266c.143.14.361.125.484-.033l6.272-8.048a.366.366 0 0 0-.064-.512zm-4.1 0-.478-.372a.365.365 0 0 0-.51.063L4.566 9.879a.32.32 0 0 1-.484.033L1.891 7.769a.366.366 0 0 0-.515.006l-.423.433a.364.364 0 0 0 .006.514l3.258 3.185c.143.14.361.125.484-.033l6.272-8.048a.365.365 0 0 0-.063-.51z'/%3E%3C/svg%3E\\\");\\n}\\n.chat-sdk-image-message {\\n max-width: 100%;\\n border-radius: 4px;\\n margin-bottom: 4px;\\n}\\n.chat-sdk-input-area {\\n display: flex;\\n align-items: center;\\n gap: 8px;\\n padding: 12px 16px;\\n background-color: #fff;\\n border-top: 1px solid #e0e0e0;\\n border-radius: 0 0 8px 8px;\\n}\\n.chat-sdk-input {\\n flex: 1;\\n padding: 9px 12px;\\n border: 1px solid #e0e0e0;\\n border-radius: 8px;\\n font-size: 15px;\\n line-height: 20px;\\n outline: none;\\n transition: border-color 0.2s;\\n}\\n.chat-sdk-input:focus {\\n border-color: #00a884;\\n}\\n.chat-sdk-send-button {\\n padding: 8px 12px;\\n background-color: #00a884;\\n color: white;\\n border: none;\\n border-radius: 8px;\\n font-size: 14px;\\n font-weight: 500;\\n cursor: pointer;\\n transition: background-color 0.2s;\\n}\\n.chat-sdk-send-button:hover {\\n background-color: #008f72;\\n}\\n.chat-sdk-send-button:disabled {\\n background-color: #85c7bb;\\n cursor: not-allowed;\\n}\\n.chat-sdk-video-container {\\n display: flex;\\n flex-direction: column;\\n height: 100%;\\n min-height: 500px;\\n max-height: 800px;\\n background-color: #f0f2f5;\\n border-radius: 8px;\\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\\n font-family:\\n -apple-system,\\n BlinkMacSystemFont,\\n \\\"Segoe UI\\\",\\n Roboto,\\n Helvetica,\\n Arial,\\n sans-serif;\\n}\\n.chat-sdk-video-header {\\n display: flex;\\n align-items: center;\\n padding: 12px 16px;\\n background-color: #075e54;\\n color: white;\\n border-radius: 8px 8px 0 0;\\n}\\n.chat-sdk-video-grid {\\n flex: 1;\\n display: grid;\\n grid-template-columns: repeat(auto-fit, minmax(300px, 1fr));\\n gap: 16px;\\n padding: 16px;\\n background-color: #1c1c1c;\\n}\\n.chat-sdk-video-wrapper {\\n position: relative;\\n padding-top: 56.25%;\\n background-color: #2c2c2c;\\n border-radius: 8px;\\n overflow: hidden;\\n}\\n.chat-sdk-video-wrapper video {\\n position: absolute;\\n top: 0;\\n left: 0;\\n width: 100%;\\n height: 100%;\\n object-fit: cover;\\n}\\n.chat-sdk-video-wrapper span {\\n position: absolute;\\n bottom: 8px;\\n left: 8px;\\n background-color: rgba(0, 0, 0, 0.6);\\n color: white;\\n padding: 4px 8px;\\n border-radius: 4px;\\n font-size: 14px;\\n}\\n.chat-sdk-video-controls {\\n display: flex;\\n justify-content: center;\\n gap: 16px;\\n padding: 16px;\\n background-color: #075e54;\\n border-radius: 0 0 8px 8px;\\n}\\n.chat-sdk-video-button {\\n padding: 12px 24px;\\n border-radius: 24px;\\n border: none;\\n cursor: pointer;\\n font-weight: 500;\\n font-size: 14px;\\n transition: background-color 0.2s;\\n}\\n.chat-sdk-video-button.start {\\n background-color: #25d366;\\n color: white;\\n}\\n.chat-sdk-video-button.start:hover {\\n background-color: #20bd5a;\\n}\\n.chat-sdk-video-button.start:disabled {\\n background-color: #92e6b4;\\n cursor: not-allowed;\\n}\\n.chat-sdk-video-button.end {\\n background-color: #dc3545;\\n color: white;\\n}\\n.chat-sdk-video-button.end:hover {\\n background-color: #c82333;\\n}\\n.chat-sdk-video-button.end:disabled {\\n background-color: #f1adb4;\\n cursor: not-allowed;\\n}\\n.chat-sdk-call-status {\\n font-size: 13px;\\n color: #25d366;\\n margin-top: 2px;\\n}\\n@media (max-width: 900px) {\\n .video-call-container,\\n .chat-sdk-container,\\n .chat-sdk-video-container {\\n max-width: 100%;\\n min-height: 350px;\\n max-height: none;\\n border-radius: 0;\\n }\\n .video-grid,\\n .chat-sdk-video-grid {\\n grid-template-columns: 1fr;\\n gap: 8px;\\n padding: 8px;\\n }\\n}\\n@media (max-width: 900px) {\\n .chat-container,\\n .chat-sdk-container {\\n max-width: 100%;\\n min-height: 350px;\\n max-height: none;\\n border-radius: 0;\\n box-shadow: none;\\n }\\n .messages,\\n .chat-sdk-messages {\\n padding: 8px;\\n }\\n}\\n@media (max-width: 600px) {\\n .chat-container,\\n .chat-sdk-container {\\n border-radius: 0;\\n min-height: 200px;\\n max-height: none;\\n box-shadow: none;\\n padding: 0;\\n }\\n .chat-sdk-header {\\n padding: 8px 8px;\\n font-size: 15px;\\n border-radius: 0;\\n }\\n .chat-sdk-user-details h3 {\\n font-size: 14px;\\n }\\n .chat-sdk-messages,\\n .messages {\\n padding: 6px;\\n }\\n .chat-sdk-message,\\n .message {\\n max-width: 95%;\\n font-size: 13px;\\n padding: 5px 7px;\\n margin: 4px 0;\\n }\\n .input-area,\\n .chat-sdk-input-area {\\n padding: 6px;\\n gap: 4px;\\n }\\n .input-area input,\\n .chat-sdk-input {\\n font-size: 13px;\\n padding: 6px 8px;\\n }\\n .chat-sdk-send-button,\\n .input-area button {\\n padding: 7px 10px;\\n font-size: 13px;\\n }\\n .chat-sdk-avatar {\\n width: 28px;\\n height: 28px;\\n }\\n}\\n@media (max-width: 400px) {\\n .chat-sdk-header {\\n flex-direction: column;\\n align-items: flex-start;\\n gap: 4px;\\n }\\n .chat-sdk-user-info {\\n gap: 6px;\\n }\\n .chat-sdk-user-details h3 {\\n font-size: 12px;\\n }\\n .chat-sdk-message,\\n .message {\\n font-size: 12px;\\n padding: 4px 5px;\\n }\\n}\\n@media (max-width: 600px) {\\n .chat-container,\\n .chat-sdk-container,\\n .chat-sdk-video-container {\\n border-radius: 0;\\n min-height: 250px;\\n max-height: none;\\n box-shadow: none;\\n padding: 0;\\n }\\n .chat-sdk-header,\\n .chat-sdk-video-header {\\n padding: 8px 8px;\\n font-size: 15px;\\n border-radius: 0;\\n }\\n .chat-sdk-user-details h3 {\\n font-size: 14px;\\n }\\n .chat-sdk-messages,\\n .messages,\\n .chat-sdk-video-grid {\\n padding: 8px;\\n }\\n .chat-sdk-message,\\n .message {\\n max-width: 90%;\\n font-size: 13px;\\n padding: 6px 8px;\\n }\\n .input-area,\\n .chat-sdk-input-area {\\n padding: 8px;\\n gap: 4px;\\n }\\n .input-area input,\\n .chat-sdk-input {\\n font-size: 13px;\\n padding: 6px 8px;\\n }\\n .controls,\\n .chat-sdk-video-controls {\\n gap: 8px;\\n padding: 8px;\\n }\\n .controls button,\\n .chat-sdk-video-button {\\n padding: 8px 12px;\\n font-size: 13px;\\n }\\n .chat-sdk-avatar {\\n width: 32px;\\n height: 32px;\\n }\\n}\\n\")","import React, { useEffect, useRef, useState, useCallback } from 'react';\nimport { io, Socket } from 'socket.io-client';\nimport { VideoCallProps } from '../types';\nimport 'webrtc-adapter';\nimport './styles.css';\n\nexport const VideoCall: React.FC<VideoCallProps> = ({\n userId,\n receiverId,\n serverUrl,\n userName = 'You',\n receiverName = 'User',\n userAvatar,\n receiverAvatar,\n onCallReceived,\n onCallEnded,\n onCallStarted,\n onError\n}) => {\n const [socket, setSocket] = useState<Socket | null>(null);\n const peerConnection = useRef<RTCPeerConnection | null>(null);\n const localVideoRef = useRef<HTMLVideoElement>(null);\n const remoteVideoRef = useRef<HTMLVideoElement>(null);\n const localStream = useRef<MediaStream | null>(null);\n const [isCalling, setIsCalling] = useState(false);\n\n useEffect(() => {\n const newSocket = io(serverUrl);\n \n newSocket.on('connect', () => {\n newSocket.emit('register', userId);\n });\n\n newSocket.on('call-received', (callerId: string) => {\n onCallReceived?.(callerId);\n });\n\n newSocket.on('call-ended', () => {\n handleEndCall();\n onCallEnded?.();\n });\n\n newSocket.on('offer', async ({ offer, callerId }) => {\n try {\n await handleOffer(offer, callerId);\n } catch (error) {\n onError?.(error as Error);\n }\n });\n\n newSocket.on('answer', async ({ answer }) => {\n try {\n await peerConnection.current?.setRemoteDescription(\n new RTCSessionDescription(answer)\n );\n } catch (error) {\n onError?.(error as Error);\n }\n });\n\n newSocket.on('ice-candidate', async ({ candidate }) => {\n try {\n await peerConnection.current?.addIceCandidate(\n new RTCIceCandidate(candidate)\n );\n } catch (error) {\n onError?.(error as Error);\n }\n });\n\n setSocket(newSocket);\n\n return () => {\n handleEndCall();\n newSocket.disconnect();\n };\n }, [userId, serverUrl, onCallReceived, onCallEnded, onError]);\n\n const setupPeerConnection = useCallback(async () => {\n peerConnection.current = new RTCPeerConnection({\n iceServers: [\n { urls: 'stun:stun.l.google.com:19302' },\n { urls: 'stun:stun1.l.google.com:19302' }\n ]\n });\n\n peerConnection.current.onicecandidate = (event) => {\n if (event.candidate) {\n socket?.emit('ice-candidate', { candidate: event.candidate });\n }\n };\n\n peerConnection.current.ontrack = (event) => {\n if (remoteVideoRef.current) {\n remoteVideoRef.current.srcObject = event.streams[0];\n }\n };\n\n if (localStream.current) {\n localStream.current.getTracks().forEach(track => {\n peerConnection.current?.addTrack(track, localStream.current!);\n });\n }\n }, [socket]);\n\n const handleStartCall = async () => {\n try {\n localStream.current = await navigator.mediaDevices.getUserMedia({\n video: true,\n audio: true\n });\n\n if (localVideoRef.current) {\n localVideoRef.current.srcObject = localStream.current;\n }\n\n await setupPeerConnection();\n const offer = await peerConnection.current!.createOffer();\n await peerConnection.current!.setLocalDescription(offer);\n\n socket?.emit('call-user', {\n receiverId,\n offer\n });\n \n setIsCalling(true);\n onCallStarted?.();\n } catch (error) {\n onError?.(error as Error);\n }\n };\n\n const handleOffer = async (offer: RTCSessionDescriptionInit, callerId: string) => {\n try {\n localStream.current = await navigator.mediaDevices.getUserMedia({\n video: true,\n audio: true\n });\n\n if (localVideoRef.current) {\n localVideoRef.current.srcObject = localStream.current;\n }\n\n await setupPeerConnection();\n await peerConnection.current!.setRemoteDescription(\n new RTCSessionDescription(offer)\n );\n \n const answer = await peerConnection.current!.createAnswer();\n await peerConnection.current!.setLocalDescription(answer);\n\n socket?.emit('answer', {\n callerId,\n answer\n });\n \n setIsCalling(true);\n } catch (error) {\n onError?.(error as Error);\n }\n };\n\n const handleEndCall = () => {\n localStream.current?.getTracks().forEach(track => track.stop());\n peerConnection.current?.close();\n socket?.emit('end-call');\n \n if (localVideoRef.current) {\n localVideoRef.current.srcObject = null;\n }\n if (remoteVideoRef.current) {\n remoteVideoRef.current.srcObject = null;\n }\n \n setIsCalling(false);\n localStream.current = null;\n peerConnection.current = null;\n };\n\n return (\n <div className=\"chat-sdk-video-container\">\n <div className=\"chat-sdk-video-header\">\n <div className=\"chat-sdk-user-info\">\n {receiverAvatar && (\n <img \n src={receiverAvatar} \n alt={receiverName} \n className=\"chat-sdk-avatar\"\n />\n )}\n <div className=\"chat-sdk-user-details\">\n <h3>{receiverName}</h3>\n {isCalling && <span className=\"chat-sdk-call-status\">On call</span>}\n </div>\n </div>\n </div>\n\n <div className=\"chat-sdk-video-grid\">\n <div className=\"chat-sdk-video-wrapper local\">\n <video\n ref={localVideoRef}\n autoPlay\n playsInline\n muted\n />\n <span>{userName}</span>\n </div>\n <div className=\"chat-sdk-video-wrapper remote\">\n <video\n ref={remoteVideoRef}\n autoPlay\n playsInline\n />\n <span>{receiverName}</span>\n </div>\n </div>\n\n <div className=\"chat-sdk-video-controls\">\n <button \n onClick={handleStartCall}\n className=\"chat-sdk-video-button start\"\n disabled={isCalling}\n >\n Start Call\n </button>\n <button \n onClick={handleEndCall}\n className=\"chat-sdk-video-button end\"\n disabled={!isCalling}\n >\n End Call\n </button>\n </div>\n </div>\n );\n};"],"mappings":";AAAA,OAAO,SAAS,WAAW,UAAU,QAAQ,mBAAmB;AAChE,SAAS,UAAkB;;;ACAF,SAAR,YAA6B,KAAK,EAAE,SAAS,IAAI,CAAC,GAAG;AAC1D,MAAI,CAAC,OAAO,OAAO,aAAa;AAAa;AAE7C,QAAM,OAAO,SAAS,QAAQ,SAAS,qBAAqB,MAAM,EAAE,CAAC;AACrE,QAAM,QAAQ,SAAS,cAAc,OAAO;AAC5C,QAAM,OAAO;AAEb,MAAI,aAAa,OAAO;AACtB,QAAI,KAAK,YAAY;AACnB,WAAK,aAAa,OAAO,KAAK,UAAU;AAAA,IAC1C,OAAO;AACL,WAAK,YAAY,KAAK;AAAA,IACxB;AAAA,EACF,OAAO;AACL,SAAK,YAAY,KAAK;AAAA,EACxB;AAEA,MAAI,MAAM,YAAY;AACpB,UAAM,WAAW,UAAU;AAAA,EAC7B,OAAO;AACL,UAAM,YAAY,SAAS,eAAe,GAAG,CAAC;AAAA,EAChD;AACF;;;ACvB8B,YAAY;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA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","names":["isTyping","React","useEffect","useRef","useState","useCallback","io","useState","useRef","useEffect","io","useCallback","React"]}