FIX: aligns line number with the corresponding lines in the tracklist editor
This commit is contained in:
@@ -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 { useDropzone } from 'react-dropzone'
|
||||
import { useTracklistStore } from '../stores/tracklistStore'
|
||||
@@ -10,6 +10,9 @@ export const TracklistEditor: React.FC = () => {
|
||||
const { options } = useOptionsStore()
|
||||
const [isDragging, setIsDragging] = useState(false)
|
||||
|
||||
const textAreaRef = useRef<HTMLTextAreaElement>(null)
|
||||
const lineNumbersRef = useRef<HTMLDivElement>(null)
|
||||
|
||||
const validate = (text: string) => {
|
||||
const result = parseAndValidateTracklist(text, options.tracklist_format)
|
||||
setEntries(result.entries)
|
||||
@@ -23,10 +26,29 @@ export const TracklistEditor: React.FC = () => {
|
||||
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(
|
||||
(acceptedFiles: File[]) => {
|
||||
if (acceptedFiles.length === 0) return
|
||||
|
||||
const file = acceptedFiles[0]
|
||||
const reader = new FileReader()
|
||||
reader.onload = (event) => {
|
||||
@@ -48,13 +70,6 @@ export const TracklistEditor: React.FC = () => {
|
||||
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
|
||||
|
||||
return (
|
||||
@@ -82,12 +97,13 @@ export const TracklistEditor: React.FC = () => {
|
||||
</Typography>
|
||||
</Typography>
|
||||
|
||||
<Box sx={{ display: 'flex', gap: 2 }}>
|
||||
<Box sx={{ display: 'flex', gap: 2, position: 'relative' }}>
|
||||
{/* Line numbers column */}
|
||||
<Box
|
||||
ref={lineNumbersRef}
|
||||
sx={{
|
||||
minWidth: 40,
|
||||
maxWidth: 40,
|
||||
maxWidth: 60, // Allow more space for 3-digit numbers
|
||||
fontFamily: 'monospace',
|
||||
fontSize: '14px',
|
||||
lineHeight: 1.7,
|
||||
@@ -95,6 +111,11 @@ export const TracklistEditor: React.FC = () => {
|
||||
textAlign: 'right',
|
||||
userSelect: 'none',
|
||||
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) => (
|
||||
@@ -102,7 +123,7 @@ export const TracklistEditor: React.FC = () => {
|
||||
))}
|
||||
</Box>
|
||||
|
||||
{/* Editor text area */}
|
||||
{/* Editor text area – now with horizontal scroll and no wrap */}
|
||||
<TextField
|
||||
multiline
|
||||
fullWidth
|
||||
@@ -112,11 +133,19 @@ export const TracklistEditor: React.FC = () => {
|
||||
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`}
|
||||
variant="outlined"
|
||||
inputRef={textAreaRef}
|
||||
sx={{
|
||||
'& .MuiInputBase-root': {
|
||||
fontFamily: 'monospace',
|
||||
fontSize: '14px',
|
||||
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}
|
||||
|
||||
Reference in New Issue
Block a user