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:
parent
70485e8808
commit
dbf9dbcb8c
@ -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
|
||||||
|
|||||||
@ -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>
|
||||||
|
|
||||||
|
|||||||
@ -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();
|
||||||
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user