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);
- }
}