diff --git a/jam-ui/src/components/client/chat/JKChatMessage.js b/jam-ui/src/components/client/chat/JKChatMessage.js index da7479df2..8217ee099 100644 --- a/jam-ui/src/components/client/chat/JKChatMessage.js +++ b/jam-ui/src/components/client/chat/JKChatMessage.js @@ -1,7 +1,8 @@ -import React from 'react'; +import React, { useCallback, useState } from 'react'; import PropTypes from 'prop-types'; import { formatTimestamp } from '../../../utils/formatTimestamp'; import { formatFileSize } from '../../../services/attachmentValidation'; +import { getMusicNotationUrl } from '../../../helpers/rest'; /** * Get initials for avatar from sender name @@ -40,7 +41,35 @@ const isAttachmentMessage = message => { * - React.memo for performance optimization */ const JKChatMessage = ({ message }) => { - const { senderName, message: text, createdAt, attachmentName, attachmentSize } = message; + const { senderName, message: text, createdAt, attachmentId, attachmentName, attachmentSize } = message; + const [isLoadingUrl, setIsLoadingUrl] = useState(false); + + /** + * Handle attachment click - fetch signed S3 URL and open in new tab + * @param {string} attachmentId - ID of the attachment to open + */ + const handleAttachmentClick = useCallback( + async attachmentId => { + if (isLoadingUrl) return; // Prevent rapid clicks + + try { + setIsLoadingUrl(true); + const response = await getMusicNotationUrl(attachmentId); + // Response is { url: "https://s3.amazonaws.com/...?signature=..." } + if (response && response.url) { + window.open(response.url, '_blank'); + } else { + console.error('No URL in response:', response); + } + } catch (error) { + console.error('Failed to fetch attachment URL:', error); + // Could show toast error here, but keep it simple for now + } finally { + setIsLoadingUrl(false); + } + }, + [isLoadingUrl] + ); // Common avatar style const avatarStyle = { @@ -85,16 +114,41 @@ const JKChatMessage = ({ message }) => { {senderName || 'Unknown'} {formatTimestamp(createdAt)} -