fix(sync): reference correct processed count in job result; fix(search): keep focus in search while playing by blurring audio and focusing search; cleanup lints

This commit is contained in:
Geert Rademakes 2025-08-08 11:30:59 +02:00
parent 70485e8808
commit dbf9dbcb8c
3 changed files with 12 additions and 21 deletions

View File

@ -398,7 +398,7 @@ class BackgroundJobService {
errors: 0 errors: 0
}, },
total: { total: {
processed: allMusicFiles.length, processed: newAudioFiles.length,
matched: quickMatches.length + complexMatches, matched: quickMatches.length + complexMatches,
unmatched: stillUnmatched, unmatched: stillUnmatched,
errors: 0 errors: 0

View File

@ -6,20 +6,14 @@ import {
Button, Button,
IconButton, IconButton,
HStack, HStack,
Menu,
MenuButton,
MenuList,
MenuItem,
MenuDivider,
Checkbox, Checkbox,
Tooltip,
Spinner, Spinner,
useDisclosure, useDisclosure,
Input, Input,
InputGroup, InputGroup,
InputLeftElement, InputLeftElement,
} from '@chakra-ui/react'; } from '@chakra-ui/react';
import { Search2Icon, ChevronDownIcon } from '@chakra-ui/icons'; import { Search2Icon } from '@chakra-ui/icons';
import { FiPlay } from 'react-icons/fi'; import { FiPlay } from 'react-icons/fi';
import type { Song, PlaylistNode } from '../types/interfaces'; import type { Song, PlaylistNode } from '../types/interfaces';
import { formatDuration, formatTotalDuration } from '../utils/formatters'; import { formatDuration, formatTotalDuration } from '../utils/formatters';
@ -191,7 +185,7 @@ export const PaginatedSongList: React.FC<PaginatedSongListProps> = memo(({
}, []); }, []);
// Memoized flattened list of all playlists // Memoized flattened list of all playlists
const allPlaylists = useMemo(() => getAllPlaylists(playlists), [playlists, getAllPlaylists]); // const allPlaylists = useMemo(() => getAllPlaylists(playlists), [playlists, getAllPlaylists]);
const toggleSelection = useCallback((songId: string) => { const toggleSelection = useCallback((songId: string) => {
setSelectedSongs(prev => { setSelectedSongs(prev => {
@ -231,10 +225,7 @@ export const PaginatedSongList: React.FC<PaginatedSongListProps> = memo(({
}, [onSongSelect]); }, [onSongSelect]);
// Memoized search handler with debouncing // Memoized search handler with debouncing
const handleSearch = useCallback((query: string) => { // Search handled inline via localSearchQuery effect
setLocalSearchQuery(query);
onSearch(query);
}, [onSearch]);
// Memoized song items to prevent unnecessary re-renders // Memoized song items to prevent unnecessary re-renders
const songItems = useMemo(() => { const songItems = useMemo(() => {
@ -270,13 +261,7 @@ export const PaginatedSongList: React.FC<PaginatedSongListProps> = memo(({
}, [songs, totalPlaylistDuration]); }, [songs, totalPlaylistDuration]);
// Memoized playlist options for bulk actions // Memoized playlist options for bulk actions
const playlistOptions = useMemo(() => { // Playlist options built directly in the modal
return allPlaylists.map(playlist => (
<MenuItem key={playlist.id} onClick={() => handleBulkAddToPlaylist(playlist.name)}>
{playlist.name}
</MenuItem>
));
}, [allPlaylists, handleBulkAddToPlaylist]);
// Handle debounced search // Handle debounced search
useEffect(() => { useEffect(() => {
@ -345,6 +330,7 @@ export const PaginatedSongList: React.FC<PaginatedSongListProps> = memo(({
borderColor="gray.600" borderColor="gray.600"
_hover={{ borderColor: "gray.500" }} _hover={{ borderColor: "gray.500" }}
_focus={{ borderColor: "blue.300", boxShadow: "0 0 0 1px var(--chakra-colors-blue-300)" }} _focus={{ borderColor: "blue.300", boxShadow: "0 0 0 1px var(--chakra-colors-blue-300)" }}
autoFocus
/> />
</InputGroup> </InputGroup>

View File

@ -228,8 +228,13 @@ export const PersistentMusicPlayer: React.FC<PersistentMusicPlayerProps> = ({
audioRef.current?.blur(); audioRef.current?.blur();
}} }}
onPlay={() => { onPlay={() => {
// Extra safeguard to avoid focus jump while playing
audioRef.current?.blur(); audioRef.current?.blur();
// Return focus to active text input if present
const active = document.activeElement as HTMLElement | null;
if (!active || active.tagName !== 'INPUT') {
const search = document.querySelector('#song-list-container input[type="text"]') as HTMLInputElement | null;
search?.focus();
}
}} }}
/> />