add tag-album and clean-playlist-files tasks, script step support, stop fix, rename fix
- New tag-album task: renames tracks to NNN format, sets ID3 tags via mutagen - New clean-playlist-files task: deletes .cue, .m3u, .nfo and similar junk files - Pipeline executor now supports script-mode steps (runs directly, no agent) - Build discography pipeline: convert-audio → clean-playlist-files → prepare → fetch → tag - Fix stop button: abort signal now kills running agent processes - Fix job manager: broadcast stopped/error events to WebSocket viewers - Fix file browser rename: delay focus to avoid context menu close race, left-align input Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
+13
-7
@@ -368,13 +368,14 @@ const InlineRenameInput = ({
|
||||
}) => {
|
||||
const [value, setValue] = useState(initialName);
|
||||
const inputRef = useRef<HTMLInputElement | null>(null);
|
||||
const focused = useRef(false);
|
||||
const ready = useRef(false);
|
||||
|
||||
useEffect(() => {
|
||||
const node = inputRef.current;
|
||||
if (!node || focused.current) return;
|
||||
focused.current = true;
|
||||
requestAnimationFrame(() => {
|
||||
if (!node) return;
|
||||
// Delay focus to let the context menu fully close and avoid focus races
|
||||
const timer = setTimeout(() => {
|
||||
ready.current = true;
|
||||
node.focus();
|
||||
const dotIndex = initialName.lastIndexOf('.');
|
||||
if (dotIndex > 0) {
|
||||
@@ -382,7 +383,8 @@ const InlineRenameInput = ({
|
||||
} else {
|
||||
node.select();
|
||||
}
|
||||
});
|
||||
}, 50);
|
||||
return () => clearTimeout(timer);
|
||||
}, []);
|
||||
|
||||
const commit = () => {
|
||||
@@ -399,13 +401,17 @@ const InlineRenameInput = ({
|
||||
ref={inputRef}
|
||||
value={value}
|
||||
onChange={(ev) => setValue(ev.target.value)}
|
||||
onBlur={commit}
|
||||
onBlur={() => {
|
||||
// Ignore blur before the input is ready (context menu closing steals focus)
|
||||
if (!ready.current) return;
|
||||
commit();
|
||||
}}
|
||||
onKeyDown={(ev) => {
|
||||
if (ev.key === 'Enter') commit();
|
||||
if (ev.key === 'Escape') onCancel();
|
||||
}}
|
||||
onClick={(ev) => ev.stopPropagation()}
|
||||
className="text-sm font-medium text-duck-dark bg-background border border-duck-teal/50 rounded px-1 py-0.5 outline-none w-full text-center"
|
||||
className="text-sm font-medium text-duck-dark bg-background border border-duck-teal/50 rounded px-1 py-0.5 outline-none max-w-full text-left"
|
||||
/>
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user