From b28fe4cbc96a6f6ed7ddf07b4f5398775f78ea3b Mon Sep 17 00:00:00 2001 From: jeffvli Date: Wed, 18 Oct 2023 19:51:55 -0700 Subject: [PATCH] Convert play icon from base64 to svg --- .../virtual-table/cells/row-index-cell.tsx | 138 +++++++++++++++++- .../virtual-table/hooks/use-virtual-table.ts | 6 +- .../components/virtual-table/index.tsx | 51 ++++++- .../components/album-detail-content.tsx | 4 +- .../now-playing/components/play-queue.tsx | 1 + .../playlist-detail-song-list-content.tsx | 5 +- .../songs/components/song-list-table-view.tsx | 10 +- src/renderer/themes/default.scss | 26 ---- 8 files changed, 204 insertions(+), 37 deletions(-) diff --git a/src/renderer/components/virtual-table/cells/row-index-cell.tsx b/src/renderer/components/virtual-table/cells/row-index-cell.tsx index 32721b0a..48e9ac7b 100644 --- a/src/renderer/components/virtual-table/cells/row-index-cell.tsx +++ b/src/renderer/components/virtual-table/cells/row-index-cell.tsx @@ -2,9 +2,145 @@ import type { ICellRendererParams } from '@ag-grid-community/core'; import { Text } from '/@/renderer/components/text'; import { CellContainer } from '/@/renderer/components/virtual-table/cells/generic-cell'; -export const RowIndexCell = ({ value }: ICellRendererParams) => { +const AnimatedSvg = () => { + return ( +
+ + + + + + + + + + + + + + + + +
+ ); +}; + +const StaticSvg = () => { + return ( +
+ + + + + + +
+ ); +}; + +export const RowIndexCell = ({ value, eGridCell }: ICellRendererParams) => { + const isFocused = eGridCell.classList.contains('focused'); + const isCurrentSong = + eGridCell.classList.contains('current-song') || + eGridCell.classList.contains('current-playlist-song'); + return ( + {isFocused && isCurrentSong ? : isCurrentSong ? : null} = ( ) => Promise; interface UseAgGridProps { + columnType?: 'albumDetail' | 'generic'; contextMenu: SetContextMenuItems; customFilters?: Partial; isClientSideSort?: boolean; @@ -52,6 +53,7 @@ export const useVirtualTable = ({ customFilters, isSearchParams, isClientSideSort, + columnType, }: UseAgGridProps) => { const queryClient = useQueryClient(); const navigate = useNavigate(); @@ -75,8 +77,8 @@ export const useVirtualTable = ({ const isPaginationEnabled = properties.display === ListDisplayType.TABLE_PAGINATED; const columnDefs: ColDef[] = useMemo(() => { - return getColumnDefs(properties.table.columns, true); - }, [properties.table.columns]); + return getColumnDefs(properties.table.columns, true, columnType); + }, [columnType, properties.table.columns]); const defaultColumnDefs: ColDef = useMemo(() => { return { diff --git a/src/renderer/components/virtual-table/index.tsx b/src/renderer/components/virtual-table/index.tsx index 9ff51992..a6b528b3 100644 --- a/src/renderer/components/virtual-table/index.tsx +++ b/src/renderer/components/virtual-table/index.tsx @@ -19,7 +19,6 @@ import dayjs from 'dayjs'; import relativeTime from 'dayjs/plugin/relativeTime'; import formatDuration from 'format-duration'; import { AnimatePresence } from 'framer-motion'; -import isElectron from 'is-electron'; import { generatePath } from 'react-router'; import styled from 'styled-components'; import { AlbumArtistCell } from '/@/renderer/components/virtual-table/cells/album-artist-cell'; @@ -268,8 +267,40 @@ const tableColumns: { [key: string]: ColDef } = { rowIndex: { cellClass: 'row-index', cellClassRules: { + 'current-playlist-song': (params) => { + return params.data?.uniqueId === params.context?.currentSong?.uniqueId; + }, + 'current-song': (params) => { + return params.data?.uniqueId === params.context?.currentSong?.uniqueId; + }, focused: (params) => { - return isElectron() && params.context?.isFocused; + return params.context?.isFocused; + }, + playing: (params) => { + return params.context?.status === PlayerStatus.PLAYING; + }, + }, + cellRenderer: RowIndexCell, + colId: TableColumn.ROW_INDEX, + headerComponent: (params: IHeaderParams) => + GenericTableHeader(params, { position: 'right', preset: 'rowIndex' }), + suppressSizeToFit: true, + valueGetter: (params) => { + return (params.node?.rowIndex || 0) + 1; + }, + width: 65, + }, + rowIndexGeneric: { + cellClass: 'row-index', + cellClassRules: { + 'current-song': (params) => { + return ( + params.data?.id === params.context?.currentSong?.id && + params.data?.albumId === params.context?.currentSong?.albumId + ); + }, + focused: (params) => { + return params.context?.isFocused; }, playing: (params) => { return params.context?.status === PlayerStatus.PLAYING; @@ -341,8 +372,14 @@ const tableColumns: { [key: string]: ColDef } = { trackNumberDetail: { cellClass: 'row-index', cellClassRules: { + 'current-song': (params) => { + return ( + params.data?.id === params.context?.currentSong?.id && + params.data?.albumId === params.context?.currentSong?.albumId + ); + }, focused: (params) => { - return isElectron() && params.context?.isFocused; + return params.context?.isFocused; }, playing: (params) => { return params.context?.status === PlayerStatus.PLAYING; @@ -394,16 +431,20 @@ export const getColumnDef = (column: TableColumn) => { export const getColumnDefs = ( columns: PersistedTableColumn[], useWidth?: boolean, - type?: 'albumDetail', + type?: 'albumDetail' | 'generic', ) => { const columnDefs: ColDef[] = []; for (const column of columns) { let presetColumn = tableColumns[column.column as keyof typeof tableColumns]; - if (type === 'albumDetail' && column.column === TableColumn.TRACK_NUMBER) { + if (column.column === TableColumn.TRACK_NUMBER && type === 'albumDetail') { presetColumn = tableColumns['trackNumberDetail' as keyof typeof tableColumns]; } + if (column.column === TableColumn.ROW_INDEX && type === 'generic') { + presetColumn = tableColumns['rowIndexGeneric' as keyof typeof tableColumns]; + } + if (presetColumn) { columnDefs.push({ ...presetColumn, diff --git a/src/renderer/features/albums/components/album-detail-content.tsx b/src/renderer/features/albums/components/album-detail-content.tsx index 2d363032..a9f34232 100644 --- a/src/renderer/features/albums/components/album-detail-content.tsx +++ b/src/renderer/features/albums/components/album-detail-content.tsx @@ -33,7 +33,7 @@ import { PlayButton, useCreateFavorite, useDeleteFavorite } from '/@/renderer/fe import { LibraryBackgroundOverlay } from '/@/renderer/features/shared/components/library-background-overlay'; import { useAppFocus, useContainerQuery } from '/@/renderer/hooks'; import { AppRoute } from '/@/renderer/router/routes'; -import { useCurrentServer, useCurrentStatus } from '/@/renderer/store'; +import { useCurrentServer, useCurrentSong, useCurrentStatus } from '/@/renderer/store'; import { usePlayButtonBehavior, useSettingsStoreActions, @@ -72,6 +72,7 @@ export const AlbumDetailContent = ({ tableRef, background }: AlbumDetailContentP const { setTable } = useSettingsStoreActions(); const status = useCurrentStatus(); const isFocused = useAppFocus(); + const currentSong = useCurrentSong(); const columnDefs = useMemo( () => getColumnDefs(tableConfig.columns, false, 'albumDetail'), @@ -401,6 +402,7 @@ export const AlbumDetailContent = ({ tableRef, background }: AlbumDetailContentP autoFitColumns={tableConfig.autoFit} columnDefs={columnDefs} context={{ + currentSong, isFocused, onCellContextMenu, status, diff --git a/src/renderer/features/now-playing/components/play-queue.tsx b/src/renderer/features/now-playing/components/play-queue.tsx index d1df1b5d..0b12453c 100644 --- a/src/renderer/features/now-playing/components/play-queue.tsx +++ b/src/renderer/features/now-playing/components/play-queue.tsx @@ -223,6 +223,7 @@ export const PlayQueue = forwardRef(({ type }: QueueProps, ref: Ref) => { autoFitColumns={tableConfig.autoFit} columnDefs={columnDefs} context={{ + currentSong, isFocused, onCellContextMenu, status, diff --git a/src/renderer/features/playlists/components/playlist-detail-song-list-content.tsx b/src/renderer/features/playlists/components/playlist-detail-song-list-content.tsx index 7365d886..dc406352 100644 --- a/src/renderer/features/playlists/components/playlist-detail-song-list-content.tsx +++ b/src/renderer/features/playlists/components/playlist-detail-song-list-content.tsx @@ -34,6 +34,7 @@ import { usePlaylistDetail } from '/@/renderer/features/playlists/queries/playli import { usePlaylistSongList } from '/@/renderer/features/playlists/queries/playlist-song-list-query'; import { useCurrentServer, + useCurrentSong, useCurrentStatus, usePlaylistDetailStore, usePlaylistDetailTablePagination, @@ -53,6 +54,7 @@ export const PlaylistDetailSongListContent = ({ tableRef }: PlaylistDetailConten const queryClient = useQueryClient(); const status = useCurrentStatus(); const isFocused = useAppFocus(); + const currentSong = useCurrentSong(); const server = useCurrentServer(); const page = usePlaylistDetailStore(); const filters: Partial = useMemo(() => { @@ -90,7 +92,7 @@ export const PlaylistDetailSongListContent = ({ tableRef }: PlaylistDetailConten }); const columnDefs: ColDef[] = useMemo( - () => getColumnDefs(page.table.columns), + () => getColumnDefs(page.table.columns, false, 'generic'), [page.table.columns], ); @@ -241,6 +243,7 @@ export const PlaylistDetailSongListContent = ({ tableRef }: PlaylistDetailConten autoFitColumns={page.table.autoFit} columnDefs={columnDefs} context={{ + currentSong, isFocused, onCellContextMenu: handleContextMenu, status, diff --git a/src/renderer/features/songs/components/song-list-table-view.tsx b/src/renderer/features/songs/components/song-list-table-view.tsx index 06de099d..701bc38a 100644 --- a/src/renderer/features/songs/components/song-list-table-view.tsx +++ b/src/renderer/features/songs/components/song-list-table-view.tsx @@ -9,7 +9,12 @@ import { useVirtualTable } from '/@/renderer/components/virtual-table/hooks/use- import { useListContext } from '/@/renderer/context/list-context'; import { SONG_CONTEXT_MENU_ITEMS } from '/@/renderer/features/context-menu/context-menu-items'; import { useAppFocus } from '/@/renderer/hooks'; -import { useCurrentServer, useCurrentStatus, usePlayButtonBehavior } from '/@/renderer/store'; +import { + useCurrentServer, + useCurrentSong, + useCurrentStatus, + usePlayButtonBehavior, +} from '/@/renderer/store'; interface SongListTableViewProps { itemCount?: number; @@ -20,11 +25,13 @@ export const SongListTableView = ({ tableRef, itemCount }: SongListTableViewProp const server = useCurrentServer(); const { pageKey, id, handlePlay, customFilters } = useListContext(); const isFocused = useAppFocus(); + const currentSong = useCurrentSong(); const status = useCurrentStatus(); const { rowClassRules } = useCurrentSongRowStyles({ tableRef }); const tableProps = useVirtualTable({ + columnType: 'generic', contextMenu: SONG_CONTEXT_MENU_ITEMS, customFilters, isSearchParams: Boolean(id), @@ -51,6 +58,7 @@ export const SongListTableView = ({ tableRef, itemCount }: SongListTableViewProp {...tableProps} context={{ ...tableProps.context, + currentSong, isFocused, status, }} diff --git a/src/renderer/themes/default.scss b/src/renderer/themes/default.scss index 709e0606..970e6f4e 100644 --- a/src/renderer/themes/default.scss +++ b/src/renderer/themes/default.scss @@ -196,30 +196,4 @@ .current-song > .row-index.playing .current-song-index { display: none; } - - .current-song > .row-index.playing.focused ::before { - content: ' '; - display: block; - height: 1rem; - width: 1rem; - background-color: var(--primary-color); - -webkit-mask-image: var(--current-song-image-animated); - -webkit-mask-repeat: no-repeat; - mask-repeat: no-repeat; - transform: rotate(180deg); - mask-image: var(--current-song-image-animated); - } - - .current-song > .row-index.playing ::before { - content: ' '; - display: block; - height: 1rem; - width: 1rem; - background-color: var(--primary-color); - -webkit-mask-image: var(--current-song-image); - -webkit-mask-repeat: no-repeat; - mask-repeat: no-repeat; - transform: rotate(180deg); - mask-image: var(--current-song-image); - } }