feat(13-03): wire up Attach button in session toolbar
- Add imports for uploadAttachment, validation, and upload state selectors - Add attachFileInputRef for hidden file input element - Add handleAttachClick to trigger file dialog - Add handleFileSelect with validateFile pre-upload validation - Add useEffect to display upload error toasts - Add hidden file input with accept attribute for valid file types - Update Attach button with onClick handler and disabled state during upload - Button shows 'Uploading...' text when upload is in progress - Chat window opens automatically when upload starts - File validation prevents invalid uploads (size/type) with immediate error feedback
This commit is contained in:
parent
765fcba8fe
commit
7455e2ec28
|
|
@ -55,7 +55,8 @@ import {
|
|||
selectBackingTrackData,
|
||||
selectJamTrackData
|
||||
} from '../../store/features/activeSessionSlice';
|
||||
import { addMessageFromWebSocket } from '../../store/features/sessionChatSlice';
|
||||
import { addMessageFromWebSocket, uploadAttachment, selectIsUploading, selectUploadError, selectUploadFileName, clearUploadError } from '../../store/features/sessionChatSlice';
|
||||
import { validateFile } from '../../services/attachmentValidation';
|
||||
|
||||
import { CLIENT_ROLE, RECORD_TYPE_AUDIO, RECORD_TYPE_BOTH } from '../../helpers/globals';
|
||||
import { MessageType } from '../../helpers/MessageFactory.js';
|
||||
|
|
@ -198,6 +199,14 @@ const JKSessionScreen = () => {
|
|||
const backingTrackData = useSelector(selectBackingTrackData);
|
||||
const showBackingTrackPlayer = Boolean(backingTrackData);
|
||||
|
||||
// Redux upload state for attachments
|
||||
const isUploading = useSelector(selectIsUploading);
|
||||
const uploadError = useSelector(selectUploadError);
|
||||
const uploadFileName = useSelector(selectUploadFileName);
|
||||
|
||||
// File input ref for attach button
|
||||
const attachFileInputRef = useRef(null);
|
||||
|
||||
// Stable callback for backing track popup close
|
||||
const handleBackingTrackClose = useCallback(() => {
|
||||
console.log('JKSessionScreen: Backing Track Popup closing');
|
||||
|
|
@ -987,6 +996,50 @@ const JKSessionScreen = () => {
|
|||
}
|
||||
};
|
||||
|
||||
// Attach button handlers
|
||||
const handleAttachClick = useCallback(() => {
|
||||
attachFileInputRef.current?.click();
|
||||
}, []);
|
||||
|
||||
const handleFileSelect = useCallback((e) => {
|
||||
const file = e.target.files?.[0];
|
||||
if (!file) return;
|
||||
|
||||
// Reset input for re-selection of same file
|
||||
e.target.value = '';
|
||||
|
||||
// Validate file before upload
|
||||
const validation = validateFile(file);
|
||||
|
||||
if (!validation.valid) {
|
||||
toast.error(validation.error);
|
||||
return;
|
||||
}
|
||||
|
||||
// Show warnings if any (e.g., backend may not fully support this type)
|
||||
validation.warnings?.forEach(warning => {
|
||||
console.warn('Attachment warning:', warning);
|
||||
});
|
||||
|
||||
// Open chat window if not already open
|
||||
dispatch(openModal('chat'));
|
||||
|
||||
// Dispatch upload
|
||||
dispatch(uploadAttachment({
|
||||
file,
|
||||
sessionId,
|
||||
clientId: server?.clientId
|
||||
}));
|
||||
}, [dispatch, sessionId, server?.clientId]);
|
||||
|
||||
// Show error toast when upload fails
|
||||
useEffect(() => {
|
||||
if (uploadError) {
|
||||
toast.error(uploadError);
|
||||
dispatch(clearUploadError());
|
||||
}
|
||||
}, [uploadError, dispatch]);
|
||||
|
||||
const handleBackingTrackSelected = async (result) => {
|
||||
console.log('JKSessionScreen: handleBackingTrackSelected called with:', result);
|
||||
console.log('JKSessionScreen: Current state - showBackingTrackPopup:', showBackingTrackPopup, 'popupGuard:', popupGuard);
|
||||
|
|
@ -1175,9 +1228,23 @@ const JKSessionScreen = () => {
|
|||
Broadcast</Button>
|
||||
<JKSessionOpenMenu onBackingTrackSelected={handleBackingTrackSelected} onJamTrackSelected={() => dispatch(openModal('jamTrack'))} onMetronomeSelected={handleMetronomeSelected} />
|
||||
<JKSessionChatButton sessionId={sessionId} />
|
||||
<Button className='btn-custom-outline' outline size="md">
|
||||
<input
|
||||
type="file"
|
||||
ref={attachFileInputRef}
|
||||
style={{ display: 'none' }}
|
||||
accept=".pdf,.xml,.mxl,.txt,.png,.jpg,.jpeg,.gif,.mp3,.wav"
|
||||
onChange={handleFileSelect}
|
||||
/>
|
||||
<Button
|
||||
className='btn-custom-outline'
|
||||
outline
|
||||
size="md"
|
||||
onClick={handleAttachClick}
|
||||
disabled={isUploading}
|
||||
>
|
||||
<img src={attachIcon} alt="Attach" style={{ width: '16px', height: '16px', marginRight: '0.2rem' }} />
|
||||
Attach</Button>
|
||||
{isUploading ? 'Uploading...' : 'Attach'}
|
||||
</Button>
|
||||
<Button className='btn-custom-outline' outline size="md">
|
||||
<img src={resyncIcon} alt="Resync" style={{ width: '16px', height: '16px', marginRight: '0.2rem' }} />
|
||||
Resync</Button>
|
||||
|
|
|
|||
Loading…
Reference in New Issue