mirror of
https://github.com/jeffvli/feishin.git
synced 2026-06-15 16:04:19 +02:00
@@ -2,11 +2,12 @@ import { useQueryClient, useSuspenseQuery } from '@tanstack/react-query';
|
|||||||
import { lazy, Suspense, useEffect, useMemo, useRef, useState } from 'react';
|
import { lazy, Suspense, useEffect, useMemo, useRef, useState } from 'react';
|
||||||
import { useParams } from 'react-router';
|
import { useParams } from 'react-router';
|
||||||
|
|
||||||
|
import { PlaylistDetailSongListEditTable } from './playlist-detail-song-list-table';
|
||||||
|
|
||||||
import { ItemListHandle } from '/@/renderer/components/item-list/types';
|
import { ItemListHandle } from '/@/renderer/components/item-list/types';
|
||||||
import { useListContext } from '/@/renderer/context/list-context';
|
import { useListContext } from '/@/renderer/context/list-context';
|
||||||
import { eventEmitter } from '/@/renderer/events/event-emitter';
|
import { eventEmitter } from '/@/renderer/events/event-emitter';
|
||||||
import { playlistsQueries } from '/@/renderer/features/playlists/api/playlists-api';
|
import { playlistsQueries } from '/@/renderer/features/playlists/api/playlists-api';
|
||||||
import { PlaylistDetailSongListEditTable } from '/@/renderer/features/playlists/components/playlist-detail-song-list-table';
|
|
||||||
import { useCurrentServer, useListSettings } from '/@/renderer/store';
|
import { useCurrentServer, useListSettings } from '/@/renderer/store';
|
||||||
import { Spinner } from '/@/shared/components/spinner/spinner';
|
import { Spinner } from '/@/shared/components/spinner/spinner';
|
||||||
import { PlaylistSongListQuery, PlaylistSongListResponse } from '/@/shared/types/domain-types';
|
import { PlaylistSongListQuery, PlaylistSongListResponse } from '/@/shared/types/domain-types';
|
||||||
@@ -20,6 +21,14 @@ const PlaylistDetailSongListTable = lazy(() =>
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const PlaylistDetailSongListGrid = lazy(() =>
|
||||||
|
import('/@/renderer/features/playlists/components/playlist-detail-song-list-grid').then(
|
||||||
|
(module) => ({
|
||||||
|
default: module.PlaylistDetailSongListGrid,
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
export const PlaylistDetailSongListContent = () => {
|
export const PlaylistDetailSongListContent = () => {
|
||||||
const { playlistId } = useParams() as { playlistId: string };
|
const { playlistId } = useParams() as { playlistId: string };
|
||||||
const server = useCurrentServer();
|
const server = useCurrentServer();
|
||||||
@@ -82,6 +91,9 @@ export const PlaylistDetailSongListView = ({ data }: { data: PlaylistSongListRes
|
|||||||
const { display, table } = useListSettings(ItemListKey.PLAYLIST_SONG);
|
const { display, table } = useListSettings(ItemListKey.PLAYLIST_SONG);
|
||||||
|
|
||||||
switch (display) {
|
switch (display) {
|
||||||
|
case ListDisplayType.GRID: {
|
||||||
|
return <PlaylistDetailSongListGrid data={data} serverId={server.id} />;
|
||||||
|
}
|
||||||
case ListDisplayType.TABLE: {
|
case ListDisplayType.TABLE: {
|
||||||
return (
|
return (
|
||||||
<PlaylistDetailSongListTable
|
<PlaylistDetailSongListTable
|
||||||
@@ -210,6 +222,7 @@ export const PlaylistDetailSongListEdit = ({ data }: { data: PlaylistSongListRes
|
|||||||
}, [localData, setListData]);
|
}, [localData, setListData]);
|
||||||
|
|
||||||
switch (display) {
|
switch (display) {
|
||||||
|
case ListDisplayType.GRID:
|
||||||
case ListDisplayType.TABLE: {
|
case ListDisplayType.TABLE: {
|
||||||
return (
|
return (
|
||||||
<PlaylistDetailSongListEditTable
|
<PlaylistDetailSongListEditTable
|
||||||
|
|||||||
@@ -0,0 +1,76 @@
|
|||||||
|
import { forwardRef, useMemo } from 'react';
|
||||||
|
import { useEffect } from 'react';
|
||||||
|
|
||||||
|
import { useGridRows } from '/@/renderer/components/item-list/helpers/use-grid-rows';
|
||||||
|
import { useItemListScrollPersist } from '/@/renderer/components/item-list/helpers/use-item-list-scroll-persist';
|
||||||
|
import { ItemGridList } from '/@/renderer/components/item-list/item-grid-list/item-grid-list';
|
||||||
|
import { ItemListGridComponentProps } from '/@/renderer/components/item-list/types';
|
||||||
|
import { useListContext } from '/@/renderer/context/list-context';
|
||||||
|
import { usePlaylistSongListFilters } from '/@/renderer/features/playlists/hooks/use-playlist-song-list-filters';
|
||||||
|
import { useSearchTermFilter } from '/@/renderer/features/shared/hooks/use-search-term-filter';
|
||||||
|
import { searchLibraryItems } from '/@/renderer/features/shared/utils';
|
||||||
|
import { useListSettings } from '/@/renderer/store';
|
||||||
|
import { sortSongList } from '/@/shared/api/utils';
|
||||||
|
import {
|
||||||
|
LibraryItem,
|
||||||
|
PlaylistSongListQuery,
|
||||||
|
PlaylistSongListResponse,
|
||||||
|
} from '/@/shared/types/domain-types';
|
||||||
|
import { ItemListKey } from '/@/shared/types/types';
|
||||||
|
|
||||||
|
interface PlaylistDetailSongListGridProps
|
||||||
|
extends Omit<ItemListGridComponentProps<PlaylistSongListQuery>, 'query'> {
|
||||||
|
data: PlaylistSongListResponse;
|
||||||
|
}
|
||||||
|
|
||||||
|
export const PlaylistDetailSongListGrid = forwardRef<any, PlaylistDetailSongListGridProps>(
|
||||||
|
({ data, saveScrollOffset = true }) => {
|
||||||
|
const { handleOnScrollEnd, scrollOffset } = useItemListScrollPersist({
|
||||||
|
enabled: saveScrollOffset,
|
||||||
|
});
|
||||||
|
|
||||||
|
const { searchTerm } = useSearchTermFilter();
|
||||||
|
const { query } = usePlaylistSongListFilters();
|
||||||
|
const { setListData } = useListContext();
|
||||||
|
|
||||||
|
const songData = useMemo(() => {
|
||||||
|
let items = data?.items || [];
|
||||||
|
|
||||||
|
if (searchTerm) {
|
||||||
|
items = searchLibraryItems(items, searchTerm, LibraryItem.SONG);
|
||||||
|
}
|
||||||
|
|
||||||
|
return sortSongList(items, query.sortBy, query.sortOrder);
|
||||||
|
}, [data?.items, searchTerm, query.sortBy, query.sortOrder]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (setListData) {
|
||||||
|
setListData(songData);
|
||||||
|
}
|
||||||
|
}, [songData, setListData]);
|
||||||
|
|
||||||
|
const gridProps = useListSettings(ItemListKey.PLAYLIST_SONG).grid;
|
||||||
|
|
||||||
|
const rows = useGridRows(
|
||||||
|
LibraryItem.PLAYLIST_SONG,
|
||||||
|
ItemListKey.PLAYLIST_SONG,
|
||||||
|
gridProps.size,
|
||||||
|
);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<ItemGridList
|
||||||
|
data={songData}
|
||||||
|
gap={gridProps.itemGap}
|
||||||
|
initialTop={{
|
||||||
|
to: scrollOffset ?? 0,
|
||||||
|
type: 'offset',
|
||||||
|
}}
|
||||||
|
itemsPerRow={gridProps.itemsPerRowEnabled ? gridProps.itemsPerRow : undefined}
|
||||||
|
itemType={LibraryItem.SONG}
|
||||||
|
onScrollEnd={handleOnScrollEnd}
|
||||||
|
rows={rows}
|
||||||
|
size={gridProps.size}
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
},
|
||||||
|
);
|
||||||
+3
-7
@@ -10,6 +10,7 @@ import { useListContext } from '/@/renderer/context/list-context';
|
|||||||
import { ContextMenuController } from '/@/renderer/features/context-menu/context-menu-controller';
|
import { ContextMenuController } from '/@/renderer/features/context-menu/context-menu-controller';
|
||||||
import { playlistsQueries } from '/@/renderer/features/playlists/api/playlists-api';
|
import { playlistsQueries } from '/@/renderer/features/playlists/api/playlists-api';
|
||||||
import { ListConfigMenu } from '/@/renderer/features/shared/components/list-config-menu';
|
import { ListConfigMenu } from '/@/renderer/features/shared/components/list-config-menu';
|
||||||
|
import { ListDisplayTypeToggleButton } from '/@/renderer/features/shared/components/list-display-type-toggle-button';
|
||||||
import { ListRefreshButton } from '/@/renderer/features/shared/components/list-refresh-button';
|
import { ListRefreshButton } from '/@/renderer/features/shared/components/list-refresh-button';
|
||||||
import { ListSearchInput } from '/@/renderer/features/shared/components/list-search-input';
|
import { ListSearchInput } from '/@/renderer/features/shared/components/list-search-input';
|
||||||
import { ListSortByDropdown } from '/@/renderer/features/shared/components/list-sort-by-dropdown';
|
import { ListSortByDropdown } from '/@/renderer/features/shared/components/list-sort-by-dropdown';
|
||||||
@@ -26,7 +27,7 @@ import { Icon } from '/@/shared/components/icon/icon';
|
|||||||
import { Tooltip } from '/@/shared/components/tooltip/tooltip';
|
import { Tooltip } from '/@/shared/components/tooltip/tooltip';
|
||||||
import { useLocalStorage } from '/@/shared/hooks/use-local-storage';
|
import { useLocalStorage } from '/@/shared/hooks/use-local-storage';
|
||||||
import { LibraryItem, SongListSort, SortOrder } from '/@/shared/types/domain-types';
|
import { LibraryItem, SongListSort, SortOrder } from '/@/shared/types/domain-types';
|
||||||
import { ItemListKey, ListDisplayType } from '/@/shared/types/types';
|
import { ItemListKey } from '/@/shared/types/types';
|
||||||
|
|
||||||
interface PlaylistDetailSongListHeaderFiltersProps {
|
interface PlaylistDetailSongListHeaderFiltersProps {
|
||||||
isSmartPlaylist?: boolean;
|
isSmartPlaylist?: boolean;
|
||||||
@@ -108,13 +109,8 @@ export const PlaylistDetailSongListHeaderFilters = ({
|
|||||||
variant="subtle"
|
variant="subtle"
|
||||||
/>
|
/>
|
||||||
</Tooltip>
|
</Tooltip>
|
||||||
|
<ListDisplayTypeToggleButton listKey={ItemListKey.PLAYLIST_SONG} />
|
||||||
<ListConfigMenu
|
<ListConfigMenu
|
||||||
displayTypes={[
|
|
||||||
{
|
|
||||||
hidden: true,
|
|
||||||
value: ListDisplayType.GRID,
|
|
||||||
},
|
|
||||||
]}
|
|
||||||
listKey={ItemListKey.PLAYLIST_SONG}
|
listKey={ItemListKey.PLAYLIST_SONG}
|
||||||
tableColumnsData={PLAYLIST_SONG_TABLE_COLUMNS}
|
tableColumnsData={PLAYLIST_SONG_TABLE_COLUMNS}
|
||||||
/>
|
/>
|
||||||
|
|||||||
@@ -1300,7 +1300,25 @@ const initialState: SettingsState = {
|
|||||||
itemGap: 'sm',
|
itemGap: 'sm',
|
||||||
itemsPerRow: 6,
|
itemsPerRow: 6,
|
||||||
itemsPerRowEnabled: false,
|
itemsPerRowEnabled: false,
|
||||||
rows: [],
|
rows: pickGridRows({
|
||||||
|
alignLeftColumns: [TableColumn.TITLE, TableColumn.ARTIST],
|
||||||
|
columns: PLAYLIST_SONG_TABLE_COLUMNS,
|
||||||
|
enabledColumns: [TableColumn.TITLE, TableColumn.ARTIST],
|
||||||
|
pickColumns: [
|
||||||
|
TableColumn.TITLE,
|
||||||
|
TableColumn.ARTIST,
|
||||||
|
TableColumn.DURATION,
|
||||||
|
TableColumn.YEAR,
|
||||||
|
TableColumn.BIT_RATE,
|
||||||
|
TableColumn.BPM,
|
||||||
|
TableColumn.CODEC,
|
||||||
|
TableColumn.DATE_ADDED,
|
||||||
|
TableColumn.GENRE,
|
||||||
|
TableColumn.LAST_PLAYED,
|
||||||
|
TableColumn.RELEASE_DATE,
|
||||||
|
TableColumn.TRACK_NUMBER,
|
||||||
|
],
|
||||||
|
}),
|
||||||
size: 'default',
|
size: 'default',
|
||||||
},
|
},
|
||||||
itemsPerPage: 100,
|
itemsPerPage: 100,
|
||||||
|
|||||||
Reference in New Issue
Block a user