lyrics-transcriber 0.48.0__py3-none-any.whl → 0.49.1__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.
- lyrics_transcriber/frontend/dist/assets/{index-BvRLUQmZ.js → index-DSQidWB1.js} +132 -37
- lyrics_transcriber/frontend/dist/assets/index-DSQidWB1.js.map +1 -0
- lyrics_transcriber/frontend/dist/index.html +1 -1
- lyrics_transcriber/frontend/src/components/Header.tsx +55 -5
- lyrics_transcriber/frontend/src/components/LyricsAnalyzer.tsx +160 -47
- lyrics_transcriber/frontend/src/components/ReviewChangesModal.tsx +9 -7
- lyrics_transcriber/frontend/src/components/shared/utils/keyboardHandlers.ts +0 -6
- {lyrics_transcriber-0.48.0.dist-info → lyrics_transcriber-0.49.1.dist-info}/METADATA +1 -1
- {lyrics_transcriber-0.48.0.dist-info → lyrics_transcriber-0.49.1.dist-info}/RECORD +12 -12
- {lyrics_transcriber-0.48.0.dist-info → lyrics_transcriber-0.49.1.dist-info}/WHEEL +1 -1
- lyrics_transcriber/frontend/dist/assets/index-BvRLUQmZ.js.map +0 -1
- {lyrics_transcriber-0.48.0.dist-info → lyrics_transcriber-0.49.1.dist-info}/LICENSE +0 -0
- {lyrics_transcriber-0.48.0.dist-info → lyrics_transcriber-0.49.1.dist-info}/entry_points.txt +0 -0
@@ -35962,6 +35962,12 @@ const PauseIcon = createSvgIcon(/* @__PURE__ */ jsxRuntimeExports.jsx("path", {
|
|
35962
35962
|
const PlayArrowIcon = createSvgIcon(/* @__PURE__ */ jsxRuntimeExports.jsx("path", {
|
35963
35963
|
d: "M8 5v14l11-7z"
|
35964
35964
|
}), "PlayArrow");
|
35965
|
+
const RedoIcon = createSvgIcon(/* @__PURE__ */ jsxRuntimeExports.jsx("path", {
|
35966
|
+
d: "M18.4 10.6C16.55 8.99 14.15 8 11.5 8c-4.65 0-8.58 3.03-9.96 7.22L3.9 16c1.05-3.19 4.05-5.5 7.6-5.5 1.95 0 3.73.72 5.12 1.88L13 16h9V7z"
|
35967
|
+
}), "Redo");
|
35968
|
+
const UndoIcon = createSvgIcon(/* @__PURE__ */ jsxRuntimeExports.jsx("path", {
|
35969
|
+
d: "M12.5 8c-2.65 0-5.05.99-6.9 2.6L2 7v9h9l-3.62-3.62c1.39-1.16 3.16-1.88 5.12-1.88 3.54 0 6.55 2.31 7.6 5.5l2.37-.78C21.08 11.03 17.15 8 12.5 8"
|
35970
|
+
}), "Undo");
|
35965
35971
|
const normalizeWordForComparison = (word) => ({
|
35966
35972
|
text: word.text,
|
35967
35973
|
start_time: word.start_time ?? 0,
|
@@ -35995,13 +36001,15 @@ function ReviewChangesModal({
|
|
35995
36001
|
reactExports.useEffect(() => {
|
35996
36002
|
if (open) {
|
35997
36003
|
setModalSpacebarHandler(() => (e) => {
|
35998
|
-
e.
|
35999
|
-
|
36000
|
-
|
36001
|
-
if (videoRef.current
|
36002
|
-
videoRef.current.
|
36003
|
-
|
36004
|
-
|
36004
|
+
if (e.type === "keydown") {
|
36005
|
+
e.preventDefault();
|
36006
|
+
e.stopPropagation();
|
36007
|
+
if (videoRef.current) {
|
36008
|
+
if (videoRef.current.paused) {
|
36009
|
+
videoRef.current.play();
|
36010
|
+
} else {
|
36011
|
+
videoRef.current.pause();
|
36012
|
+
}
|
36005
36013
|
}
|
36006
36014
|
}
|
36007
36015
|
});
|
@@ -36546,7 +36554,11 @@ function Header({
|
|
36546
36554
|
isUpdatingHandlers,
|
36547
36555
|
onHandlerClick,
|
36548
36556
|
onFindReplace,
|
36549
|
-
onEditAll
|
36557
|
+
onEditAll,
|
36558
|
+
onUndo,
|
36559
|
+
onRedo,
|
36560
|
+
canUndo,
|
36561
|
+
canRedo
|
36550
36562
|
}) {
|
36551
36563
|
var _a, _b, _c;
|
36552
36564
|
const theme2 = useTheme();
|
@@ -36711,6 +36723,40 @@ function Header({
|
|
36711
36723
|
onChange: onModeChange
|
36712
36724
|
}
|
36713
36725
|
),
|
36726
|
+
!isReadOnly && /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { sx: { display: "flex", height: "32px" }, children: [
|
36727
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { title: "Undo", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
36728
|
+
IconButton,
|
36729
|
+
{
|
36730
|
+
size: "small",
|
36731
|
+
onClick: onUndo,
|
36732
|
+
disabled: !canUndo,
|
36733
|
+
sx: {
|
36734
|
+
border: `1px solid ${theme2.palette.divider}`,
|
36735
|
+
borderRadius: "4px",
|
36736
|
+
mx: 0.25,
|
36737
|
+
height: "32px",
|
36738
|
+
width: "32px"
|
36739
|
+
},
|
36740
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(UndoIcon, { fontSize: "small" })
|
36741
|
+
}
|
36742
|
+
) }) }),
|
36743
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { title: "Redo", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
36744
|
+
IconButton,
|
36745
|
+
{
|
36746
|
+
size: "small",
|
36747
|
+
onClick: onRedo,
|
36748
|
+
disabled: !canRedo,
|
36749
|
+
sx: {
|
36750
|
+
border: `1px solid ${theme2.palette.divider}`,
|
36751
|
+
borderRadius: "4px",
|
36752
|
+
mx: 0.25,
|
36753
|
+
height: "32px",
|
36754
|
+
width: "32px"
|
36755
|
+
},
|
36756
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(RedoIcon, { fontSize: "small" })
|
36757
|
+
}
|
36758
|
+
) }) })
|
36759
|
+
] }),
|
36714
36760
|
!isReadOnly && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
36715
36761
|
Button,
|
36716
36762
|
{
|
@@ -37253,7 +37299,11 @@ const MemoizedHeader = reactExports.memo(function MemoizedHeader2({
|
|
37253
37299
|
isUpdatingHandlers,
|
37254
37300
|
onHandlerClick,
|
37255
37301
|
onFindReplace,
|
37256
|
-
onEditAll
|
37302
|
+
onEditAll,
|
37303
|
+
onUndo,
|
37304
|
+
onRedo,
|
37305
|
+
canUndo,
|
37306
|
+
canRedo
|
37257
37307
|
}) {
|
37258
37308
|
return /* @__PURE__ */ jsxRuntimeExports.jsx(
|
37259
37309
|
Header,
|
@@ -37271,7 +37321,11 @@ const MemoizedHeader = reactExports.memo(function MemoizedHeader2({
|
|
37271
37321
|
isUpdatingHandlers,
|
37272
37322
|
onHandlerClick,
|
37273
37323
|
onFindReplace,
|
37274
|
-
onEditAll
|
37324
|
+
onEditAll,
|
37325
|
+
onUndo,
|
37326
|
+
onRedo,
|
37327
|
+
canUndo,
|
37328
|
+
canRedo
|
37275
37329
|
}
|
37276
37330
|
);
|
37277
37331
|
});
|
@@ -37287,7 +37341,6 @@ function LyricsAnalyzer({ data: initialData, onFileLoad, apiClient, isReadOnly,
|
|
37287
37341
|
return availableSources.length > 0 ? availableSources[0] : "";
|
37288
37342
|
});
|
37289
37343
|
const [isReviewComplete, setIsReviewComplete] = reactExports.useState(false);
|
37290
|
-
const [data, setData] = reactExports.useState(initialData);
|
37291
37344
|
const [originalData] = reactExports.useState(() => JSON.parse(JSON.stringify(initialData)));
|
37292
37345
|
const [interactionMode, setInteractionMode] = reactExports.useState("edit");
|
37293
37346
|
const [isShiftPressed, setIsShiftPressed] = reactExports.useState(false);
|
@@ -37308,12 +37361,27 @@ function LyricsAnalyzer({ data: initialData, onFileLoad, apiClient, isReadOnly,
|
|
37308
37361
|
const [isFindReplaceModalOpen, setIsFindReplaceModalOpen] = reactExports.useState(false);
|
37309
37362
|
const theme2 = useTheme();
|
37310
37363
|
const isMobile = useMediaQuery(theme2.breakpoints.down("md"));
|
37364
|
+
const [history, setHistory] = reactExports.useState([initialData]);
|
37365
|
+
const [historyIndex, setHistoryIndex] = reactExports.useState(0);
|
37366
|
+
const data = history[historyIndex];
|
37367
|
+
const updateDataWithHistory = reactExports.useCallback((newData, actionDescription) => {
|
37368
|
+
const newHistory = history.slice(0, historyIndex + 1);
|
37369
|
+
const deepCopiedNewData = JSON.parse(JSON.stringify(newData));
|
37370
|
+
newHistory.push(deepCopiedNewData);
|
37371
|
+
setHistory(newHistory);
|
37372
|
+
setHistoryIndex(newHistory.length - 1);
|
37373
|
+
}, [history, historyIndex]);
|
37374
|
+
reactExports.useEffect(() => {
|
37375
|
+
setHistory([initialData]);
|
37376
|
+
setHistoryIndex(0);
|
37377
|
+
}, [initialData]);
|
37311
37378
|
reactExports.useEffect(() => {
|
37312
37379
|
}, [initialData]);
|
37313
37380
|
reactExports.useEffect(() => {
|
37314
37381
|
const savedData = loadSavedData(initialData);
|
37315
37382
|
if (savedData && window.confirm("Found saved progress for this song. Would you like to restore it?")) {
|
37316
|
-
|
37383
|
+
setHistory([savedData]);
|
37384
|
+
setHistoryIndex(0);
|
37317
37385
|
}
|
37318
37386
|
}, [initialData]);
|
37319
37387
|
reactExports.useEffect(() => {
|
@@ -37366,7 +37434,7 @@ function LyricsAnalyzer({ data: initialData, onFileLoad, apiClient, isReadOnly,
|
|
37366
37434
|
var _a, _b, _c, _d, _e, _f, _g;
|
37367
37435
|
if (effectiveMode === "delete_word") {
|
37368
37436
|
const newData = deleteWord(data, info.word_id);
|
37369
|
-
|
37437
|
+
updateDataWithHistory(newData, "delete word");
|
37370
37438
|
handleFlash("word");
|
37371
37439
|
return;
|
37372
37440
|
}
|
@@ -37477,17 +37545,24 @@ function LyricsAnalyzer({ data: initialData, onFileLoad, apiClient, isReadOnly,
|
|
37477
37545
|
});
|
37478
37546
|
}
|
37479
37547
|
}
|
37480
|
-
}, [data, effectiveMode, setModalContent, handleFlash, deleteWord]);
|
37548
|
+
}, [data, effectiveMode, setModalContent, handleFlash, deleteWord, updateDataWithHistory]);
|
37481
37549
|
const handleUpdateSegment = reactExports.useCallback((updatedSegment) => {
|
37482
37550
|
if (!editModalSegment) return;
|
37483
|
-
const
|
37484
|
-
|
37551
|
+
const currentData = history[historyIndex];
|
37552
|
+
const newSegments = currentData.corrected_segments.map(
|
37553
|
+
(segment, i) => i === editModalSegment.index ? updatedSegment : segment
|
37554
|
+
);
|
37555
|
+
const newDataImmutable = {
|
37556
|
+
...currentData,
|
37557
|
+
corrected_segments: newSegments
|
37558
|
+
};
|
37559
|
+
updateDataWithHistory(newDataImmutable, "update segment");
|
37485
37560
|
setEditModalSegment(null);
|
37486
|
-
}, [
|
37561
|
+
}, [history, historyIndex, editModalSegment, updateDataWithHistory]);
|
37487
37562
|
const handleDeleteSegment = reactExports.useCallback((segmentIndex) => {
|
37488
37563
|
const newData = deleteSegment(data, segmentIndex);
|
37489
|
-
|
37490
|
-
}, [data]);
|
37564
|
+
updateDataWithHistory(newData, "delete segment");
|
37565
|
+
}, [data, updateDataWithHistory]);
|
37491
37566
|
const handleFinishReview = reactExports.useCallback(() => {
|
37492
37567
|
setIsReviewModalOpen(true);
|
37493
37568
|
}, []);
|
@@ -37512,7 +37587,8 @@ function LyricsAnalyzer({ data: initialData, onFileLoad, apiClient, isReadOnly,
|
|
37512
37587
|
const handleResetCorrections = reactExports.useCallback(() => {
|
37513
37588
|
if (window.confirm("Are you sure you want to reset all corrections? This cannot be undone.")) {
|
37514
37589
|
clearSavedData(initialData);
|
37515
|
-
|
37590
|
+
setHistory([JSON.parse(JSON.stringify(initialData))]);
|
37591
|
+
setHistoryIndex(0);
|
37516
37592
|
setModalContent(null);
|
37517
37593
|
setFlashingType(null);
|
37518
37594
|
setHighlightInfo(null);
|
@@ -37521,20 +37597,20 @@ function LyricsAnalyzer({ data: initialData, onFileLoad, apiClient, isReadOnly,
|
|
37521
37597
|
}, [initialData]);
|
37522
37598
|
const handleAddSegment = reactExports.useCallback((beforeIndex) => {
|
37523
37599
|
const newData = addSegmentBefore(data, beforeIndex);
|
37524
|
-
|
37525
|
-
}, [data]);
|
37600
|
+
updateDataWithHistory(newData, "add segment");
|
37601
|
+
}, [data, updateDataWithHistory]);
|
37526
37602
|
const handleSplitSegment = reactExports.useCallback((segmentIndex, afterWordIndex) => {
|
37527
37603
|
const newData = splitSegment(data, segmentIndex, afterWordIndex);
|
37528
37604
|
if (newData) {
|
37529
|
-
|
37605
|
+
updateDataWithHistory(newData, "split segment");
|
37530
37606
|
setEditModalSegment(null);
|
37531
37607
|
}
|
37532
|
-
}, [data]);
|
37608
|
+
}, [data, updateDataWithHistory]);
|
37533
37609
|
const handleMergeSegment = reactExports.useCallback((segmentIndex, mergeWithNext) => {
|
37534
37610
|
const newData = mergeSegment(data, segmentIndex, mergeWithNext);
|
37535
|
-
|
37611
|
+
updateDataWithHistory(newData, "merge segment");
|
37536
37612
|
setEditModalSegment(null);
|
37537
|
-
}, [data]);
|
37613
|
+
}, [data, updateDataWithHistory]);
|
37538
37614
|
const handleHandlerToggle = reactExports.useCallback(async (handler, enabled) => {
|
37539
37615
|
if (!apiClient) return;
|
37540
37616
|
try {
|
@@ -37546,7 +37622,7 @@ function LyricsAnalyzer({ data: initialData, onFileLoad, apiClient, isReadOnly,
|
|
37546
37622
|
currentEnabled.delete(handler);
|
37547
37623
|
}
|
37548
37624
|
const newData = await apiClient.updateHandlers(Array.from(currentEnabled));
|
37549
|
-
|
37625
|
+
updateDataWithHistory(newData, `toggle handler ${handler}`);
|
37550
37626
|
setModalContent(null);
|
37551
37627
|
setFlashingType(null);
|
37552
37628
|
setHighlightInfo(null);
|
@@ -37557,7 +37633,7 @@ function LyricsAnalyzer({ data: initialData, onFileLoad, apiClient, isReadOnly,
|
|
37557
37633
|
} finally {
|
37558
37634
|
setIsUpdatingHandlers(false);
|
37559
37635
|
}
|
37560
|
-
}, [apiClient, data.metadata.enabled_handlers, handleFlash]);
|
37636
|
+
}, [apiClient, data.metadata.enabled_handlers, handleFlash, updateDataWithHistory]);
|
37561
37637
|
const handleHandlerClick = reactExports.useCallback((handler) => {
|
37562
37638
|
setFlashingHandler(handler);
|
37563
37639
|
setFlashingType("handler");
|
@@ -37574,14 +37650,14 @@ function LyricsAnalyzer({ data: initialData, onFileLoad, apiClient, isReadOnly,
|
|
37574
37650
|
try {
|
37575
37651
|
setIsAddingLyrics(true);
|
37576
37652
|
const newData = await apiClient.addLyrics(source, lyrics);
|
37577
|
-
|
37653
|
+
updateDataWithHistory(newData, "add lyrics");
|
37578
37654
|
} finally {
|
37579
37655
|
setIsAddingLyrics(false);
|
37580
37656
|
}
|
37581
|
-
}, [apiClient]);
|
37657
|
+
}, [apiClient, updateDataWithHistory]);
|
37582
37658
|
const handleFindReplace = (findText, replaceText, options) => {
|
37583
37659
|
const newData = findAndReplace(data, findText, replaceText, options);
|
37584
|
-
|
37660
|
+
updateDataWithHistory(newData, "find/replace");
|
37585
37661
|
};
|
37586
37662
|
const handleEditAll = reactExports.useCallback(() => {
|
37587
37663
|
console.log("EditAll - Starting process");
|
@@ -37714,13 +37790,28 @@ function LyricsAnalyzer({ data: initialData, onFileLoad, apiClient, isReadOnly,
|
|
37714
37790
|
totalWordCount: updatedSegments.reduce((count, segment) => count + segment.words.length, 0),
|
37715
37791
|
originalTotalWordCount: data.corrected_segments.reduce((count, segment) => count + segment.words.length, 0)
|
37716
37792
|
});
|
37717
|
-
|
37793
|
+
const newData = {
|
37718
37794
|
...data,
|
37719
37795
|
corrected_segments: updatedSegments
|
37720
|
-
}
|
37796
|
+
};
|
37797
|
+
updateDataWithHistory(newData, "edit all");
|
37721
37798
|
setIsEditAllModalOpen(false);
|
37722
37799
|
setGlobalEditSegment(null);
|
37723
|
-
}, [data]);
|
37800
|
+
}, [data, updateDataWithHistory]);
|
37801
|
+
const handleUndo = reactExports.useCallback(() => {
|
37802
|
+
if (historyIndex > 0) {
|
37803
|
+
const newIndex = historyIndex - 1;
|
37804
|
+
setHistoryIndex(newIndex);
|
37805
|
+
}
|
37806
|
+
}, [historyIndex, history]);
|
37807
|
+
const handleRedo = reactExports.useCallback(() => {
|
37808
|
+
if (historyIndex < history.length - 1) {
|
37809
|
+
const newIndex = historyIndex + 1;
|
37810
|
+
setHistoryIndex(newIndex);
|
37811
|
+
}
|
37812
|
+
}, [historyIndex, history]);
|
37813
|
+
const canUndo = historyIndex > 0;
|
37814
|
+
const canRedo = historyIndex < history.length - 1;
|
37724
37815
|
const metricClickHandlers = reactExports.useMemo(() => ({
|
37725
37816
|
anchor: () => handleFlash("anchor"),
|
37726
37817
|
corrected: () => handleFlash("corrected"),
|
@@ -37750,7 +37841,11 @@ function LyricsAnalyzer({ data: initialData, onFileLoad, apiClient, isReadOnly,
|
|
37750
37841
|
onHandlerClick: handleHandlerClick,
|
37751
37842
|
onAddLyrics: () => setIsAddLyricsModalOpen(true),
|
37752
37843
|
onFindReplace: () => setIsFindReplaceModalOpen(true),
|
37753
|
-
onEditAll: handleEditAll
|
37844
|
+
onEditAll: handleEditAll,
|
37845
|
+
onUndo: handleUndo,
|
37846
|
+
onRedo: handleRedo,
|
37847
|
+
canUndo,
|
37848
|
+
canRedo
|
37754
37849
|
}
|
37755
37850
|
),
|
37756
37851
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(Grid, { container: true, direction: isMobile ? "column" : "row", children: [
|
@@ -37770,7 +37865,7 @@ function LyricsAnalyzer({ data: initialData, onFileLoad, apiClient, isReadOnly,
|
|
37770
37865
|
anchors: data.anchor_sequences,
|
37771
37866
|
disableHighlighting: isAnyModalOpenMemo,
|
37772
37867
|
onDataChange: (updatedData) => {
|
37773
|
-
|
37868
|
+
updateDataWithHistory(updatedData, "direct data change");
|
37774
37869
|
}
|
37775
37870
|
}
|
37776
37871
|
),
|
@@ -38253,4 +38348,4 @@ ReactDOM$1.createRoot(document.getElementById("root")).render(
|
|
38253
38348
|
/* @__PURE__ */ jsxRuntimeExports.jsx(App, {})
|
38254
38349
|
] })
|
38255
38350
|
);
|
38256
|
-
//# sourceMappingURL=index-
|
38351
|
+
//# sourceMappingURL=index-DSQidWB1.js.map
|