lyrics-transcriber 0.46.0__py3-none-any.whl → 0.47.0__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-BXOpmKq-.js → index-2vK-qVJS.js} +128 -65
- lyrics_transcriber/frontend/dist/assets/{index-BXOpmKq-.js.map → index-2vK-qVJS.js.map} +1 -1
- lyrics_transcriber/frontend/dist/index.html +1 -1
- lyrics_transcriber/frontend/src/components/EditModal.tsx +36 -36
- lyrics_transcriber/frontend/src/components/EditWordList.tsx +73 -2
- lyrics_transcriber/frontend/src/components/LyricsAnalyzer.tsx +21 -5
- lyrics_transcriber/frontend/src/components/ModeSelector.tsx +35 -16
- lyrics_transcriber/frontend/src/components/shared/hooks/useWordClick.ts +3 -2
- lyrics_transcriber/frontend/src/components/shared/utils/keyboardHandlers.ts +45 -8
- lyrics_transcriber/frontend/src/components/shared/utils/segmentOperations.ts +47 -0
- lyrics_transcriber/frontend/src/types.ts +1 -1
- {lyrics_transcriber-0.46.0.dist-info → lyrics_transcriber-0.47.0.dist-info}/METADATA +1 -1
- {lyrics_transcriber-0.46.0.dist-info → lyrics_transcriber-0.47.0.dist-info}/RECORD +16 -16
- {lyrics_transcriber-0.46.0.dist-info → lyrics_transcriber-0.47.0.dist-info}/LICENSE +0 -0
- {lyrics_transcriber-0.46.0.dist-info → lyrics_transcriber-0.47.0.dist-info}/WHEEL +0 -0
- {lyrics_transcriber-0.46.0.dist-info → lyrics_transcriber-0.47.0.dist-info}/entry_points.txt +0 -0
@@ -33018,7 +33018,7 @@ function useWordClick({
|
|
33018
33018
|
gap2 = matchingGap2;
|
33019
33019
|
}
|
33020
33020
|
}
|
33021
|
-
if (mode === "highlight" || mode === "edit") {
|
33021
|
+
if (mode === "highlight" || mode === "edit" || mode === "delete_word") {
|
33022
33022
|
if (belongsToAnchor && anchor) {
|
33023
33023
|
onWordClick == null ? void 0 : onWordClick({
|
33024
33024
|
word_id: wordId,
|
@@ -33050,7 +33050,7 @@ function useWordClick({
|
|
33050
33050
|
gap: void 0
|
33051
33051
|
});
|
33052
33052
|
}
|
33053
|
-
} else
|
33053
|
+
} else {
|
33054
33054
|
if (belongsToAnchor && anchor) {
|
33055
33055
|
onElementClick({
|
33056
33056
|
type: "anchor",
|
@@ -34766,9 +34766,16 @@ const WordRow = reactExports.memo(function WordRow2({
|
|
34766
34766
|
onWordUpdate,
|
34767
34767
|
onSplitWord,
|
34768
34768
|
onRemoveWord,
|
34769
|
-
wordsLength
|
34769
|
+
wordsLength,
|
34770
|
+
onTabNavigation
|
34770
34771
|
}) {
|
34771
34772
|
var _a, _b;
|
34773
|
+
const handleKeyDown = (e) => {
|
34774
|
+
if (e.key === "Tab" && !e.shiftKey) {
|
34775
|
+
e.preventDefault();
|
34776
|
+
onTabNavigation(index);
|
34777
|
+
}
|
34778
|
+
};
|
34772
34779
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { sx: {
|
34773
34780
|
display: "flex",
|
34774
34781
|
gap: 2,
|
@@ -34781,8 +34788,10 @@ const WordRow = reactExports.memo(function WordRow2({
|
|
34781
34788
|
label: `Word ${index}`,
|
34782
34789
|
value: word.text,
|
34783
34790
|
onChange: (e) => onWordUpdate(index, { text: e.target.value }),
|
34791
|
+
onKeyDown: handleKeyDown,
|
34784
34792
|
fullWidth: true,
|
34785
|
-
size: "small"
|
34793
|
+
size: "small",
|
34794
|
+
id: `word-text-${index}`
|
34786
34795
|
}
|
34787
34796
|
),
|
34788
34797
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
@@ -34844,7 +34853,8 @@ const WordItem = reactExports.memo(function WordItem2({
|
|
34844
34853
|
onAddSegment,
|
34845
34854
|
onMergeSegment,
|
34846
34855
|
wordsLength,
|
34847
|
-
isGlobal
|
34856
|
+
isGlobal,
|
34857
|
+
onTabNavigation
|
34848
34858
|
}) {
|
34849
34859
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { children: [
|
34850
34860
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
@@ -34855,7 +34865,8 @@ const WordItem = reactExports.memo(function WordItem2({
|
|
34855
34865
|
onWordUpdate,
|
34856
34866
|
onSplitWord,
|
34857
34867
|
onRemoveWord,
|
34858
|
-
wordsLength
|
34868
|
+
wordsLength,
|
34869
|
+
onTabNavigation
|
34859
34870
|
}
|
34860
34871
|
),
|
34861
34872
|
!isGlobal && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
@@ -34915,6 +34926,33 @@ function EditWordList({
|
|
34915
34926
|
const handlePageChange = (_event, value) => {
|
34916
34927
|
setPage(value);
|
34917
34928
|
};
|
34929
|
+
const handleTabNavigation = (currentIndex) => {
|
34930
|
+
const nextIndex = (currentIndex + 1) % words.length;
|
34931
|
+
if (isGlobal && (nextIndex < startIndex || nextIndex >= endIndex)) {
|
34932
|
+
const nextPage = Math.floor(nextIndex / pageSize) + 1;
|
34933
|
+
setPage(nextPage);
|
34934
|
+
setTimeout(() => {
|
34935
|
+
focusWordTextField(nextIndex);
|
34936
|
+
}, 50);
|
34937
|
+
} else {
|
34938
|
+
focusWordTextField(nextIndex);
|
34939
|
+
}
|
34940
|
+
};
|
34941
|
+
const focusWordTextField = (index) => {
|
34942
|
+
const element = document.getElementById(`word-text-${index}`);
|
34943
|
+
if (element) {
|
34944
|
+
let input = element.querySelector("input");
|
34945
|
+
if (!input) {
|
34946
|
+
input = element.querySelector(".MuiInputBase-input");
|
34947
|
+
}
|
34948
|
+
if (input) {
|
34949
|
+
input.focus();
|
34950
|
+
input.select();
|
34951
|
+
} else {
|
34952
|
+
element.focus();
|
34953
|
+
}
|
34954
|
+
}
|
34955
|
+
};
|
34918
34956
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { sx: { display: "flex", flexDirection: "column", gap: 1, flexGrow: 1, minHeight: 0 }, children: [
|
34919
34957
|
!isGlobal && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
34920
34958
|
WordDivider,
|
@@ -34966,7 +35004,8 @@ function EditWordList({
|
|
34966
35004
|
onAddSegment,
|
34967
35005
|
onMergeSegment,
|
34968
35006
|
wordsLength: words.length,
|
34969
|
-
isGlobal
|
35007
|
+
isGlobal,
|
35008
|
+
onTabNavigation: handleTabNavigation
|
34970
35009
|
},
|
34971
35010
|
word.id
|
34972
35011
|
);
|
@@ -35179,15 +35218,6 @@ function EditModal({
|
|
35179
35218
|
isGlobal = false,
|
35180
35219
|
isLoading = false
|
35181
35220
|
}) {
|
35182
|
-
console.log("EditModal - Render", {
|
35183
|
-
open,
|
35184
|
-
isGlobal,
|
35185
|
-
isLoading,
|
35186
|
-
hasSegment: !!segment,
|
35187
|
-
segmentIndex,
|
35188
|
-
hasOriginalSegment: !!originalSegment,
|
35189
|
-
hasOriginalTranscribedSegment: !!originalTranscribedSegment
|
35190
|
-
});
|
35191
35221
|
const [editedSegment, setEditedSegment] = reactExports.useState(segment);
|
35192
35222
|
const [isPlaying, setIsPlaying] = reactExports.useState(false);
|
35193
35223
|
const updateSegment2 = reactExports.useCallback((newWords) => {
|
@@ -35218,19 +35248,12 @@ function EditModal({
|
|
35218
35248
|
updateSegment: updateSegment2
|
35219
35249
|
});
|
35220
35250
|
const handleClose = reactExports.useCallback(() => {
|
35221
|
-
console.log("EditModal - handleClose called");
|
35222
35251
|
cleanupManualSync();
|
35223
35252
|
onClose();
|
35224
35253
|
}, [onClose, cleanupManualSync]);
|
35225
35254
|
reactExports.useEffect(() => {
|
35226
35255
|
const spacebarHandler = handleSpacebar;
|
35227
35256
|
if (open) {
|
35228
|
-
console.log("EditModal - Setting up modal spacebar handler", {
|
35229
|
-
hasPlaySegment: !!onPlaySegment,
|
35230
|
-
editedSegmentId: editedSegment == null ? void 0 : editedSegment.id,
|
35231
|
-
handlerFunction: spacebarHandler.toString().slice(0, 100),
|
35232
|
-
isLoading
|
35233
|
-
});
|
35234
35257
|
const handleKeyEvent = (e) => {
|
35235
35258
|
if (e.code === "Space") {
|
35236
35259
|
spacebarHandler(e);
|
@@ -35239,7 +35262,6 @@ function EditModal({
|
|
35239
35262
|
setModalSpacebarHandler(() => handleKeyEvent);
|
35240
35263
|
return () => {
|
35241
35264
|
if (!open) {
|
35242
|
-
console.log("EditModal - Cleanup: clearing modal spacebar handler");
|
35243
35265
|
setModalSpacebarHandler(void 0);
|
35244
35266
|
}
|
35245
35267
|
};
|
@@ -35261,11 +35283,6 @@ function EditModal({
|
|
35261
35283
|
}
|
35262
35284
|
}, [currentTime, editedSegment]);
|
35263
35285
|
reactExports.useEffect(() => {
|
35264
|
-
console.log("EditModal - segment changed", {
|
35265
|
-
hasSegment: !!segment,
|
35266
|
-
segmentId: segment == null ? void 0 : segment.id,
|
35267
|
-
wordCount: segment == null ? void 0 : segment.words.length
|
35268
|
-
});
|
35269
35286
|
setEditedSegment(segment);
|
35270
35287
|
}, [segment]);
|
35271
35288
|
reactExports.useEffect(() => {
|
@@ -35273,7 +35290,6 @@ function EditModal({
|
|
35273
35290
|
if (!editedSegment) return;
|
35274
35291
|
const endTime = editedSegment.end_time ?? 0;
|
35275
35292
|
if (window.isAudioPlaying && currentTime > endTime) {
|
35276
|
-
console.log("Stopping playback: current time exceeded end time");
|
35277
35293
|
(_a = window.toggleAudioPlayback) == null ? void 0 : _a.call(window);
|
35278
35294
|
cleanupManualSync();
|
35279
35295
|
}
|
@@ -35436,7 +35452,6 @@ function EditModal({
|
|
35436
35452
|
return getSafeTimeRange(editedSegment);
|
35437
35453
|
}, [getSafeTimeRange, editedSegment]);
|
35438
35454
|
const dialogTitle = reactExports.useMemo(() => {
|
35439
|
-
console.log("EditModal - Rendering dialog title", { isLoading, isGlobal });
|
35440
35455
|
if (isLoading) {
|
35441
35456
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(DialogTitle, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
|
35442
35457
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { sx: { flex: 1, display: "flex", alignItems: "center", gap: 1 }, children: [
|
@@ -35466,23 +35481,11 @@ function EditModal({
|
|
35466
35481
|
] });
|
35467
35482
|
}, [isGlobal, segmentIndex, segment, onPlaySegment, handlePlayButtonClick, isPlaying, onClose, isLoading]);
|
35468
35483
|
if (!isLoading && (!segment || !editedSegment || !originalSegment)) {
|
35469
|
-
console.log("EditModal - Early return: missing required data", {
|
35470
|
-
hasSegment: !!segment,
|
35471
|
-
hasEditedSegment: !!editedSegment,
|
35472
|
-
hasOriginalSegment: !!originalSegment,
|
35473
|
-
isLoading
|
35474
|
-
});
|
35475
35484
|
return null;
|
35476
35485
|
}
|
35477
35486
|
if (!isLoading && !isGlobal && segmentIndex === null) {
|
35478
|
-
console.log("EditModal - Early return: non-global mode with null segmentIndex");
|
35479
35487
|
return null;
|
35480
35488
|
}
|
35481
|
-
console.log("EditModal - Rendering dialog content", {
|
35482
|
-
isLoading,
|
35483
|
-
hasEditedSegment: !!editedSegment,
|
35484
|
-
hasOriginalSegment: !!originalSegment
|
35485
|
-
});
|
35486
35489
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
35487
35490
|
Dialog,
|
35488
35491
|
{
|
@@ -36165,6 +36168,30 @@ function findAndReplace(data, findText, replaceText, options = {
|
|
36165
36168
|
newData.corrected_segments = newData.corrected_segments.filter((segment) => segment.words.length > 0);
|
36166
36169
|
return newData;
|
36167
36170
|
}
|
36171
|
+
function deleteWord(data, wordId) {
|
36172
|
+
const segmentIndex = data.corrected_segments.findIndex(
|
36173
|
+
(segment2) => segment2.words.some((word) => word.id === wordId)
|
36174
|
+
);
|
36175
|
+
if (segmentIndex === -1) {
|
36176
|
+
return data;
|
36177
|
+
}
|
36178
|
+
const segment = data.corrected_segments[segmentIndex];
|
36179
|
+
const wordIndex = segment.words.findIndex((word) => word.id === wordId);
|
36180
|
+
if (wordIndex === -1) {
|
36181
|
+
return data;
|
36182
|
+
}
|
36183
|
+
const updatedWords = segment.words.filter((_, index) => index !== wordIndex);
|
36184
|
+
if (updatedWords.length > 0) {
|
36185
|
+
const updatedSegment = {
|
36186
|
+
...segment,
|
36187
|
+
words: updatedWords,
|
36188
|
+
text: updatedWords.map((w) => w.text).join(" ")
|
36189
|
+
};
|
36190
|
+
return updateSegment(data, segmentIndex, updatedSegment);
|
36191
|
+
} else {
|
36192
|
+
return deleteSegment(data, segmentIndex);
|
36193
|
+
}
|
36194
|
+
}
|
36168
36195
|
const generateStorageKey = (data) => {
|
36169
36196
|
var _a;
|
36170
36197
|
const text = ((_a = data.original_segments[0]) == null ? void 0 : _a.text) || "";
|
@@ -36238,6 +36265,12 @@ const setModalHandler = (handler, open) => {
|
|
36238
36265
|
};
|
36239
36266
|
const setupKeyboardHandlers = (state) => {
|
36240
36267
|
Math.random().toString(36).substr(2, 9);
|
36268
|
+
const resetModifierStates = () => {
|
36269
|
+
var _a;
|
36270
|
+
state.setIsShiftPressed(false);
|
36271
|
+
(_a = state.setIsCtrlPressed) == null ? void 0 : _a.call(state, false);
|
36272
|
+
document.body.style.userSelect = "";
|
36273
|
+
};
|
36241
36274
|
const handleKeyDown = (e) => {
|
36242
36275
|
var _a;
|
36243
36276
|
if (e.target instanceof HTMLInputElement || e.target instanceof HTMLTextAreaElement) {
|
@@ -36246,7 +36279,7 @@ const setupKeyboardHandlers = (state) => {
|
|
36246
36279
|
if (e.key === "Shift") {
|
36247
36280
|
state.setIsShiftPressed(true);
|
36248
36281
|
document.body.style.userSelect = "none";
|
36249
|
-
} else if (e.key === "Meta") {
|
36282
|
+
} else if (e.key === "Control" || e.key === "Ctrl" || e.key === "Meta") {
|
36250
36283
|
(_a = state.setIsCtrlPressed) == null ? void 0 : _a.call(state, true);
|
36251
36284
|
} else if (e.key === " " || e.code === "Space") {
|
36252
36285
|
e.preventDefault();
|
@@ -36258,20 +36291,30 @@ const setupKeyboardHandlers = (state) => {
|
|
36258
36291
|
}
|
36259
36292
|
};
|
36260
36293
|
const handleKeyUp = (e) => {
|
36261
|
-
|
36262
|
-
if (e.key === "
|
36263
|
-
state.setIsShiftPressed(false);
|
36264
|
-
document.body.style.userSelect = "";
|
36265
|
-
} else if (e.key === "Meta") {
|
36266
|
-
(_a = state.setIsCtrlPressed) == null ? void 0 : _a.call(state, false);
|
36267
|
-
} else if (e.key === " " || e.code === "Space") {
|
36294
|
+
resetModifierStates();
|
36295
|
+
if (e.key === " " || e.code === "Space") {
|
36268
36296
|
e.preventDefault();
|
36269
36297
|
if (isModalOpen && currentModalHandler) {
|
36270
36298
|
currentModalHandler(e);
|
36271
36299
|
}
|
36272
36300
|
}
|
36273
36301
|
};
|
36274
|
-
|
36302
|
+
const handleWindowBlur = () => {
|
36303
|
+
resetModifierStates();
|
36304
|
+
};
|
36305
|
+
const handleWindowFocus = () => {
|
36306
|
+
resetModifierStates();
|
36307
|
+
};
|
36308
|
+
window.addEventListener("blur", handleWindowBlur);
|
36309
|
+
window.addEventListener("focus", handleWindowFocus);
|
36310
|
+
return {
|
36311
|
+
handleKeyDown,
|
36312
|
+
handleKeyUp,
|
36313
|
+
cleanup: () => {
|
36314
|
+
window.removeEventListener("blur", handleWindowBlur);
|
36315
|
+
window.removeEventListener("focus", handleWindowFocus);
|
36316
|
+
}
|
36317
|
+
};
|
36275
36318
|
};
|
36276
36319
|
function ModeSelector({ effectiveMode, onChange }) {
|
36277
36320
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(Box, { sx: { display: "flex", alignItems: "center", gap: 1.2, height: "32px" }, children: [
|
@@ -36281,7 +36324,7 @@ function ModeSelector({ effectiveMode, onChange }) {
|
|
36281
36324
|
{
|
36282
36325
|
value: effectiveMode,
|
36283
36326
|
exclusive: true,
|
36284
|
-
onChange: (_, newMode) => newMode && onChange(newMode),
|
36327
|
+
onChange: (_, newMode) => newMode === "edit" && onChange(newMode),
|
36285
36328
|
size: "small",
|
36286
36329
|
sx: {
|
36287
36330
|
height: "32px",
|
@@ -36292,28 +36335,38 @@ function ModeSelector({ effectiveMode, onChange }) {
|
|
36292
36335
|
}
|
36293
36336
|
},
|
36294
36337
|
children: [
|
36295
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
36338
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { title: "Default mode; click words to edit that lyrics segment", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
36296
36339
|
ToggleButton,
|
36297
36340
|
{
|
36298
36341
|
value: "edit",
|
36299
|
-
title: "Click to edit segments and make corrections in the transcription view",
|
36300
36342
|
children: [
|
36301
36343
|
/* @__PURE__ */ jsxRuntimeExports.jsx(EditIcon, { sx: { mr: 0.5, fontSize: "1rem" } }),
|
36302
36344
|
"Edit"
|
36303
36345
|
]
|
36304
36346
|
}
|
36305
|
-
),
|
36306
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
36347
|
+
) }),
|
36348
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { title: "Hold SHIFT and click words to highlight the matching anchor sequence in the reference lyrics", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
36307
36349
|
ToggleButton,
|
36308
36350
|
{
|
36309
36351
|
value: "highlight",
|
36310
|
-
|
36352
|
+
disabled: true,
|
36311
36353
|
children: [
|
36312
36354
|
/* @__PURE__ */ jsxRuntimeExports.jsx(HighlightIcon, { sx: { mr: 0.5, fontSize: "1rem" } }),
|
36313
36355
|
"Highlight"
|
36314
36356
|
]
|
36315
36357
|
}
|
36316
|
-
)
|
36358
|
+
) }) }),
|
36359
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(Tooltip, { title: "Hold CTRL and click words to delete them", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
36360
|
+
ToggleButton,
|
36361
|
+
{
|
36362
|
+
value: "delete_word",
|
36363
|
+
disabled: true,
|
36364
|
+
children: [
|
36365
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(DeleteIcon, { sx: { mr: 0.5, fontSize: "1rem" } }),
|
36366
|
+
"Delete"
|
36367
|
+
]
|
36368
|
+
}
|
36369
|
+
) }) })
|
36317
36370
|
]
|
36318
36371
|
}
|
36319
36372
|
)
|
@@ -37209,6 +37262,7 @@ function LyricsAnalyzer({ data: initialData, onFileLoad, apiClient, isReadOnly,
|
|
37209
37262
|
const [originalData] = reactExports.useState(() => JSON.parse(JSON.stringify(initialData)));
|
37210
37263
|
const [interactionMode, setInteractionMode] = reactExports.useState("edit");
|
37211
37264
|
const [isShiftPressed, setIsShiftPressed] = reactExports.useState(false);
|
37265
|
+
const [isCtrlPressed, setIsCtrlPressed] = reactExports.useState(false);
|
37212
37266
|
const [editModalSegment, setEditModalSegment] = reactExports.useState(null);
|
37213
37267
|
const [isEditAllModalOpen, setIsEditAllModalOpen] = reactExports.useState(false);
|
37214
37268
|
const [globalEditSegment, setGlobalEditSegment] = reactExports.useState(null);
|
@@ -37239,27 +37293,30 @@ function LyricsAnalyzer({ data: initialData, onFileLoad, apiClient, isReadOnly,
|
|
37239
37293
|
}
|
37240
37294
|
}, [data, isReadOnly, initialData]);
|
37241
37295
|
reactExports.useEffect(() => {
|
37242
|
-
const { handleKeyDown, handleKeyUp } = setupKeyboardHandlers({
|
37243
|
-
setIsShiftPressed
|
37296
|
+
const { handleKeyDown, handleKeyUp, cleanup } = setupKeyboardHandlers({
|
37297
|
+
setIsShiftPressed,
|
37298
|
+
setIsCtrlPressed
|
37244
37299
|
});
|
37245
37300
|
window.addEventListener("keydown", handleKeyDown);
|
37246
37301
|
window.addEventListener("keyup", handleKeyUp);
|
37247
37302
|
if (isAnyModalOpen) {
|
37248
37303
|
setIsShiftPressed(false);
|
37304
|
+
setIsCtrlPressed(false);
|
37249
37305
|
}
|
37250
37306
|
return () => {
|
37251
37307
|
window.removeEventListener("keydown", handleKeyDown);
|
37252
37308
|
window.removeEventListener("keyup", handleKeyUp);
|
37253
37309
|
document.body.style.userSelect = "";
|
37310
|
+
cleanup();
|
37254
37311
|
};
|
37255
|
-
}, [setIsShiftPressed, isAnyModalOpen]);
|
37312
|
+
}, [setIsShiftPressed, setIsCtrlPressed, isAnyModalOpen]);
|
37256
37313
|
reactExports.useEffect(() => {
|
37257
37314
|
const modalOpen = Boolean(
|
37258
37315
|
modalContent || editModalSegment || isReviewModalOpen || isAddLyricsModalOpen || isFindReplaceModalOpen || isEditAllModalOpen
|
37259
37316
|
);
|
37260
37317
|
setIsAnyModalOpen(modalOpen);
|
37261
37318
|
}, [modalContent, editModalSegment, isReviewModalOpen, isAddLyricsModalOpen, isFindReplaceModalOpen, isEditAllModalOpen]);
|
37262
|
-
const effectiveMode = isShiftPressed ? "highlight" : interactionMode;
|
37319
|
+
const effectiveMode = isCtrlPressed ? "delete_word" : isShiftPressed ? "highlight" : interactionMode;
|
37263
37320
|
const handleFlash = reactExports.useCallback((type, info) => {
|
37264
37321
|
setFlashingType(null);
|
37265
37322
|
setHighlightInfo(null);
|
@@ -37278,6 +37335,12 @@ function LyricsAnalyzer({ data: initialData, onFileLoad, apiClient, isReadOnly,
|
|
37278
37335
|
}, []);
|
37279
37336
|
const handleWordClick = reactExports.useCallback((info) => {
|
37280
37337
|
var _a, _b, _c, _d, _e, _f, _g;
|
37338
|
+
if (effectiveMode === "delete_word") {
|
37339
|
+
const newData = deleteWord(data, info.word_id);
|
37340
|
+
setData(newData);
|
37341
|
+
handleFlash("word");
|
37342
|
+
return;
|
37343
|
+
}
|
37281
37344
|
if (effectiveMode === "highlight") {
|
37282
37345
|
const correction = (_a = data.corrections) == null ? void 0 : _a.find(
|
37283
37346
|
(c) => c.corrected_word_id === info.word_id || c.word_id === info.word_id
|
@@ -37385,7 +37448,7 @@ function LyricsAnalyzer({ data: initialData, onFileLoad, apiClient, isReadOnly,
|
|
37385
37448
|
});
|
37386
37449
|
}
|
37387
37450
|
}
|
37388
|
-
}, [data, effectiveMode, setModalContent]);
|
37451
|
+
}, [data, effectiveMode, setModalContent, handleFlash, deleteWord]);
|
37389
37452
|
const handleUpdateSegment = reactExports.useCallback((updatedSegment) => {
|
37390
37453
|
if (!editModalSegment) return;
|
37391
37454
|
const newData = updateSegment(data, editModalSegment.index, updatedSegment);
|
@@ -38158,4 +38221,4 @@ ReactDOM$1.createRoot(document.getElementById("root")).render(
|
|
38158
38221
|
/* @__PURE__ */ jsxRuntimeExports.jsx(App, {})
|
38159
38222
|
] })
|
38160
38223
|
);
|
38161
|
-
//# sourceMappingURL=index-
|
38224
|
+
//# sourceMappingURL=index-2vK-qVJS.js.map
|