mirror of
https://github.com/antebudimir/feishin.git
synced 2026-01-02 10:53:33 +00:00
restructure files onto electron-vite boilerplate
This commit is contained in:
parent
91ce2cd8a1
commit
1cf587bc8f
457 changed files with 9927 additions and 11705 deletions
|
|
@ -1,22 +1,23 @@
|
|||
/* eslint-disable react/no-unknown-property */
|
||||
import { useCallback, useState, Fragment, useRef } from 'react';
|
||||
import { ActionIcon, Group, Kbd, ScrollArea } from '@mantine/core';
|
||||
import { useDisclosure, useDebouncedValue } from '@mantine/hooks';
|
||||
import { useDebouncedValue, useDisclosure } from '@mantine/hooks';
|
||||
import { Fragment, useCallback, useRef, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { RiSearchLine, RiCloseFill } from 'react-icons/ri';
|
||||
import { RiCloseFill, RiSearchLine } from 'react-icons/ri';
|
||||
import { generatePath, useNavigate } from 'react-router';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { GoToCommands } from './go-to-commands';
|
||||
import { Command, CommandPalettePages } from '/@/renderer/features/search/components/command';
|
||||
import { Button, Modal, Paper, Spinner, TextInput } from '/@/renderer/components';
|
||||
import { HomeCommands } from './home-commands';
|
||||
|
||||
import { LibraryItem } from '/@/renderer/api/types';
|
||||
import { Button, Modal, Paper, Spinner, TextInput } from '/@/renderer/components';
|
||||
import { usePlayQueueAdd } from '/@/renderer/features/player';
|
||||
import { Command, CommandPalettePages } from '/@/renderer/features/search/components/command';
|
||||
import { LibraryCommandItem } from '/@/renderer/features/search/components/library-command-item';
|
||||
import { ServerCommands } from '/@/renderer/features/search/components/server-commands';
|
||||
import { useSearch } from '/@/renderer/features/search/queries/search-query';
|
||||
import { useCurrentServer } from '/@/renderer/store';
|
||||
import { AppRoute } from '/@/renderer/router/routes';
|
||||
import { LibraryCommandItem } from '/@/renderer/features/search/components/library-command-item';
|
||||
import { LibraryItem } from '/@/renderer/api/types';
|
||||
import { usePlayQueueAdd } from '/@/renderer/features/player';
|
||||
import { useCurrentServer } from '/@/renderer/store';
|
||||
|
||||
interface CommandPaletteProps {
|
||||
modalProps: (typeof useDisclosure)['arguments'];
|
||||
|
|
@ -118,13 +119,14 @@ export const CommandPalette = ({ modalProps }: CommandPaletteProps) => {
|
|||
return 0;
|
||||
}}
|
||||
label="Global Command Menu"
|
||||
value={value}
|
||||
onValueChange={setValue}
|
||||
value={value}
|
||||
>
|
||||
<TextInput
|
||||
ref={searchInputRef}
|
||||
data-autofocus
|
||||
icon={<RiSearchLine />}
|
||||
onChange={(e) => setQuery(e.currentTarget.value)}
|
||||
ref={searchInputRef}
|
||||
rightSection={
|
||||
<ActionIcon
|
||||
onClick={() => {
|
||||
|
|
@ -137,7 +139,6 @@ export const CommandPalette = ({ modalProps }: CommandPaletteProps) => {
|
|||
}
|
||||
size="lg"
|
||||
value={query}
|
||||
onChange={(e) => setQuery(e.currentTarget.value)}
|
||||
/>
|
||||
<Command.Separator />
|
||||
<Command.List>
|
||||
|
|
@ -147,7 +148,6 @@ export const CommandPalette = ({ modalProps }: CommandPaletteProps) => {
|
|||
{data?.albums?.map((album) => (
|
||||
<Command.Item
|
||||
key={`search-album-${album.id}`}
|
||||
value={`search-${album.id}`}
|
||||
onSelect={() => {
|
||||
navigate(
|
||||
generatePath(AppRoute.LIBRARY_ALBUMS_DETAIL, {
|
||||
|
|
@ -157,6 +157,7 @@ export const CommandPalette = ({ modalProps }: CommandPaletteProps) => {
|
|||
modalProps.handlers.close();
|
||||
setQuery('');
|
||||
}}
|
||||
value={`search-${album.id}`}
|
||||
>
|
||||
<LibraryCommandItem
|
||||
handlePlayQueueAdd={handlePlayQueueAdd}
|
||||
|
|
@ -177,7 +178,6 @@ export const CommandPalette = ({ modalProps }: CommandPaletteProps) => {
|
|||
{data?.albumArtists.map((artist) => (
|
||||
<Command.Item
|
||||
key={`artist-${artist.id}`}
|
||||
value={`search-${artist.id}`}
|
||||
onSelect={() => {
|
||||
navigate(
|
||||
generatePath(AppRoute.LIBRARY_ALBUM_ARTISTS_DETAIL, {
|
||||
|
|
@ -187,6 +187,7 @@ export const CommandPalette = ({ modalProps }: CommandPaletteProps) => {
|
|||
modalProps.handlers.close();
|
||||
setQuery('');
|
||||
}}
|
||||
value={`search-${artist.id}`}
|
||||
>
|
||||
<LibraryCommandItem
|
||||
disabled={artist?.albumCount === 0}
|
||||
|
|
@ -213,7 +214,6 @@ export const CommandPalette = ({ modalProps }: CommandPaletteProps) => {
|
|||
{data?.songs.map((song) => (
|
||||
<Command.Item
|
||||
key={`artist-${song.id}`}
|
||||
value={`search-${song.id}`}
|
||||
onSelect={() => {
|
||||
navigate(
|
||||
generatePath(AppRoute.LIBRARY_ALBUMS_DETAIL, {
|
||||
|
|
@ -223,6 +223,7 @@ export const CommandPalette = ({ modalProps }: CommandPaletteProps) => {
|
|||
modalProps.handlers.close();
|
||||
setQuery('');
|
||||
}}
|
||||
value={`search-${song.id}`}
|
||||
>
|
||||
<LibraryCommandItem
|
||||
handlePlayQueueAdd={handlePlayQueueAdd}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
import { useCallback, Dispatch } from 'react';
|
||||
import { Dispatch, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigate } from 'react-router';
|
||||
|
||||
import { Command, CommandPalettePages } from '/@/renderer/features/search/components/command';
|
||||
import { AppRoute } from '/@/renderer/router/routes';
|
||||
|
||||
|
|
@ -10,7 +11,7 @@ interface GoToCommandsProps {
|
|||
setQuery: Dispatch<string>;
|
||||
}
|
||||
|
||||
export const GoToCommands = ({ setQuery, setPages, handleClose }: GoToCommandsProps) => {
|
||||
export const GoToCommands = ({ handleClose, setPages, setQuery }: GoToCommandsProps) => {
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import { Dispatch, useCallback } from 'react';
|
||||
import { openModal, closeAllModals } from '@mantine/modals';
|
||||
import { closeAllModals, openModal } from '@mantine/modals';
|
||||
import { nanoid } from 'nanoid/non-secure';
|
||||
import { Dispatch, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { generatePath, useNavigate } from 'react-router';
|
||||
import { createSearchParams } from 'react-router-dom';
|
||||
|
||||
import { LibraryItem, ServerType } from '/@/renderer/api/types';
|
||||
import { CreatePlaylistForm } from '/@/renderer/features/playlists';
|
||||
import { Command, CommandPalettePages } from '/@/renderer/features/search/components/command';
|
||||
|
|
@ -19,11 +20,11 @@ interface HomeCommandsProps {
|
|||
}
|
||||
|
||||
export const HomeCommands = ({
|
||||
query,
|
||||
setQuery,
|
||||
pages,
|
||||
setPages,
|
||||
handleClose,
|
||||
pages,
|
||||
query,
|
||||
setPages,
|
||||
setQuery,
|
||||
}: HomeCommandsProps) => {
|
||||
const { t } = useTranslation();
|
||||
const navigate = useNavigate();
|
||||
|
|
@ -61,8 +62,8 @@ export const HomeCommands = ({
|
|||
<>
|
||||
<Command.Group heading={t('page.globalSearch.title', { postProcess: 'titleCase' })}>
|
||||
<Command.Item
|
||||
value={t('common.search', { postProcess: 'sentenceCase' })}
|
||||
onSelect={handleSearch}
|
||||
value={t('common.search', { postProcess: 'sentenceCase' })}
|
||||
>
|
||||
{query
|
||||
? t('page.globalSearch.commands.searchFor', {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import { useCallback, MouseEvent } from 'react';
|
||||
import { Center, Flex } from '@mantine/core';
|
||||
import { MouseEvent, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
RiAddBoxFill,
|
||||
|
|
@ -10,6 +10,7 @@ import {
|
|||
RiUserVoiceFill,
|
||||
} from 'react-icons/ri';
|
||||
import styled from 'styled-components';
|
||||
|
||||
import { LibraryItem } from '/@/renderer/api/types';
|
||||
import { Button, Text } from '/@/renderer/components';
|
||||
import { Play, PlayQueueAddOptions } from '/@/renderer/types';
|
||||
|
|
@ -56,7 +57,7 @@ interface LibraryCommandItemProps {
|
|||
disabled?: boolean;
|
||||
handlePlayQueueAdd?: (options: PlayQueueAddOptions) => void;
|
||||
id: string;
|
||||
imageUrl: string | null;
|
||||
imageUrl: null | string;
|
||||
itemType: LibraryItem;
|
||||
subtitle?: string;
|
||||
title?: string;
|
||||
|
|
@ -64,12 +65,12 @@ interface LibraryCommandItemProps {
|
|||
|
||||
export const LibraryCommandItem = ({
|
||||
disabled,
|
||||
handlePlayQueueAdd,
|
||||
id,
|
||||
imageUrl,
|
||||
itemType,
|
||||
subtitle,
|
||||
title,
|
||||
itemType,
|
||||
handlePlayQueueAdd,
|
||||
}: LibraryCommandItemProps) => {
|
||||
const { t } = useTranslation();
|
||||
let Placeholder = RiAlbumFill;
|
||||
|
|
@ -78,10 +79,10 @@ export const LibraryCommandItem = ({
|
|||
case LibraryItem.ALBUM:
|
||||
Placeholder = RiAlbumFill;
|
||||
break;
|
||||
case LibraryItem.ARTIST:
|
||||
case LibraryItem.ALBUM_ARTIST:
|
||||
Placeholder = RiUserVoiceFill;
|
||||
break;
|
||||
case LibraryItem.ALBUM_ARTIST:
|
||||
case LibraryItem.ARTIST:
|
||||
Placeholder = RiUserVoiceFill;
|
||||
break;
|
||||
case LibraryItem.PLAYLIST:
|
||||
|
|
@ -157,19 +158,20 @@ export const LibraryCommandItem = ({
|
|||
<Button
|
||||
compact
|
||||
disabled={disabled}
|
||||
onClick={(e) => handlePlay(e, id, Play.NOW)}
|
||||
size="md"
|
||||
tooltip={{
|
||||
label: t('player.play', { postProcess: 'sentenceCase' }),
|
||||
openDelay: 500,
|
||||
}}
|
||||
variant="default"
|
||||
onClick={(e) => handlePlay(e, id, Play.NOW)}
|
||||
>
|
||||
<RiPlayFill />
|
||||
</Button>
|
||||
<Button
|
||||
compact
|
||||
disabled={disabled}
|
||||
onClick={(e) => handlePlay(e, id, Play.LAST)}
|
||||
size="md"
|
||||
tooltip={{
|
||||
label: t('player.addLast', { postProcess: 'sentenceCase' }),
|
||||
|
|
@ -177,20 +179,19 @@ export const LibraryCommandItem = ({
|
|||
openDelay: 500,
|
||||
}}
|
||||
variant="default"
|
||||
onClick={(e) => handlePlay(e, id, Play.LAST)}
|
||||
>
|
||||
<RiAddBoxFill />
|
||||
</Button>
|
||||
<Button
|
||||
compact
|
||||
disabled={disabled}
|
||||
onClick={(e) => handlePlay(e, id, Play.NEXT)}
|
||||
size="md"
|
||||
tooltip={{
|
||||
label: t('player.addNext', { postProcess: 'sentenceCase' }),
|
||||
openDelay: 500,
|
||||
}}
|
||||
variant="default"
|
||||
onClick={(e) => handlePlay(e, id, Play.NEXT)}
|
||||
>
|
||||
<RiAddCircleFill />
|
||||
</Button>
|
||||
|
|
|
|||
|
|
@ -1,9 +1,12 @@
|
|||
import { RowDoubleClickedEvent } from '@ag-grid-community/core';
|
||||
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
|
||||
|
||||
import { RowDoubleClickedEvent } from '@ag-grid-community/core';
|
||||
import { MutableRefObject } from 'react';
|
||||
import { generatePath, useNavigate } from 'react-router';
|
||||
import { useParams, useSearchParams } from 'react-router-dom';
|
||||
|
||||
import { AppRoute } from '../../../router/routes';
|
||||
|
||||
import { LibraryItem, QueueSong, SongListQuery } from '/@/renderer/api/types';
|
||||
import { VirtualGridAutoSizerContainer } from '/@/renderer/components/virtual-grid';
|
||||
import { VirtualTable } from '/@/renderer/components/virtual-table';
|
||||
|
|
@ -93,17 +96,17 @@ export const SearchContent = ({ tableRef }: SearchContentProps) => {
|
|||
<VirtualGridAutoSizerContainer>
|
||||
<VirtualTable
|
||||
{...tableProps}
|
||||
key={`table-${itemType}-${tableProps.rowHeight}-${server?.id}`}
|
||||
ref={tableRef}
|
||||
context={{
|
||||
itemType,
|
||||
query: searchParams.get('query'),
|
||||
}}
|
||||
getRowId={(data) => data.data.id}
|
||||
infiniteInitialRowCount={25}
|
||||
key={`table-${itemType}-${tableProps.rowHeight}-${server?.id}`}
|
||||
onRowDoubleClicked={handleRowDoubleClick}
|
||||
ref={tableRef}
|
||||
rowClassRules={rowClassRules}
|
||||
shouldUpdateSong={itemType === LibraryItem.SONG}
|
||||
onRowDoubleClicked={handleRowDoubleClick}
|
||||
/>
|
||||
</VirtualGridAutoSizerContainer>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -1,10 +1,13 @@
|
|||
import { ChangeEvent, MutableRefObject } from 'react';
|
||||
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
|
||||
|
||||
import { Flex, Group, Stack } from '@mantine/core';
|
||||
import debounce from 'lodash/debounce';
|
||||
import { ChangeEvent, MutableRefObject } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { generatePath, Link, useParams, useSearchParams } from 'react-router-dom';
|
||||
|
||||
import { useCurrentServer } from '../../../store/auth.store';
|
||||
|
||||
import {
|
||||
AlbumArtistListQuery,
|
||||
AlbumListQuery,
|
||||
|
|
@ -23,13 +26,13 @@ interface SearchHeaderProps {
|
|||
tableRef: MutableRefObject<AgGridReactType | null>;
|
||||
}
|
||||
|
||||
export const SearchHeader = ({ tableRef, navigationId }: SearchHeaderProps) => {
|
||||
export const SearchHeader = ({ navigationId, tableRef }: SearchHeaderProps) => {
|
||||
const { t } = useTranslation();
|
||||
const { itemType } = useParams() as { itemType: LibraryItem };
|
||||
const [searchParams, setSearchParams] = useSearchParams();
|
||||
const cq = useContainerQuery();
|
||||
const server = useCurrentServer();
|
||||
const { filter } = useListStoreByKey<AlbumListQuery | AlbumArtistListQuery | SongListQuery>({
|
||||
const { filter } = useListStoreByKey<AlbumArtistListQuery | AlbumListQuery | SongListQuery>({
|
||||
key: itemType,
|
||||
});
|
||||
|
||||
|
|
@ -59,8 +62,8 @@ export const SearchHeader = ({ tableRef, navigationId }: SearchHeaderProps) => {
|
|||
<Group>
|
||||
<SearchInput
|
||||
defaultValue={searchParams.get('query') || ''}
|
||||
openedWidth={cq.isMd ? 250 : cq.isSm ? 200 : 150}
|
||||
onChange={handleSearch}
|
||||
openedWidth={cq.isMd ? 250 : cq.isSm ? 200 : 150}
|
||||
/>
|
||||
</Group>
|
||||
</Flex>
|
||||
|
|
@ -69,9 +72,9 @@ export const SearchHeader = ({ tableRef, navigationId }: SearchHeaderProps) => {
|
|||
<Group>
|
||||
<Button
|
||||
compact
|
||||
replace
|
||||
component={Link}
|
||||
fw={600}
|
||||
replace
|
||||
size="md"
|
||||
state={{ navigationId }}
|
||||
to={{
|
||||
|
|
@ -84,9 +87,9 @@ export const SearchHeader = ({ tableRef, navigationId }: SearchHeaderProps) => {
|
|||
</Button>
|
||||
<Button
|
||||
compact
|
||||
replace
|
||||
component={Link}
|
||||
fw={600}
|
||||
replace
|
||||
size="md"
|
||||
state={{ navigationId }}
|
||||
to={{
|
||||
|
|
@ -101,9 +104,9 @@ export const SearchHeader = ({ tableRef, navigationId }: SearchHeaderProps) => {
|
|||
</Button>
|
||||
<Button
|
||||
compact
|
||||
replace
|
||||
component={Link}
|
||||
fw={600}
|
||||
replace
|
||||
size="md"
|
||||
state={{ navigationId }}
|
||||
to={{
|
||||
|
|
|
|||
|
|
@ -1,12 +1,13 @@
|
|||
import { useCallback, Dispatch } from 'react';
|
||||
import { openModal } from '@mantine/modals';
|
||||
import { Command, CommandPalettePages } from '/@/renderer/features/search/components/command';
|
||||
import { ServerList } from '/@/renderer/features/servers';
|
||||
import { useAuthStoreActions, useServerList } from '/@/renderer/store';
|
||||
import { ServerListItem } from '/@/renderer/api/types';
|
||||
import { Dispatch, useCallback } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import { useNavigate } from 'react-router';
|
||||
|
||||
import { ServerListItem } from '/@/renderer/api/types';
|
||||
import { Command, CommandPalettePages } from '/@/renderer/features/search/components/command';
|
||||
import { ServerList } from '/@/renderer/features/servers';
|
||||
import { AppRoute } from '/@/renderer/router/routes';
|
||||
import { useAuthStoreActions, useServerList } from '/@/renderer/store';
|
||||
|
||||
interface ServerCommandsProps {
|
||||
handleClose: () => void;
|
||||
|
|
@ -14,7 +15,7 @@ interface ServerCommandsProps {
|
|||
setQuery: Dispatch<string>;
|
||||
}
|
||||
|
||||
export const ServerCommands = ({ setQuery, setPages, handleClose }: ServerCommandsProps) => {
|
||||
export const ServerCommands = ({ handleClose, setPages, setQuery }: ServerCommandsProps) => {
|
||||
const { t } = useTranslation();
|
||||
const serverList = useServerList();
|
||||
const navigate = useNavigate();
|
||||
|
|
|
|||
|
|
@ -1,9 +1,10 @@
|
|||
import { useQuery } from '@tanstack/react-query';
|
||||
|
||||
import { api } from '/@/renderer/api';
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { SearchQuery } from '/@/renderer/api/types';
|
||||
import { QueryHookArgs } from '/@/renderer/lib/react-query';
|
||||
import { useQuery } from '@tanstack/react-query';
|
||||
import { queryKeys } from '/@/renderer/api/query-keys';
|
||||
import { getServerById } from '/@/renderer/store';
|
||||
import { api } from '/@/renderer/api';
|
||||
|
||||
export const useSearch = (args: QueryHookArgs<SearchQuery>) => {
|
||||
const { options, query, serverId } = args;
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
import type { AgGridReact as AgGridReactType } from '@ag-grid-community/react/lib/agGridReact';
|
||||
|
||||
import { useId, useRef } from 'react';
|
||||
import { useLocation, useParams } from 'react-router';
|
||||
|
||||
import { SearchContent } from '/@/renderer/features/search/components/search-content';
|
||||
import { SearchHeader } from '/@/renderer/features/search/components/search-header';
|
||||
import { AnimatedPage } from '/@/renderer/features/shared';
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue