mirror of
https://github.com/jeffvli/feishin.git
synced 2026-08-12 07:12:58 +02:00
fix various imports
This commit is contained in:
@@ -1,13 +1,14 @@
|
|||||||
import axios, { AxiosResponse } from 'axios';
|
import axios, { AxiosResponse } from 'axios';
|
||||||
import { load } from 'cheerio';
|
import { load } from 'cheerio';
|
||||||
|
|
||||||
|
import { orderSearchResults } from './shared';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
InternetProviderLyricResponse,
|
InternetProviderLyricResponse,
|
||||||
InternetProviderLyricSearchResponse,
|
InternetProviderLyricSearchResponse,
|
||||||
LyricSearchQuery,
|
LyricSearchQuery,
|
||||||
LyricSource,
|
LyricSource,
|
||||||
} from '.';
|
} from '/@/shared/types/domain/lyric-domain-types';
|
||||||
import { orderSearchResults } from './shared';
|
|
||||||
|
|
||||||
const SEARCH_URL = 'https://genius.com/api/search/song';
|
const SEARCH_URL = 'https://genius.com/api/search/song';
|
||||||
|
|
||||||
|
|||||||
@@ -17,36 +17,13 @@ import {
|
|||||||
getSearchResults as searchNetease,
|
getSearchResults as searchNetease,
|
||||||
} from './netease';
|
} from './netease';
|
||||||
|
|
||||||
|
import {
|
||||||
|
InternetProviderLyricResponse,
|
||||||
|
InternetProviderLyricSearchResponse,
|
||||||
|
LyricSource,
|
||||||
|
} from '/@/shared/types/domain/lyric-domain-types';
|
||||||
import { Song } from '/@/shared/types/domain/song-domain-types';
|
import { Song } from '/@/shared/types/domain/song-domain-types';
|
||||||
|
|
||||||
export enum LyricSource {
|
|
||||||
GENIUS = 'Genius',
|
|
||||||
LRCLIB = 'lrclib.net',
|
|
||||||
NETEASE = 'NetEase',
|
|
||||||
}
|
|
||||||
|
|
||||||
export type FullLyricsMetadata = Omit<InternetProviderLyricResponse, 'id' | 'lyrics' | 'source'> & {
|
|
||||||
lyrics: LyricsResponse;
|
|
||||||
remote: boolean;
|
|
||||||
source: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type InternetProviderLyricResponse = {
|
|
||||||
artist: string;
|
|
||||||
id: string;
|
|
||||||
lyrics: string;
|
|
||||||
name: string;
|
|
||||||
source: LyricSource;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type InternetProviderLyricSearchResponse = {
|
|
||||||
artist: string;
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
score?: number;
|
|
||||||
source: LyricSource;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type LyricGetQuery = {
|
export type LyricGetQuery = {
|
||||||
remoteSongId: string;
|
remoteSongId: string;
|
||||||
remoteSource: LyricSource;
|
remoteSource: LyricSource;
|
||||||
|
|||||||
@@ -1,13 +1,14 @@
|
|||||||
// Credits to https://github.com/tranxuanthang/lrcget for API implementation
|
// Credits to https://github.com/tranxuanthang/lrcget for API implementation
|
||||||
import axios, { AxiosResponse } from 'axios';
|
import axios, { AxiosResponse } from 'axios';
|
||||||
|
|
||||||
|
import { orderSearchResults } from './shared';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
InternetProviderLyricResponse,
|
InternetProviderLyricResponse,
|
||||||
InternetProviderLyricSearchResponse,
|
InternetProviderLyricSearchResponse,
|
||||||
LyricSearchQuery,
|
LyricSearchQuery,
|
||||||
LyricSource,
|
LyricSource,
|
||||||
} from '.';
|
} from '/@/shared/types/domain/lyric-domain-types';
|
||||||
import { orderSearchResults } from './shared';
|
|
||||||
|
|
||||||
const FETCH_URL = 'https://lrclib.net/api/get';
|
const FETCH_URL = 'https://lrclib.net/api/get';
|
||||||
const SEEARCH_URL = 'https://lrclib.net/api/search';
|
const SEEARCH_URL = 'https://lrclib.net/api/search';
|
||||||
|
|||||||
@@ -1,43 +1,20 @@
|
|||||||
import axios, { AxiosResponse } from 'axios';
|
import axios, { AxiosResponse } from 'axios';
|
||||||
|
|
||||||
|
import { store } from '../settings';
|
||||||
|
import { orderSearchResults } from './shared';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
InternetProviderLyricResponse,
|
InternetProviderLyricResponse,
|
||||||
InternetProviderLyricSearchResponse,
|
InternetProviderLyricSearchResponse,
|
||||||
LyricSearchQuery,
|
LyricSearchQuery,
|
||||||
LyricSource,
|
LyricSource,
|
||||||
} from '.';
|
} from '/@/shared/types/domain/lyric-domain-types';
|
||||||
import { store } from '../settings';
|
|
||||||
import { orderSearchResults } from './shared';
|
|
||||||
|
|
||||||
const SEARCH_URL = 'https://music.163.com/api/search/get';
|
const SEARCH_URL = 'https://music.163.com/api/search/get';
|
||||||
const LYRICS_URL = 'https://music.163.com/api/song/lyric';
|
const LYRICS_URL = 'https://music.163.com/api/song/lyric';
|
||||||
|
|
||||||
// Adapted from https://github.com/NyaomiDEV/Sunamu/blob/master/src/main/lyricproviders/netease.ts
|
// Adapted from https://github.com/NyaomiDEV/Sunamu/blob/master/src/main/lyricproviders/netease.ts
|
||||||
|
|
||||||
export interface Result {
|
|
||||||
hasMore: boolean;
|
|
||||||
songCount: number;
|
|
||||||
songs: Song[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface Song {
|
|
||||||
album: Album;
|
|
||||||
alias: string[];
|
|
||||||
artists: Artist[];
|
|
||||||
copyrightId: number;
|
|
||||||
duration: number;
|
|
||||||
fee: number;
|
|
||||||
ftype: number;
|
|
||||||
id: number;
|
|
||||||
mark: number;
|
|
||||||
mvid: number;
|
|
||||||
name: string;
|
|
||||||
rtype: number;
|
|
||||||
rUrl: null;
|
|
||||||
status: number;
|
|
||||||
transNames?: string[];
|
|
||||||
}
|
|
||||||
|
|
||||||
interface Album {
|
interface Album {
|
||||||
artist: Artist;
|
artist: Artist;
|
||||||
copyrightId: number;
|
copyrightId: number;
|
||||||
@@ -69,6 +46,30 @@ interface NetEaseResponse {
|
|||||||
result: Result;
|
result: Result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
interface Result {
|
||||||
|
hasMore: boolean;
|
||||||
|
songCount: number;
|
||||||
|
songs: Song[];
|
||||||
|
}
|
||||||
|
|
||||||
|
interface Song {
|
||||||
|
album: Album;
|
||||||
|
alias: string[];
|
||||||
|
artists: Artist[];
|
||||||
|
copyrightId: number;
|
||||||
|
duration: number;
|
||||||
|
fee: number;
|
||||||
|
ftype: number;
|
||||||
|
id: number;
|
||||||
|
mark: number;
|
||||||
|
mvid: number;
|
||||||
|
name: string;
|
||||||
|
rtype: number;
|
||||||
|
rUrl: null;
|
||||||
|
status: number;
|
||||||
|
transNames?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
export async function getLyricsBySongId(songId: string): Promise<null | string> {
|
export async function getLyricsBySongId(songId: string): Promise<null | string> {
|
||||||
let result: AxiosResponse<any, any>;
|
let result: AxiosResponse<any, any>;
|
||||||
try {
|
try {
|
||||||
|
|||||||
@@ -1,27 +1,31 @@
|
|||||||
import type {
|
import { QueryFunctionContext } from '@tanstack/react-query';
|
||||||
|
|
||||||
|
import { AlbumDetailQuery, AlbumListQuery } from '/@/shared/types/domain/album-domain-types';
|
||||||
|
import {
|
||||||
AlbumArtistDetailQuery,
|
AlbumArtistDetailQuery,
|
||||||
AlbumArtistListQuery,
|
AlbumArtistListQuery,
|
||||||
AlbumDetailQuery,
|
|
||||||
AlbumListQuery,
|
|
||||||
ArtistListQuery,
|
ArtistListQuery,
|
||||||
GenreListQuery,
|
} from '/@/shared/types/domain/artist-domain-types';
|
||||||
|
import { GenreListQuery } from '/@/shared/types/domain/genre-domain-types';
|
||||||
|
import {
|
||||||
LyricSearchQuery,
|
LyricSearchQuery,
|
||||||
|
LyricSource,
|
||||||
LyricsQuery,
|
LyricsQuery,
|
||||||
|
} from '/@/shared/types/domain/lyric-domain-types';
|
||||||
|
import {
|
||||||
PlaylistDetailQuery,
|
PlaylistDetailQuery,
|
||||||
PlaylistListQuery,
|
PlaylistListQuery,
|
||||||
PlaylistSongListQuery,
|
PlaylistSongListQuery,
|
||||||
|
} from '/@/shared/types/domain/playlist-domain-types';
|
||||||
|
import { SearchQuery } from '/@/shared/types/domain/search-domain-types';
|
||||||
|
import {
|
||||||
RandomSongListQuery,
|
RandomSongListQuery,
|
||||||
SearchQuery,
|
|
||||||
SimilarSongsQuery,
|
SimilarSongsQuery,
|
||||||
SongDetailQuery,
|
SongDetailQuery,
|
||||||
SongListQuery,
|
SongListQuery,
|
||||||
TopSongListQuery,
|
TopSongListQuery,
|
||||||
UserListQuery,
|
} from '/@/shared/types/domain/song-domain-types';
|
||||||
} from '/@/shared/types/domain-types';
|
import { UserListQuery } from '/@/shared/types/domain/user-domain-types';
|
||||||
|
|
||||||
import { QueryFunctionContext } from '@tanstack/react-query';
|
|
||||||
|
|
||||||
import { LyricSource } from '/@/shared/types/domain-types';
|
|
||||||
|
|
||||||
export const splitPaginatedQuery = (key: any) => {
|
export const splitPaginatedQuery = (key: any) => {
|
||||||
const { limit, startIndex, ...filter } = key || {};
|
const { limit, startIndex, ...filter } = key || {};
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import type { Song } from '/@/shared/types/domain-types';
|
|
||||||
import type { CrossfadeStyle } from '/@/shared/types/types';
|
import type { CrossfadeStyle } from '/@/shared/types/types';
|
||||||
import type { ReactPlayerProps } from 'react-player';
|
import type { ReactPlayerProps } from 'react-player';
|
||||||
|
|
||||||
@@ -20,9 +19,11 @@ import {
|
|||||||
gaplessHandler,
|
gaplessHandler,
|
||||||
} from '/@/renderer/components/audio-player/utils/list-handlers';
|
} from '/@/renderer/components/audio-player/utils/list-handlers';
|
||||||
import { useWebAudio } from '/@/renderer/features/player/hooks/use-webaudio';
|
import { useWebAudio } from '/@/renderer/features/player/hooks/use-webaudio';
|
||||||
import { getServerById, TranscodingConfig, usePlaybackSettings, useSpeed } from '/@/renderer/store';
|
import { TranscodingConfig, usePlaybackSettings, useSpeed } from '/@/renderer/store';
|
||||||
import { useSettingsStore, useSettingsStoreActions } from '/@/renderer/store/settings.store';
|
import { useSettingsStore, useSettingsStoreActions } from '/@/renderer/store/settings.store';
|
||||||
import { toast } from '/@/shared/components/toast/toast';
|
import { toast } from '/@/shared/components/toast/toast';
|
||||||
|
import { QueueSong } from '/@/shared/types/domain/player-domain-types';
|
||||||
|
import { Song } from '/@/shared/types/domain/song-domain-types';
|
||||||
import { PlaybackStyle, PlayerStatus } from '/@/shared/types/types';
|
import { PlaybackStyle, PlayerStatus } from '/@/shared/types/types';
|
||||||
|
|
||||||
export type AudioPlayerProgress = {
|
export type AudioPlayerProgress = {
|
||||||
@@ -57,27 +58,28 @@ const getDuration = (ref: any) => {
|
|||||||
const EMPTY_SOURCE =
|
const EMPTY_SOURCE =
|
||||||
'data:audio/mp3;base64,SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU2LjM2LjEwMAAAAAAAAAAAAAAA//OEAAAAAAAAAAAAAAAAAAAAAAAASW5mbwAAAA8AAAAEAAABIADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV6urq6urq6urq6urq6urq6urq6urq6urq6v////////////////////////////////8AAAAATGF2YzU2LjQxAAAAAAAAAAAAAAAAJAAAAAAAAAAAASDs90hvAAAAAAAAAAAAAAAAAAAA//MUZAAAAAGkAAAAAAAAA0gAAAAATEFN//MUZAMAAAGkAAAAAAAAA0gAAAAARTMu//MUZAYAAAGkAAAAAAAAA0gAAAAAOTku//MUZAkAAAGkAAAAAAAAA0gAAAAANVVV';
|
'data:audio/mp3;base64,SUQzBAAAAAAAI1RTU0UAAAAPAAADTGF2ZjU2LjM2LjEwMAAAAAAAAAAAAAAA//OEAAAAAAAAAAAAAAAAAAAAAAAASW5mbwAAAA8AAAAEAAABIADAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDV1dXV1dXV1dXV1dXV1dXV1dXV1dXV1dXV6urq6urq6urq6urq6urq6urq6urq6urq6v////////////////////////////////8AAAAATGF2YzU2LjQxAAAAAAAAAAAAAAAAJAAAAAAAAAAAASDs90hvAAAAAAAAAAAAAAAAAAAA//MUZAAAAAGkAAAAAAAAA0gAAAAATEFN//MUZAMAAAGkAAAAAAAAA0gAAAAARTMu//MUZAYAAAGkAAAAAAAAA0gAAAAAOTku//MUZAkAAAGkAAAAAAAAA0gAAAAANVVV';
|
||||||
|
|
||||||
const useSongUrl = (transcode: TranscodingConfig, current: boolean, song?: Song): null | string => {
|
const useSongUrl = (
|
||||||
|
transcode: TranscodingConfig,
|
||||||
|
current: boolean,
|
||||||
|
song?: QueueSong,
|
||||||
|
): null | string => {
|
||||||
const prior = useRef(['', '']);
|
const prior = useRef(['', '']);
|
||||||
|
|
||||||
return useMemo(() => {
|
return useMemo(() => {
|
||||||
if (song?.serverId) {
|
if (song?._serverId) {
|
||||||
// If we are the current track, we do not want a transcoding
|
// If we are the current track, we do not want a transcoding
|
||||||
// reconfiguration to force a restart.
|
// reconfiguration to force a restart.
|
||||||
if (current && prior.current[0] === song.uniqueId) {
|
if (current && prior.current[0] === song._uniqueId) {
|
||||||
return prior.current[1];
|
return prior.current[1] as string;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!transcode.enabled) {
|
if (!transcode.enabled) {
|
||||||
// transcoding disabled; save the result
|
// transcoding disabled; save the result
|
||||||
prior.current = [song.uniqueId, song.streamUrl];
|
prior.current = [song._uniqueId, song.streamUrl];
|
||||||
return song.streamUrl;
|
return song.streamUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
const result = api.controller.getTranscodingUrl({
|
const result = api.controller.getTranscodingUrl({
|
||||||
apiClientProps: {
|
|
||||||
server: getServerById(song.serverId),
|
|
||||||
},
|
|
||||||
query: {
|
query: {
|
||||||
base: song.streamUrl,
|
base: song.streamUrl,
|
||||||
...transcode,
|
...transcode,
|
||||||
@@ -85,14 +87,14 @@ const useSongUrl = (transcode: TranscodingConfig, current: boolean, song?: Song)
|
|||||||
})!;
|
})!;
|
||||||
|
|
||||||
// transcoding enabled; save the updated result
|
// transcoding enabled; save the updated result
|
||||||
prior.current = [song.uniqueId, result];
|
prior.current = [song._uniqueId, result];
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
// no track; clear result
|
// no track; clear result
|
||||||
prior.current = ['', ''];
|
prior.current = ['', ''];
|
||||||
return null;
|
return null;
|
||||||
}, [current, song?.uniqueId, song?.serverId, song?.streamUrl, transcode]);
|
}, [song?._serverId, song?._uniqueId, song?.streamUrl, current, transcode]);
|
||||||
};
|
};
|
||||||
|
|
||||||
export interface AudioPlayerRef {
|
export interface AudioPlayerRef {
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { ActionIcon } from '/@/shared/components/action-icon/action-icon';
|
|||||||
import { Button } from '/@/shared/components/button/button';
|
import { Button } from '/@/shared/components/button/button';
|
||||||
import { Group } from '/@/shared/components/group/group';
|
import { Group } from '/@/shared/components/group/group';
|
||||||
import { Icon } from '/@/shared/components/icon/icon';
|
import { Icon } from '/@/shared/components/icon/icon';
|
||||||
import { LibraryItem } from '/@/shared/types/domain-types';
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
import { Play } from '/@/shared/types/types';
|
import { Play } from '/@/shared/types/types';
|
||||||
|
|
||||||
export const CardControls = ({
|
export const CardControls = ({
|
||||||
|
|||||||
@@ -3,18 +3,21 @@ import formatDuration from 'format-duration';
|
|||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { generatePath } from 'react-router';
|
import { generatePath } from 'react-router';
|
||||||
import { Link } from 'react-router-dom';
|
import { Link } from 'react-router-dom';
|
||||||
|
import { Song } from 'src/main/features/core/lyrics/netease';
|
||||||
|
|
||||||
import styles from './card-rows.module.css';
|
import styles from './card-rows.module.css';
|
||||||
|
|
||||||
import { AppRoute } from '/@/renderer/router/routes';
|
import { AppRoute } from '/@/renderer/router/routes';
|
||||||
import { formatDateAbsolute, formatDateRelative, formatRating } from '/@/renderer/utils/format';
|
import { formatDateAbsolute, formatDateRelative, formatRating } from '/@/renderer/utils/format';
|
||||||
import { Text } from '/@/shared/components/text/text';
|
import { Text } from '/@/shared/components/text/text';
|
||||||
import { Album, AlbumArtist, Artist, Playlist, Song } from '/@/shared/types/domain-types';
|
import { Album } from '/@/shared/types/domain/album-domain-types';
|
||||||
|
import { Artist } from '/@/shared/types/domain/artist-domain-types';
|
||||||
|
import { Playlist } from '/@/shared/types/domain/playlist-domain-types';
|
||||||
import { CardRow } from '/@/shared/types/types';
|
import { CardRow } from '/@/shared/types/types';
|
||||||
|
|
||||||
interface CardRowsProps {
|
interface CardRowsProps {
|
||||||
data: any;
|
data: any;
|
||||||
rows: CardRow<Album>[] | CardRow<AlbumArtist>[] | CardRow<Artist>[];
|
rows: CardRow<Album>[] | CardRow<Artist>[];
|
||||||
}
|
}
|
||||||
|
|
||||||
export const CardRows = ({ data, rows }: CardRowsProps) => {
|
export const CardRows = ({ data, rows }: CardRowsProps) => {
|
||||||
|
|||||||
@@ -8,12 +8,14 @@ import { GridCardControls } from '/@/renderer/components/virtual-grid/grid-card/
|
|||||||
import { Image } from '/@/shared/components/image/image';
|
import { Image } from '/@/shared/components/image/image';
|
||||||
import { Skeleton } from '/@/shared/components/skeleton/skeleton';
|
import { Skeleton } from '/@/shared/components/skeleton/skeleton';
|
||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import { Album, AlbumArtist, Artist, LibraryItem } from '/@/shared/types/domain-types';
|
import { Album } from '/@/shared/types/domain/album-domain-types';
|
||||||
|
import { Artist } from '/@/shared/types/domain/artist-domain-types';
|
||||||
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
import { CardRoute, CardRow, Play, PlayQueueAddOptions } from '/@/shared/types/types';
|
import { CardRoute, CardRow, Play, PlayQueueAddOptions } from '/@/shared/types/types';
|
||||||
|
|
||||||
interface BaseGridCardProps {
|
interface BaseGridCardProps {
|
||||||
controls: {
|
controls: {
|
||||||
cardRows: CardRow<Album>[] | CardRow<AlbumArtist>[] | CardRow<Artist>[];
|
cardRows: CardRow<Album>[] | CardRow<Artist>[];
|
||||||
handleFavorite: (options: {
|
handleFavorite: (options: {
|
||||||
id: string[];
|
id: string[];
|
||||||
isFavorite: boolean;
|
isFavorite: boolean;
|
||||||
|
|||||||
@@ -20,7 +20,8 @@ import { Image } from '/@/shared/components/image/image';
|
|||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import { TextTitle } from '/@/shared/components/text-title/text-title';
|
import { TextTitle } from '/@/shared/components/text-title/text-title';
|
||||||
import { Text } from '/@/shared/components/text/text';
|
import { Text } from '/@/shared/components/text/text';
|
||||||
import { Album, LibraryItem } from '/@/shared/types/domain-types';
|
import { Album } from '/@/shared/types/domain/album-domain-types';
|
||||||
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
import { Play } from '/@/shared/types/types';
|
import { Play } from '/@/shared/types/types';
|
||||||
|
|
||||||
const variants: Variants = {
|
const variants: Variants = {
|
||||||
|
|||||||
@@ -24,13 +24,9 @@ import { Group } from '/@/shared/components/group/group';
|
|||||||
import { Icon } from '/@/shared/components/icon/icon';
|
import { Icon } from '/@/shared/components/icon/icon';
|
||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import { TextTitle } from '/@/shared/components/text-title/text-title';
|
import { TextTitle } from '/@/shared/components/text-title/text-title';
|
||||||
import {
|
import { Album } from '/@/shared/types/domain/album-domain-types';
|
||||||
Album,
|
import { Artist, RelatedArtist } from '/@/shared/types/domain/artist-domain-types';
|
||||||
AlbumArtist,
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
Artist,
|
|
||||||
LibraryItem,
|
|
||||||
RelatedArtist,
|
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
import { CardRoute, CardRow } from '/@/shared/types/types';
|
import { CardRoute, CardRow } from '/@/shared/types/types';
|
||||||
|
|
||||||
const getSlidesPerView = (windowWidth: number) => {
|
const getSlidesPerView = (windowWidth: number) => {
|
||||||
|
|||||||
@@ -10,20 +10,17 @@ import { GridCardControls } from '/@/renderer/components/virtual-grid/grid-card/
|
|||||||
import { Image } from '/@/shared/components/image/image';
|
import { Image } from '/@/shared/components/image/image';
|
||||||
import { Skeleton } from '/@/shared/components/skeleton/skeleton';
|
import { Skeleton } from '/@/shared/components/skeleton/skeleton';
|
||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import {
|
import { Album } from '/@/shared/types/domain/album-domain-types';
|
||||||
Album,
|
import { Artist } from '/@/shared/types/domain/artist-domain-types';
|
||||||
AlbumArtist,
|
import { Playlist } from '/@/shared/types/domain/playlist-domain-types';
|
||||||
Artist,
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
LibraryItem,
|
import { Song } from '/@/shared/types/domain/song-domain-types';
|
||||||
Playlist,
|
|
||||||
Song,
|
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
import { CardRoute, CardRow, Play, PlayQueueAddOptions } from '/@/shared/types/types';
|
import { CardRoute, CardRow, Play, PlayQueueAddOptions } from '/@/shared/types/types';
|
||||||
|
|
||||||
interface BaseGridCardProps {
|
interface BaseGridCardProps {
|
||||||
columnIndex: number;
|
columnIndex: number;
|
||||||
controls: {
|
controls: {
|
||||||
cardRows: CardRow<Album | AlbumArtist | Artist | Playlist | Song>[];
|
cardRows: CardRow<Album | Artist | Playlist | Song>[];
|
||||||
handleFavorite: (options: {
|
handleFavorite: (options: {
|
||||||
id: string[];
|
id: string[];
|
||||||
isFavorite: boolean;
|
isFavorite: boolean;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
|
|||||||
import { ActionIcon } from '/@/shared/components/action-icon/action-icon';
|
import { ActionIcon } from '/@/shared/components/action-icon/action-icon';
|
||||||
import { Button } from '/@/shared/components/button/button';
|
import { Button } from '/@/shared/components/button/button';
|
||||||
import { Icon } from '/@/shared/components/icon/icon';
|
import { Icon } from '/@/shared/components/icon/icon';
|
||||||
import { LibraryItem } from '/@/shared/types/domain-types';
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
import { Play, PlayQueueAddOptions } from '/@/shared/types/types';
|
import { Play, PlayQueueAddOptions } from '/@/shared/types/types';
|
||||||
|
|
||||||
export const GridCardControls = ({
|
export const GridCardControls = ({
|
||||||
|
|||||||
@@ -10,20 +10,17 @@ import { GridCardControls } from '/@/renderer/components/virtual-grid/grid-card/
|
|||||||
import { Image } from '/@/shared/components/image/image';
|
import { Image } from '/@/shared/components/image/image';
|
||||||
import { Skeleton } from '/@/shared/components/skeleton/skeleton';
|
import { Skeleton } from '/@/shared/components/skeleton/skeleton';
|
||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import {
|
import { Album } from '/@/shared/types/domain/album-domain-types';
|
||||||
Album,
|
import { Artist } from '/@/shared/types/domain/artist-domain-types';
|
||||||
AlbumArtist,
|
import { Playlist } from '/@/shared/types/domain/playlist-domain-types';
|
||||||
Artist,
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
LibraryItem,
|
import { Song } from '/@/shared/types/domain/song-domain-types';
|
||||||
Playlist,
|
|
||||||
Song,
|
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
import { CardRoute, CardRow, Play, PlayQueueAddOptions } from '/@/shared/types/types';
|
import { CardRoute, CardRow, Play, PlayQueueAddOptions } from '/@/shared/types/types';
|
||||||
|
|
||||||
interface BaseGridCardProps {
|
interface BaseGridCardProps {
|
||||||
columnIndex: number;
|
columnIndex: number;
|
||||||
controls: {
|
controls: {
|
||||||
cardRows: CardRow<Album | AlbumArtist | Artist | Playlist | Song>[];
|
cardRows: CardRow<Album | Artist | Playlist | Song>[];
|
||||||
handleFavorite: (options: {
|
handleFavorite: (options: {
|
||||||
id: string[];
|
id: string[];
|
||||||
isFavorite: boolean;
|
isFavorite: boolean;
|
||||||
|
|||||||
@@ -14,7 +14,9 @@ import { FixedSizeList } from 'react-window';
|
|||||||
import styles from './virtual-grid-wrapper.module.css';
|
import styles from './virtual-grid-wrapper.module.css';
|
||||||
|
|
||||||
import { GridCard } from '/@/renderer/components/virtual-grid/grid-card';
|
import { GridCard } from '/@/renderer/components/virtual-grid/grid-card';
|
||||||
import { Album, AlbumArtist, Artist, LibraryItem } from '/@/shared/types/domain-types';
|
import { Album } from '/@/shared/types/domain/album-domain-types';
|
||||||
|
import { Artist } from '/@/shared/types/domain/artist-domain-types';
|
||||||
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
|
|
||||||
const createItemData = memoize(
|
const createItemData = memoize(
|
||||||
(
|
(
|
||||||
@@ -72,7 +74,7 @@ export const VirtualGridWrapper = ({
|
|||||||
width,
|
width,
|
||||||
...rest
|
...rest
|
||||||
}: Omit<FixedSizeListProps, 'children' | 'height' | 'itemSize' | 'ref' | 'width'> & {
|
}: Omit<FixedSizeListProps, 'children' | 'height' | 'itemSize' | 'ref' | 'width'> & {
|
||||||
cardRows: CardRow<Album | AlbumArtist | Artist>[];
|
cardRows: CardRow<Album | Artist>[];
|
||||||
columnCount: number;
|
columnCount: number;
|
||||||
display: ListDisplayType;
|
display: ListDisplayType;
|
||||||
handleFavorite?: (options: {
|
handleFavorite?: (options: {
|
||||||
|
|||||||
@@ -14,7 +14,8 @@ import {
|
|||||||
import InfiniteLoader from 'react-window-infinite-loader';
|
import InfiniteLoader from 'react-window-infinite-loader';
|
||||||
|
|
||||||
import { VirtualGridWrapper } from '/@/renderer/components/virtual-grid/virtual-grid-wrapper';
|
import { VirtualGridWrapper } from '/@/renderer/components/virtual-grid/virtual-grid-wrapper';
|
||||||
import { AnyLibraryItem, Genre, LibraryItem } from '/@/shared/types/domain-types';
|
import { Genre } from '/@/shared/types/domain/genre-domain-types';
|
||||||
|
import { AnyLibraryItem, LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
import { ListDisplayType } from '/@/shared/types/types';
|
import { ListDisplayType } from '/@/shared/types/types';
|
||||||
|
|
||||||
export type VirtualInfiniteGridRef = {
|
export type VirtualInfiniteGridRef = {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import type { AlbumArtist, Artist } from '/@/shared/types/domain-types';
|
|
||||||
import type { ICellRendererParams } from '@ag-grid-community/core';
|
import type { ICellRendererParams } from '@ag-grid-community/core';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
@@ -10,6 +9,7 @@ import { AppRoute } from '/@/renderer/router/routes';
|
|||||||
import { Separator } from '/@/shared/components/separator/separator';
|
import { Separator } from '/@/shared/components/separator/separator';
|
||||||
import { Skeleton } from '/@/shared/components/skeleton/skeleton';
|
import { Skeleton } from '/@/shared/components/skeleton/skeleton';
|
||||||
import { Text } from '/@/shared/components/text/text';
|
import { Text } from '/@/shared/components/text/text';
|
||||||
|
import { Artist } from '/@/shared/types/domain/artist-domain-types';
|
||||||
|
|
||||||
export const AlbumArtistCell = ({ data, value }: ICellRendererParams) => {
|
export const AlbumArtistCell = ({ data, value }: ICellRendererParams) => {
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
@@ -23,7 +23,7 @@ export const AlbumArtistCell = ({ data, value }: ICellRendererParams) => {
|
|||||||
return (
|
return (
|
||||||
<CellContainer position="left">
|
<CellContainer position="left">
|
||||||
<Text isMuted overflow="hidden" size="md">
|
<Text isMuted overflow="hidden" size="md">
|
||||||
{value?.map((item: AlbumArtist | Artist, index: number) => (
|
{value?.map((item: Artist, index: number) => (
|
||||||
<React.Fragment key={`row-${item.id}-${data.uniqueId}`}>
|
<React.Fragment key={`row-${item.id}-${data.uniqueId}`}>
|
||||||
{index > 0 && <Separator />}
|
{index > 0 && <Separator />}
|
||||||
{item.id ? (
|
{item.id ? (
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import type { AlbumArtist, Artist } from '/@/shared/types/domain-types';
|
|
||||||
import type { ICellRendererParams } from '@ag-grid-community/core';
|
import type { ICellRendererParams } from '@ag-grid-community/core';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
@@ -10,6 +9,7 @@ import { AppRoute } from '/@/renderer/router/routes';
|
|||||||
import { Separator } from '/@/shared/components/separator/separator';
|
import { Separator } from '/@/shared/components/separator/separator';
|
||||||
import { Skeleton } from '/@/shared/components/skeleton/skeleton';
|
import { Skeleton } from '/@/shared/components/skeleton/skeleton';
|
||||||
import { Text } from '/@/shared/components/text/text';
|
import { Text } from '/@/shared/components/text/text';
|
||||||
|
import { Artist } from '/@/shared/types/domain/artist-domain-types';
|
||||||
|
|
||||||
export const ArtistCell = ({ data, value }: ICellRendererParams) => {
|
export const ArtistCell = ({ data, value }: ICellRendererParams) => {
|
||||||
if (value === undefined) {
|
if (value === undefined) {
|
||||||
@@ -23,7 +23,7 @@ export const ArtistCell = ({ data, value }: ICellRendererParams) => {
|
|||||||
return (
|
return (
|
||||||
<CellContainer position="left">
|
<CellContainer position="left">
|
||||||
<Text isMuted overflow="hidden" size="md">
|
<Text isMuted overflow="hidden" size="md">
|
||||||
{value?.map((item: AlbumArtist | Artist, index: number) => (
|
{value?.map((item: Artist, index: number) => (
|
||||||
<React.Fragment key={`row-${item.id}-${data.uniqueId}`}>
|
<React.Fragment key={`row-${item.id}-${data.uniqueId}`}>
|
||||||
{index > 0 && <Separator />}
|
{index > 0 && <Separator />}
|
||||||
{item.id ? (
|
{item.id ? (
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import styles from './combined-title-cell-controls.module.css';
|
|||||||
import { usePlayQueueAdd } from '/@/renderer/features/player';
|
import { usePlayQueueAdd } from '/@/renderer/features/player';
|
||||||
import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
|
import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
|
||||||
import { ActionIcon } from '/@/shared/components/action-icon/action-icon';
|
import { ActionIcon } from '/@/shared/components/action-icon/action-icon';
|
||||||
import { LibraryItem } from '/@/shared/types/domain-types';
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
import { Play } from '/@/shared/types/types';
|
import { Play } from '/@/shared/types/types';
|
||||||
|
|
||||||
export const ListCoverControls = ({
|
export const ListCoverControls = ({
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { SEPARATOR_STRING } from '/@/shared/api/utils';
|
|||||||
import { Image } from '/@/shared/components/image/image';
|
import { Image } from '/@/shared/components/image/image';
|
||||||
import { Skeleton } from '/@/shared/components/skeleton/skeleton';
|
import { Skeleton } from '/@/shared/components/skeleton/skeleton';
|
||||||
import { Text } from '/@/shared/components/text/text';
|
import { Text } from '/@/shared/components/text/text';
|
||||||
import { AlbumArtist, Artist } from '/@/shared/types/domain-types';
|
import { Artist } from '/@/shared/types/domain/artist-domain-types';
|
||||||
|
|
||||||
export const CombinedTitleCell = ({
|
export const CombinedTitleCell = ({
|
||||||
context,
|
context,
|
||||||
@@ -74,7 +74,7 @@ export const CombinedTitleCell = ({
|
|||||||
</Text>
|
</Text>
|
||||||
<Text isMuted overflow="hidden" size="md">
|
<Text isMuted overflow="hidden" size="md">
|
||||||
{artists?.length ? (
|
{artists?.length ? (
|
||||||
artists.map((artist: AlbumArtist | Artist, index: number) => (
|
artists.map((artist: Artist, index: number) => (
|
||||||
<React.Fragment key={`queue-${rowIndex}-artist-${artist.id}`}>
|
<React.Fragment key={`queue-${rowIndex}-artist-${artist.id}`}>
|
||||||
{index > 0 ? SEPARATOR_STRING : null}
|
{index > 0 ? SEPARATOR_STRING : null}
|
||||||
{artist.id ? (
|
{artist.id ? (
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import type { AlbumArtist, Artist } from '/@/shared/types/domain-types';
|
|
||||||
import type { ICellRendererParams } from '@ag-grid-community/core';
|
import type { ICellRendererParams } from '@ag-grid-community/core';
|
||||||
|
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
@@ -8,13 +7,14 @@ import { CellContainer } from '/@/renderer/components/virtual-table/cells/generi
|
|||||||
import { useGenreRoute } from '/@/renderer/hooks/use-genre-route';
|
import { useGenreRoute } from '/@/renderer/hooks/use-genre-route';
|
||||||
import { Separator } from '/@/shared/components/separator/separator';
|
import { Separator } from '/@/shared/components/separator/separator';
|
||||||
import { Text } from '/@/shared/components/text/text';
|
import { Text } from '/@/shared/components/text/text';
|
||||||
|
import { Artist } from '/@/shared/types/domain/artist-domain-types';
|
||||||
|
|
||||||
export const GenreCell = ({ data, value }: ICellRendererParams) => {
|
export const GenreCell = ({ data, value }: ICellRendererParams) => {
|
||||||
const genrePath = useGenreRoute();
|
const genrePath = useGenreRoute();
|
||||||
return (
|
return (
|
||||||
<CellContainer position="left">
|
<CellContainer position="left">
|
||||||
<Text isMuted overflow="hidden" size="md">
|
<Text isMuted overflow="hidden" size="md">
|
||||||
{value?.map((item: AlbumArtist | Artist, index: number) => (
|
{value?.map((item: Artist, index: number) => (
|
||||||
<React.Fragment key={`row-${item.id}-${data.uniqueId}`}>
|
<React.Fragment key={`row-${item.id}-${data.uniqueId}`}>
|
||||||
{index > 0 && <Separator />}
|
{index > 0 && <Separator />}
|
||||||
<Text
|
<Text
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { MutableRefObject, useEffect, useMemo, useRef } from 'react';
|
|||||||
|
|
||||||
import { useAppFocus } from '/@/renderer/hooks';
|
import { useAppFocus } from '/@/renderer/hooks';
|
||||||
import { useCurrentSong, usePlayerStore } from '/@/renderer/store';
|
import { useCurrentSong, usePlayerStore } from '/@/renderer/store';
|
||||||
import { Song } from '/@/shared/types/domain-types';
|
import { Song } from '/@/shared/types/domain/song-domain-types';
|
||||||
import { PlayerStatus } from '/@/shared/types/types';
|
import { PlayerStatus } from '/@/shared/types/types';
|
||||||
|
|
||||||
interface UseCurrentSongRowStylesProps {
|
interface UseCurrentSongRowStylesProps {
|
||||||
|
|||||||
@@ -23,12 +23,9 @@ import { SetContextMenuItems, useHandleTableContextMenu } from '/@/renderer/feat
|
|||||||
import { AppRoute } from '/@/renderer/router/routes';
|
import { AppRoute } from '/@/renderer/router/routes';
|
||||||
import { PersistedTableColumn, useListStoreActions } from '/@/renderer/store';
|
import { PersistedTableColumn, useListStoreActions } from '/@/renderer/store';
|
||||||
import { ListKey, useListStoreByKey } from '/@/renderer/store/list.store';
|
import { ListKey, useListStoreByKey } from '/@/renderer/store/list.store';
|
||||||
import {
|
import { BasePaginatedResponse, BaseQuery } from '/@/shared/types/adapter/api-controller-types';
|
||||||
BasePaginatedResponse,
|
import { ServerListItem } from '/@/shared/types/domain/server-domain-types';
|
||||||
BaseQuery,
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
LibraryItem,
|
|
||||||
ServerListItem,
|
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
import { ListDisplayType, TablePagination } from '/@/shared/types/types';
|
import { ListDisplayType, TablePagination } from '/@/shared/types/types';
|
||||||
|
|
||||||
export type AgGridFetchFn<TResponse, TFilter> = (
|
export type AgGridFetchFn<TResponse, TFilter> = (
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import { Icon } from '/@/shared/components/icon/icon';
|
|||||||
import { ScrollArea } from '/@/shared/components/scroll-area/scroll-area';
|
import { ScrollArea } from '/@/shared/components/scroll-area/scroll-area';
|
||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import { Text } from '/@/shared/components/text/text';
|
import { Text } from '/@/shared/components/text/text';
|
||||||
import { ServerListItem, ServerType } from '/@/shared/types/domain-types';
|
import { ServerListItem, ServerType } from '/@/shared/types/domain/server-domain-types';
|
||||||
|
|
||||||
const localSettings = isElectron() ? window.api.localSettings : null;
|
const localSettings = isElectron() ? window.api.localSettings : null;
|
||||||
|
|
||||||
|
|||||||
@@ -49,13 +49,9 @@ import { Group } from '/@/shared/components/group/group';
|
|||||||
import { Popover } from '/@/shared/components/popover/popover';
|
import { Popover } from '/@/shared/components/popover/popover';
|
||||||
import { Spoiler } from '/@/shared/components/spoiler/spoiler';
|
import { Spoiler } from '/@/shared/components/spoiler/spoiler';
|
||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import {
|
import { AlbumListQuery, AlbumListSort } from '/@/shared/types/domain/album-domain-types';
|
||||||
AlbumListQuery,
|
import { QueueSong } from '/@/shared/types/domain/player-domain-types';
|
||||||
AlbumListSort,
|
import { LibraryItem, ListSortOrder } from '/@/shared/types/domain/shared-domain-types';
|
||||||
LibraryItem,
|
|
||||||
QueueSong,
|
|
||||||
SortOrder,
|
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
import { Play } from '/@/shared/types/types';
|
import { Play } from '/@/shared/types/types';
|
||||||
|
|
||||||
const isFullWidthRow = (node: RowNode) => {
|
const isFullWidthRow = (node: RowNode) => {
|
||||||
@@ -170,7 +166,7 @@ export const AlbumDetailContent = ({ background, tableRef }: AlbumDetailContentP
|
|||||||
: undefined,
|
: undefined,
|
||||||
limit: 15,
|
limit: 15,
|
||||||
sortBy: AlbumListSort.YEAR,
|
sortBy: AlbumListSort.YEAR,
|
||||||
sortOrder: SortOrder.DESC,
|
sortOrder: ListSortOrder.DESC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
serverId: server?.id,
|
serverId: server?.id,
|
||||||
@@ -180,7 +176,7 @@ export const AlbumDetailContent = ({ background, tableRef }: AlbumDetailContentP
|
|||||||
genres: detailQuery.data?.genres.length ? [detailQuery.data.genres[0].id] : undefined,
|
genres: detailQuery.data?.genres.length ? [detailQuery.data.genres[0].id] : undefined,
|
||||||
limit: 15,
|
limit: 15,
|
||||||
sortBy: AlbumListSort.RANDOM,
|
sortBy: AlbumListSort.RANDOM,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: ListSortOrder.ASC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -16,7 +16,9 @@ import { Group } from '/@/shared/components/group/group';
|
|||||||
import { Rating } from '/@/shared/components/rating/rating';
|
import { Rating } from '/@/shared/components/rating/rating';
|
||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import { Text } from '/@/shared/components/text/text';
|
import { Text } from '/@/shared/components/text/text';
|
||||||
import { AlbumDetailResponse, LibraryItem, ServerType } from '/@/shared/types/domain-types';
|
import { AlbumDetailResponse } from '/@/shared/types/domain/album-domain-types';
|
||||||
|
import { ServerType } from '/@/shared/types/domain/server-domain-types';
|
||||||
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
|
|
||||||
interface AlbumDetailHeaderProps {
|
interface AlbumDetailHeaderProps {
|
||||||
background: {
|
background: {
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ import {
|
|||||||
AlbumListQuery,
|
AlbumListQuery,
|
||||||
AlbumListResponse,
|
AlbumListResponse,
|
||||||
AlbumListSort,
|
AlbumListSort,
|
||||||
LibraryItem,
|
} from '/@/shared/types/domain/album-domain-types';
|
||||||
} from '/@/shared/types/domain-types';
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
import { CardRow, ListDisplayType } from '/@/shared/types/types';
|
import { CardRow, ListDisplayType } from '/@/shared/types/types';
|
||||||
|
|
||||||
export const AlbumListGridView = ({ gridRef, itemCount }: any) => {
|
export const AlbumListGridView = ({ gridRef, itemCount }: any) => {
|
||||||
|
|||||||
@@ -34,158 +34,154 @@ import { DropdownMenu } from '/@/shared/components/dropdown-menu/dropdown-menu';
|
|||||||
import { Flex } from '/@/shared/components/flex/flex';
|
import { Flex } from '/@/shared/components/flex/flex';
|
||||||
import { Group } from '/@/shared/components/group/group';
|
import { Group } from '/@/shared/components/group/group';
|
||||||
import { Icon } from '/@/shared/components/icon/icon';
|
import { Icon } from '/@/shared/components/icon/icon';
|
||||||
import {
|
import { AlbumListQuery, AlbumListSort } from '/@/shared/types/domain/album-domain-types';
|
||||||
AlbumListQuery,
|
import { ServerType } from '/@/shared/types/domain/server-domain-types';
|
||||||
AlbumListSort,
|
import { LibraryItem, ListSortOrder } from '/@/shared/types/domain/shared-domain-types';
|
||||||
LibraryItem,
|
|
||||||
ServerType,
|
|
||||||
SortOrder,
|
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
import { ListDisplayType, Play, TableColumn } from '/@/shared/types/types';
|
import { ListDisplayType, Play, TableColumn } from '/@/shared/types/types';
|
||||||
|
|
||||||
const FILTERS = {
|
const FILTERS = {
|
||||||
jellyfin: [
|
jellyfin: [
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.albumArtist', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.albumArtist', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.ALBUM_ARTIST,
|
value: AlbumListSort.ALBUM_ARTIST,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.communityRating', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.communityRating', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.COMMUNITY_RATING,
|
value: AlbumListSort.COMMUNITY_RATING,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.criticRating', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.criticRating', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.CRITIC_RATING,
|
value: AlbumListSort.CRITIC_RATING,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.NAME,
|
value: AlbumListSort.NAME,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.playCount', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.playCount', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.PLAY_COUNT,
|
value: AlbumListSort.PLAY_COUNT,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.random', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.random', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.RANDOM,
|
value: AlbumListSort.RANDOM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.recentlyAdded', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.recentlyAdded', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.RECENTLY_ADDED,
|
value: AlbumListSort.RECENTLY_ADDED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.releaseDate', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.releaseDate', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.RELEASE_DATE,
|
value: AlbumListSort.RELEASE_DATE,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
navidrome: [
|
navidrome: [
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.albumArtist', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.albumArtist', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.ALBUM_ARTIST,
|
value: AlbumListSort.ALBUM_ARTIST,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.artist', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.artist', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.ARTIST,
|
value: AlbumListSort.ARTIST,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.duration', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.duration', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.DURATION,
|
value: AlbumListSort.DURATION,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.mostPlayed', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.mostPlayed', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.PLAY_COUNT,
|
value: AlbumListSort.PLAY_COUNT,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.NAME,
|
value: AlbumListSort.NAME,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.random', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.random', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.RANDOM,
|
value: AlbumListSort.RANDOM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.rating', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.rating', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.RATING,
|
value: AlbumListSort.RATING,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.recentlyAdded', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.recentlyAdded', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.RECENTLY_ADDED,
|
value: AlbumListSort.RECENTLY_ADDED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.recentlyPlayed', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.recentlyPlayed', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.RECENTLY_PLAYED,
|
value: AlbumListSort.RECENTLY_PLAYED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.songCount', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.songCount', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.SONG_COUNT,
|
value: AlbumListSort.SONG_COUNT,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.favorited', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.favorited', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.FAVORITED,
|
value: AlbumListSort.FAVORITED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.releaseYear', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.releaseYear', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.YEAR,
|
value: AlbumListSort.YEAR,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
subsonic: [
|
subsonic: [
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.albumArtist', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.albumArtist', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.ALBUM_ARTIST,
|
value: AlbumListSort.ALBUM_ARTIST,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.mostPlayed', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.mostPlayed', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.PLAY_COUNT,
|
value: AlbumListSort.PLAY_COUNT,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.NAME,
|
value: AlbumListSort.NAME,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.random', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.random', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.RANDOM,
|
value: AlbumListSort.RANDOM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.recentlyAdded', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.recentlyAdded', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.RECENTLY_ADDED,
|
value: AlbumListSort.RECENTLY_ADDED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.recentlyPlayed', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.recentlyPlayed', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.RECENTLY_PLAYED,
|
value: AlbumListSort.RECENTLY_PLAYED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.favorited', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.favorited', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.FAVORITED,
|
value: AlbumListSort.FAVORITED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.releaseYear', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.releaseYear', { postProcess: 'titleCase' }),
|
||||||
value: AlbumListSort.YEAR,
|
value: AlbumListSort.YEAR,
|
||||||
},
|
},
|
||||||
@@ -299,7 +295,7 @@ export const AlbumListHeaderFilters = ({
|
|||||||
customFilters,
|
customFilters,
|
||||||
data: {
|
data: {
|
||||||
sortBy: e.currentTarget.value as AlbumListSort,
|
sortBy: e.currentTarget.value as AlbumListSort,
|
||||||
sortOrder: sortOrder || SortOrder.ASC,
|
sortOrder: sortOrder || ListSortOrder.ASC,
|
||||||
},
|
},
|
||||||
itemType: LibraryItem.ALBUM,
|
itemType: LibraryItem.ALBUM,
|
||||||
key: pageKey,
|
key: pageKey,
|
||||||
@@ -337,7 +333,8 @@ export const AlbumListHeaderFilters = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const handleToggleSortOrder = useCallback(() => {
|
const handleToggleSortOrder = useCallback(() => {
|
||||||
const newSortOrder = filter.sortOrder === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC;
|
const newSortOrder =
|
||||||
|
filter.sortOrder === ListSortOrder.ASC ? ListSortOrder.DESC : ListSortOrder.ASC;
|
||||||
const updatedFilters = setFilter({
|
const updatedFilters = setFilter({
|
||||||
customFilters,
|
customFilters,
|
||||||
data: { sortOrder: newSortOrder },
|
data: { sortOrder: newSortOrder },
|
||||||
|
|||||||
@@ -16,7 +16,8 @@ import { titleCase } from '/@/renderer/utils';
|
|||||||
import { Flex } from '/@/shared/components/flex/flex';
|
import { Flex } from '/@/shared/components/flex/flex';
|
||||||
import { Group } from '/@/shared/components/group/group';
|
import { Group } from '/@/shared/components/group/group';
|
||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import { AlbumListQuery, LibraryItem } from '/@/shared/types/domain-types';
|
import { AlbumListQuery } from '/@/shared/types/domain/album-domain-types';
|
||||||
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
|
|
||||||
interface AlbumListHeaderProps {
|
interface AlbumListHeaderProps {
|
||||||
genreId?: string;
|
genreId?: string;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { useVirtualTable } from '/@/renderer/components/virtual-table/hooks/use-
|
|||||||
import { useListContext } from '/@/renderer/context/list-context';
|
import { useListContext } from '/@/renderer/context/list-context';
|
||||||
import { ALBUM_CONTEXT_MENU_ITEMS } from '/@/renderer/features/context-menu/context-menu-items';
|
import { ALBUM_CONTEXT_MENU_ITEMS } from '/@/renderer/features/context-menu/context-menu-items';
|
||||||
import { useCurrentServer } from '/@/renderer/store';
|
import { useCurrentServer } from '/@/renderer/store';
|
||||||
import { LibraryItem } from '/@/shared/types/domain-types';
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
|
|
||||||
export const AlbumListTableView = ({ itemCount, tableRef }: any) => {
|
export const AlbumListTableView = ({ itemCount, tableRef }: any) => {
|
||||||
const server = useCurrentServer();
|
const server = useCurrentServer();
|
||||||
|
|||||||
@@ -14,13 +14,10 @@ import { SpinnerIcon } from '/@/shared/components/spinner/spinner';
|
|||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import { Text } from '/@/shared/components/text/text';
|
import { Text } from '/@/shared/components/text/text';
|
||||||
import { YesNoSelect } from '/@/shared/components/yes-no-select/yes-no-select';
|
import { YesNoSelect } from '/@/shared/components/yes-no-select/yes-no-select';
|
||||||
import {
|
import { AlbumListQuery } from '/@/shared/types/domain/album-domain-types';
|
||||||
AlbumArtistListSort,
|
import { AlbumArtistListSort } from '/@/shared/types/domain/artist-domain-types';
|
||||||
AlbumListQuery,
|
import { GenreListSort } from '/@/shared/types/domain/genre-domain-types';
|
||||||
GenreListSort,
|
import { LibraryItem, ListSortOrder } from '/@/shared/types/domain/shared-domain-types';
|
||||||
LibraryItem,
|
|
||||||
SortOrder,
|
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
|
|
||||||
interface JellyfinAlbumFiltersProps {
|
interface JellyfinAlbumFiltersProps {
|
||||||
customFilters?: Partial<AlbumListFilter>;
|
customFilters?: Partial<AlbumListFilter>;
|
||||||
@@ -50,7 +47,7 @@ export const JellyfinAlbumFilters = ({
|
|||||||
query: {
|
query: {
|
||||||
musicFolderId: filter?.musicFolderId,
|
musicFolderId: filter?.musicFolderId,
|
||||||
sortBy: GenreListSort.NAME,
|
sortBy: GenreListSort.NAME,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: ListSortOrder.ASC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
serverId,
|
serverId,
|
||||||
@@ -178,7 +175,7 @@ export const JellyfinAlbumFilters = ({
|
|||||||
},
|
},
|
||||||
query: {
|
query: {
|
||||||
sortBy: AlbumArtistListSort.NAME,
|
sortBy: AlbumArtistListSort.NAME,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: ListSortOrder.ASC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
serverId,
|
serverId,
|
||||||
|
|||||||
@@ -16,13 +16,10 @@ import { Stack } from '/@/shared/components/stack/stack';
|
|||||||
import { Switch } from '/@/shared/components/switch/switch';
|
import { Switch } from '/@/shared/components/switch/switch';
|
||||||
import { Text } from '/@/shared/components/text/text';
|
import { Text } from '/@/shared/components/text/text';
|
||||||
import { YesNoSelect } from '/@/shared/components/yes-no-select/yes-no-select';
|
import { YesNoSelect } from '/@/shared/components/yes-no-select/yes-no-select';
|
||||||
import {
|
import { AlbumListQuery } from '/@/shared/types/domain/album-domain-types';
|
||||||
AlbumArtistListSort,
|
import { AlbumArtistListSort } from '/@/shared/types/domain/artist-domain-types';
|
||||||
AlbumListQuery,
|
import { GenreListSort } from '/@/shared/types/domain/genre-domain-types';
|
||||||
GenreListSort,
|
import { LibraryItem, ListSortOrder } from '/@/shared/types/domain/shared-domain-types';
|
||||||
LibraryItem,
|
|
||||||
SortOrder,
|
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
|
|
||||||
interface NavidromeAlbumFiltersProps {
|
interface NavidromeAlbumFiltersProps {
|
||||||
customFilters?: Partial<AlbumListFilter>;
|
customFilters?: Partial<AlbumListFilter>;
|
||||||
@@ -50,7 +47,7 @@ export const NavidromeAlbumFilters = ({
|
|||||||
},
|
},
|
||||||
query: {
|
query: {
|
||||||
sortBy: GenreListSort.NAME,
|
sortBy: GenreListSort.NAME,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: ListSortOrder.ASC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
serverId,
|
serverId,
|
||||||
@@ -194,7 +191,7 @@ export const NavidromeAlbumFilters = ({
|
|||||||
query: {
|
query: {
|
||||||
// searchTerm: debouncedSearchTerm,
|
// searchTerm: debouncedSearchTerm,
|
||||||
sortBy: AlbumArtistListSort.NAME,
|
sortBy: AlbumArtistListSort.NAME,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: ListSortOrder.ASC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
serverId,
|
serverId,
|
||||||
|
|||||||
@@ -14,13 +14,10 @@ import { SpinnerIcon } from '/@/shared/components/spinner/spinner';
|
|||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import { Switch } from '/@/shared/components/switch/switch';
|
import { Switch } from '/@/shared/components/switch/switch';
|
||||||
import { Text } from '/@/shared/components/text/text';
|
import { Text } from '/@/shared/components/text/text';
|
||||||
import {
|
import { AlbumListQuery } from '/@/shared/types/domain/album-domain-types';
|
||||||
AlbumArtistListSort,
|
import { AlbumArtistListSort } from '/@/shared/types/domain/artist-domain-types';
|
||||||
AlbumListQuery,
|
import { GenreListSort } from '/@/shared/types/domain/genre-domain-types';
|
||||||
GenreListSort,
|
import { LibraryItem, ListSortOrder } from '/@/shared/types/domain/shared-domain-types';
|
||||||
LibraryItem,
|
|
||||||
SortOrder,
|
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
|
|
||||||
interface SubsonicAlbumFiltersProps {
|
interface SubsonicAlbumFiltersProps {
|
||||||
disableArtistFilter?: boolean;
|
disableArtistFilter?: boolean;
|
||||||
@@ -47,7 +44,7 @@ export const SubsonicAlbumFilters = ({
|
|||||||
},
|
},
|
||||||
query: {
|
query: {
|
||||||
sortBy: AlbumArtistListSort.NAME,
|
sortBy: AlbumArtistListSort.NAME,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: ListSortOrder.ASC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
serverId,
|
serverId,
|
||||||
@@ -80,7 +77,7 @@ export const SubsonicAlbumFilters = ({
|
|||||||
},
|
},
|
||||||
query: {
|
query: {
|
||||||
sortBy: GenreListSort.NAME,
|
sortBy: GenreListSort.NAME,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: ListSortOrder.ASC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
serverId,
|
serverId,
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import type { QueryHookArgs } from '/@/renderer/lib/react-query';
|
import type { QueryHookArgs } from '/@/renderer/lib/react-query';
|
||||||
import type { AlbumDetailQuery } from '/@/shared/types/domain-types';
|
|
||||||
|
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { controller } from '/@/renderer/api/controller';
|
import { controller } from '/@/renderer/api/controller';
|
||||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||||
import { getServerById } from '/@/renderer/store';
|
import { getServerById } from '/@/renderer/store';
|
||||||
|
import { AlbumDetailQuery } from '/@/shared/types/domain/album-domain-types';
|
||||||
|
|
||||||
export const useAlbumDetail = (args: QueryHookArgs<AlbumDetailQuery>) => {
|
export const useAlbumDetail = (args: QueryHookArgs<AlbumDetailQuery>) => {
|
||||||
const { options, query, serverId } = args;
|
const { options, query, serverId } = args;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import type { QueryHookArgs } from '/@/renderer/lib/react-query';
|
import type { QueryHookArgs } from '/@/renderer/lib/react-query';
|
||||||
import type { AlbumListQuery } from '/@/shared/types/domain-types';
|
|
||||||
|
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { api } from '/@/renderer/api';
|
import { api } from '/@/renderer/api';
|
||||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||||
import { getServerById } from '/@/renderer/store';
|
import { getServerById } from '/@/renderer/store';
|
||||||
|
import { AlbumListQuery } from '/@/shared/types/domain/album-domain-types';
|
||||||
|
|
||||||
export const useAlbumListCount = (args: QueryHookArgs<AlbumListQuery>) => {
|
export const useAlbumListCount = (args: QueryHookArgs<AlbumListQuery>) => {
|
||||||
const { options, query, serverId } = args;
|
const { options, query, serverId } = args;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import type { QueryHookArgs } from '/@/renderer/lib/react-query';
|
import type { QueryHookArgs } from '/@/renderer/lib/react-query';
|
||||||
import type { AlbumListQuery, AlbumListResponse } from '/@/shared/types/domain-types';
|
|
||||||
|
|
||||||
import { useInfiniteQuery, useQuery } from '@tanstack/react-query';
|
import { useInfiniteQuery, useQuery } from '@tanstack/react-query';
|
||||||
|
|
||||||
@@ -7,6 +6,7 @@ import { api } from '/@/renderer/api';
|
|||||||
import { controller } from '/@/renderer/api/controller';
|
import { controller } from '/@/renderer/api/controller';
|
||||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||||
import { getServerById } from '/@/renderer/store';
|
import { getServerById } from '/@/renderer/store';
|
||||||
|
import { AlbumListQuery, AlbumListResponse } from '/@/shared/types/domain/album-domain-types';
|
||||||
|
|
||||||
export const useAlbumList = (args: QueryHookArgs<AlbumListQuery>) => {
|
export const useAlbumList = (args: QueryHookArgs<AlbumListQuery>) => {
|
||||||
const { options, query, serverId } = args;
|
const { options, query, serverId } = args;
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import { AnimatedPage, LibraryHeaderBar } from '/@/renderer/features/shared';
|
|||||||
import { useFastAverageColor } from '/@/renderer/hooks';
|
import { useFastAverageColor } from '/@/renderer/hooks';
|
||||||
import { useCurrentServer, useGeneralSettings } from '/@/renderer/store';
|
import { useCurrentServer, useGeneralSettings } from '/@/renderer/store';
|
||||||
import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
|
import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
|
||||||
import { LibraryItem } from '/@/shared/types/domain-types';
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
|
|
||||||
const AlbumDetailRoute = () => {
|
const AlbumDetailRoute = () => {
|
||||||
const tableRef = useRef<AgGridReactType | null>(null);
|
const tableRef = useRef<AgGridReactType | null>(null);
|
||||||
|
|||||||
@@ -16,12 +16,9 @@ import { usePlayQueueAdd } from '/@/renderer/features/player';
|
|||||||
import { AnimatedPage } from '/@/renderer/features/shared';
|
import { AnimatedPage } from '/@/renderer/features/shared';
|
||||||
import { queryClient } from '/@/renderer/lib/react-query';
|
import { queryClient } from '/@/renderer/lib/react-query';
|
||||||
import { useCurrentServer, useListFilterByKey } from '/@/renderer/store';
|
import { useCurrentServer, useListFilterByKey } from '/@/renderer/store';
|
||||||
import {
|
import { AlbumListQuery } from '/@/shared/types/domain/album-domain-types';
|
||||||
AlbumListQuery,
|
import { GenreListSort } from '/@/shared/types/domain/genre-domain-types';
|
||||||
GenreListSort,
|
import { LibraryItem, ListSortOrder } from '/@/shared/types/domain/shared-domain-types';
|
||||||
LibraryItem,
|
|
||||||
SortOrder,
|
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
import { Play } from '/@/shared/types/types';
|
import { Play } from '/@/shared/types/types';
|
||||||
|
|
||||||
const AlbumListRoute = () => {
|
const AlbumListRoute = () => {
|
||||||
@@ -60,7 +57,7 @@ const AlbumListRoute = () => {
|
|||||||
},
|
},
|
||||||
query: {
|
query: {
|
||||||
sortBy: GenreListSort.NAME,
|
sortBy: GenreListSort.NAME,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: ListSortOrder.ASC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
serverId: server?.id,
|
serverId: server?.id,
|
||||||
|
|||||||
@@ -33,7 +33,8 @@ import { Icon } from '/@/shared/components/icon/icon';
|
|||||||
import { Spoiler } from '/@/shared/components/spoiler/spoiler';
|
import { Spoiler } from '/@/shared/components/spoiler/spoiler';
|
||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import { Text } from '/@/shared/components/text/text';
|
import { Text } from '/@/shared/components/text/text';
|
||||||
import { LibraryItem, SongDetailResponse } from '/@/shared/types/domain-types';
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
|
import { SongDetailResponse } from '/@/shared/types/domain/song-domain-types';
|
||||||
|
|
||||||
const DummyAlbumDetailRoute = () => {
|
const DummyAlbumDetailRoute = () => {
|
||||||
const cq = useContainerQuery();
|
const cq = useContainerQuery();
|
||||||
|
|||||||
@@ -35,15 +35,10 @@ import { Group } from '/@/shared/components/group/group';
|
|||||||
import { Spoiler } from '/@/shared/components/spoiler/spoiler';
|
import { Spoiler } from '/@/shared/components/spoiler/spoiler';
|
||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import { TextTitle } from '/@/shared/components/text-title/text-title';
|
import { TextTitle } from '/@/shared/components/text-title/text-title';
|
||||||
import {
|
import { Album, AlbumListSort } from '/@/shared/types/domain/album-domain-types';
|
||||||
Album,
|
import { QueueSong } from '/@/shared/types/domain/player-domain-types';
|
||||||
AlbumArtist,
|
import { ServerType } from '/@/shared/types/domain/server-domain-types';
|
||||||
AlbumListSort,
|
import { LibraryItem, ListSortOrder } from '/@/shared/types/domain/shared-domain-types';
|
||||||
LibraryItem,
|
|
||||||
QueueSong,
|
|
||||||
ServerType,
|
|
||||||
SortOrder,
|
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
import { CardRow, Play, TableColumn } from '/@/shared/types/types';
|
import { CardRow, Play, TableColumn } from '/@/shared/types/types';
|
||||||
|
|
||||||
interface AlbumArtistDetailContentProps {
|
interface AlbumArtistDetailContentProps {
|
||||||
@@ -106,7 +101,7 @@ export const AlbumArtistDetailContent = ({ background }: AlbumArtistDetailConten
|
|||||||
compilation: false,
|
compilation: false,
|
||||||
limit: 15,
|
limit: 15,
|
||||||
sortBy: AlbumListSort.RELEASE_DATE,
|
sortBy: AlbumListSort.RELEASE_DATE,
|
||||||
sortOrder: SortOrder.DESC,
|
sortOrder: ListSortOrder.DESC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
serverId: server?.id,
|
serverId: server?.id,
|
||||||
@@ -121,7 +116,7 @@ export const AlbumArtistDetailContent = ({ background }: AlbumArtistDetailConten
|
|||||||
compilation: true,
|
compilation: true,
|
||||||
limit: 15,
|
limit: 15,
|
||||||
sortBy: AlbumListSort.RELEASE_DATE,
|
sortBy: AlbumListSort.RELEASE_DATE,
|
||||||
sortOrder: SortOrder.DESC,
|
sortOrder: ListSortOrder.DESC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
serverId: server?.id,
|
serverId: server?.id,
|
||||||
|
|||||||
@@ -11,7 +11,8 @@ import { Group } from '/@/shared/components/group/group';
|
|||||||
import { Rating } from '/@/shared/components/rating/rating';
|
import { Rating } from '/@/shared/components/rating/rating';
|
||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import { Text } from '/@/shared/components/text/text';
|
import { Text } from '/@/shared/components/text/text';
|
||||||
import { LibraryItem, ServerType } from '/@/shared/types/domain-types';
|
import { ServerType } from '/@/shared/types/domain/server-domain-types';
|
||||||
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
|
|
||||||
interface AlbumArtistDetailHeaderProps {
|
interface AlbumArtistDetailHeaderProps {
|
||||||
background?: string;
|
background?: string;
|
||||||
|
|||||||
+3
-1
@@ -12,7 +12,9 @@ import { SONG_CONTEXT_MENU_ITEMS } from '/@/renderer/features/context-menu/conte
|
|||||||
import { usePlayQueueAdd } from '/@/renderer/features/player';
|
import { usePlayQueueAdd } from '/@/renderer/features/player';
|
||||||
import { useCurrentServer } from '/@/renderer/store';
|
import { useCurrentServer } from '/@/renderer/store';
|
||||||
import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
|
import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
|
||||||
import { LibraryItem, QueueSong, SongListQuery } from '/@/shared/types/domain-types';
|
import { QueueSong } from '/@/shared/types/domain/player-domain-types';
|
||||||
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
|
import { SongListQuery } from '/@/shared/types/domain/song-domain-types';
|
||||||
|
|
||||||
interface AlbumArtistSongListContentProps {
|
interface AlbumArtistSongListContentProps {
|
||||||
data: QueueSong[];
|
data: QueueSong[];
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ import { LibraryHeaderBar } from '/@/renderer/features/shared';
|
|||||||
import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
|
import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
|
||||||
import { Badge } from '/@/shared/components/badge/badge';
|
import { Badge } from '/@/shared/components/badge/badge';
|
||||||
import { SpinnerIcon } from '/@/shared/components/spinner/spinner';
|
import { SpinnerIcon } from '/@/shared/components/spinner/spinner';
|
||||||
import { QueueSong } from '/@/shared/types/domain-types';
|
import { QueueSong } from '/@/shared/types/domain/player-domain-types';
|
||||||
import { Play } from '/@/shared/types/types';
|
import { Play } from '/@/shared/types/types';
|
||||||
|
|
||||||
interface AlbumArtistDetailTopSongsListHeaderProps {
|
interface AlbumArtistDetailTopSongsListHeaderProps {
|
||||||
|
|||||||
@@ -17,12 +17,11 @@ import { useHandleFavorite } from '/@/renderer/features/shared/hooks/use-handle-
|
|||||||
import { AppRoute } from '/@/renderer/router/routes';
|
import { AppRoute } from '/@/renderer/router/routes';
|
||||||
import { useCurrentServer, useListStoreActions, useListStoreByKey } from '/@/renderer/store';
|
import { useCurrentServer, useListStoreActions, useListStoreByKey } from '/@/renderer/store';
|
||||||
import {
|
import {
|
||||||
AlbumArtist,
|
|
||||||
AlbumArtistListQuery,
|
AlbumArtistListQuery,
|
||||||
AlbumArtistListResponse,
|
AlbumArtistListResponse,
|
||||||
AlbumArtistListSort,
|
AlbumArtistListSort,
|
||||||
LibraryItem,
|
} from '/@/shared/types/domain/artist-domain-types';
|
||||||
} from '/@/shared/types/domain-types';
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
import { CardRow, ListDisplayType } from '/@/shared/types/types';
|
import { CardRow, ListDisplayType } from '/@/shared/types/types';
|
||||||
|
|
||||||
interface AlbumArtistListGridViewProps {
|
interface AlbumArtistListGridViewProps {
|
||||||
|
|||||||
@@ -34,91 +34,90 @@ import { Icon } from '/@/shared/components/icon/icon';
|
|||||||
import {
|
import {
|
||||||
AlbumArtistListQuery,
|
AlbumArtistListQuery,
|
||||||
AlbumArtistListSort,
|
AlbumArtistListSort,
|
||||||
LibraryItem,
|
} from '/@/shared/types/domain/artist-domain-types';
|
||||||
ServerType,
|
import { ServerType } from '/@/shared/types/domain/server-domain-types';
|
||||||
SortOrder,
|
import { LibraryItem, ListSortOrder } from '/@/shared/types/domain/shared-domain-types';
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
import { ListDisplayType } from '/@/shared/types/types';
|
import { ListDisplayType } from '/@/shared/types/types';
|
||||||
|
|
||||||
const FILTERS = {
|
const FILTERS = {
|
||||||
jellyfin: [
|
jellyfin: [
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.album', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.album', { postProcess: 'titleCase' }),
|
||||||
value: AlbumArtistListSort.ALBUM,
|
value: AlbumArtistListSort.ALBUM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.duration', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.duration', { postProcess: 'titleCase' }),
|
||||||
value: AlbumArtistListSort.DURATION,
|
value: AlbumArtistListSort.DURATION,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
||||||
value: AlbumArtistListSort.NAME,
|
value: AlbumArtistListSort.NAME,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.random', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.random', { postProcess: 'titleCase' }),
|
||||||
value: AlbumArtistListSort.RANDOM,
|
value: AlbumArtistListSort.RANDOM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.recentlyAdded', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.recentlyAdded', { postProcess: 'titleCase' }),
|
||||||
value: AlbumArtistListSort.RECENTLY_ADDED,
|
value: AlbumArtistListSort.RECENTLY_ADDED,
|
||||||
},
|
},
|
||||||
// { defaultOrder: SortOrder.DESC, name: 'Release Date', value: AlbumArtistListSort.RELEASE_DATE },
|
// { defaultOrder: ListSortOrder.DESC, name: 'Release Date', value: AlbumArtistListSort.RELEASE_DATE },
|
||||||
],
|
],
|
||||||
navidrome: [
|
navidrome: [
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.albumCount', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.albumCount', { postProcess: 'titleCase' }),
|
||||||
value: AlbumArtistListSort.ALBUM_COUNT,
|
value: AlbumArtistListSort.ALBUM_COUNT,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.isFavorited', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.isFavorited', { postProcess: 'titleCase' }),
|
||||||
value: AlbumArtistListSort.FAVORITED,
|
value: AlbumArtistListSort.FAVORITED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.mostPlayed', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.mostPlayed', { postProcess: 'titleCase' }),
|
||||||
value: AlbumArtistListSort.PLAY_COUNT,
|
value: AlbumArtistListSort.PLAY_COUNT,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
||||||
value: AlbumArtistListSort.NAME,
|
value: AlbumArtistListSort.NAME,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.rating', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.rating', { postProcess: 'titleCase' }),
|
||||||
value: AlbumArtistListSort.RATING,
|
value: AlbumArtistListSort.RATING,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.songCount', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.songCount', { postProcess: 'titleCase' }),
|
||||||
value: AlbumArtistListSort.SONG_COUNT,
|
value: AlbumArtistListSort.SONG_COUNT,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
subsonic: [
|
subsonic: [
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.albumCount', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.albumCount', { postProcess: 'titleCase' }),
|
||||||
value: AlbumArtistListSort.ALBUM_COUNT,
|
value: AlbumArtistListSort.ALBUM_COUNT,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.isFavorited', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.isFavorited', { postProcess: 'titleCase' }),
|
||||||
value: AlbumArtistListSort.FAVORITED,
|
value: AlbumArtistListSort.FAVORITED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
||||||
value: AlbumArtistListSort.NAME,
|
value: AlbumArtistListSort.NAME,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.rating', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.rating', { postProcess: 'titleCase' }),
|
||||||
value: AlbumArtistListSort.RATING,
|
value: AlbumArtistListSort.RATING,
|
||||||
},
|
},
|
||||||
@@ -270,7 +269,7 @@ export const AlbumArtistListHeaderFilters = ({
|
|||||||
const updatedFilters = setFilter({
|
const updatedFilters = setFilter({
|
||||||
data: {
|
data: {
|
||||||
sortBy: e.currentTarget.value as AlbumArtistListSort,
|
sortBy: e.currentTarget.value as AlbumArtistListSort,
|
||||||
sortOrder: sortOrder || SortOrder.ASC,
|
sortOrder: sortOrder || ListSortOrder.ASC,
|
||||||
},
|
},
|
||||||
itemType: LibraryItem.ALBUM_ARTIST,
|
itemType: LibraryItem.ALBUM_ARTIST,
|
||||||
key: pageKey,
|
key: pageKey,
|
||||||
@@ -306,7 +305,8 @@ export const AlbumArtistListHeaderFilters = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const handleToggleSortOrder = useCallback(() => {
|
const handleToggleSortOrder = useCallback(() => {
|
||||||
const newSortOrder = filter.sortOrder === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC;
|
const newSortOrder =
|
||||||
|
filter.sortOrder === ListSortOrder.ASC ? ListSortOrder.DESC : ListSortOrder.ASC;
|
||||||
const updatedFilters = setFilter({
|
const updatedFilters = setFilter({
|
||||||
data: { sortOrder: newSortOrder },
|
data: { sortOrder: newSortOrder },
|
||||||
itemType: LibraryItem.ALBUM_ARTIST,
|
itemType: LibraryItem.ALBUM_ARTIST,
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ import { AlbumArtistListFilter, useCurrentServer } from '/@/renderer/store';
|
|||||||
import { Flex } from '/@/shared/components/flex/flex';
|
import { Flex } from '/@/shared/components/flex/flex';
|
||||||
import { Group } from '/@/shared/components/group/group';
|
import { Group } from '/@/shared/components/group/group';
|
||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import { AlbumArtistListQuery, LibraryItem } from '/@/shared/types/domain-types';
|
import { AlbumArtistListQuery } from '/@/shared/types/domain/artist-domain-types';
|
||||||
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
|
|
||||||
interface AlbumArtistListHeaderProps {
|
interface AlbumArtistListHeaderProps {
|
||||||
gridRef: MutableRefObject<null | VirtualInfiniteGridRef>;
|
gridRef: MutableRefObject<null | VirtualInfiniteGridRef>;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { useVirtualTable } from '/@/renderer/components/virtual-table/hooks/use-
|
|||||||
import { useListContext } from '/@/renderer/context/list-context';
|
import { useListContext } from '/@/renderer/context/list-context';
|
||||||
import { ARTIST_CONTEXT_MENU_ITEMS } from '/@/renderer/features/context-menu/context-menu-items';
|
import { ARTIST_CONTEXT_MENU_ITEMS } from '/@/renderer/features/context-menu/context-menu-items';
|
||||||
import { useCurrentServer } from '/@/renderer/store';
|
import { useCurrentServer } from '/@/renderer/store';
|
||||||
import { LibraryItem } from '/@/shared/types/domain-types';
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
|
|
||||||
interface AlbumArtistListTableViewProps {
|
interface AlbumArtistListTableViewProps {
|
||||||
itemCount?: number;
|
itemCount?: number;
|
||||||
|
|||||||
@@ -18,12 +18,11 @@ import { AppRoute } from '/@/renderer/router/routes';
|
|||||||
import { useCurrentServer, useListStoreActions } from '/@/renderer/store';
|
import { useCurrentServer, useListStoreActions } from '/@/renderer/store';
|
||||||
import { useListStoreByKey } from '/@/renderer/store/list.store';
|
import { useListStoreByKey } from '/@/renderer/store/list.store';
|
||||||
import {
|
import {
|
||||||
AlbumArtist,
|
|
||||||
ArtistListQuery,
|
ArtistListQuery,
|
||||||
ArtistListResponse,
|
ArtistListResponse,
|
||||||
ArtistListSort,
|
ArtistListSort,
|
||||||
LibraryItem,
|
} from '/@/shared/types/domain/artist-domain-types';
|
||||||
} from '/@/shared/types/domain-types';
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
import { CardRow, ListDisplayType } from '/@/shared/types/types';
|
import { CardRow, ListDisplayType } from '/@/shared/types/types';
|
||||||
|
|
||||||
interface ArtistListGridViewProps {
|
interface ArtistListGridViewProps {
|
||||||
|
|||||||
@@ -33,93 +33,89 @@ import { Flex } from '/@/shared/components/flex/flex';
|
|||||||
import { Group } from '/@/shared/components/group/group';
|
import { Group } from '/@/shared/components/group/group';
|
||||||
import { Icon } from '/@/shared/components/icon/icon';
|
import { Icon } from '/@/shared/components/icon/icon';
|
||||||
import { Select } from '/@/shared/components/select/select';
|
import { Select } from '/@/shared/components/select/select';
|
||||||
import {
|
import { ArtistListQuery, ArtistListSort } from '/@/shared/types/domain/artist-domain-types';
|
||||||
ArtistListQuery,
|
import { ServerType } from '/@/shared/types/domain/server-domain-types';
|
||||||
ArtistListSort,
|
import { LibraryItem, ListSortOrder } from '/@/shared/types/domain/shared-domain-types';
|
||||||
LibraryItem,
|
|
||||||
ServerType,
|
|
||||||
SortOrder,
|
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
import { ListDisplayType } from '/@/shared/types/types';
|
import { ListDisplayType } from '/@/shared/types/types';
|
||||||
|
|
||||||
const FILTERS = {
|
const FILTERS = {
|
||||||
jellyfin: [
|
jellyfin: [
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.album', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.album', { postProcess: 'titleCase' }),
|
||||||
value: ArtistListSort.ALBUM,
|
value: ArtistListSort.ALBUM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.duration', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.duration', { postProcess: 'titleCase' }),
|
||||||
value: ArtistListSort.DURATION,
|
value: ArtistListSort.DURATION,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
||||||
value: ArtistListSort.NAME,
|
value: ArtistListSort.NAME,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.random', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.random', { postProcess: 'titleCase' }),
|
||||||
value: ArtistListSort.RANDOM,
|
value: ArtistListSort.RANDOM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.recentlyAdded', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.recentlyAdded', { postProcess: 'titleCase' }),
|
||||||
value: ArtistListSort.RECENTLY_ADDED,
|
value: ArtistListSort.RECENTLY_ADDED,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
navidrome: [
|
navidrome: [
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.albumCount', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.albumCount', { postProcess: 'titleCase' }),
|
||||||
value: ArtistListSort.ALBUM_COUNT,
|
value: ArtistListSort.ALBUM_COUNT,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.isFavorited', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.isFavorited', { postProcess: 'titleCase' }),
|
||||||
value: ArtistListSort.FAVORITED,
|
value: ArtistListSort.FAVORITED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.mostPlayed', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.mostPlayed', { postProcess: 'titleCase' }),
|
||||||
value: ArtistListSort.PLAY_COUNT,
|
value: ArtistListSort.PLAY_COUNT,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
||||||
value: ArtistListSort.NAME,
|
value: ArtistListSort.NAME,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.rating', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.rating', { postProcess: 'titleCase' }),
|
||||||
value: ArtistListSort.RATING,
|
value: ArtistListSort.RATING,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.songCount', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.songCount', { postProcess: 'titleCase' }),
|
||||||
value: ArtistListSort.SONG_COUNT,
|
value: ArtistListSort.SONG_COUNT,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
subsonic: [
|
subsonic: [
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.albumCount', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.albumCount', { postProcess: 'titleCase' }),
|
||||||
value: ArtistListSort.ALBUM_COUNT,
|
value: ArtistListSort.ALBUM_COUNT,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.isFavorited', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.isFavorited', { postProcess: 'titleCase' }),
|
||||||
value: ArtistListSort.FAVORITED,
|
value: ArtistListSort.FAVORITED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
||||||
value: ArtistListSort.NAME,
|
value: ArtistListSort.NAME,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.rating', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.rating', { postProcess: 'titleCase' }),
|
||||||
value: ArtistListSort.RATING,
|
value: ArtistListSort.RATING,
|
||||||
},
|
},
|
||||||
@@ -276,7 +272,7 @@ export const ArtistListHeaderFilters = ({ gridRef, tableRef }: ArtistListHeaderF
|
|||||||
const updatedFilters = setFilter({
|
const updatedFilters = setFilter({
|
||||||
data: {
|
data: {
|
||||||
sortBy: e.currentTarget.value as ArtistListSort,
|
sortBy: e.currentTarget.value as ArtistListSort,
|
||||||
sortOrder: sortOrder || SortOrder.ASC,
|
sortOrder: sortOrder || ListSortOrder.ASC,
|
||||||
},
|
},
|
||||||
itemType: LibraryItem.ARTIST,
|
itemType: LibraryItem.ARTIST,
|
||||||
key: pageKey,
|
key: pageKey,
|
||||||
@@ -312,7 +308,8 @@ export const ArtistListHeaderFilters = ({ gridRef, tableRef }: ArtistListHeaderF
|
|||||||
);
|
);
|
||||||
|
|
||||||
const handleToggleSortOrder = useCallback(() => {
|
const handleToggleSortOrder = useCallback(() => {
|
||||||
const newSortOrder = filter.sortOrder === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC;
|
const newSortOrder =
|
||||||
|
filter.sortOrder === ListSortOrder.ASC ? ListSortOrder.DESC : ListSortOrder.ASC;
|
||||||
const updatedFilters = setFilter({
|
const updatedFilters = setFilter({
|
||||||
data: { sortOrder: newSortOrder },
|
data: { sortOrder: newSortOrder },
|
||||||
itemType: LibraryItem.ARTIST,
|
itemType: LibraryItem.ARTIST,
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ import { ArtistListFilter, useCurrentServer } from '/@/renderer/store';
|
|||||||
import { Flex } from '/@/shared/components/flex/flex';
|
import { Flex } from '/@/shared/components/flex/flex';
|
||||||
import { Group } from '/@/shared/components/group/group';
|
import { Group } from '/@/shared/components/group/group';
|
||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import { ArtistListQuery, LibraryItem } from '/@/shared/types/domain-types';
|
import { ArtistListQuery } from '/@/shared/types/domain/artist-domain-types';
|
||||||
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
|
|
||||||
interface ArtistListHeaderProps {
|
interface ArtistListHeaderProps {
|
||||||
gridRef: MutableRefObject<null | VirtualInfiniteGridRef>;
|
gridRef: MutableRefObject<null | VirtualInfiniteGridRef>;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { useVirtualTable } from '/@/renderer/components/virtual-table/hooks/use-
|
|||||||
import { useListContext } from '/@/renderer/context/list-context';
|
import { useListContext } from '/@/renderer/context/list-context';
|
||||||
import { ARTIST_CONTEXT_MENU_ITEMS } from '/@/renderer/features/context-menu/context-menu-items';
|
import { ARTIST_CONTEXT_MENU_ITEMS } from '/@/renderer/features/context-menu/context-menu-items';
|
||||||
import { useCurrentServer } from '/@/renderer/store';
|
import { useCurrentServer } from '/@/renderer/store';
|
||||||
import { LibraryItem } from '/@/shared/types/domain-types';
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
|
|
||||||
interface ArtistListTableViewProps {
|
interface ArtistListTableViewProps {
|
||||||
itemCount?: number;
|
itemCount?: number;
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import type { AlbumArtistDetailQuery } from '/@/shared/types/domain-types';
|
|
||||||
|
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { api } from '/@/renderer/api';
|
import { api } from '/@/renderer/api';
|
||||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||||
import { QueryHookArgs } from '/@/renderer/lib/react-query';
|
import { QueryHookArgs } from '/@/renderer/lib/react-query';
|
||||||
import { getServerById } from '/@/renderer/store';
|
import { getServerById } from '/@/renderer/store';
|
||||||
|
import { AlbumArtistDetailQuery } from '/@/shared/types/domain/artist-domain-types';
|
||||||
|
|
||||||
export const useAlbumArtistDetail = (args: QueryHookArgs<AlbumArtistDetailQuery>) => {
|
export const useAlbumArtistDetail = (args: QueryHookArgs<AlbumArtistDetailQuery>) => {
|
||||||
const { options, query, serverId } = args || {};
|
const { options, query, serverId } = args || {};
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { api } from '/@/renderer/api';
|
|||||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||||
import { QueryHookArgs } from '/@/renderer/lib/react-query';
|
import { QueryHookArgs } from '/@/renderer/lib/react-query';
|
||||||
import { getServerById } from '/@/renderer/store';
|
import { getServerById } from '/@/renderer/store';
|
||||||
import { AlbumArtistListQuery } from '/@/shared/types/domain-types';
|
import { AlbumArtistListQuery } from '/@/shared/types/domain/artist-domain-types';
|
||||||
|
|
||||||
export const useAlbumArtistListCount = (args: QueryHookArgs<AlbumArtistListQuery>) => {
|
export const useAlbumArtistListCount = (args: QueryHookArgs<AlbumArtistListQuery>) => {
|
||||||
const { options, query, serverId } = args;
|
const { options, query, serverId } = args;
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import type { AlbumArtistListQuery } from '/@/shared/types/domain-types';
|
|
||||||
|
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { api } from '/@/renderer/api';
|
import { api } from '/@/renderer/api';
|
||||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||||
import { QueryHookArgs } from '/@/renderer/lib/react-query';
|
import { QueryHookArgs } from '/@/renderer/lib/react-query';
|
||||||
import { getServerById } from '/@/renderer/store';
|
import { getServerById } from '/@/renderer/store';
|
||||||
|
import { AlbumArtistListQuery } from '/@/shared/types/domain/artist-domain-types';
|
||||||
|
|
||||||
export const useAlbumArtistList = (args: QueryHookArgs<AlbumArtistListQuery>) => {
|
export const useAlbumArtistList = (args: QueryHookArgs<AlbumArtistListQuery>) => {
|
||||||
const { options, query, serverId } = args || {};
|
const { options, query, serverId } = args || {};
|
||||||
|
|||||||
@@ -1,11 +1,10 @@
|
|||||||
import type { AlbumArtistDetailQuery } from '/@/shared/types/domain-types';
|
|
||||||
|
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { api } from '/@/renderer/api';
|
import { api } from '/@/renderer/api';
|
||||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||||
import { QueryHookArgs } from '/@/renderer/lib/react-query';
|
import { QueryHookArgs } from '/@/renderer/lib/react-query';
|
||||||
import { getServerById } from '/@/renderer/store';
|
import { getServerById } from '/@/renderer/store';
|
||||||
|
import { AlbumArtistDetailQuery } from '/@/shared/types/domain/artist-domain-types';
|
||||||
|
|
||||||
export const useAlbumArtistInfo = (args: QueryHookArgs<AlbumArtistDetailQuery>) => {
|
export const useAlbumArtistInfo = (args: QueryHookArgs<AlbumArtistDetailQuery>) => {
|
||||||
const { options, query, serverId } = args || {};
|
const { options, query, serverId } = args || {};
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import { api } from '/@/renderer/api';
|
|||||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||||
import { QueryHookArgs } from '/@/renderer/lib/react-query';
|
import { QueryHookArgs } from '/@/renderer/lib/react-query';
|
||||||
import { getServerById } from '/@/renderer/store';
|
import { getServerById } from '/@/renderer/store';
|
||||||
import { ArtistListQuery } from '/@/shared/types/domain-types';
|
import { ArtistListQuery } from '/@/shared/types/domain/artist-domain-types';
|
||||||
|
|
||||||
export const useArtistListCount = (args: QueryHookArgs<ArtistListQuery>) => {
|
export const useArtistListCount = (args: QueryHookArgs<ArtistListQuery>) => {
|
||||||
const { options, query, serverId } = args;
|
const { options, query, serverId } = args;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import type { QueryHookArgs } from '/@/renderer/lib/react-query';
|
import type { QueryHookArgs } from '/@/renderer/lib/react-query';
|
||||||
import type { TopSongListQuery } from '/@/shared/types/domain-types';
|
|
||||||
|
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { api } from '/@/renderer/api';
|
import { api } from '/@/renderer/api';
|
||||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||||
import { getServerById } from '/@/renderer/store';
|
import { getServerById } from '/@/renderer/store';
|
||||||
|
import { TopSongListQuery } from '/@/shared/types/domain/song-domain-types';
|
||||||
|
|
||||||
export const useTopSongsList = (args: QueryHookArgs<TopSongListQuery>) => {
|
export const useTopSongsList = (args: QueryHookArgs<TopSongListQuery>) => {
|
||||||
const { options, query, serverId } = args || {};
|
const { options, query, serverId } = args || {};
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { AnimatedPage, LibraryHeaderBar } from '/@/renderer/features/shared';
|
|||||||
import { useFastAverageColor } from '/@/renderer/hooks';
|
import { useFastAverageColor } from '/@/renderer/hooks';
|
||||||
import { useCurrentServer } from '/@/renderer/store';
|
import { useCurrentServer } from '/@/renderer/store';
|
||||||
import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
|
import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
|
||||||
import { LibraryItem } from '/@/shared/types/domain-types';
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
|
|
||||||
const AlbumArtistDetailRoute = () => {
|
const AlbumArtistDetailRoute = () => {
|
||||||
const scrollAreaRef = useRef<HTMLDivElement>(null);
|
const scrollAreaRef = useRef<HTMLDivElement>(null);
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { useAlbumArtistDetail } from '/@/renderer/features/artists/queries/album
|
|||||||
import { useTopSongsList } from '/@/renderer/features/artists/queries/top-songs-list-query';
|
import { useTopSongsList } from '/@/renderer/features/artists/queries/top-songs-list-query';
|
||||||
import { AnimatedPage } from '/@/renderer/features/shared';
|
import { AnimatedPage } from '/@/renderer/features/shared';
|
||||||
import { useCurrentServer } from '/@/renderer/store/auth.store';
|
import { useCurrentServer } from '/@/renderer/store/auth.store';
|
||||||
import { LibraryItem } from '/@/shared/types/domain-types';
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
|
|
||||||
const AlbumArtistDetailTopSongsListRoute = () => {
|
const AlbumArtistDetailTopSongsListRoute = () => {
|
||||||
const tableRef = useRef<AgGridReactType | null>(null);
|
const tableRef = useRef<AgGridReactType | null>(null);
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ import { useAlbumArtistListCount } from '/@/renderer/features/artists/queries/al
|
|||||||
import { AnimatedPage } from '/@/renderer/features/shared';
|
import { AnimatedPage } from '/@/renderer/features/shared';
|
||||||
import { useCurrentServer } from '/@/renderer/store/auth.store';
|
import { useCurrentServer } from '/@/renderer/store/auth.store';
|
||||||
import { useListFilterByKey } from '/@/renderer/store/list.store';
|
import { useListFilterByKey } from '/@/renderer/store/list.store';
|
||||||
import { AlbumArtistListQuery, LibraryItem } from '/@/shared/types/domain-types';
|
import { AlbumArtistListQuery } from '/@/shared/types/domain/artist-domain-types';
|
||||||
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
|
|
||||||
const AlbumArtistListRoute = () => {
|
const AlbumArtistListRoute = () => {
|
||||||
const gridRef = useRef<null | VirtualInfiniteGridRef>(null);
|
const gridRef = useRef<null | VirtualInfiniteGridRef>(null);
|
||||||
|
|||||||
@@ -10,7 +10,8 @@ import { useArtistListCount } from '/@/renderer/features/artists/queries/artist-
|
|||||||
import { AnimatedPage } from '/@/renderer/features/shared';
|
import { AnimatedPage } from '/@/renderer/features/shared';
|
||||||
import { useCurrentServer } from '/@/renderer/store/auth.store';
|
import { useCurrentServer } from '/@/renderer/store/auth.store';
|
||||||
import { useListFilterByKey } from '/@/renderer/store/list.store';
|
import { useListFilterByKey } from '/@/renderer/store/list.store';
|
||||||
import { ArtistListQuery, LibraryItem } from '/@/shared/types/domain-types';
|
import { ArtistListQuery } from '/@/shared/types/domain/artist-domain-types';
|
||||||
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
|
|
||||||
const ArtistListRoute = () => {
|
const ArtistListRoute = () => {
|
||||||
const gridRef = useRef<null | VirtualInfiniteGridRef>(null);
|
const gridRef = useRef<null | VirtualInfiniteGridRef>(null);
|
||||||
|
|||||||
@@ -57,13 +57,12 @@ import { Rating } from '/@/shared/components/rating/rating';
|
|||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import { Text } from '/@/shared/components/text/text';
|
import { Text } from '/@/shared/components/text/text';
|
||||||
import { toast } from '/@/shared/components/toast/toast';
|
import { toast } from '/@/shared/components/toast/toast';
|
||||||
|
import { ServerFeature, ServerType } from '/@/shared/types/domain/server-domain-types';
|
||||||
import {
|
import {
|
||||||
AnyLibraryItem,
|
AnyLibraryItem,
|
||||||
AnyLibraryItems,
|
AnyLibraryItems,
|
||||||
LibraryItem,
|
LibraryItem,
|
||||||
ServerType,
|
} from '/@/shared/types/domain/shared-domain-types';
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
import { ServerFeature } from '/@/shared/types/features-types';
|
|
||||||
import { Play, PlaybackType } from '/@/shared/types/types';
|
import { Play, PlaybackType } from '/@/shared/types/types';
|
||||||
|
|
||||||
type ContextMenuContextProps = {
|
type ContextMenuContextProps = {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import { GridOptions, RowNode } from '@ag-grid-community/core';
|
import { GridOptions, RowNode } from '@ag-grid-community/core';
|
||||||
|
|
||||||
import { LibraryItem } from '/@/shared/types/domain-types';
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
import { createUseExternalEvents } from '/@/shared/utils/create-use-external-events';
|
import { createUseExternalEvents } from '/@/shared/utils/create-use-external-events';
|
||||||
|
|
||||||
export type ContextMenuEvents = {
|
export type ContextMenuEvents = {
|
||||||
|
|||||||
@@ -2,14 +2,11 @@ import { CellContextMenuEvent, GridApi } from '@ag-grid-community/core';
|
|||||||
import sortBy from 'lodash/sortBy';
|
import sortBy from 'lodash/sortBy';
|
||||||
|
|
||||||
import { openContextMenu, SetContextMenuItems } from '/@/renderer/features/context-menu/events';
|
import { openContextMenu, SetContextMenuItems } from '/@/renderer/features/context-menu/events';
|
||||||
import {
|
import { Album } from '/@/shared/types/domain/album-domain-types';
|
||||||
Album,
|
import { Artist } from '/@/shared/types/domain/artist-domain-types';
|
||||||
AlbumArtist,
|
import { QueueSong } from '/@/shared/types/domain/player-domain-types';
|
||||||
Artist,
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
LibraryItem,
|
import { Song } from '/@/shared/types/domain/song-domain-types';
|
||||||
QueueSong,
|
|
||||||
Song,
|
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
|
|
||||||
export const useHandleTableContextMenu = (
|
export const useHandleTableContextMenu = (
|
||||||
itemType: LibraryItem,
|
itemType: LibraryItem,
|
||||||
|
|||||||
@@ -11,8 +11,9 @@ import {
|
|||||||
useGeneralSettings,
|
useGeneralSettings,
|
||||||
usePlayerStore,
|
usePlayerStore,
|
||||||
} from '/@/renderer/store';
|
} from '/@/renderer/store';
|
||||||
import { QueueSong, ServerType } from '/@/shared/types/domain-types';
|
import { QueueSong } from '/@/shared/types/domain/player-domain-types';
|
||||||
import { PlayerStatus } from '/@/shared/types/types';
|
import { ServerType } from '/@/shared/types/domain/server-domain-types';
|
||||||
|
import { PlayerStatus, PlayerStatus } from '/@/shared/types/types';
|
||||||
|
|
||||||
const discordRpc = isElectron() ? window.api.discordRpc : null;
|
const discordRpc = isElectron() ? window.api.discordRpc : null;
|
||||||
|
|
||||||
|
|||||||
@@ -15,13 +15,13 @@ import { useListContext } from '/@/renderer/context/list-context';
|
|||||||
import { usePlayQueueAdd } from '/@/renderer/features/player';
|
import { usePlayQueueAdd } from '/@/renderer/features/player';
|
||||||
import { useGenreRoute } from '/@/renderer/hooks/use-genre-route';
|
import { useGenreRoute } from '/@/renderer/hooks/use-genre-route';
|
||||||
import { useCurrentServer, useListStoreActions, useListStoreByKey } from '/@/renderer/store';
|
import { useCurrentServer, useListStoreActions, useListStoreByKey } from '/@/renderer/store';
|
||||||
|
import { Album } from '/@/shared/types/domain/album-domain-types';
|
||||||
import {
|
import {
|
||||||
Album,
|
|
||||||
Genre,
|
Genre,
|
||||||
GenreListQuery,
|
GenreListQuery,
|
||||||
GenreListResponse,
|
GenreListResponse,
|
||||||
LibraryItem,
|
} from '/@/shared/types/domain/genre-domain-types';
|
||||||
} from '/@/shared/types/domain-types';
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
import { CardRow, ListDisplayType } from '/@/shared/types/types';
|
import { CardRow, ListDisplayType } from '/@/shared/types/types';
|
||||||
|
|
||||||
export const GenreListGridView = ({ gridRef, itemCount }: any) => {
|
export const GenreListGridView = ({ gridRef, itemCount }: any) => {
|
||||||
|
|||||||
@@ -33,33 +33,29 @@ import { DropdownMenu } from '/@/shared/components/dropdown-menu/dropdown-menu';
|
|||||||
import { Flex } from '/@/shared/components/flex/flex';
|
import { Flex } from '/@/shared/components/flex/flex';
|
||||||
import { Group } from '/@/shared/components/group/group';
|
import { Group } from '/@/shared/components/group/group';
|
||||||
import { Icon } from '/@/shared/components/icon/icon';
|
import { Icon } from '/@/shared/components/icon/icon';
|
||||||
import {
|
import { GenreListQuery, GenreListSort } from '/@/shared/types/domain/genre-domain-types';
|
||||||
GenreListQuery,
|
import { ServerType } from '/@/shared/types/domain/server-domain-types';
|
||||||
GenreListSort,
|
import { LibraryItem, ListSortOrder } from '/@/shared/types/domain/shared-domain-types';
|
||||||
LibraryItem,
|
|
||||||
ServerType,
|
|
||||||
SortOrder,
|
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
import { ListDisplayType } from '/@/shared/types/types';
|
import { ListDisplayType } from '/@/shared/types/types';
|
||||||
|
|
||||||
const FILTERS = {
|
const FILTERS = {
|
||||||
jellyfin: [
|
jellyfin: [
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
||||||
value: GenreListSort.NAME,
|
value: GenreListSort.NAME,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
navidrome: [
|
navidrome: [
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
||||||
value: GenreListSort.NAME,
|
value: GenreListSort.NAME,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
subsonic: [
|
subsonic: [
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
||||||
value: GenreListSort.NAME,
|
value: GenreListSort.NAME,
|
||||||
},
|
},
|
||||||
@@ -137,7 +133,7 @@ export const GenreListHeaderFilters = ({
|
|||||||
customFilters,
|
customFilters,
|
||||||
data: {
|
data: {
|
||||||
sortBy: e.currentTarget.value as GenreListSort,
|
sortBy: e.currentTarget.value as GenreListSort,
|
||||||
sortOrder: sortOrder || SortOrder.ASC,
|
sortOrder: sortOrder || ListSortOrder.ASC,
|
||||||
},
|
},
|
||||||
itemType: LibraryItem.GENRE,
|
itemType: LibraryItem.GENRE,
|
||||||
key: pageKey,
|
key: pageKey,
|
||||||
@@ -175,7 +171,8 @@ export const GenreListHeaderFilters = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const handleToggleSortOrder = useCallback(() => {
|
const handleToggleSortOrder = useCallback(() => {
|
||||||
const newSortOrder = filter.sortOrder === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC;
|
const newSortOrder =
|
||||||
|
filter.sortOrder === ListSortOrder.ASC ? ListSortOrder.DESC : ListSortOrder.ASC;
|
||||||
const updatedFilters = setFilter({
|
const updatedFilters = setFilter({
|
||||||
customFilters,
|
customFilters,
|
||||||
data: { sortOrder: newSortOrder },
|
data: { sortOrder: newSortOrder },
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ import { GenreListFilter, useCurrentServer } from '/@/renderer/store';
|
|||||||
import { Flex } from '/@/shared/components/flex/flex';
|
import { Flex } from '/@/shared/components/flex/flex';
|
||||||
import { Group } from '/@/shared/components/group/group';
|
import { Group } from '/@/shared/components/group/group';
|
||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import { GenreListQuery, LibraryItem } from '/@/shared/types/domain-types';
|
import { GenreListQuery } from '/@/shared/types/domain/genre-domain-types';
|
||||||
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
|
|
||||||
interface GenreListHeaderProps {
|
interface GenreListHeaderProps {
|
||||||
gridRef: MutableRefObject<null | VirtualInfiniteGridRef>;
|
gridRef: MutableRefObject<null | VirtualInfiniteGridRef>;
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ import { useListContext } from '/@/renderer/context/list-context';
|
|||||||
import { GENRE_CONTEXT_MENU_ITEMS } from '/@/renderer/features/context-menu/context-menu-items';
|
import { GENRE_CONTEXT_MENU_ITEMS } from '/@/renderer/features/context-menu/context-menu-items';
|
||||||
import { useGenreRoute } from '/@/renderer/hooks/use-genre-route';
|
import { useGenreRoute } from '/@/renderer/hooks/use-genre-route';
|
||||||
import { useCurrentServer } from '/@/renderer/store';
|
import { useCurrentServer } from '/@/renderer/store';
|
||||||
import { LibraryItem } from '/@/shared/types/domain-types';
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
|
|
||||||
interface GenreListTableViewProps {
|
interface GenreListTableViewProps {
|
||||||
itemCount?: number;
|
itemCount?: number;
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
import type { QueryHookArgs } from '/@/renderer/lib/react-query';
|
import type { QueryHookArgs } from '/@/renderer/lib/react-query';
|
||||||
import type { GenreListQuery } from '/@/shared/types/domain-types';
|
|
||||||
|
|
||||||
import { useQuery } from '@tanstack/react-query';
|
import { useQuery } from '@tanstack/react-query';
|
||||||
|
|
||||||
import { api } from '/@/renderer/api';
|
import { api } from '/@/renderer/api';
|
||||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||||
import { getServerById } from '/@/renderer/store';
|
import { getServerById } from '/@/renderer/store';
|
||||||
|
import { GenreListQuery } from '/@/shared/types/domain/genre-domain-types';
|
||||||
|
|
||||||
export const useGenreList = (args: QueryHookArgs<GenreListQuery>) => {
|
export const useGenreList = (args: QueryHookArgs<GenreListQuery>) => {
|
||||||
const { options, query, serverId } = args || {};
|
const { options, query, serverId } = args || {};
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ import { useGenreList } from '/@/renderer/features/genres/queries/genre-list-que
|
|||||||
import { AnimatedPage } from '/@/renderer/features/shared';
|
import { AnimatedPage } from '/@/renderer/features/shared';
|
||||||
import { useCurrentServer } from '/@/renderer/store';
|
import { useCurrentServer } from '/@/renderer/store';
|
||||||
import { useListStoreByKey } from '/@/renderer/store/list.store';
|
import { useListStoreByKey } from '/@/renderer/store/list.store';
|
||||||
import { GenreListQuery } from '/@/shared/types/domain-types';
|
import { GenreListQuery } from '/@/shared/types/domain/genre-domain-types';
|
||||||
|
|
||||||
const GenreListRoute = () => {
|
const GenreListRoute = () => {
|
||||||
const gridRef = useRef<null | VirtualInfiniteGridRef>(null);
|
const gridRef = useRef<null | VirtualInfiniteGridRef>(null);
|
||||||
|
|||||||
@@ -4,7 +4,8 @@ import { api } from '/@/renderer/api';
|
|||||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||||
import { QueryHookArgs } from '/@/renderer/lib/react-query';
|
import { QueryHookArgs } from '/@/renderer/lib/react-query';
|
||||||
import { getServerById } from '/@/renderer/store';
|
import { getServerById } from '/@/renderer/store';
|
||||||
import { AlbumListQuery, AlbumListSort, SortOrder } from '/@/shared/types/domain-types';
|
import { AlbumListQuery, AlbumListSort } from '/@/shared/types/domain/album-domain-types';
|
||||||
|
import { ListSortOrder } from '/@/shared/types/domain/shared-domain-types';
|
||||||
|
|
||||||
export const useRecentlyPlayed = (args: QueryHookArgs<Partial<AlbumListQuery>>) => {
|
export const useRecentlyPlayed = (args: QueryHookArgs<Partial<AlbumListQuery>>) => {
|
||||||
const { options, query, serverId } = args;
|
const { options, query, serverId } = args;
|
||||||
@@ -13,7 +14,7 @@ export const useRecentlyPlayed = (args: QueryHookArgs<Partial<AlbumListQuery>>)
|
|||||||
const requestQuery: AlbumListQuery = {
|
const requestQuery: AlbumListQuery = {
|
||||||
limit: 5,
|
limit: 5,
|
||||||
sortBy: AlbumListSort.RECENTLY_PLAYED,
|
sortBy: AlbumListSort.RECENTLY_PLAYED,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: ListSortOrder.ASC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
...query,
|
...query,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -23,13 +23,10 @@ import { Icon } from '/@/shared/components/icon/icon';
|
|||||||
import { Spinner } from '/@/shared/components/spinner/spinner';
|
import { Spinner } from '/@/shared/components/spinner/spinner';
|
||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import { TextTitle } from '/@/shared/components/text-title/text-title';
|
import { TextTitle } from '/@/shared/components/text-title/text-title';
|
||||||
import {
|
import { AlbumListSort } from '/@/shared/types/domain/album-domain-types';
|
||||||
AlbumListSort,
|
import { ServerType } from '/@/shared/types/domain/server-domain-types';
|
||||||
LibraryItem,
|
import { LibraryItem, ListSortOrder } from '/@/shared/types/domain/shared-domain-types';
|
||||||
ServerType,
|
import { SongListSort } from '/@/shared/types/domain/song-domain-types';
|
||||||
SongListSort,
|
|
||||||
SortOrder,
|
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
import { Platform } from '/@/shared/types/types';
|
import { Platform } from '/@/shared/types/types';
|
||||||
|
|
||||||
const HomeRoute = () => {
|
const HomeRoute = () => {
|
||||||
@@ -50,7 +47,7 @@ const HomeRoute = () => {
|
|||||||
query: {
|
query: {
|
||||||
limit: 20,
|
limit: 20,
|
||||||
sortBy: AlbumListSort.RANDOM,
|
sortBy: AlbumListSort.RANDOM,
|
||||||
sortOrder: SortOrder.DESC,
|
sortOrder: ListSortOrder.DESC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
serverId: server?.id,
|
serverId: server?.id,
|
||||||
@@ -67,7 +64,7 @@ const HomeRoute = () => {
|
|||||||
query: {
|
query: {
|
||||||
limit: itemsPerPage,
|
limit: itemsPerPage,
|
||||||
sortBy: AlbumListSort.RANDOM,
|
sortBy: AlbumListSort.RANDOM,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: ListSortOrder.ASC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
serverId: server?.id,
|
serverId: server?.id,
|
||||||
@@ -80,7 +77,7 @@ const HomeRoute = () => {
|
|||||||
query: {
|
query: {
|
||||||
limit: itemsPerPage,
|
limit: itemsPerPage,
|
||||||
sortBy: AlbumListSort.RECENTLY_PLAYED,
|
sortBy: AlbumListSort.RECENTLY_PLAYED,
|
||||||
sortOrder: SortOrder.DESC,
|
sortOrder: ListSortOrder.DESC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
serverId: server?.id,
|
serverId: server?.id,
|
||||||
@@ -93,7 +90,7 @@ const HomeRoute = () => {
|
|||||||
query: {
|
query: {
|
||||||
limit: itemsPerPage,
|
limit: itemsPerPage,
|
||||||
sortBy: AlbumListSort.RECENTLY_ADDED,
|
sortBy: AlbumListSort.RECENTLY_ADDED,
|
||||||
sortOrder: SortOrder.DESC,
|
sortOrder: ListSortOrder.DESC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
serverId: server?.id,
|
serverId: server?.id,
|
||||||
@@ -107,7 +104,7 @@ const HomeRoute = () => {
|
|||||||
query: {
|
query: {
|
||||||
limit: itemsPerPage,
|
limit: itemsPerPage,
|
||||||
sortBy: AlbumListSort.PLAY_COUNT,
|
sortBy: AlbumListSort.PLAY_COUNT,
|
||||||
sortOrder: SortOrder.DESC,
|
sortOrder: ListSortOrder.DESC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
serverId: server?.id,
|
serverId: server?.id,
|
||||||
@@ -122,7 +119,7 @@ const HomeRoute = () => {
|
|||||||
query: {
|
query: {
|
||||||
limit: itemsPerPage,
|
limit: itemsPerPage,
|
||||||
sortBy: SongListSort.PLAY_COUNT,
|
sortBy: SongListSort.PLAY_COUNT,
|
||||||
sortOrder: SortOrder.DESC,
|
sortOrder: ListSortOrder.DESC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
serverId: server?.id,
|
serverId: server?.id,
|
||||||
@@ -156,14 +153,14 @@ const HomeRoute = () => {
|
|||||||
server?.type === ServerType.JELLYFIN
|
server?.type === ServerType.JELLYFIN
|
||||||
? SongListSort.PLAY_COUNT
|
? SongListSort.PLAY_COUNT
|
||||||
: AlbumListSort.PLAY_COUNT,
|
: AlbumListSort.PLAY_COUNT,
|
||||||
sortOrder: SortOrder.DESC,
|
sortOrder: ListSortOrder.DESC,
|
||||||
title: t('page.home.mostPlayed', { postProcess: 'sentenceCase' }),
|
title: t('page.home.mostPlayed', { postProcess: 'sentenceCase' }),
|
||||||
},
|
},
|
||||||
[HomeItem.RANDOM]: {
|
[HomeItem.RANDOM]: {
|
||||||
data: random?.data?.items,
|
data: random?.data?.items,
|
||||||
itemType: LibraryItem.ALBUM,
|
itemType: LibraryItem.ALBUM,
|
||||||
sortBy: AlbumListSort.RANDOM,
|
sortBy: AlbumListSort.RANDOM,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: ListSortOrder.ASC,
|
||||||
title: t('page.home.explore', { postProcess: 'sentenceCase' }),
|
title: t('page.home.explore', { postProcess: 'sentenceCase' }),
|
||||||
},
|
},
|
||||||
[HomeItem.RECENTLY_ADDED]: {
|
[HomeItem.RECENTLY_ADDED]: {
|
||||||
@@ -173,7 +170,7 @@ const HomeRoute = () => {
|
|||||||
itemsPerPage,
|
itemsPerPage,
|
||||||
},
|
},
|
||||||
sortBy: AlbumListSort.RECENTLY_ADDED,
|
sortBy: AlbumListSort.RECENTLY_ADDED,
|
||||||
sortOrder: SortOrder.DESC,
|
sortOrder: ListSortOrder.DESC,
|
||||||
title: t('page.home.newlyAdded', { postProcess: 'sentenceCase' }),
|
title: t('page.home.newlyAdded', { postProcess: 'sentenceCase' }),
|
||||||
},
|
},
|
||||||
[HomeItem.RECENTLY_PLAYED]: {
|
[HomeItem.RECENTLY_PLAYED]: {
|
||||||
@@ -183,7 +180,7 @@ const HomeRoute = () => {
|
|||||||
itemsPerPage,
|
itemsPerPage,
|
||||||
},
|
},
|
||||||
sortBy: AlbumListSort.RECENTLY_PLAYED,
|
sortBy: AlbumListSort.RECENTLY_PLAYED,
|
||||||
sortOrder: SortOrder.DESC,
|
sortOrder: ListSortOrder.DESC,
|
||||||
title: t('page.home.recentlyPlayed', { postProcess: 'sentenceCase' }),
|
title: t('page.home.recentlyPlayed', { postProcess: 'sentenceCase' }),
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
@@ -207,7 +204,7 @@ const HomeRoute = () => {
|
|||||||
const invalidateCarouselQuery = (carousel: {
|
const invalidateCarouselQuery = (carousel: {
|
||||||
itemType: LibraryItem;
|
itemType: LibraryItem;
|
||||||
sortBy: AlbumListSort | SongListSort;
|
sortBy: AlbumListSort | SongListSort;
|
||||||
sortOrder: SortOrder;
|
sortOrder: ListSortOrder;
|
||||||
}) => {
|
}) => {
|
||||||
if (carousel.itemType === LibraryItem.ALBUM) {
|
if (carousel.itemType === LibraryItem.ALBUM) {
|
||||||
queryClient.invalidateQueries({
|
queryClient.invalidateQueries({
|
||||||
|
|||||||
@@ -16,18 +16,14 @@ import { Separator } from '/@/shared/components/separator/separator';
|
|||||||
import { Spoiler } from '/@/shared/components/spoiler/spoiler';
|
import { Spoiler } from '/@/shared/components/spoiler/spoiler';
|
||||||
import { Table } from '/@/shared/components/table/table';
|
import { Table } from '/@/shared/components/table/table';
|
||||||
import { Text } from '/@/shared/components/text/text';
|
import { Text } from '/@/shared/components/text/text';
|
||||||
import {
|
import { Album } from '/@/shared/types/domain/album-domain-types';
|
||||||
Album,
|
import { RelatedArtist } from '/@/shared/types/domain/artist-domain-types';
|
||||||
AlbumArtist,
|
import { Playlist } from '/@/shared/types/domain/playlist-domain-types';
|
||||||
AnyLibraryItem,
|
import { AnyLibraryItem, LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
LibraryItem,
|
import { Song } from '/@/shared/types/domain/song-domain-types';
|
||||||
Playlist,
|
|
||||||
RelatedArtist,
|
|
||||||
Song,
|
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
|
|
||||||
export type ItemDetailsModalProps = {
|
export type ItemDetailsModalProps = {
|
||||||
item: Album | AlbumArtist | Playlist | Song;
|
item: Album | Playlist | Song;
|
||||||
};
|
};
|
||||||
|
|
||||||
type ItemDetailRow<T> = {
|
type ItemDetailRow<T> = {
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ import {
|
|||||||
InternetProviderLyricSearchResponse,
|
InternetProviderLyricSearchResponse,
|
||||||
LyricSource,
|
LyricSource,
|
||||||
LyricsOverride,
|
LyricsOverride,
|
||||||
} from '/@/shared/types/domain-types';
|
} from '/@/shared/types/domain/lyric-domain-types';
|
||||||
|
|
||||||
interface SearchResultProps {
|
interface SearchResultProps {
|
||||||
data: InternetProviderLyricSearchResponse;
|
data: InternetProviderLyricSearchResponse;
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ import { Group } from '/@/shared/components/group/group';
|
|||||||
import { NumberInput } from '/@/shared/components/number-input/number-input';
|
import { NumberInput } from '/@/shared/components/number-input/number-input';
|
||||||
import { Select } from '/@/shared/components/select/select';
|
import { Select } from '/@/shared/components/select/select';
|
||||||
import { Tooltip } from '/@/shared/components/tooltip/tooltip';
|
import { Tooltip } from '/@/shared/components/tooltip/tooltip';
|
||||||
import { LyricsOverride } from '/@/shared/types/domain-types';
|
import { LyricsOverride } from '/@/shared/types/domain/lyric-domain-types';
|
||||||
|
|
||||||
interface LyricsActionsProps {
|
interface LyricsActionsProps {
|
||||||
index: number;
|
index: number;
|
||||||
|
|||||||
@@ -28,7 +28,11 @@ import { Group } from '/@/shared/components/group/group';
|
|||||||
import { Icon } from '/@/shared/components/icon/icon';
|
import { Icon } from '/@/shared/components/icon/icon';
|
||||||
import { Spinner } from '/@/shared/components/spinner/spinner';
|
import { Spinner } from '/@/shared/components/spinner/spinner';
|
||||||
import { Text } from '/@/shared/components/text/text';
|
import { Text } from '/@/shared/components/text/text';
|
||||||
import { FullLyricsMetadata, LyricSource, LyricsOverride } from '/@/shared/types/domain-types';
|
import {
|
||||||
|
FullLyricsMetadata,
|
||||||
|
LyricSource,
|
||||||
|
LyricsOverride,
|
||||||
|
} from '/@/shared/types/domain/lyric-domain-types';
|
||||||
|
|
||||||
export const Lyrics = () => {
|
export const Lyrics = () => {
|
||||||
const currentSong = useCurrentSong();
|
const currentSong = useCurrentSong();
|
||||||
|
|||||||
@@ -11,12 +11,11 @@ import {
|
|||||||
InternetProviderLyricResponse,
|
InternetProviderLyricResponse,
|
||||||
LyricGetQuery,
|
LyricGetQuery,
|
||||||
LyricsQuery,
|
LyricsQuery,
|
||||||
QueueSong,
|
|
||||||
ServerType,
|
|
||||||
StructuredLyric,
|
StructuredLyric,
|
||||||
SynchronizedLyricsArray,
|
SynchronizedLyricsArray,
|
||||||
} from '/@/shared/types/domain-types';
|
} from '/@/shared/types/domain/lyric-domain-types';
|
||||||
import { ServerFeature } from '/@/shared/types/features-types';
|
import { QueueSong } from '/@/shared/types/domain/player-domain-types';
|
||||||
|
import { ServerFeature, ServerType } from '/@/shared/types/domain/server-domain-types';
|
||||||
|
|
||||||
const lyricsIpc = isElectron() ? window.api.lyrics : null;
|
const lyricsIpc = isElectron() ? window.api.lyrics : null;
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ import {
|
|||||||
InternetProviderLyricSearchResponse,
|
InternetProviderLyricSearchResponse,
|
||||||
LyricSearchQuery,
|
LyricSearchQuery,
|
||||||
LyricSource,
|
LyricSource,
|
||||||
} from '/@/shared/types/domain-types';
|
} from '/@/shared/types/domain/lyric-domain-types';
|
||||||
|
|
||||||
const lyricsIpc = isElectron() ? window.api.lyrics : null;
|
const lyricsIpc = isElectron() ? window.api.lyrics : null;
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,10 @@ import {
|
|||||||
useSeeked,
|
useSeeked,
|
||||||
useSetCurrentTime,
|
useSetCurrentTime,
|
||||||
} from '/@/renderer/store';
|
} from '/@/renderer/store';
|
||||||
import { FullLyricsMetadata, SynchronizedLyricsArray } from '/@/shared/types/domain-types';
|
import {
|
||||||
|
FullLyricsMetadata,
|
||||||
|
SynchronizedLyricsArray,
|
||||||
|
} from '/@/shared/types/domain/lyric-domain-types';
|
||||||
import { PlaybackType, PlayerStatus } from '/@/shared/types/types';
|
import { PlaybackType, PlayerStatus } from '/@/shared/types/types';
|
||||||
|
|
||||||
const mpvPlayer = isElectron() ? window.api.mpvPlayer : null;
|
const mpvPlayer = isElectron() ? window.api.mpvPlayer : null;
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ import styles from './unsynchronized-lyrics.module.css';
|
|||||||
|
|
||||||
import { LyricLine } from '/@/renderer/features/lyrics/lyric-line';
|
import { LyricLine } from '/@/renderer/features/lyrics/lyric-line';
|
||||||
import { useLyricsSettings } from '/@/renderer/store';
|
import { useLyricsSettings } from '/@/renderer/store';
|
||||||
import { FullLyricsMetadata } from '/@/shared/types/domain-types';
|
import { FullLyricsMetadata } from '/@/shared/types/domain/lyric-domain-types';
|
||||||
|
|
||||||
export interface UnsynchronizedLyricsProps extends Omit<FullLyricsMetadata, 'lyrics'> {
|
export interface UnsynchronizedLyricsProps extends Omit<FullLyricsMetadata, 'lyrics'> {
|
||||||
lyrics: string;
|
lyrics: string;
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { useRef } from 'react';
|
|||||||
import { PlayQueue } from '/@/renderer/features/now-playing/components/play-queue';
|
import { PlayQueue } from '/@/renderer/features/now-playing/components/play-queue';
|
||||||
import { PlayQueueListControls } from '/@/renderer/features/now-playing/components/play-queue-list-controls';
|
import { PlayQueueListControls } from '/@/renderer/features/now-playing/components/play-queue-list-controls';
|
||||||
import { Flex } from '/@/shared/components/flex/flex';
|
import { Flex } from '/@/shared/components/flex/flex';
|
||||||
import { Song } from '/@/shared/types/domain-types';
|
import { Song } from '/@/shared/types/domain/song-domain-types';
|
||||||
|
|
||||||
export const DrawerPlayQueue = () => {
|
export const DrawerPlayQueue = () => {
|
||||||
const queueRef = useRef<null | { grid: AgGridReactType<Song> }>(null);
|
const queueRef = useRef<null | { grid: AgGridReactType<Song> }>(null);
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ import { setQueue, setQueueNext } from '/@/renderer/utils/set-transcoded-queue-d
|
|||||||
import { ActionIcon } from '/@/shared/components/action-icon/action-icon';
|
import { ActionIcon } from '/@/shared/components/action-icon/action-icon';
|
||||||
import { Group } from '/@/shared/components/group/group';
|
import { Group } from '/@/shared/components/group/group';
|
||||||
import { Popover } from '/@/shared/components/popover/popover';
|
import { Popover } from '/@/shared/components/popover/popover';
|
||||||
import { Song } from '/@/shared/types/domain-types';
|
import { Song } from '/@/shared/types/domain/song-domain-types';
|
||||||
import { PlaybackType, TableType } from '/@/shared/types/types';
|
import { PlaybackType, TableType } from '/@/shared/types/types';
|
||||||
|
|
||||||
const mpvPlayer = isElectron() ? window.api.mpvPlayer : null;
|
const mpvPlayer = isElectron() ? window.api.mpvPlayer : null;
|
||||||
|
|||||||
@@ -40,7 +40,8 @@ import {
|
|||||||
useTableSettings,
|
useTableSettings,
|
||||||
} from '/@/renderer/store/settings.store';
|
} from '/@/renderer/store/settings.store';
|
||||||
import { setQueue, setQueueNext } from '/@/renderer/utils/set-transcoded-queue-data';
|
import { setQueue, setQueueNext } from '/@/renderer/utils/set-transcoded-queue-data';
|
||||||
import { LibraryItem, QueueSong } from '/@/shared/types/domain-types';
|
import { QueueSong } from '/@/shared/types/domain/player-domain-types';
|
||||||
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
import { PlaybackType, TableType } from '/@/shared/types/types';
|
import { PlaybackType, TableType } from '/@/shared/types/types';
|
||||||
|
|
||||||
const mpvPlayer = isElectron() ? window.api.mpvPlayer : null;
|
const mpvPlayer = isElectron() ? window.api.mpvPlayer : null;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ import { VirtualGridContainer } from '/@/renderer/components/virtual-grid';
|
|||||||
import { PlayQueue } from '/@/renderer/features/now-playing/components/play-queue';
|
import { PlayQueue } from '/@/renderer/features/now-playing/components/play-queue';
|
||||||
import { useWindowSettings } from '/@/renderer/store/settings.store';
|
import { useWindowSettings } from '/@/renderer/store/settings.store';
|
||||||
import { Box } from '/@/shared/components/box/box';
|
import { Box } from '/@/shared/components/box/box';
|
||||||
import { Song } from '/@/shared/types/domain-types';
|
import { Song } from '/@/shared/types/domain/song-domain-types';
|
||||||
import { Platform } from '/@/shared/types/types';
|
import { Platform } from '/@/shared/types/types';
|
||||||
|
|
||||||
export const SidebarPlayQueue = () => {
|
export const SidebarPlayQueue = () => {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
import type { Song } from '/@/shared/types/domain-types';
|
|
||||||
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
|
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
|
||||||
|
|
||||||
import { useRef } from 'react';
|
import { useRef } from 'react';
|
||||||
@@ -8,6 +7,7 @@ import { NowPlayingHeader } from '/@/renderer/features/now-playing/components/no
|
|||||||
import { PlayQueue } from '/@/renderer/features/now-playing/components/play-queue';
|
import { PlayQueue } from '/@/renderer/features/now-playing/components/play-queue';
|
||||||
import { PlayQueueListControls } from '/@/renderer/features/now-playing/components/play-queue-list-controls';
|
import { PlayQueueListControls } from '/@/renderer/features/now-playing/components/play-queue-list-controls';
|
||||||
import { AnimatedPage } from '/@/renderer/features/shared';
|
import { AnimatedPage } from '/@/renderer/features/shared';
|
||||||
|
import { Song } from '/@/shared/types/domain/song-domain-types';
|
||||||
|
|
||||||
const NowPlayingRoute = () => {
|
const NowPlayingRoute = () => {
|
||||||
const queueRef = useRef<null | { grid: AgGridReactType<Song> }>(null);
|
const queueRef = useRef<null | { grid: AgGridReactType<Song> }>(null);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ import { Group } from '/@/shared/components/group/group';
|
|||||||
import { Icon } from '/@/shared/components/icon/icon';
|
import { Icon } from '/@/shared/components/icon/icon';
|
||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import { Text } from '/@/shared/components/text/text';
|
import { Text } from '/@/shared/components/text/text';
|
||||||
import { PlayerData, QueueSong } from '/@/shared/types/domain-types';
|
import { PlayerData, QueueSong } from '/@/shared/types/domain/player-domain-types';
|
||||||
|
|
||||||
const imageVariants: Variants = {
|
const imageVariants: Variants = {
|
||||||
closed: {
|
closed: {
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ import { Image } from '/@/shared/components/image/image';
|
|||||||
import { Separator } from '/@/shared/components/separator/separator';
|
import { Separator } from '/@/shared/components/separator/separator';
|
||||||
import { Text } from '/@/shared/components/text/text';
|
import { Text } from '/@/shared/components/text/text';
|
||||||
import { Tooltip } from '/@/shared/components/tooltip/tooltip';
|
import { Tooltip } from '/@/shared/components/tooltip/tooltip';
|
||||||
import { LibraryItem } from '/@/shared/types/domain-types';
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
|
|
||||||
export const LeftControls = () => {
|
export const LeftControls = () => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
|
|||||||
@@ -24,7 +24,10 @@ import { Flex } from '/@/shared/components/flex/flex';
|
|||||||
import { Group } from '/@/shared/components/group/group';
|
import { Group } from '/@/shared/components/group/group';
|
||||||
import { Rating } from '/@/shared/components/rating/rating';
|
import { Rating } from '/@/shared/components/rating/rating';
|
||||||
import { Slider } from '/@/shared/components/slider/slider';
|
import { Slider } from '/@/shared/components/slider/slider';
|
||||||
import { LibraryItem, QueueSong, ServerType, Song } from '/@/shared/types/domain-types';
|
import { QueueSong } from '/@/shared/types/domain/player-domain-types';
|
||||||
|
import { ServerType } from '/@/shared/types/domain/server-domain-types';
|
||||||
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
|
import { Song } from '/@/shared/types/domain/song-domain-types';
|
||||||
|
|
||||||
const ipc = isElectron() ? window.api.ipc : null;
|
const ipc = isElectron() ? window.api.ipc : null;
|
||||||
const remote = isElectron() ? window.api.remote : null;
|
const remote = isElectron() ? window.api.remote : null;
|
||||||
|
|||||||
@@ -19,17 +19,12 @@ import { Icon } from '/@/shared/components/icon/icon';
|
|||||||
import { NumberInput } from '/@/shared/components/number-input/number-input';
|
import { NumberInput } from '/@/shared/components/number-input/number-input';
|
||||||
import { Select } from '/@/shared/components/select/select';
|
import { Select } from '/@/shared/components/select/select';
|
||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import {
|
import { GenreListResponse, GenreListSort } from '/@/shared/types/domain/genre-domain-types';
|
||||||
GenreListResponse,
|
import { Played } from '/@/shared/types/domain/player-domain-types';
|
||||||
GenreListSort,
|
import { ServerListItem, ServerType } from '/@/shared/types/domain/server-domain-types';
|
||||||
MusicFolderListResponse,
|
import { RandomSongListQuery } from '/@/shared/types/domain/song-domain-types';
|
||||||
Played,
|
|
||||||
RandomSongListQuery,
|
|
||||||
ServerListItem,
|
|
||||||
ServerType,
|
|
||||||
SortOrder,
|
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
import { Play, PlayQueueAddOptions } from '/@/shared/types/types';
|
import { Play, PlayQueueAddOptions } from '/@/shared/types/types';
|
||||||
|
import { ListSortOrder } from '/@/shared/types/domain/shared-domain-types';
|
||||||
|
|
||||||
interface ShuffleAllSlice extends RandomSongListQuery {
|
interface ShuffleAllSlice extends RandomSongListQuery {
|
||||||
actions: {
|
actions: {
|
||||||
@@ -262,7 +257,7 @@ export const openShuffleAllModal = async (
|
|||||||
},
|
},
|
||||||
query: {
|
query: {
|
||||||
sortBy: GenreListSort.NAME,
|
sortBy: GenreListSort.NAME,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: ListSortOrder.ASC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
|
|||||||
@@ -20,13 +20,10 @@ import { useCurrentServer, usePlayerControls, usePlayerStore } from '/@/renderer
|
|||||||
import { useGeneralSettings, usePlaybackType } from '/@/renderer/store/settings.store';
|
import { useGeneralSettings, usePlaybackType } from '/@/renderer/store/settings.store';
|
||||||
import { setQueue, setQueueNext } from '/@/renderer/utils/set-transcoded-queue-data';
|
import { setQueue, setQueueNext } from '/@/renderer/utils/set-transcoded-queue-data';
|
||||||
import { toast } from '/@/shared/components/toast/toast';
|
import { toast } from '/@/shared/components/toast/toast';
|
||||||
import {
|
import { instanceOfCancellationError } from '/@/shared/types/domain/api-domain-types';
|
||||||
instanceOfCancellationError,
|
import { QueueSong } from '/@/shared/types/domain/player-domain-types';
|
||||||
LibraryItem,
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
QueueSong,
|
import { Song, SongListResponse } from '/@/shared/types/domain/song-domain-types';
|
||||||
Song,
|
|
||||||
SongListResponse,
|
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
import { Play, PlaybackType, PlayQueueAddOptions } from '/@/shared/types/types';
|
import { Play, PlaybackType, PlayQueueAddOptions } from '/@/shared/types/types';
|
||||||
|
|
||||||
const getRootQueryKey = (itemType: LibraryItem, serverId: string) => {
|
const getRootQueryKey = (itemType: LibraryItem, serverId: string) => {
|
||||||
|
|||||||
@@ -2,7 +2,8 @@ import { useCallback, useEffect, useRef, useState } from 'react';
|
|||||||
|
|
||||||
import { useSendScrobble } from '/@/renderer/features/player/mutations/scrobble-mutation';
|
import { useSendScrobble } from '/@/renderer/features/player/mutations/scrobble-mutation';
|
||||||
import { useAppStore, usePlaybackSettings, usePlayerStore } from '/@/renderer/store';
|
import { useAppStore, usePlaybackSettings, usePlayerStore } from '/@/renderer/store';
|
||||||
import { QueueSong, ServerType } from '/@/shared/types/domain-types';
|
import { QueueSong } from '/@/shared/types/domain/player-domain-types';
|
||||||
|
import { ServerType } from '/@/shared/types/domain/server-domain-types';
|
||||||
import { PlayerStatus } from '/@/shared/types/types';
|
import { PlayerStatus } from '/@/shared/types/types';
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import { api } from '/@/renderer/api';
|
|||||||
import { MutationOptions } from '/@/renderer/lib/react-query';
|
import { MutationOptions } from '/@/renderer/lib/react-query';
|
||||||
import { getServerById, useIncrementQueuePlayCount } from '/@/renderer/store';
|
import { getServerById, useIncrementQueuePlayCount } from '/@/renderer/store';
|
||||||
import { usePlayEvent } from '/@/renderer/store/event.store';
|
import { usePlayEvent } from '/@/renderer/store/event.store';
|
||||||
import { ScrobbleArgs, ScrobbleResponse } from '/@/shared/types/domain-types';
|
import { ScrobbleRequest, ScrobbleResponse } from '/@/shared/types/domain/user-domain-types';
|
||||||
|
|
||||||
export const useSendScrobble = (options?: MutationOptions) => {
|
export const useSendScrobble = (options?: MutationOptions) => {
|
||||||
const incrementPlayCount = useIncrementQueuePlayCount();
|
const incrementPlayCount = useIncrementQueuePlayCount();
|
||||||
@@ -14,7 +14,7 @@ export const useSendScrobble = (options?: MutationOptions) => {
|
|||||||
return useMutation<
|
return useMutation<
|
||||||
ScrobbleResponse,
|
ScrobbleResponse,
|
||||||
AxiosError,
|
AxiosError,
|
||||||
Omit<ScrobbleArgs, 'apiClientProps' | 'server'>,
|
Omit<ScrobbleRequest, 'apiClientProps' | 'server'>,
|
||||||
null
|
null
|
||||||
>({
|
>({
|
||||||
mutationFn: (args) => {
|
mutationFn: (args) => {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import isElectron from 'is-electron';
|
import isElectron from 'is-electron';
|
||||||
|
|
||||||
import { QueueSong } from '/@/shared/types/domain-types';
|
import { QueueSong } from '/@/shared/types/domain/player-domain-types';
|
||||||
|
|
||||||
const remote = isElectron() ? window.api.remote : null;
|
const remote = isElectron() ? window.api.remote : null;
|
||||||
const mediaSession = navigator.mediaSession;
|
const mediaSession = navigator.mediaSession;
|
||||||
|
|||||||
@@ -2,15 +2,15 @@ import { QueryClient } from '@tanstack/react-query';
|
|||||||
|
|
||||||
import { api } from '/@/renderer/api';
|
import { api } from '/@/renderer/api';
|
||||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||||
|
import { PlaylistSongListQuery } from '/@/shared/types/domain/playlist-domain-types';
|
||||||
|
import { ServerListItem } from '/@/shared/types/domain/server-domain-types';
|
||||||
import {
|
import {
|
||||||
PlaylistSongListQuery,
|
|
||||||
ServerListItem,
|
|
||||||
SongDetailQuery,
|
SongDetailQuery,
|
||||||
SongListQuery,
|
SongListQuery,
|
||||||
SongListResponse,
|
SongListResponse,
|
||||||
SongListSort,
|
SongListSort,
|
||||||
SortOrder,
|
} from '/@/shared/types/domain/song-domain-types';
|
||||||
} from '/@/shared/types/domain-types';
|
import { ListSortOrder } from '/@/shared/types/domain/shared-domain-types';
|
||||||
|
|
||||||
export const getPlaylistSongsById = async (args: {
|
export const getPlaylistSongsById = async (args: {
|
||||||
id: string;
|
id: string;
|
||||||
@@ -23,7 +23,7 @@ export const getPlaylistSongsById = async (args: {
|
|||||||
const queryFilter: PlaylistSongListQuery = {
|
const queryFilter: PlaylistSongListQuery = {
|
||||||
id,
|
id,
|
||||||
sortBy: SongListSort.ID,
|
sortBy: SongListSort.ID,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: ListSortOrder.ASC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
...query,
|
...query,
|
||||||
};
|
};
|
||||||
@@ -61,7 +61,7 @@ export const getAlbumSongsById = async (args: {
|
|||||||
const queryFilter: SongListQuery = {
|
const queryFilter: SongListQuery = {
|
||||||
albumIds: id,
|
albumIds: id,
|
||||||
sortBy: SongListSort.ALBUM,
|
sortBy: SongListSort.ALBUM,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: ListSortOrder.ASC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
...query,
|
...query,
|
||||||
};
|
};
|
||||||
@@ -105,7 +105,7 @@ export const getGenreSongsById = async (args: {
|
|||||||
const queryFilter: SongListQuery = {
|
const queryFilter: SongListQuery = {
|
||||||
genreIds: [genreId],
|
genreIds: [genreId],
|
||||||
sortBy: SongListSort.GENRE,
|
sortBy: SongListSort.GENRE,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: ListSortOrder.ASC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
...query,
|
...query,
|
||||||
};
|
};
|
||||||
@@ -149,7 +149,7 @@ export const getAlbumArtistSongsById = async (args: {
|
|||||||
const queryFilter: SongListQuery = {
|
const queryFilter: SongListQuery = {
|
||||||
albumArtistIds: id || [],
|
albumArtistIds: id || [],
|
||||||
sortBy: SongListSort.ALBUM_ARTIST,
|
sortBy: SongListSort.ALBUM_ARTIST,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: ListSortOrder.ASC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
...query,
|
...query,
|
||||||
};
|
};
|
||||||
@@ -186,7 +186,7 @@ export const getArtistSongsById = async (args: {
|
|||||||
const queryFilter: SongListQuery = {
|
const queryFilter: SongListQuery = {
|
||||||
artistIds: id,
|
artistIds: id,
|
||||||
sortBy: SongListSort.ALBUM,
|
sortBy: SongListSort.ALBUM,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: ListSortOrder.ASC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
...query,
|
...query,
|
||||||
};
|
};
|
||||||
@@ -221,7 +221,7 @@ export const getSongsByQuery = async (args: {
|
|||||||
|
|
||||||
const queryFilter: SongListQuery = {
|
const queryFilter: SongListQuery = {
|
||||||
sortBy: SongListSort.ALBUM,
|
sortBy: SongListSort.ALBUM,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: ListSortOrder.ASC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
...query,
|
...query,
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -16,12 +16,9 @@ import { MultiSelect } from '/@/shared/components/multi-select/multi-select';
|
|||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import { Switch } from '/@/shared/components/switch/switch';
|
import { Switch } from '/@/shared/components/switch/switch';
|
||||||
import { toast } from '/@/shared/components/toast/toast';
|
import { toast } from '/@/shared/components/toast/toast';
|
||||||
import {
|
import { PlaylistListSort } from '/@/shared/types/domain/playlist-domain-types';
|
||||||
PlaylistListSort,
|
import { SongListQuery, SongListSort } from '/@/shared/types/domain/song-domain-types';
|
||||||
SongListQuery,
|
import { ListSortOrder } from '/@/shared/types/domain/shared-domain-types';
|
||||||
SongListSort,
|
|
||||||
SortOrder,
|
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
|
|
||||||
export const AddToPlaylistContextModal = ({
|
export const AddToPlaylistContextModal = ({
|
||||||
id,
|
id,
|
||||||
@@ -48,7 +45,7 @@ export const AddToPlaylistContextModal = ({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
sortBy: PlaylistListSort.NAME,
|
sortBy: PlaylistListSort.NAME,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: ListSortOrder.ASC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
serverId: server?.id,
|
serverId: server?.id,
|
||||||
@@ -74,7 +71,7 @@ export const AddToPlaylistContextModal = ({
|
|||||||
const query: SongListQuery = {
|
const query: SongListQuery = {
|
||||||
albumIds: [albumId],
|
albumIds: [albumId],
|
||||||
sortBy: SongListSort.ALBUM,
|
sortBy: SongListSort.ALBUM,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: ListSortOrder.ASC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -92,7 +89,7 @@ export const AddToPlaylistContextModal = ({
|
|||||||
const query: SongListQuery = {
|
const query: SongListQuery = {
|
||||||
artistIds: [artistId],
|
artistIds: [artistId],
|
||||||
sortBy: SongListSort.ARTIST,
|
sortBy: SongListSort.ARTIST,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: ListSortOrder.ASC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -165,7 +162,7 @@ export const AddToPlaylistContextModal = ({
|
|||||||
query: {
|
query: {
|
||||||
id: playlistId,
|
id: playlistId,
|
||||||
sortBy: SongListSort.ID,
|
sortBy: SongListSort.ID,
|
||||||
sortOrder: SortOrder.ASC,
|
sortOrder: ListSortOrder.ASC,
|
||||||
startIndex: 0,
|
startIndex: 0,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -18,8 +18,9 @@ import { TextInput } from '/@/shared/components/text-input/text-input';
|
|||||||
import { Text } from '/@/shared/components/text/text';
|
import { Text } from '/@/shared/components/text/text';
|
||||||
import { Textarea } from '/@/shared/components/textarea/textarea';
|
import { Textarea } from '/@/shared/components/textarea/textarea';
|
||||||
import { toast } from '/@/shared/components/toast/toast';
|
import { toast } from '/@/shared/components/toast/toast';
|
||||||
import { CreatePlaylistBody, ServerType, SongListSort } from '/@/shared/types/domain-types';
|
import { CreatePlaylistBody } from '/@/shared/types/domain/playlist-domain-types';
|
||||||
import { ServerFeature } from '/@/shared/types/features-types';
|
import { ServerFeature, ServerType } from '/@/shared/types/domain/server-domain-types';
|
||||||
|
import { SongListSort } from '/@/shared/types/domain/song-domain-types';
|
||||||
|
|
||||||
interface CreatePlaylistFormProps {
|
interface CreatePlaylistFormProps {
|
||||||
onCancel: () => void;
|
onCancel: () => void;
|
||||||
|
|||||||
@@ -40,15 +40,12 @@ import {
|
|||||||
} from '/@/renderer/store';
|
} from '/@/renderer/store';
|
||||||
import { PersistedTableColumn, usePlayButtonBehavior } from '/@/renderer/store/settings.store';
|
import { PersistedTableColumn, usePlayButtonBehavior } from '/@/renderer/store/settings.store';
|
||||||
import { toast } from '/@/shared/components/toast/toast';
|
import { toast } from '/@/shared/components/toast/toast';
|
||||||
import {
|
import { QueueSong } from '/@/shared/types/domain/player-domain-types';
|
||||||
LibraryItem,
|
import { PlaylistSongListQuery } from '/@/shared/types/domain/playlist-domain-types';
|
||||||
PlaylistSongListQuery,
|
import { ServerType } from '/@/shared/types/domain/server-domain-types';
|
||||||
QueueSong,
|
import { LibraryItem, ListSortOrder } from '/@/shared/types/domain/shared-domain-types';
|
||||||
Song,
|
import { Song, SongListSort } from '/@/shared/types/domain/song-domain-types';
|
||||||
SongListSort,
|
import { ListDisplayType } from '/@/shared/types/types';
|
||||||
SortOrder,
|
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
import { ListDisplayType, ServerType } from '/@/shared/types/types';
|
|
||||||
|
|
||||||
interface PlaylistDetailContentProps {
|
interface PlaylistDetailContentProps {
|
||||||
songs?: Song[];
|
songs?: Song[];
|
||||||
@@ -66,7 +63,7 @@ export const PlaylistDetailSongListContent = ({ songs, tableRef }: PlaylistDetai
|
|||||||
const filters: Partial<PlaylistSongListQuery> = useMemo(() => {
|
const filters: Partial<PlaylistSongListQuery> = useMemo(() => {
|
||||||
return {
|
return {
|
||||||
sortBy: page?.table.id[playlistId]?.filter?.sortBy || SongListSort.ID,
|
sortBy: page?.table.id[playlistId]?.filter?.sortBy || SongListSort.ID,
|
||||||
sortOrder: page?.table.id[playlistId]?.filter?.sortOrder || SortOrder.ASC,
|
sortOrder: page?.table.id[playlistId]?.filter?.sortOrder || ListSortOrder.ASC,
|
||||||
};
|
};
|
||||||
}, [page?.table.id, playlistId]);
|
}, [page?.table.id, playlistId]);
|
||||||
|
|
||||||
|
|||||||
+48
-50
@@ -40,213 +40,210 @@ import { Icon } from '/@/shared/components/icon/icon';
|
|||||||
import { ConfirmModal } from '/@/shared/components/modal/modal';
|
import { ConfirmModal } from '/@/shared/components/modal/modal';
|
||||||
import { Text } from '/@/shared/components/text/text';
|
import { Text } from '/@/shared/components/text/text';
|
||||||
import { toast } from '/@/shared/components/toast/toast';
|
import { toast } from '/@/shared/components/toast/toast';
|
||||||
import {
|
import { PlaylistSongListQuery } from '/@/shared/types/domain/playlist-domain-types';
|
||||||
LibraryItem,
|
import { ServerType } from '/@/shared/types/domain/server-domain-types';
|
||||||
PlaylistSongListQuery,
|
import { LibraryItem, ListSortOrder } from '/@/shared/types/domain/shared-domain-types';
|
||||||
ServerType,
|
import { SongListSort } from '/@/shared/types/domain/song-domain-types';
|
||||||
SongListSort,
|
|
||||||
SortOrder,
|
|
||||||
} from '/@/shared/types/domain-types';
|
|
||||||
import { ListDisplayType, Play } from '/@/shared/types/types';
|
import { ListDisplayType, Play } from '/@/shared/types/types';
|
||||||
|
|
||||||
const FILTERS = {
|
const FILTERS = {
|
||||||
jellyfin: [
|
jellyfin: [
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.id', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.id', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.ID,
|
value: SongListSort.ID,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.album', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.album', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.ALBUM,
|
value: SongListSort.ALBUM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.albumArtist', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.albumArtist', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.ALBUM_ARTIST,
|
value: SongListSort.ALBUM_ARTIST,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.artist', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.artist', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.ARTIST,
|
value: SongListSort.ARTIST,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.duration', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.duration', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.DURATION,
|
value: SongListSort.DURATION,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.playCount', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.playCount', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.PLAY_COUNT,
|
value: SongListSort.PLAY_COUNT,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.NAME,
|
value: SongListSort.NAME,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.random', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.random', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.RANDOM,
|
value: SongListSort.RANDOM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.recentlyAdded', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.recentlyAdded', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.RECENTLY_ADDED,
|
value: SongListSort.RECENTLY_ADDED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.recentlyPlayed', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.recentlyPlayed', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.RECENTLY_PLAYED,
|
value: SongListSort.RECENTLY_PLAYED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.releaseDate', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.releaseDate', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.RELEASE_DATE,
|
value: SongListSort.RELEASE_DATE,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
navidrome: [
|
navidrome: [
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.id', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.id', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.ID,
|
value: SongListSort.ID,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.album', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.album', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.ALBUM,
|
value: SongListSort.ALBUM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.albumArtist', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.albumArtist', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.ALBUM_ARTIST,
|
value: SongListSort.ALBUM_ARTIST,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.artist', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.artist', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.ARTIST,
|
value: SongListSort.ARTIST,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.bpm', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.bpm', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.BPM,
|
value: SongListSort.BPM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('common.channel', { count: 2, postProcess: 'titleCase' }),
|
name: i18n.t('common.channel', { count: 2, postProcess: 'titleCase' }),
|
||||||
value: SongListSort.CHANNELS,
|
value: SongListSort.CHANNELS,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.comment', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.comment', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.COMMENT,
|
value: SongListSort.COMMENT,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.duration', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.duration', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.DURATION,
|
value: SongListSort.DURATION,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.isFavorited', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.isFavorited', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.FAVORITED,
|
value: SongListSort.FAVORITED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.playCount', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.playCount', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.GENRE,
|
value: SongListSort.GENRE,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.NAME,
|
value: SongListSort.NAME,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.playCount', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.playCount', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.PLAY_COUNT,
|
value: SongListSort.PLAY_COUNT,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.rating', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.rating', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.RATING,
|
value: SongListSort.RATING,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.recentlyAdded', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.recentlyAdded', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.RECENTLY_ADDED,
|
value: SongListSort.RECENTLY_ADDED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.recentlyPlayed', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.recentlyPlayed', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.RECENTLY_PLAYED,
|
value: SongListSort.RECENTLY_PLAYED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.releaseYear', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.releaseYear', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.YEAR,
|
value: SongListSort.YEAR,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
subsonic: [
|
subsonic: [
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.id', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.id', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.ID,
|
value: SongListSort.ID,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.album', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.album', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.ALBUM,
|
value: SongListSort.ALBUM,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.albumArtist', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.albumArtist', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.ALBUM_ARTIST,
|
value: SongListSort.ALBUM_ARTIST,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.artist', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.artist', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.ARTIST,
|
value: SongListSort.ARTIST,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.duration', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.duration', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.DURATION,
|
value: SongListSort.DURATION,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.isFavorited', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.isFavorited', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.FAVORITED,
|
value: SongListSort.FAVORITED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.genre', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.genre', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.GENRE,
|
value: SongListSort.GENRE,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.ASC,
|
defaultOrder: ListSortOrder.ASC,
|
||||||
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.name', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.NAME,
|
value: SongListSort.NAME,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.rating', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.rating', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.RATING,
|
value: SongListSort.RATING,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.recentlyAdded', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.recentlyAdded', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.RECENTLY_ADDED,
|
value: SongListSort.RECENTLY_ADDED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.recentlyPlayed', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.recentlyPlayed', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.RECENTLY_PLAYED,
|
value: SongListSort.RECENTLY_PLAYED,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
defaultOrder: SortOrder.DESC,
|
defaultOrder: ListSortOrder.DESC,
|
||||||
name: i18n.t('filter.releaseYear', { postProcess: 'titleCase' }),
|
name: i18n.t('filter.releaseYear', { postProcess: 'titleCase' }),
|
||||||
value: SongListSort.YEAR,
|
value: SongListSort.YEAR,
|
||||||
},
|
},
|
||||||
@@ -272,7 +269,7 @@ export const PlaylistDetailSongListHeaderFilters = ({
|
|||||||
const page = usePlaylistDetailStore();
|
const page = usePlaylistDetailStore();
|
||||||
const filters: Partial<PlaylistSongListQuery> = {
|
const filters: Partial<PlaylistSongListQuery> = {
|
||||||
sortBy: page?.table.id[playlistId]?.filter?.sortBy || SongListSort.ID,
|
sortBy: page?.table.id[playlistId]?.filter?.sortBy || SongListSort.ID,
|
||||||
sortOrder: page?.table.id[playlistId]?.filter?.sortOrder || SortOrder.ASC,
|
sortOrder: page?.table.id[playlistId]?.filter?.sortOrder || ListSortOrder.ASC,
|
||||||
};
|
};
|
||||||
|
|
||||||
const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id });
|
const detailQuery = usePlaylistDetail({ query: { id: playlistId }, serverId: server?.id });
|
||||||
@@ -371,7 +368,7 @@ export const PlaylistDetailSongListHeaderFilters = ({
|
|||||||
|
|
||||||
const updatedFilters = setFilter(playlistId, {
|
const updatedFilters = setFilter(playlistId, {
|
||||||
sortBy: e.currentTarget.value as SongListSort,
|
sortBy: e.currentTarget.value as SongListSort,
|
||||||
sortOrder: sortOrder || SortOrder.ASC,
|
sortOrder: sortOrder || ListSortOrder.ASC,
|
||||||
});
|
});
|
||||||
|
|
||||||
handleFilterChange(updatedFilters);
|
handleFilterChange(updatedFilters);
|
||||||
@@ -380,7 +377,8 @@ export const PlaylistDetailSongListHeaderFilters = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const handleToggleSortOrder = useCallback(() => {
|
const handleToggleSortOrder = useCallback(() => {
|
||||||
const newSortOrder = filters.sortOrder === SortOrder.ASC ? SortOrder.DESC : SortOrder.ASC;
|
const newSortOrder =
|
||||||
|
filters.sortOrder === ListSortOrder.ASC ? ListSortOrder.DESC : ListSortOrder.ASC;
|
||||||
const updatedFilters = setFilter(playlistId, { sortOrder: newSortOrder });
|
const updatedFilters = setFilter(playlistId, { sortOrder: newSortOrder });
|
||||||
handleFilterChange(updatedFilters);
|
handleFilterChange(updatedFilters);
|
||||||
}, [filters.sortOrder, handleFilterChange, playlistId, setFilter]);
|
}, [filters.sortOrder, handleFilterChange, playlistId, setFilter]);
|
||||||
@@ -498,7 +496,7 @@ export const PlaylistDetailSongListHeaderFilters = ({
|
|||||||
<Divider orientation="vertical" />
|
<Divider orientation="vertical" />
|
||||||
<OrderToggleButton
|
<OrderToggleButton
|
||||||
onToggle={handleToggleSortOrder}
|
onToggle={handleToggleSortOrder}
|
||||||
sortOrder={filters.sortOrder || SortOrder.ASC}
|
sortOrder={filters.sortOrder || ListSortOrder.ASC}
|
||||||
/>
|
/>
|
||||||
<DropdownMenu position="bottom-start">
|
<DropdownMenu position="bottom-start">
|
||||||
<DropdownMenu.Target>
|
<DropdownMenu.Target>
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
|
|||||||
import { Badge } from '/@/shared/components/badge/badge';
|
import { Badge } from '/@/shared/components/badge/badge';
|
||||||
import { SpinnerIcon } from '/@/shared/components/spinner/spinner';
|
import { SpinnerIcon } from '/@/shared/components/spinner/spinner';
|
||||||
import { Stack } from '/@/shared/components/stack/stack';
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
import { LibraryItem } from '/@/shared/types/domain-types';
|
import { LibraryItem } from '/@/shared/types/domain/shared-domain-types';
|
||||||
import { Play } from '/@/shared/types/types';
|
import { Play } from '/@/shared/types/types';
|
||||||
|
|
||||||
interface PlaylistDetailHeaderProps {
|
interface PlaylistDetailHeaderProps {
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user