restructure files onto electron-vite boilerplate

This commit is contained in:
jeffvli
2025-05-18 14:03:18 -07:00
parent 91ce2cd8a1
commit 1cf587bc8f
457 changed files with 9927 additions and 11705 deletions
@@ -1,14 +1,15 @@
import { Center, Stack } from '@mantine/core';
import { RiAlbumFill, RiUserVoiceFill, RiPlayListFill } from 'react-icons/ri';
import { RiAlbumFill, RiPlayListFill, RiUserVoiceFill } from 'react-icons/ri';
import { generatePath, useNavigate } from 'react-router-dom';
import { SimpleImg } from 'react-simple-img';
import { ListChildComponentProps } from 'react-window';
import styled from 'styled-components';
import { Album, AlbumArtist, Artist, LibraryItem, Playlist, Song } from '/@/renderer/api/types';
import { CardRows } from '/@/renderer/components/card';
import { Skeleton } from '/@/renderer/components/skeleton';
import { GridCardControls } from '/@/renderer/components/virtual-grid/grid-card/grid-card-controls';
import { CardRow, PlayQueueAddOptions, Play, CardRoute } from '/@/renderer/types';
import { CardRoute, CardRow, Play, PlayQueueAddOptions } from '/@/renderer/types';
interface BaseGridCardProps {
columnIndex: number;
@@ -131,11 +132,11 @@ const DetailContainer = styled.div`
`;
export const DefaultCard = ({
listChildProps,
data,
columnIndex,
controls,
data,
isHidden,
listChildProps,
}: BaseGridCardProps) => {
const navigate = useNavigate();
@@ -156,10 +157,10 @@ export const DefaultCard = ({
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:
@@ -172,8 +173,8 @@ export const DefaultCard = ({
return (
<DefaultCardContainer
key={`card-${columnIndex}-${listChildProps.index}`}
$itemGap={controls.itemGap}
key={`card-${columnIndex}-${listChildProps.index}`}
onClick={() => navigate(path)}
>
<InnerCardContainer>
@@ -221,25 +222,25 @@ export const DefaultCard = ({
return (
<DefaultCardContainer
key={`card-${columnIndex}-${listChildProps.index}`}
$isHidden={isHidden}
$itemGap={controls.itemGap}
key={`card-${columnIndex}-${listChildProps.index}`}
>
<InnerCardContainer>
<ImageContainer>
<Skeleton
visible
radius="sm"
visible
/>
</ImageContainer>
<DetailContainer>
<Stack spacing="sm">
{(controls?.cardRows || []).map((row, index) => (
<Skeleton
key={`${index}-${columnIndex}-${row.arrayProperty}`}
visible
height={14}
key={`${index}-${columnIndex}-${row.arrayProperty}`}
radius="sm"
visible
/>
))}
</Stack>
@@ -1,20 +1,23 @@
import React, { MouseEvent, useState } from 'react';
import type { UnstyledButtonProps } from '@mantine/core';
import { RiPlayFill, RiHeartFill, RiHeartLine, RiMoreFill } from 'react-icons/ri';
import styled from 'styled-components';
import { _Button } from '/@/renderer/components/button';
import type { PlayQueueAddOptions } from '/@/renderer/types';
import { Play } from '/@/renderer/types';
import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
import { LibraryItem } from '/@/renderer/api/types';
import { useHandleGridContextMenu } from '/@/renderer/features/context-menu/hooks/use-handle-context-menu';
import type { UnstyledButtonProps } from '@mantine/core';
import React, { MouseEvent, useState } from 'react';
import { RiHeartFill, RiHeartLine, RiMoreFill, RiPlayFill } from 'react-icons/ri';
import styled from 'styled-components';
import {
PLAYLIST_CONTEXT_MENU_ITEMS,
ALBUM_CONTEXT_MENU_ITEMS,
ARTIST_CONTEXT_MENU_ITEMS,
PLAYLIST_CONTEXT_MENU_ITEMS,
} from '../../../features/context-menu/context-menu-items';
type PlayButtonType = UnstyledButtonProps & React.ComponentPropsWithoutRef<'button'>;
import { LibraryItem } from '/@/renderer/api/types';
import { _Button } from '/@/renderer/components/button';
import { useHandleGridContextMenu } from '/@/renderer/features/context-menu/hooks/use-handle-context-menu';
import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
import { Play } from '/@/renderer/types';
type PlayButtonType = React.ComponentPropsWithoutRef<'button'> & UnstyledButtonProps;
const PlayButton = styled.button<PlayButtonType>`
position: absolute;
@@ -108,10 +111,10 @@ const FavoriteWrapper = styled.span<{ isFavorite: boolean }>`
`;
export const GridCardControls = ({
handleFavorite,
handlePlayQueueAdd,
itemData,
itemType,
handlePlayQueueAdd,
handleFavorite,
resetInfiniteLoaderCache,
}: {
handleFavorite: (options: {
@@ -178,9 +181,9 @@ export const GridCardControls = ({
<BottomControls>
{itemType !== LibraryItem.PLAYLIST && (
<SecondaryButton
onClick={(e) => handleFavorites(e, itemData?.serverId)}
p={5}
variant="subtle"
onClick={(e) => handleFavorites(e, itemData?.serverId)}
>
<FavoriteWrapper isFavorite={itemData?.isFavorite}>
{isFavorite ? (
@@ -196,13 +199,13 @@ export const GridCardControls = ({
)}
<SecondaryButton
p={5}
variant="subtle"
onClick={(e) => {
e.preventDefault();
e.stopPropagation();
handleContextMenu(e, [itemData]);
}}
p={5}
variant="subtle"
>
<RiMoreFill
color="white"
@@ -1,24 +1,26 @@
import { memo } from 'react';
import type { ListChildComponentProps } from 'react-window';
import { memo } from 'react';
import { areEqual } from 'react-window';
import { DefaultCard } from '/@/renderer/components/virtual-grid/grid-card/default-card';
import { PosterCard } from '/@/renderer/components/virtual-grid/grid-card/poster-card';
import { GridCardData, ListDisplayType } from '/@/renderer/types';
export const GridCard = memo(({ data, index, style }: ListChildComponentProps) => {
const {
columnCount,
itemCount,
cardRows,
itemData,
itemType,
itemGap,
playButtonBehavior,
handlePlayQueueAdd,
handleFavorite,
route,
columnCount,
display,
handleFavorite,
handlePlayQueueAdd,
itemCount,
itemData,
itemGap,
itemType,
playButtonBehavior,
resetInfiniteLoaderCache,
route,
} = data as GridCardData;
const cards = [];
@@ -35,7 +37,6 @@ export const GridCard = memo(({ data, index, style }: ListChildComponentProps) =
for (let i = startIndex; i <= stopIndex + columnCountToAdd; i += 1) {
cards.push(
<View
key={`card-${i}-${index}`}
columnIndex={i}
controls={{
cardRows,
@@ -49,6 +50,7 @@ export const GridCard = memo(({ data, index, style }: ListChildComponentProps) =
}}
data={itemData[i]}
isHidden={i > stopIndex}
key={`card-${i}-${index}`}
listChildProps={{ index }}
/>,
);
@@ -4,11 +4,12 @@ import { generatePath, useNavigate } from 'react-router-dom';
import { SimpleImg } from 'react-simple-img';
import { ListChildComponentProps } from 'react-window';
import styled from 'styled-components';
import { Album, AlbumArtist, Artist, LibraryItem, Playlist, Song } from '/@/renderer/api/types';
import { CardRows } from '/@/renderer/components/card';
import { Skeleton } from '/@/renderer/components/skeleton';
import { GridCardControls } from '/@/renderer/components/virtual-grid/grid-card/grid-card-controls';
import { CardRow, PlayQueueAddOptions, Play, CardRoute } from '/@/renderer/types';
import { CardRoute, CardRow, Play, PlayQueueAddOptions } from '/@/renderer/types';
interface BaseGridCardProps {
columnIndex: number;
@@ -119,11 +120,11 @@ const DetailContainer = styled.div`
`;
export const PosterCard = ({
listChildProps,
data,
columnIndex,
controls,
data,
isHidden,
listChildProps,
}: BaseGridCardProps) => {
const navigate = useNavigate();
@@ -144,10 +145,10 @@ export const PosterCard = ({
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:
@@ -160,8 +161,8 @@ export const PosterCard = ({
return (
<PosterCardContainer
key={`card-${columnIndex}-${listChildProps.index}`}
$itemGap={controls.itemGap}
key={`card-${columnIndex}-${listChildProps.index}`}
>
<LinkContainer onClick={() => navigate(path)}>
<ImageContainer $isFavorite={data?.userFavorite}>
@@ -207,13 +208,13 @@ export const PosterCard = ({
return (
<PosterCardContainer
key={`card-${columnIndex}-${listChildProps.index}`}
$isHidden={isHidden}
$itemGap={controls.itemGap}
key={`card-${columnIndex}-${listChildProps.index}`}
>
<Skeleton
visible
radius="sm"
visible
>
<ImageContainer />
</Skeleton>
@@ -221,10 +222,10 @@ export const PosterCard = ({
<Stack spacing="sm">
{(controls?.cardRows || []).map((row, index) => (
<Skeleton
key={`${index}-${columnIndex}-${row.arrayProperty}`}
visible
height={14}
key={`${index}-${columnIndex}-${row.arrayProperty}`}
radius="sm"
visible
/>
))}
</Stack>
@@ -1,12 +1,14 @@
import type { CardRoute, CardRow, ListDisplayType, PlayQueueAddOptions } from '/@/renderer/types';
import type { Ref } from 'react';
import type { FixedSizeListProps } from 'react-window';
import debounce from 'lodash/debounce';
import memoize from 'memoize-one';
import type { FixedSizeListProps } from 'react-window';
import { FixedSizeList } from 'react-window';
import styled from 'styled-components';
import { GridCard } from '/@/renderer/components/virtual-grid/grid-card';
import type { CardRow, ListDisplayType, CardRoute, PlayQueueAddOptions } from '/@/renderer/types';
import { Album, AlbumArtist, Artist, LibraryItem } from '/@/renderer/api/types';
import { GridCard } from '/@/renderer/components/virtual-grid/grid-card';
const createItemData = memoize(
(
@@ -43,27 +45,27 @@ const createItemData = memoize(
const createScrollHandler = memoize((onScroll) => debounce(onScroll, 250));
export const VirtualGridWrapper = ({
refInstance,
cardRows,
itemGap,
itemType,
itemWidth,
display,
itemHeight,
itemCount,
columnCount,
rowCount,
initialScrollOffset,
display,
handleFavorite,
handlePlayQueueAdd,
itemData,
route,
onScroll,
height,
width,
initialScrollOffset,
itemCount,
itemData,
itemGap,
itemHeight,
itemType,
itemWidth,
onScroll,
refInstance,
resetInfiniteLoaderCache,
route,
rowCount,
width,
...rest
}: Omit<FixedSizeListProps, 'ref' | 'itemSize' | 'children' | 'height' | 'width'> & {
}: Omit<FixedSizeListProps, 'children' | 'height' | 'itemSize' | 'ref' | 'width'> & {
cardRows: CardRow<Album | AlbumArtist | Artist>[];
columnCount: number;
display: ListDisplayType;
@@ -112,9 +114,9 @@ export const VirtualGridWrapper = ({
itemCount={rowCount}
itemData={memoizedItemData}
itemSize={itemHeight}
onScroll={memoizedOnScroll}
overscanCount={5}
width={(width && Number(width)) || 0}
onScroll={memoizedOnScroll}
>
{GridCard}
</FixedSizeList>
@@ -1,21 +1,21 @@
import type { CardRoute, CardRow, PlayQueueAddOptions } from '/@/renderer/types';
import type { FixedSizeListProps } from 'react-window';
import debounce from 'lodash/debounce';
import {
useState,
useRef,
useMemo,
useCallback,
forwardRef,
Ref,
useCallback,
useImperativeHandle,
useMemo,
useRef,
useState,
} from 'react';
import debounce from 'lodash/debounce';
import type { FixedSizeListProps } from 'react-window';
import InfiniteLoader from 'react-window-infinite-loader';
import { VirtualGridWrapper } from '/@/renderer/components/virtual-grid/virtual-grid-wrapper';
import type { CardRoute, CardRow, PlayQueueAddOptions } from '/@/renderer/types';
import { ListDisplayType } from '/@/renderer/types';
import { AnyLibraryItem, Genre, LibraryItem } from '/@/renderer/api/types';
type LibraryItemOrGenre = AnyLibraryItem | Genre;
import { AnyLibraryItem, Genre, LibraryItem } from '/@/renderer/api/types';
import { VirtualGridWrapper } from '/@/renderer/components/virtual-grid/virtual-grid-wrapper';
import { ListDisplayType } from '/@/renderer/types';
export type VirtualInfiniteGridRef = {
resetLoadMoreItemsCache: () => void;
@@ -24,8 +24,10 @@ export type VirtualInfiniteGridRef = {
updateItemData: (rule: (item: LibraryItemOrGenre) => LibraryItemOrGenre) => void;
};
type LibraryItemOrGenre = AnyLibraryItem | Genre;
interface VirtualGridProps
extends Omit<FixedSizeListProps, 'children' | 'itemSize' | 'height' | 'width'> {
extends Omit<FixedSizeListProps, 'children' | 'height' | 'itemSize' | 'width'> {
cardRows: CardRow<any>[];
display?: ListDisplayType;
fetchFn: (options: { columnCount: number; skip: number; take: number }) => Promise<any>;
@@ -49,22 +51,22 @@ interface VirtualGridProps
export const VirtualInfiniteGrid = forwardRef(
(
{
cardRows,
display,
fetchFn,
fetchInitialData,
handleFavorite,
handlePlayQueueAdd,
height,
initialScrollOffset,
itemCount,
itemGap,
itemSize,
itemType,
cardRows,
route,
onScroll,
display,
handlePlayQueueAdd,
minimumBatchSize,
fetchFn,
fetchInitialData,
loading,
initialScrollOffset,
handleFavorite,
height,
minimumBatchSize,
onScroll,
route,
width,
}: VirtualGridProps,
ref: Ref<VirtualInfiniteGridRef>,
@@ -78,7 +80,7 @@ export const VirtualInfiniteGrid = forwardRef(
fetchInitialData?.() || [],
);
const { itemHeight, rowCount, columnCount } = useMemo(() => {
const { columnCount, itemHeight, rowCount } = useMemo(() => {
const itemsPerRow = width ? Math.floor(width / (itemSize + itemGap * 2)) : 5;
const widthPerItem = Number(width) / itemsPerRow;
const itemHeight = widthPerItem + cardRows.length * 26;
@@ -165,11 +167,11 @@ export const VirtualInfiniteGrid = forwardRef(
return (
<>
<InfiniteLoader
ref={loader}
isItemLoaded={(index) => isItemLoaded(index)}
itemCount={itemCount || 0}
loadMoreItems={debouncedLoadMoreItems}
minimumBatchSize={minimumBatchSize}
ref={loader}
threshold={30}
>
{({ onItemsRendered, ref: infiniteLoaderRef }) => (
@@ -187,6 +189,8 @@ export const VirtualInfiniteGrid = forwardRef(
itemHeight={itemHeight}
itemType={itemType}
itemWidth={itemSize}
onItemsRendered={onItemsRendered}
onScroll={onScroll}
refInstance={(list) => {
infiniteLoaderRef(list);
listRef.current = list;
@@ -200,8 +204,6 @@ export const VirtualInfiniteGrid = forwardRef(
route={route}
rowCount={rowCount}
width={width}
onItemsRendered={onItemsRendered}
onScroll={onScroll}
/>
)}
</InfiniteLoader>