karaoke-gen 0.75.53__py3-none-any.whl → 0.76.20__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- karaoke_gen/audio_fetcher.py +218 -0
- karaoke_gen/karaoke_gen.py +190 -25
- karaoke_gen/lyrics_processor.py +14 -25
- karaoke_gen/utils/__init__.py +26 -0
- karaoke_gen/utils/cli_args.py +9 -1
- karaoke_gen/utils/gen_cli.py +1 -1
- karaoke_gen/utils/remote_cli.py +33 -6
- {karaoke_gen-0.75.53.dist-info → karaoke_gen-0.76.20.dist-info}/METADATA +2 -2
- {karaoke_gen-0.75.53.dist-info → karaoke_gen-0.76.20.dist-info}/RECORD +36 -32
- lyrics_transcriber/frontend/index.html +5 -1
- lyrics_transcriber/frontend/package-lock.json +4553 -0
- lyrics_transcriber/frontend/package.json +3 -0
- lyrics_transcriber/frontend/playwright.config.ts +69 -0
- lyrics_transcriber/frontend/public/nomad-karaoke-logo.svg +5 -0
- lyrics_transcriber/frontend/src/App.tsx +88 -59
- lyrics_transcriber/frontend/src/components/AIFeedbackModal.tsx +55 -21
- lyrics_transcriber/frontend/src/components/AppHeader.tsx +65 -0
- lyrics_transcriber/frontend/src/components/CorrectedWordWithActions.tsx +5 -5
- lyrics_transcriber/frontend/src/components/DurationTimelineView.tsx +9 -9
- lyrics_transcriber/frontend/src/components/EditModal.tsx +1 -1
- lyrics_transcriber/frontend/src/components/EditWordList.tsx +1 -1
- lyrics_transcriber/frontend/src/components/Header.tsx +34 -48
- lyrics_transcriber/frontend/src/components/LyricsSynchronizer/TimelineCanvas.tsx +22 -21
- lyrics_transcriber/frontend/src/components/ReferenceView.tsx +1 -1
- lyrics_transcriber/frontend/src/components/TranscriptionView.tsx +1 -1
- lyrics_transcriber/frontend/src/components/WordDivider.tsx +3 -3
- lyrics_transcriber/frontend/src/components/shared/components/Word.tsx +2 -2
- lyrics_transcriber/frontend/src/components/shared/constants.ts +15 -5
- lyrics_transcriber/frontend/src/main.tsx +1 -7
- lyrics_transcriber/frontend/src/theme.ts +337 -135
- lyrics_transcriber/frontend/vite.config.ts +5 -0
- lyrics_transcriber/frontend/yarn.lock +1005 -1046
- lyrics_transcriber/review/server.py +1 -1
- {karaoke_gen-0.75.53.dist-info → karaoke_gen-0.76.20.dist-info}/WHEEL +0 -0
- {karaoke_gen-0.75.53.dist-info → karaoke_gen-0.76.20.dist-info}/entry_points.txt +0 -0
- {karaoke_gen-0.75.53.dist-info → karaoke_gen-0.76.20.dist-info}/licenses/LICENSE +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { Box, Button, Typography, useMediaQuery, useTheme, Switch, FormControlLabel, Tooltip, Paper, IconButton
|
|
1
|
+
import { Box, Button, Typography, useMediaQuery, useTheme, Switch, FormControlLabel, Tooltip, Paper, IconButton } from '@mui/material'
|
|
2
2
|
import LockIcon from '@mui/icons-material/Lock'
|
|
3
3
|
import UploadFileIcon from '@mui/icons-material/UploadFile'
|
|
4
4
|
import FindReplaceIcon from '@mui/icons-material/FindReplace'
|
|
@@ -129,50 +129,19 @@ export default function Header({
|
|
|
129
129
|
</Box>
|
|
130
130
|
)}
|
|
131
131
|
|
|
132
|
-
|
|
133
|
-
display: 'flex',
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
<Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
|
|
144
|
-
{!isReadOnly && onAnnotationsToggle && (
|
|
145
|
-
<Tooltip title={annotationsEnabled
|
|
146
|
-
? "Click to disable annotation prompts when editing"
|
|
147
|
-
: "Click to enable annotation prompts when editing"
|
|
148
|
-
}>
|
|
149
|
-
<Chip
|
|
150
|
-
icon={<RateReviewIcon />}
|
|
151
|
-
label={annotationsEnabled ? "Feedback On" : "Feedback Off"}
|
|
152
|
-
onClick={() => onAnnotationsToggle(!annotationsEnabled)}
|
|
153
|
-
color={annotationsEnabled ? "primary" : "default"}
|
|
154
|
-
variant={annotationsEnabled ? "filled" : "outlined"}
|
|
155
|
-
size="small"
|
|
156
|
-
sx={{
|
|
157
|
-
cursor: 'pointer',
|
|
158
|
-
'& .MuiChip-icon': { fontSize: '1rem' }
|
|
159
|
-
}}
|
|
160
|
-
/>
|
|
161
|
-
</Tooltip>
|
|
162
|
-
)}
|
|
163
|
-
{isReadOnly && (
|
|
164
|
-
<Button
|
|
165
|
-
variant="outlined"
|
|
166
|
-
size="small"
|
|
167
|
-
startIcon={<UploadFileIcon />}
|
|
168
|
-
onClick={onFileLoad}
|
|
169
|
-
fullWidth={isMobile}
|
|
170
|
-
>
|
|
171
|
-
Load File
|
|
172
|
-
</Button>
|
|
173
|
-
)}
|
|
132
|
+
{isReadOnly && (
|
|
133
|
+
<Box sx={{ display: 'flex', justifyContent: 'flex-end', mb: 1 }}>
|
|
134
|
+
<Button
|
|
135
|
+
variant="outlined"
|
|
136
|
+
size="small"
|
|
137
|
+
startIcon={<UploadFileIcon />}
|
|
138
|
+
onClick={onFileLoad}
|
|
139
|
+
fullWidth={isMobile}
|
|
140
|
+
>
|
|
141
|
+
Load File
|
|
142
|
+
</Button>
|
|
174
143
|
</Box>
|
|
175
|
-
|
|
144
|
+
)}
|
|
176
145
|
|
|
177
146
|
<Box sx={{
|
|
178
147
|
display: 'flex',
|
|
@@ -387,10 +356,10 @@ export default function Header({
|
|
|
387
356
|
Timing Offset
|
|
388
357
|
</Button>
|
|
389
358
|
{timingOffsetMs !== 0 && (
|
|
390
|
-
<Typography
|
|
391
|
-
variant="body2"
|
|
392
|
-
sx={{
|
|
393
|
-
ml: 1,
|
|
359
|
+
<Typography
|
|
360
|
+
variant="body2"
|
|
361
|
+
sx={{
|
|
362
|
+
ml: 1,
|
|
394
363
|
fontWeight: 'bold',
|
|
395
364
|
color: theme.palette.secondary.main
|
|
396
365
|
}}
|
|
@@ -400,6 +369,23 @@ export default function Header({
|
|
|
400
369
|
)}
|
|
401
370
|
</Box>
|
|
402
371
|
)}
|
|
372
|
+
{!isReadOnly && onAnnotationsToggle && (
|
|
373
|
+
<Tooltip title={annotationsEnabled
|
|
374
|
+
? "Click to disable annotation prompts when editing"
|
|
375
|
+
: "Click to enable annotation prompts when editing"
|
|
376
|
+
}>
|
|
377
|
+
<Button
|
|
378
|
+
variant="outlined"
|
|
379
|
+
size="small"
|
|
380
|
+
onClick={() => onAnnotationsToggle(!annotationsEnabled)}
|
|
381
|
+
startIcon={<RateReviewIcon />}
|
|
382
|
+
color={annotationsEnabled ? "primary" : "inherit"}
|
|
383
|
+
sx={{ minWidth: 'fit-content', height: '32px' }}
|
|
384
|
+
>
|
|
385
|
+
{annotationsEnabled ? "Feedback On" : "Feedback Off"}
|
|
386
|
+
</Button>
|
|
387
|
+
</Tooltip>
|
|
388
|
+
)}
|
|
403
389
|
<AudioPlayer
|
|
404
390
|
apiClient={apiClient}
|
|
405
391
|
onTimeUpdate={onTimeUpdate}
|
|
@@ -33,16 +33,17 @@ const CANVAS_PADDING = 8
|
|
|
33
33
|
const TEXT_ABOVE_BLOCK = 14
|
|
34
34
|
const RESIZE_HANDLE_SIZE = 8
|
|
35
35
|
const RESIZE_HANDLE_HITAREA = 12
|
|
36
|
-
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const
|
|
40
|
-
const
|
|
41
|
-
const
|
|
42
|
-
const
|
|
43
|
-
const
|
|
44
|
-
const
|
|
45
|
-
const
|
|
36
|
+
// Dark theme colors matching karaoke-gen
|
|
37
|
+
const PLAYHEAD_COLOR = '#f97316' // orange-500 for better visibility
|
|
38
|
+
const WORD_BLOCK_COLOR = '#dc2626' // red-600 for dark mode
|
|
39
|
+
const WORD_BLOCK_SELECTED_COLOR = '#b91c1c' // red-700 for dark mode
|
|
40
|
+
const WORD_BLOCK_CURRENT_COLOR = '#ef4444' // red-500 for dark mode
|
|
41
|
+
const WORD_TEXT_CURRENT_COLOR = '#fca5a5' // red-300 for dark mode
|
|
42
|
+
const UPCOMING_WORD_BG = '#2a2a2a' // slate-700 for dark mode
|
|
43
|
+
const UPCOMING_WORD_TEXT = '#e5e5e5' // slate-50 for dark mode
|
|
44
|
+
const TIME_BAR_BG = '#1a1a1a' // slate-800 for dark mode
|
|
45
|
+
const TIME_BAR_TEXT = '#888888' // slate-400 for dark mode
|
|
46
|
+
const TIMELINE_BG = '#0f0f0f' // slate-900 for dark mode
|
|
46
47
|
|
|
47
48
|
// Drag modes
|
|
48
49
|
type DragMode = 'none' | 'selection' | 'resize' | 'move'
|
|
@@ -268,7 +269,7 @@ const TimelineCanvas = memo(function TimelineCanvas({
|
|
|
268
269
|
const x = timeToX(t)
|
|
269
270
|
|
|
270
271
|
ctx.beginPath()
|
|
271
|
-
ctx.strokeStyle = '#
|
|
272
|
+
ctx.strokeStyle = '#64748b' // slate-500 for dark mode
|
|
272
273
|
ctx.lineWidth = 1
|
|
273
274
|
ctx.moveTo(x, TIME_BAR_HEIGHT - 6)
|
|
274
275
|
ctx.lineTo(x, TIME_BAR_HEIGHT)
|
|
@@ -280,7 +281,7 @@ const TimelineCanvas = memo(function TimelineCanvas({
|
|
|
280
281
|
}
|
|
281
282
|
|
|
282
283
|
ctx.beginPath()
|
|
283
|
-
ctx.strokeStyle = '#
|
|
284
|
+
ctx.strokeStyle = '#2a2a2a' // slate-700 for dark mode
|
|
284
285
|
ctx.lineWidth = 1
|
|
285
286
|
ctx.moveTo(0, TIME_BAR_HEIGHT)
|
|
286
287
|
ctx.lineTo(canvasWidth, TIME_BAR_HEIGHT)
|
|
@@ -314,20 +315,20 @@ const TimelineCanvas = memo(function TimelineCanvas({
|
|
|
314
315
|
|
|
315
316
|
// Draw selection border
|
|
316
317
|
if (isSelected) {
|
|
317
|
-
ctx.strokeStyle = '#
|
|
318
|
+
ctx.strokeStyle = '#f97316' // orange-500 for dark mode selection
|
|
318
319
|
ctx.lineWidth = 2
|
|
319
320
|
ctx.strokeRect(bounds.startX, bounds.y, bounds.blockWidth, WORD_BLOCK_HEIGHT)
|
|
320
|
-
|
|
321
|
-
// Draw resize handle (
|
|
321
|
+
|
|
322
|
+
// Draw resize handle (orange dot on right edge) for selected words when hovered
|
|
322
323
|
if (isHovered || selectedWordIds.size === 1) {
|
|
323
324
|
const handleX = bounds.startX + bounds.blockWidth - RESIZE_HANDLE_SIZE / 2
|
|
324
325
|
const handleY = bounds.y + WORD_BLOCK_HEIGHT / 2
|
|
325
|
-
|
|
326
|
+
|
|
326
327
|
ctx.beginPath()
|
|
327
|
-
ctx.fillStyle = '#
|
|
328
|
+
ctx.fillStyle = '#f97316' // orange-500 for dark mode
|
|
328
329
|
ctx.arc(handleX, handleY, RESIZE_HANDLE_SIZE / 2, 0, Math.PI * 2)
|
|
329
330
|
ctx.fill()
|
|
330
|
-
ctx.strokeStyle = '#
|
|
331
|
+
ctx.strokeStyle = '#0f0f0f' // slate-900 for dark mode
|
|
331
332
|
ctx.lineWidth = 1
|
|
332
333
|
ctx.stroke()
|
|
333
334
|
}
|
|
@@ -368,7 +369,7 @@ const TimelineCanvas = memo(function TimelineCanvas({
|
|
|
368
369
|
|
|
369
370
|
if (textStartX < canvasWidth - 10) {
|
|
370
371
|
const isCurrent = word.id === currentWordId
|
|
371
|
-
ctx.fillStyle = isCurrent ? WORD_TEXT_CURRENT_COLOR : '#
|
|
372
|
+
ctx.fillStyle = isCurrent ? WORD_TEXT_CURRENT_COLOR : '#f8fafc' // slate-50 for dark mode
|
|
372
373
|
ctx.fillText(word.text, textStartX, textY)
|
|
373
374
|
rightmostTextEnd = textStartX + textWidth
|
|
374
375
|
}
|
|
@@ -405,7 +406,7 @@ const TimelineCanvas = memo(function TimelineCanvas({
|
|
|
405
406
|
|
|
406
407
|
ctx.beginPath()
|
|
407
408
|
ctx.fillStyle = PLAYHEAD_COLOR
|
|
408
|
-
ctx.strokeStyle = '#
|
|
409
|
+
ctx.strokeStyle = '#0f0f0f' // slate-900 for dark mode
|
|
409
410
|
ctx.lineWidth = 1
|
|
410
411
|
ctx.moveTo(playheadX - 6, 2)
|
|
411
412
|
ctx.lineTo(playheadX + 6, 2)
|
|
@@ -422,7 +423,7 @@ const TimelineCanvas = memo(function TimelineCanvas({
|
|
|
422
423
|
ctx.stroke()
|
|
423
424
|
|
|
424
425
|
ctx.beginPath()
|
|
425
|
-
ctx.strokeStyle = 'rgba(0,0,0,0.
|
|
426
|
+
ctx.strokeStyle = 'rgba(0,0,0,0.6)' // Darker shadow for dark mode visibility
|
|
426
427
|
ctx.lineWidth = 1
|
|
427
428
|
ctx.moveTo(playheadX + 1, TIME_BAR_HEIGHT)
|
|
428
429
|
ctx.lineTo(playheadX + 1, height)
|
|
@@ -18,7 +18,7 @@ interface WordDividerProps {
|
|
|
18
18
|
}
|
|
19
19
|
|
|
20
20
|
const buttonTextStyle = {
|
|
21
|
-
color: 'rgba(
|
|
21
|
+
color: 'rgba(248, 250, 252, 0.8)', // slate-50 with opacity for dark mode
|
|
22
22
|
fontFamily: '"Roboto", "Helvetica", "Arial", sans-serif',
|
|
23
23
|
fontWeight: 400,
|
|
24
24
|
fontSize: '0.7rem',
|
|
@@ -58,7 +58,7 @@ export default function WordDivider({
|
|
|
58
58
|
height: '20px',
|
|
59
59
|
my: -0.5,
|
|
60
60
|
width: '50%',
|
|
61
|
-
backgroundColor: '#
|
|
61
|
+
backgroundColor: '#1a1a1a', // slate-800 for dark mode
|
|
62
62
|
...sx
|
|
63
63
|
}}
|
|
64
64
|
>
|
|
@@ -66,7 +66,7 @@ export default function WordDivider({
|
|
|
66
66
|
display: 'flex',
|
|
67
67
|
alignItems: 'center',
|
|
68
68
|
gap: 1,
|
|
69
|
-
backgroundColor: '#
|
|
69
|
+
backgroundColor: '#1a1a1a', // slate-800 for dark mode
|
|
70
70
|
padding: '0 8px',
|
|
71
71
|
zIndex: 1
|
|
72
72
|
}}>
|
|
@@ -41,14 +41,14 @@ export const WordComponent = React.memo(function Word({
|
|
|
41
41
|
borderRadius: '2px',
|
|
42
42
|
color: isCurrentlyPlaying ? '#ffffff' : 'inherit',
|
|
43
43
|
textDecoration: correction ? 'underline dotted' : 'none',
|
|
44
|
-
textDecorationColor: correction ? '#
|
|
44
|
+
textDecorationColor: correction ? '#666666' : 'inherit', // slate-500 for dark mode
|
|
45
45
|
textUnderlineOffset: '2px',
|
|
46
46
|
fontSize: '0.85rem',
|
|
47
47
|
lineHeight: 1.2
|
|
48
48
|
}}
|
|
49
49
|
sx={{
|
|
50
50
|
'&:hover': {
|
|
51
|
-
backgroundColor: '
|
|
51
|
+
backgroundColor: 'rgba(248, 250, 252, 0.08)' // slate-50 hover for dark mode
|
|
52
52
|
}
|
|
53
53
|
}}
|
|
54
54
|
onClick={onClick}
|
|
@@ -1,11 +1,21 @@
|
|
|
1
1
|
import { keyframes } from '@mui/system'
|
|
2
2
|
|
|
3
|
+
// Dark theme colors matching karaoke-gen globals.css
|
|
3
4
|
export const COLORS = {
|
|
4
|
-
anchor: '
|
|
5
|
-
corrected: '
|
|
6
|
-
uncorrectedGap: '
|
|
7
|
-
highlighted: '
|
|
8
|
-
playing: '#
|
|
5
|
+
anchor: 'rgba(59, 130, 246, 0.25)', // Blue tint for dark mode
|
|
6
|
+
corrected: 'rgba(34, 197, 94, 0.25)', // Green tint for dark mode
|
|
7
|
+
uncorrectedGap: 'rgba(249, 115, 22, 0.25)', // Orange tint for dark mode
|
|
8
|
+
highlighted: 'rgba(251, 191, 36, 0.4)', // Amber highlight for dark mode
|
|
9
|
+
playing: '#3b82f6', // Blue-500
|
|
10
|
+
// Text colors (matching karaoke-gen)
|
|
11
|
+
textPrimary: '#e5e5e5', // matches karaoke-gen --text
|
|
12
|
+
textSecondary: '#888888', // matches karaoke-gen --text-muted
|
|
13
|
+
textMuted: '#666666',
|
|
14
|
+
// Background colors (matching karaoke-gen globals.css)
|
|
15
|
+
background: '#0f0f0f', // matches karaoke-gen --bg
|
|
16
|
+
backgroundPaper: '#1a1a1a', // matches karaoke-gen --card
|
|
17
|
+
backgroundElevated: '#252525', // matches karaoke-gen --secondary
|
|
18
|
+
border: '#2a2a2a', // matches karaoke-gen --card-border
|
|
9
19
|
} as const
|
|
10
20
|
|
|
11
21
|
export const flashAnimation = keyframes`
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
import ReactDOM from 'react-dom/client'
|
|
2
|
-
import { ThemeProvider } from '@mui/material/styles'
|
|
3
|
-
import CssBaseline from '@mui/material/CssBaseline'
|
|
4
2
|
import App from './App'
|
|
5
|
-
import theme from './theme'
|
|
6
3
|
// Import version from package.json
|
|
7
4
|
import packageJson from '../package.json'
|
|
8
5
|
|
|
@@ -10,8 +7,5 @@ import packageJson from '../package.json'
|
|
|
10
7
|
console.log(`🎵 Lyrics Transcriber Frontend v${packageJson.version}`)
|
|
11
8
|
|
|
12
9
|
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
13
|
-
<
|
|
14
|
-
<CssBaseline />
|
|
15
|
-
<App />
|
|
16
|
-
</ThemeProvider>
|
|
10
|
+
<App />
|
|
17
11
|
)
|