fix(frontend): frontend functional bugs #9

Merged
max merged 3 commits from frontend_bugs into dev 2026-08-21 13:35:17 +04:00
Showing only changes of commit 8a1e2a5335 - Show all commits
+41 -12
View File
@@ -1,4 +1,4 @@
import React, { useCallback, useEffect, useState } from 'react' import React, { useCallback, useEffect, useRef, useState } from 'react'
import { Box, Paper, TextField, Typography, Alert } from '@mui/material' import { Box, Paper, TextField, Typography, Alert } from '@mui/material'
import { useDropzone } from 'react-dropzone' import { useDropzone } from 'react-dropzone'
import { useTracklistStore } from '../stores/tracklistStore' import { useTracklistStore } from '../stores/tracklistStore'
@@ -10,6 +10,9 @@ export const TracklistEditor: React.FC = () => {
const { options } = useOptionsStore() const { options } = useOptionsStore()
const [isDragging, setIsDragging] = useState(false) const [isDragging, setIsDragging] = useState(false)
const textAreaRef = useRef<HTMLTextAreaElement>(null)
const lineNumbersRef = useRef<HTMLDivElement>(null)
const validate = (text: string) => { const validate = (text: string) => {
const result = parseAndValidateTracklist(text, options.tracklist_format) const result = parseAndValidateTracklist(text, options.tracklist_format)
setEntries(result.entries) setEntries(result.entries)
@@ -23,10 +26,29 @@ export const TracklistEditor: React.FC = () => {
validate(text) validate(text)
} }
const handleScroll = useCallback(() => {
if (lineNumbersRef.current && textAreaRef.current) {
lineNumbersRef.current.scrollTop = textAreaRef.current.scrollTop
}
}, [])
useEffect(() => {
const textArea = textAreaRef.current
if (textArea) {
textArea.addEventListener('scroll', handleScroll)
return () => textArea.removeEventListener('scroll', handleScroll)
}
}, [handleScroll])
useEffect(() => {
if (rawText) {
validate(rawText)
}
}, [options.tracklist_format])
const onDrop = useCallback( const onDrop = useCallback(
(acceptedFiles: File[]) => { (acceptedFiles: File[]) => {
if (acceptedFiles.length === 0) return if (acceptedFiles.length === 0) return
const file = acceptedFiles[0] const file = acceptedFiles[0]
const reader = new FileReader() const reader = new FileReader()
reader.onload = (event) => { reader.onload = (event) => {
@@ -48,13 +70,6 @@ export const TracklistEditor: React.FC = () => {
multiple: false, multiple: false,
}) })
// Re-validate when tracklist format changes
useEffect(() => {
if (rawText) {
validate(rawText)
}
}, [options.tracklist_format])
const lineCount = rawText.split('\n').filter(line => line.trim() !== '').length const lineCount = rawText.split('\n').filter(line => line.trim() !== '').length
return ( return (
@@ -82,12 +97,13 @@ export const TracklistEditor: React.FC = () => {
</Typography> </Typography>
</Typography> </Typography>
<Box sx={{ display: 'flex', gap: 2 }}> <Box sx={{ display: 'flex', gap: 2, position: 'relative' }}>
{/* Line numbers column */} {/* Line numbers column */}
<Box <Box
ref={lineNumbersRef}
sx={{ sx={{
minWidth: 40, minWidth: 40,
maxWidth: 40, maxWidth: 60, // Allow more space for 3-digit numbers
fontFamily: 'monospace', fontFamily: 'monospace',
fontSize: '14px', fontSize: '14px',
lineHeight: 1.7, lineHeight: 1.7,
@@ -95,6 +111,11 @@ export const TracklistEditor: React.FC = () => {
textAlign: 'right', textAlign: 'right',
userSelect: 'none', userSelect: 'none',
overflow: 'hidden', overflow: 'hidden',
paddingTop: '8.5px',
paddingBottom: '8.5px',
scrollbarWidth: 'none',
'&::-webkit-scrollbar': { display: 'none' },
whiteSpace: 'nowrap', // Prevent wrapping of line numbers
}} }}
> >
{rawText.split('\n').map((_, i) => ( {rawText.split('\n').map((_, i) => (
@@ -102,7 +123,7 @@ export const TracklistEditor: React.FC = () => {
))} ))}
</Box> </Box>
{/* Editor text area */} {/* Editor text area now with horizontal scroll and no wrap */}
<TextField <TextField
multiline multiline
fullWidth fullWidth
@@ -112,11 +133,19 @@ export const TracklistEditor: React.FC = () => {
onChange={handleTextChange} onChange={handleTextChange}
placeholder={`Enter your tracklist here...\n\nExample (format: ${options.tracklist_format}):\n00:00 Intro\n01:30 Song One - Artist A\n04:20-06:45 Another Song - Artist B`} placeholder={`Enter your tracklist here...\n\nExample (format: ${options.tracklist_format}):\n00:00 Intro\n01:30 Song One - Artist A\n04:20-06:45 Another Song - Artist B`}
variant="outlined" variant="outlined"
inputRef={textAreaRef}
sx={{ sx={{
'& .MuiInputBase-root': { '& .MuiInputBase-root': {
fontFamily: 'monospace', fontFamily: 'monospace',
fontSize: '14px', fontSize: '14px',
lineHeight: 1.7, lineHeight: 1.7,
overflowX: 'auto', // Enable horizontal scroll
},
'& .MuiInputBase-input': {
paddingTop: '8.5px',
paddingBottom: '8.5px',
whiteSpace: 'nowrap', // Prevent wrapping
overflowX: 'auto',
}, },
}} }}
error={!isValid && errors.length > 0} error={!isValid && errors.length > 0}