Browse Source

Refactor list click/doubleclick to hook

master
jeffvli 3 years ago
committed by Jeff
parent
commit
b58d2c677a
  1. 33
      src/components/library/AlbumList.tsx
  2. 55
      src/components/library/AlbumView.tsx
  3. 33
      src/components/library/ArtistList.tsx
  4. 78
      src/components/library/ArtistView.tsx
  5. 67
      src/components/library/FolderList.tsx
  6. 48
      src/components/library/GenreList.tsx
  7. 55
      src/components/library/MusicList.tsx
  8. 55
      src/components/player/NowPlayingInfoView.tsx
  9. 36
      src/components/player/NowPlayingMiniView.tsx
  10. 36
      src/components/player/NowPlayingView.tsx
  11. 33
      src/components/playlist/PlaylistList.tsx
  12. 57
      src/components/playlist/PlaylistView.tsx
  13. 63
      src/components/search/SearchView.tsx
  14. 24
      src/components/settings/ConfigPanels/ListViewConfig.tsx
  15. 67
      src/components/starred/StarredView.tsx
  16. 52
      src/hooks/useListClickHandler.ts

33
src/components/library/AlbumList.tsx

@ -12,12 +12,6 @@ import useSearchQuery from '../../hooks/useSearchQuery';
import GenericPageHeader from '../layout/GenericPageHeader';
import GenericPage from '../layout/GenericPage';
import { useAppDispatch, useAppSelector } from '../../redux/hooks';
import {
toggleSelected,
setRangeSelected,
toggleRangeSelected,
clearSelected,
} from '../../redux/multiSelectSlice';
import {
StyledInputPicker,
StyledInputPickerContainer,
@ -36,6 +30,7 @@ import useColumnSort from '../../hooks/useColumnSort';
import { setFilter, setPagination, setAdvancedFilters, setColumnSort } from '../../redux/viewSlice';
import useGridScroll from '../../hooks/useGridScroll';
import useListScroll from '../../hooks/useListScroll';
import useListClickHandler from '../../hooks/useListClickHandler';
export const ALBUM_SORT_TYPES = [
{ label: i18n.t('A-Z (Name)'), value: 'alphabeticalByName', role: i18n.t('Default') },
@ -205,29 +200,9 @@ const AlbumList = () => {
}
}, [albums, config.serverType, dispatch, sortedData?.length, view.album.pagination]);
let timeout: any = null;
const handleRowClick = (e: any, rowData: any, tableData: any) => {
if (timeout === null) {
timeout = window.setTimeout(() => {
timeout = null;
if (e.ctrlKey) {
dispatch(toggleSelected(rowData));
} else if (e.shiftKey) {
dispatch(setRangeSelected(rowData));
dispatch(toggleRangeSelected(tableData));
}
}, 100);
}
};
const handleRowDoubleClick = (rowData: any) => {
window.clearTimeout(timeout);
timeout = null;
dispatch(clearSelected());
history.push(`/library/album/${rowData.id}`);
};
const { handleRowClick, handleRowDoubleClick } = useListClickHandler({
doubleClick: (rowData: any) => history.push(`/library/album/${rowData.id}`),
});
const handleRefresh = async () => {
setIsRefreshing(true);

55
src/components/library/AlbumView.tsx

@ -24,12 +24,6 @@ import {
setRate,
setStar,
} from '../../redux/playQueueSlice';
import {
toggleSelected,
setRangeSelected,
toggleRangeSelected,
clearSelected,
} from '../../redux/multiSelectSlice';
import useSearchQuery from '../../hooks/useSearchQuery';
import GenericPage from '../layout/GenericPage';
import ListViewType from '../viewtypes/ListViewType';
@ -63,6 +57,7 @@ import { setPlaylistRate } from '../../redux/playlistSlice';
import Card from '../card/Card';
import { setFilter, setPagination } from '../../redux/viewSlice';
import CenterLoader from '../loader/CenterLoader';
import useListClickHandler from '../../hooks/useListClickHandler';
interface AlbumParams {
id: string;
@ -97,39 +92,21 @@ const AlbumView = ({ ...rest }: any) => {
'path',
]);
let timeout: any = null;
const handleRowClick = (e: any, rowData: any, tableData: any) => {
if (timeout === null) {
timeout = window.setTimeout(() => {
timeout = null;
if (e.ctrlKey) {
dispatch(toggleSelected(rowData));
} else if (e.shiftKey) {
dispatch(setRangeSelected(rowData));
dispatch(toggleRangeSelected(tableData));
}
}, 100);
}
};
const handleRowDoubleClick = (rowData: any) => {
window.clearTimeout(timeout);
timeout = null;
dispatch(clearSelected());
dispatch(
setPlayQueueByRowClick({
entries: data.song,
currentIndex: rowData.rowIndex,
currentSongId: rowData.id,
uniqueSongId: rowData.uniqueId,
filters: config.playback.filters,
})
);
dispatch(setStatus('PLAYING'));
dispatch(fixPlayer2Index());
};
const { handleRowClick, handleRowDoubleClick } = useListClickHandler({
doubleClick: (rowData: any) => {
dispatch(
setPlayQueueByRowClick({
entries: data.song,
currentIndex: rowData.rowIndex,
currentSongId: rowData.id,
uniqueSongId: rowData.uniqueId,
filters: config.playback.filters,
})
);
dispatch(setStatus('PLAYING'));
dispatch(fixPlayer2Index());
},
});
const handlePlay = () => {
const songs = filterPlayQueue(config.playback.filters, data.song);

33
src/components/library/ArtistList.tsx

@ -10,12 +10,6 @@ import GenericPage from '../layout/GenericPage';
import GenericPageHeader from '../layout/GenericPageHeader';
import ListViewType from '../viewtypes/ListViewType';
import { useAppDispatch, useAppSelector } from '../../redux/hooks';
import {
clearSelected,
setRangeSelected,
toggleRangeSelected,
toggleSelected,
} from '../../redux/multiSelectSlice';
import GridViewType from '../viewtypes/GridViewType';
import { FilterButton, RefreshButton } from '../shared/ToolbarButtons';
import { apiController } from '../../api/controller';
@ -24,6 +18,7 @@ import ColumnSortPopover from '../shared/ColumnSortPopover';
import useColumnSort from '../../hooks/useColumnSort';
import { setSort } from '../../redux/artistSlice';
import { StyledTag } from '../shared/styled';
import useListClickHandler from '../../hooks/useListClickHandler';
const ArtistList = () => {
const { t } = useTranslation();
@ -60,29 +55,9 @@ const ArtistList = () => {
const filteredData = useSearchQuery(misc.searchQuery, artists, ['title']);
const { sortedData, sortColumns } = useColumnSort(artists, Item.Artist, artist.active.list.sort);
let timeout: any = null;
const handleRowClick = (e: any, rowData: any, tableData: any) => {
if (timeout === null) {
timeout = window.setTimeout(() => {
timeout = null;
if (e.ctrlKey) {
dispatch(toggleSelected(rowData));
} else if (e.shiftKey) {
dispatch(setRangeSelected(rowData));
dispatch(toggleRangeSelected(tableData));
}
}, 100);
}
};
const handleRowDoubleClick = (rowData: any) => {
window.clearTimeout(timeout);
timeout = null;
dispatch(clearSelected());
history.push(`/library/artist/${rowData.id}`);
};
const { handleRowClick, handleRowDoubleClick } = useListClickHandler({
doubleClick: (rowData: any) => history.push(`/library/artist/${rowData.id}`),
});
const handleRefresh = async () => {
setIsRefreshing(true);

78
src/components/library/ArtistView.tsx

@ -17,12 +17,6 @@ import {
PlayButton,
} from '../shared/ToolbarButtons';
import { useAppDispatch, useAppSelector } from '../../redux/hooks';
import {
toggleSelected,
setRangeSelected,
toggleRangeSelected,
clearSelected,
} from '../../redux/multiSelectSlice';
import useSearchQuery from '../../hooks/useSearchQuery';
import GenericPage from '../layout/GenericPage';
import ListViewType from '../viewtypes/ListViewType';
@ -63,6 +57,7 @@ import { setPlaylistRate } from '../../redux/playlistSlice';
import CustomTooltip from '../shared/CustomTooltip';
import { setFilter, setPagination } from '../../redux/viewSlice';
import CenterLoader from '../loader/CenterLoader';
import useListClickHandler from '../../hooks/useListClickHandler';
const fac = new FastAverageColor();
@ -151,50 +146,31 @@ const ArtistView = ({ ...rest }: any) => {
}
}, [artistId, history, rest.isModal]);
let timeout: any = null;
const handleRowClick = (e: any, rowData: any, tableData: any) => {
if (timeout === null) {
timeout = window.setTimeout(() => {
timeout = null;
const { handleRowClick, handleRowDoubleClick } = useListClickHandler({
doubleClick: (rowData: any, songs: any) => {
if (rowData.type === Item.Album) {
history.push(`/library/album/${rowData.id}`);
}
if (e.ctrlKey) {
dispatch(toggleSelected(rowData));
} else if (e.shiftKey) {
dispatch(setRangeSelected(rowData));
dispatch(toggleRangeSelected(tableData));
if (rowData.type === Item.Music) {
if (rowData.isDir) {
history.push(`/library/folder?folderId=${rowData.parent}`);
} else {
dispatch(
setPlayQueueByRowClick({
entries: songs.filter((entry: any) => entry.isDir !== true),
currentIndex: rowData.rowIndex,
currentSongId: rowData.id,
uniqueSongId: rowData.uniqueId,
filters: config.playback.filters,
})
);
dispatch(setStatus('PLAYING'));
dispatch(fixPlayer2Index());
}
}, 100);
}
};
const handleRowDoubleClick = (rowData: any) => {
window.clearTimeout(timeout);
timeout = null;
dispatch(clearSelected());
history.push(`/library/album/${rowData.id}`);
};
const handleMusicRowDoubleClick = (rowData: any, songs: any[]) => {
window.clearTimeout(timeout);
timeout = null;
dispatch(clearSelected());
if (rowData.isDir) {
history.push(`/library/folder?folderId=${rowData.parent}`);
} else {
dispatch(
setPlayQueueByRowClick({
entries: songs.filter((entry: any) => entry.isDir !== true),
currentIndex: rowData.rowIndex,
currentSongId: rowData.id,
uniqueSongId: rowData.uniqueId,
filters: config.playback.filters,
})
);
dispatch(setStatus('PLAYING'));
dispatch(fixPlayer2Index());
}
};
}
},
});
const handleFavorite = async () => {
if (!data.starred) {
@ -789,7 +765,7 @@ const ArtistView = ({ ...rest }: any) => {
data={allSongs || []}
tableColumns={config.lookAndFeel.listView.music.columns}
handleRowClick={handleRowClick}
handleRowDoubleClick={(e: any) => handleMusicRowDoubleClick(e, allSongs)}
handleRowDoubleClick={(e: any) => handleRowDoubleClick(e, allSongs)}
virtualized
rowHeight={config.lookAndFeel.listView.music.rowHeight}
fontSize={config.lookAndFeel.listView.music.fontSize}
@ -874,7 +850,7 @@ const ArtistView = ({ ...rest }: any) => {
data={topSongs || []}
tableColumns={config.lookAndFeel.listView.music.columns}
handleRowClick={handleRowClick}
handleRowDoubleClick={(e: any) => handleMusicRowDoubleClick(e, topSongs)}
handleRowDoubleClick={(e: any) => handleRowDoubleClick(e, topSongs)}
virtualized
rowHeight={config.lookAndFeel.listView.music.rowHeight}
fontSize={config.lookAndFeel.listView.music.fontSize}
@ -956,7 +932,7 @@ const ArtistView = ({ ...rest }: any) => {
handleMusicRowFavorite(rowData, ['artistTopSongs', data.title])
}
handleRowClick={handleRowClick}
handleRowDoubleClick={(e: any) => handleMusicRowDoubleClick(e, topSongs)}
handleRowDoubleClick={(e: any) => handleRowDoubleClick(e, topSongs)}
handleRating={(rowData: any, e: number) =>
handleRowRating(rowData, e, ['artistTopSongs', data?.title])
}

67
src/components/library/FolderList.tsx

@ -7,12 +7,6 @@ import { ButtonToolbar, Icon } from 'rsuite';
import { useTranslation } from 'react-i18next';
import ListViewType from '../viewtypes/ListViewType';
import { useAppDispatch, useAppSelector } from '../../redux/hooks';
import {
clearSelected,
setRangeSelected,
toggleRangeSelected,
toggleSelected,
} from '../../redux/multiSelectSlice';
import GenericPage from '../layout/GenericPage';
import GenericPageHeader from '../layout/GenericPageHeader';
import { StyledButton, StyledInputPicker, StyledInputPickerContainer } from '../shared/styled';
@ -25,6 +19,7 @@ import { Server } from '../../types';
import { apiController } from '../../api/controller';
import { setPlaylistRate } from '../../redux/playlistSlice';
import CenterLoader from '../loader/CenterLoader';
import useListClickHandler from '../../hooks/useListClickHandler';
const FolderList = () => {
const { t } = useTranslation();
@ -77,45 +72,27 @@ const FolderList = () => {
}
}, [dispatch, query]);
let timeout: any = null;
const handleRowClick = (e: any, rowData: any, tableData: any) => {
if (timeout === null) {
timeout = window.setTimeout(() => {
timeout = null;
if (e.ctrlKey) {
dispatch(toggleSelected(rowData));
} else if (e.shiftKey) {
dispatch(setRangeSelected(rowData));
dispatch(toggleRangeSelected(tableData));
}
}, 100);
}
};
const handleRowDoubleClick = (rowData: any) => {
window.clearTimeout(timeout);
timeout = null;
dispatch(clearSelected());
if (rowData.isDir) {
history.push(`/library/folder?folderId=${rowData.id}`);
dispatch(setCurrentViewedFolder(rowData.id));
} else {
const selected = folderData?.id ? folderData?.child : indexData?.child;
dispatch(
setPlayQueueByRowClick({
entries: selected.filter((entry: any) => entry?.isDir === false),
currentIndex: rowData.rowIndex,
currentSongId: rowData.id,
uniqueSongId: rowData.uniqueId,
filters: config.playback.filters,
})
);
dispatch(setStatus('PLAYING'));
dispatch(fixPlayer2Index());
}
};
const { handleRowClick, handleRowDoubleClick } = useListClickHandler({
doubleClick: (rowData: any) => {
if (rowData.isDir) {
history.push(`/library/folder?folderId=${rowData.id}`);
dispatch(setCurrentViewedFolder(rowData.id));
} else {
const selected = folderData?.id ? folderData?.child : indexData?.child;
dispatch(
setPlayQueueByRowClick({
entries: selected.filter((entry: any) => entry?.isDir === false),
currentIndex: rowData.rowIndex,
currentSongId: rowData.id,
uniqueSongId: rowData.uniqueId,
filters: config.playback.filters,
})
);
dispatch(setStatus('PLAYING'));
dispatch(fixPlayer2Index());
}
},
});
const handleRowFavorite = async (rowData: any) => {
if (!rowData.starred) {

48
src/components/library/GenreList.tsx

@ -8,17 +8,12 @@ import GenericPage from '../layout/GenericPage';
import GenericPageHeader from '../layout/GenericPageHeader';
import ListViewType from '../viewtypes/ListViewType';
import { useAppDispatch, useAppSelector } from '../../redux/hooks';
import {
clearSelected,
setRangeSelected,
toggleRangeSelected,
toggleSelected,
} from '../../redux/multiSelectSlice';
import { apiController } from '../../api/controller';
import { StyledTag } from '../shared/styled';
import { setFilter, setPagination } from '../../redux/viewSlice';
import { Item } from '../../types';
import CenterLoader from '../loader/CenterLoader';
import useListClickHandler from '../../hooks/useListClickHandler';
const GenreList = () => {
const { t } = useTranslation();
@ -37,36 +32,19 @@ const GenreList = () => {
});
const filteredData = useSearchQuery(misc.searchQuery, genres, ['title']);
let timeout: any = null;
const handleRowClick = (e: any, rowData: any, tableData: any) => {
if (timeout === null) {
timeout = window.setTimeout(() => {
timeout = null;
const { handleRowClick, handleRowDoubleClick } = useListClickHandler({
doubleClick: (rowData: any) => {
dispatch(setFilter({ listType: Item.Album, data: rowData.title }));
dispatch(setPagination({ listType: Item.Album, data: { activePage: 1 } }));
localStorage.setItem('scroll_list_albumList', '0');
localStorage.setItem('scroll_grid_albumList', '0');
if (e.ctrlKey) {
dispatch(toggleSelected(rowData));
} else if (e.shiftKey) {
dispatch(setRangeSelected(rowData));
dispatch(toggleRangeSelected(tableData));
}
}, 100);
}
};
const handleRowDoubleClick = (rowData: any) => {
window.clearTimeout(timeout);
timeout = null;
dispatch(setFilter({ listType: Item.Album, data: rowData.title }));
dispatch(setPagination({ listType: Item.Album, data: { activePage: 1 } }));
localStorage.setItem('scroll_list_albumList', '0');
localStorage.setItem('scroll_grid_albumList', '0');
dispatch(clearSelected());
// Needs a small delay or the filter won't set properly when navigating to the album list
setTimeout(() => {
history.push(`/library/album?sortType=${rowData.title}`);
}, 50);
};
// Needs a small delay or the filter won't set properly when navigating to the album list
setTimeout(() => {
history.push(`/library/album?sortType=${rowData.title}`);
}, 50);
},
});
return (
<GenericPage

55
src/components/library/MusicList.tsx

@ -10,12 +10,6 @@ import useSearchQuery from '../../hooks/useSearchQuery';
import GenericPageHeader from '../layout/GenericPageHeader';
import GenericPage from '../layout/GenericPage';
import { useAppDispatch, useAppSelector } from '../../redux/hooks';
import {
toggleSelected,
setRangeSelected,
toggleRangeSelected,
clearSelected,
} from '../../redux/multiSelectSlice';
import { StyledInputPicker, StyledInputPickerContainer, StyledTag } from '../shared/styled';
import { RefreshButton } from '../shared/ToolbarButtons';
import { setSearchQuery } from '../../redux/miscSlice';
@ -26,6 +20,7 @@ import { fixPlayer2Index, setPlayQueueByRowClick, setStar } from '../../redux/pl
import { setFilter, setPagination } from '../../redux/viewSlice';
import { setStatus } from '../../redux/playerSlice';
import useListScroll from '../../hooks/useListScroll';
import useListClickHandler from '../../hooks/useListClickHandler';
// prettier-ignore
export const MUSIC_SORT_TYPES = [
@ -162,39 +157,21 @@ const MusicList = () => {
view.music.pagination.serverSide,
]);
let timeout: any = null;
const handleRowClick = (e: any, rowData: any, tableData: any) => {
if (timeout === null) {
timeout = window.setTimeout(() => {
timeout = null;
if (e.ctrlKey) {
dispatch(toggleSelected(rowData));
} else if (e.shiftKey) {
dispatch(setRangeSelected(rowData));
dispatch(toggleRangeSelected(tableData));
}
}, 100);
}
};
const handleRowDoubleClick = (rowData: any) => {
window.clearTimeout(timeout);
timeout = null;
dispatch(clearSelected());
dispatch(
setPlayQueueByRowClick({
entries: songs.data,
currentIndex: rowData.rowIndex,
currentSongId: rowData.id,
uniqueSongId: rowData.uniqueId,
filters: config.playback.filters,
})
);
dispatch(setStatus('PLAYING'));
dispatch(fixPlayer2Index());
};
const { handleRowClick, handleRowDoubleClick } = useListClickHandler({
doubleClick: (rowData: any) => {
dispatch(
setPlayQueueByRowClick({
entries: songs.data,
currentIndex: rowData.rowIndex,
currentSongId: rowData.id,
uniqueSongId: rowData.uniqueId,
filters: config.playback.filters,
})
);
dispatch(setStatus('PLAYING'));
dispatch(fixPlayer2Index());
},
});
const handleRefresh = async () => {
setIsRefreshing(true);

55
src/components/player/NowPlayingInfoView.tsx

@ -13,12 +13,6 @@ import { SecondaryTextWrapper, StyledPanel, StyledTag } from '../shared/styled';
import ScrollingMenu from '../scrollingmenu/ScrollingMenu';
import ListViewTable from '../viewtypes/ListViewTable';
import CenterLoader from '../loader/CenterLoader';
import {
clearSelected,
setRangeSelected,
toggleRangeSelected,
toggleSelected,
} from '../../redux/multiSelectSlice';
import { fixPlayer2Index, setPlayQueueByRowClick, setRate } from '../../redux/playQueueSlice';
import { setStatus } from '../../redux/playerSlice';
import useColumnSort from '../../hooks/useColumnSort';
@ -34,6 +28,7 @@ import {
import Card from '../card/Card';
import { setFilter, setPagination } from '../../redux/viewSlice';
import { setPlaylistRate } from '../../redux/playlistSlice';
import useListClickHandler from '../../hooks/useListClickHandler';
const NowPlayingInfoView = () => {
const { t } = useTranslation();
@ -83,39 +78,21 @@ const NowPlayingInfoView = () => {
type: 'desc',
});
let timeout: any = null;
const handleRowClick = (e: any, rowData: any, tableData: any) => {
if (timeout === null) {
timeout = window.setTimeout(() => {
timeout = null;
if (e.ctrlKey) {
dispatch(toggleSelected(rowData));
} else if (e.shiftKey) {
dispatch(setRangeSelected(rowData));
dispatch(toggleRangeSelected(tableData));
}
}, 100);
}
};
const handleRowDoubleClick = (rowData: any) => {
window.clearTimeout(timeout);
timeout = null;
dispatch(clearSelected());
dispatch(
setPlayQueueByRowClick({
entries: similarToSong,
currentIndex: rowData.rowIndex,
currentSongId: rowData.id,
uniqueSongId: rowData.uniqueId,
filters: config.playback.filters,
})
);
dispatch(setStatus('PLAYING'));
dispatch(fixPlayer2Index());
};
const { handleRowClick, handleRowDoubleClick } = useListClickHandler({
doubleClick: (rowData: any, songs: any) => {
dispatch(
setPlayQueueByRowClick({
entries: songs.data,
currentIndex: rowData.rowIndex,
currentSongId: rowData.id,
uniqueSongId: rowData.uniqueId,
filters: config.playback.filters,
})
);
dispatch(setStatus('PLAYING'));
dispatch(fixPlayer2Index());
},
});
const handleRowFavorite = async (rowData: any, queryKey: any) => {
console.log(rowData);

36
src/components/player/NowPlayingMiniView.tsx

@ -6,15 +6,8 @@ import { useHotkeys } from 'react-hotkeys-hook';
import { useQuery } from 'react-query';
import { useTranslation } from 'react-i18next';
import { useAppDispatch, useAppSelector } from '../../redux/hooks';
import { clearSelected, setIsDragging } from '../../redux/multiSelectSlice';
import {
toggleSelected,
setRangeSelected,
toggleRangeSelected,
clearSelected,
setIsDragging,
} from '../../redux/multiSelectSlice';
import {
setPlayerIndex,
fixPlayer2Index,
clearPlayQueue,
shuffleInPlace,
@ -59,6 +52,7 @@ import {
import { notifyToast } from '../shared/toast';
import { apiController } from '../../api/controller';
import { Server, Song } from '../../types';
import useListClickHandler from '../../hooks/useListClickHandler';
const NowPlayingMiniView = () => {
const { t } = useTranslation();
@ -135,31 +129,7 @@ const NowPlayingMiniView = () => {
}
}, [playQueue.currentIndex, tableRef, playQueue.displayQueue, playQueue.scrollWithCurrentSong]);
let timeout: any = null;
const handleRowClick = (e: any, rowData: any, tableData: any) => {
if (timeout === null) {
timeout = window.setTimeout(() => {
timeout = null;
if (e.ctrlKey) {
dispatch(toggleSelected(rowData));
} else if (e.shiftKey) {
dispatch(setRangeSelected(rowData));
dispatch(toggleRangeSelected(tableData));
}
}, 100);
}
};
const handleRowDoubleClick = (rowData: any) => {
window.clearTimeout(timeout);
timeout = null;
dispatch(clearSelected());
dispatch(setPlayerIndex(rowData));
dispatch(fixPlayer2Index());
dispatch(setStatus('PLAYING'));
};
const { handleRowClick, handleRowDoubleClick } = useListClickHandler();
const handleDragEnd = () => {
if (multiSelect.isDragging) {

36
src/components/player/NowPlayingView.tsx

@ -8,7 +8,6 @@ import { useTranslation } from 'react-i18next';
import { useAppDispatch, useAppSelector } from '../../redux/hooks';
import useSearchQuery from '../../hooks/useSearchQuery';
import {
setPlayerIndex,
fixPlayer2Index,
clearPlayQueue,
shuffleInPlace,
@ -23,13 +22,7 @@ import {
moveToTop,
moveToBottom,
} from '../../redux/playQueueSlice';
import {
toggleSelected,
setRangeSelected,
toggleRangeSelected,
clearSelected,
setIsDragging,
} from '../../redux/multiSelectSlice';
import { clearSelected, setIsDragging } from '../../redux/multiSelectSlice';
import GenericPage from '../layout/GenericPage';
import GenericPageHeader from '../layout/GenericPageHeader';
import ListViewType from '../viewtypes/ListViewType';
@ -64,6 +57,7 @@ import { Server, Song } from '../../types';
import { setPlaylistRate } from '../../redux/playlistSlice';
import NowPlayingInfoView from './NowPlayingInfoView';
import CenterLoader from '../loader/CenterLoader';
import useListClickHandler from '../../hooks/useListClickHandler';
const NowPlayingView = () => {
const { t } = useTranslation();
@ -149,31 +143,7 @@ const NowPlayingView = () => {
}
}, [playQueue.currentIndex, playQueue.scrollWithCurrentSong, tableRef]);
let timeout: any = null;
const handleRowClick = (e: any, rowData: any, tableData: any) => {
if (timeout === null) {
timeout = window.setTimeout(() => {
timeout = null;
if (e.ctrlKey) {
dispatch(toggleSelected(rowData));
} else if (e.shiftKey) {
dispatch(setRangeSelected(rowData));
dispatch(toggleRangeSelected(tableData));
}
}, 100);
}
};
const handleRowDoubleClick = (rowData: any) => {
window.clearTimeout(timeout);
timeout = null;
dispatch(clearSelected());
dispatch(setPlayerIndex(rowData));
dispatch(fixPlayer2Index());
dispatch(setStatus('PLAYING'));
};
const { handleRowClick, handleRowDoubleClick } = useListClickHandler();
const handleDragEnd = () => {
if (multiSelect.isDragging) {

33
src/components/playlist/PlaylistList.tsx

@ -20,17 +20,12 @@ import { errorMessages, isFailedResponse } from '../../shared/utils';
import { notifyToast } from '../shared/toast';
import { AddPlaylistButton, FilterButton } from '../shared/ToolbarButtons';
import { useAppDispatch, useAppSelector } from '../../redux/hooks';
import {
clearSelected,
setRangeSelected,
toggleRangeSelected,
toggleSelected,
} from '../../redux/multiSelectSlice';
import { apiController } from '../../api/controller';
import useColumnSort from '../../hooks/useColumnSort';
import { Item, Server } from '../../types';
import { setSort } from '../../redux/playlistSlice';
import ColumnSortPopover from '../shared/ColumnSortPopover';
import useListClickHandler from '../../hooks/useListClickHandler';
const PlaylistList = () => {
const { t } = useTranslation();
@ -74,29 +69,9 @@ const PlaylistList = () => {
}
};
let timeout: any = null;
const handleRowClick = (e: any, rowData: any, tableData: any) => {
if (timeout === null) {
timeout = window.setTimeout(() => {
timeout = null;
if (e.ctrlKey) {
dispatch(toggleSelected(rowData));
} else if (e.shiftKey) {
dispatch(setRangeSelected(rowData));
dispatch(toggleRangeSelected(tableData));
}
}, 100);
}
};
const handleRowDoubleClick = (rowData: any) => {
window.clearTimeout(timeout);
timeout = null;
dispatch(clearSelected());
history.push(`playlist/${rowData.id}`);
};
const { handleRowClick, handleRowDoubleClick } = useListClickHandler({
doubleClick: (rowData: any) => history.push(`playlist/${rowData.id}`),
});
if (isError) {
return <span>{t('Error: {{error}}', { error: error.message })}</span>;

57
src/components/playlist/PlaylistView.tsx

@ -27,13 +27,7 @@ import {
setRate,
clearPlayQueue,
} from '../../redux/playQueueSlice';
import {
toggleSelected,
setRangeSelected,
toggleRangeSelected,
clearSelected,
setIsDragging,
} from '../../redux/multiSelectSlice';
import { clearSelected, setIsDragging } from '../../redux/multiSelectSlice';
import {
createRecoveryFile,
errorMessages,
@ -75,6 +69,7 @@ import { apiController } from '../../api/controller';
import { Server } from '../../types';
import Card from '../card/Card';
import CenterLoader from '../loader/CenterLoader';
import useListClickHandler from '../../hooks/useListClickHandler';
interface PlaylistParams {
id: string;
@ -153,39 +148,21 @@ const PlaylistView = ({ ...rest }) => {
}
}, [data?.song, playlist]);
let timeout: any = null;
const handleRowClick = (e: any, rowData: any, tableData: any) => {
if (timeout === null) {
timeout = window.setTimeout(() => {
timeout = null;
if (e.ctrlKey) {
dispatch(toggleSelected(rowData));
} else if (e.shiftKey) {
dispatch(setRangeSelected(rowData));
dispatch(toggleRangeSelected(tableData));
}
}, 100);
}
};
const handleRowDoubleClick = (rowData: any) => {
window.clearTimeout(timeout);
timeout = null;
dispatch(clearSelected());
dispatch(
setPlayQueueByRowClick({
entries: playlist[getCurrentEntryList(playlist)],
currentIndex: rowData.rowIndex,
currentSongId: rowData.id,
uniqueSongId: rowData.uniqueId,
filters: config.playback.filters,
})
);
dispatch(setStatus('PLAYING'));
dispatch(fixPlayer2Index());
};
const { handleRowClick, handleRowDoubleClick } = useListClickHandler({
doubleClick: (rowData: any) => {
dispatch(
setPlayQueueByRowClick({
entries: playlist[getCurrentEntryList(playlist)],
currentIndex: rowData.rowIndex,
currentSongId: rowData.id,
uniqueSongId: rowData.uniqueId,
filters: config.playback.filters,
})
);
dispatch(setStatus('PLAYING'));
dispatch(fixPlayer2Index());
},
});
const handlePlay = () => {
const songs = filterPlayQueue(config.playback.filters, playlist[getCurrentEntryList(playlist)]);

63
src/components/search/SearchView.tsx

@ -9,12 +9,6 @@ import GenericPage from '../layout/GenericPage';
import GenericPageHeader from '../layout/GenericPageHeader';
import ScrollingMenu from '../scrollingmenu/ScrollingMenu';
import { useAppDispatch, useAppSelector } from '../../redux/hooks';
import {
clearSelected,
setRangeSelected,
toggleRangeSelected,
toggleSelected,
} from '../../redux/multiSelectSlice';
import { fixPlayer2Index, setPlayQueueByRowClick, setRate } from '../../redux/playQueueSlice';
import { setStatus } from '../../redux/playerSlice';
import ListViewTable from '../viewtypes/ListViewTable';
@ -23,6 +17,7 @@ import { apiController } from '../../api/controller';
import { Server } from '../../types';
import { setPlaylistRate } from '../../redux/playlistSlice';
import CenterLoader from '../loader/CenterLoader';
import useListClickHandler from '../../hooks/useListClickHandler';
const SearchView = () => {
const { t } = useTranslation();
@ -51,43 +46,25 @@ const SearchView = () => {
})
);
let timeout: any = null;
const handleRowClick = (e: any, rowData: any, tableData: any) => {
if (timeout === null) {
timeout = window.setTimeout(() => {
timeout = null;
if (e.ctrlKey) {
dispatch(toggleSelected(rowData));
} else if (e.shiftKey) {
dispatch(setRangeSelected(rowData));
dispatch(toggleRangeSelected(tableData));
}
}, 100);
}
};
const handleRowDoubleClick = (rowData: any) => {
window.clearTimeout(timeout);
timeout = null;
dispatch(clearSelected());
if (rowData.isDir) {
history.push(`/library/folder?folderId=${rowData.parent}`);
} else {
dispatch(
setPlayQueueByRowClick({
entries: data.song.filter((entry: any) => entry.isDir !== true),
currentIndex: rowData.rowIndex,
currentSongId: rowData.id,
uniqueSongId: rowData.uniqueId,
filters: config.playback.filters,
})
);
dispatch(setStatus('PLAYING'));
dispatch(fixPlayer2Index());
}
};
const { handleRowClick, handleRowDoubleClick } = useListClickHandler({
doubleClick: (rowData: any) => {
if (rowData.isDir) {
history.push(`/library/folder?folderId=${rowData.parent}`);
} else {
dispatch(
setPlayQueueByRowClick({
entries: data.song.filter((entry: any) => entry.isDir !== true),
currentIndex: rowData.rowIndex,
currentSongId: rowData.id,
uniqueSongId: rowData.uniqueId,
filters: config.playback.filters,
})
);
dispatch(setStatus('PLAYING'));
dispatch(fixPlayer2Index());
}
},
});
const handleRowFavorite = async (rowData: any) => {
if (!rowData.starred) {

24
src/components/settings/ConfigPanels/ListViewConfig.tsx

@ -11,12 +11,7 @@ import {
} from '../../shared/styled';
import ListViewTable from '../../viewtypes/ListViewTable';
import { useAppDispatch, useAppSelector } from '../../../redux/hooks';
import {
setIsDragging,
setRangeSelected,
toggleRangeSelected,
toggleSelected,
} from '../../../redux/multiSelectSlice';
import { setIsDragging } from '../../../redux/multiSelectSlice';
import {
ColumnList,
moveToIndex,
@ -25,6 +20,7 @@ import {
setRowHeight,
} from '../../../redux/configSlice';
import ConfigOption from '../ConfigOption';
import useListClickHandler from '../../../hooks/useListClickHandler';
const columnSelectorColumns = [
{
@ -83,21 +79,7 @@ const ListViewConfig = ({
);
}, [columnListType, config.lookAndFeel.listView, settingsConfig.columnList]);
let timeout: any = null;
const handleRowClick = (e: any, rowData: any, tableData: any) => {
if (timeout === null) {
timeout = window.setTimeout(() => {
timeout = null;
if (e.ctrlKey) {
dispatch(toggleSelected(rowData));
} else if (e.shiftKey) {
dispatch(setRangeSelected(rowData));
dispatch(toggleRangeSelected(tableData));
}
}, 100);
}
};
const { handleRowClick } = useListClickHandler({});
const handleDragEnd = (listType: ColumnList) => {
if (multiSelect.isDragging) {

67
src/components/starred/StarredView.tsx

@ -12,12 +12,6 @@ import {
setRate,
setStar,
} from '../../redux/playQueueSlice';
import {
clearSelected,
toggleSelected,
toggleRangeSelected,
setRangeSelected,
} from '../../redux/multiSelectSlice';
import GenericPage from '../layout/GenericPage';
import GenericPageHeader from '../layout/GenericPageHeader';
import ListViewType from '../viewtypes/ListViewType';
@ -32,6 +26,7 @@ import { Item, Server } from '../../types';
import { FilterButton } from '../shared/ToolbarButtons';
import ColumnSortPopover from '../shared/ColumnSortPopover';
import CenterLoader from '../loader/CenterLoader';
import useListClickHandler from '../../hooks/useListClickHandler';
const StarredView = () => {
const { t } = useTranslation();
@ -79,45 +74,27 @@ const StarredView = () => {
favorite.active.tab === 'albums' ? favorite.active.album.sort : favorite.active.artist.sort
);
let timeout: any = null;
const handleRowClick = (e: any, rowData: any, tableData: any) => {
if (timeout === null) {
timeout = window.setTimeout(() => {
timeout = null;
if (e.ctrlKey) {
dispatch(toggleSelected(rowData));
} else if (e.shiftKey) {
dispatch(setRangeSelected(rowData));
dispatch(toggleRangeSelected(tableData));
}
}, 100);
}
};
const handleRowDoubleClick = (rowData: any) => {
window.clearTimeout(timeout);
timeout = null;
dispatch(clearSelected());
if (favorite.active.tab === 'tracks') {
dispatch(
setPlayQueueByRowClick({
entries: data.song,
currentIndex: rowData.rowIndex,
currentSongId: rowData.id,
uniqueSongId: rowData.uniqueId,
filters: config.playback.filters,
})
);
dispatch(setStatus('PLAYING'));
dispatch(fixPlayer2Index());
} else if (favorite.active.tab === 'albums') {
history.push(`/library/album/${rowData.id}`);
} else {
history.push(`/library/artist/${rowData.id}`);
}
};
const { handleRowClick, handleRowDoubleClick } = useListClickHandler({
doubleClick: (rowData: any) => {
if (favorite.active.tab === 'tracks') {
dispatch(
setPlayQueueByRowClick({
entries: data.song,
currentIndex: rowData.rowIndex,
currentSongId: rowData.id,
uniqueSongId: rowData.uniqueId,
filters: config.playback.filters,
})
);
dispatch(setStatus('PLAYING'));
dispatch(fixPlayer2Index());
} else if (favorite.active.tab === 'albums') {
history.push(`/library/album/${rowData.id}`);
} else {
history.push(`/library/artist/${rowData.id}`);
}
},
});
const handleRowFavorite = async (rowData: any) => {
await apiController({

52
src/hooks/useListClickHandler.ts

@ -0,0 +1,52 @@
import { useAppDispatch, useAppSelector } from '../redux/hooks';
import { clearSelected, setSelected, toggleSelected } from '../redux/multiSelectSlice';
import { setStatus } from '../redux/playerSlice';
import { fixPlayer2Index, setPlayerIndex } from '../redux/playQueueSlice';
import { sliceRangeByUniqueId } from '../shared/utils';
const useListClickHandler = (options?: { singleClick?: any; doubleClick?: any }) => {
const dispatch = useAppDispatch();
const multiSelect = useAppSelector((state) => state.multiSelect);
let timeout: any = null;
const handleRowClick = (e: any, rowData: any, tableData: any) => {
if (timeout === null) {
timeout = window.setTimeout(() => {
timeout = null;
if (!options?.singleClick) {
if (e.ctrlKey) {
dispatch(toggleSelected(rowData));
} else if (e.shiftKey) {
dispatch(
setSelected(
sliceRangeByUniqueId(tableData, multiSelect.lastSelected.uniqueId, rowData.uniqueId)
)
);
}
} else {
options.singleClick(e, rowData, tableData);
}
}, 100);
}
};
const handleRowDoubleClick = (rowData: any, e?: any) => {
window.clearTimeout(timeout);
timeout = null;
dispatch(clearSelected());
if (!options?.doubleClick) {
dispatch(setPlayerIndex(rowData));
dispatch(fixPlayer2Index());
dispatch(setStatus('PLAYING'));
} else {
options.doubleClick(rowData, e);
}
};
return { handleRowClick, handleRowDoubleClick };
};
export default useListClickHandler;
Loading…
Cancel
Save