mirror of
https://github.com/antebudimir/feishin.git
synced 2026-01-01 18:33:33 +00:00
Migrate to Mantine v8 and Design Changes (#961)
* mantine v8 migration * various design changes and improvements
This commit is contained in:
parent
bea55d48a8
commit
c1330d92b2
473 changed files with 12469 additions and 11607 deletions
|
|
@ -1,5 +1,4 @@
|
|||
import { RowNode } from '@ag-grid-community/core';
|
||||
import { Divider, Group, Portal, Stack } from '@mantine/core';
|
||||
import {
|
||||
useClickOutside,
|
||||
useMergedRef,
|
||||
|
|
@ -8,42 +7,14 @@ import {
|
|||
useViewportSize,
|
||||
} from '@mantine/hooks';
|
||||
import { closeAllModals, openContextModal, openModal } from '@mantine/modals';
|
||||
import { AnimatePresence } from 'framer-motion';
|
||||
import isElectron from 'is-electron';
|
||||
import { AnimatePresence } from 'motion/react';
|
||||
import { createContext, Fragment, ReactNode, useCallback, useMemo, useState } from 'react';
|
||||
import { useTranslation } from 'react-i18next';
|
||||
import {
|
||||
RiAddBoxFill,
|
||||
RiAddCircleFill,
|
||||
RiArrowDownLine,
|
||||
RiArrowGoForwardLine,
|
||||
RiArrowRightSFill,
|
||||
RiArrowUpLine,
|
||||
RiCloseCircleLine,
|
||||
RiDeleteBinFill,
|
||||
RiDislikeFill,
|
||||
RiDownload2Line,
|
||||
RiHeartFill,
|
||||
RiInformationFill,
|
||||
RiPlayFill,
|
||||
RiPlayListAddFill,
|
||||
RiRadio2Fill,
|
||||
RiShareForwardFill,
|
||||
RiShuffleFill,
|
||||
RiStarFill,
|
||||
} from 'react-icons/ri';
|
||||
|
||||
import { api } from '/@/renderer/api';
|
||||
import { controller } from '/@/renderer/api/controller';
|
||||
import {
|
||||
ConfirmModal,
|
||||
ContextMenu,
|
||||
ContextMenuButton,
|
||||
HoverCard,
|
||||
Rating,
|
||||
Text,
|
||||
toast,
|
||||
} from '/@/renderer/components';
|
||||
import { ContextMenu, ContextMenuButton } from '/@/renderer/components/context-menu/context-menu';
|
||||
import {
|
||||
ContextMenuItemType,
|
||||
OpenContextMenuProps,
|
||||
|
|
@ -66,6 +37,16 @@ import {
|
|||
import { usePlaybackType } from '/@/renderer/store/settings.store';
|
||||
import { setQueue, setQueueNext } from '/@/renderer/utils/set-transcoded-queue-data';
|
||||
import { hasFeature } from '/@/shared/api/utils';
|
||||
import { Divider } from '/@/shared/components/divider/divider';
|
||||
import { Group } from '/@/shared/components/group/group';
|
||||
import { HoverCard } from '/@/shared/components/hover-card/hover-card';
|
||||
import { Icon } from '/@/shared/components/icon/icon';
|
||||
import { ConfirmModal } from '/@/shared/components/modal/modal';
|
||||
import { Portal } from '/@/shared/components/portal/portal';
|
||||
import { Rating } from '/@/shared/components/rating/rating';
|
||||
import { Stack } from '/@/shared/components/stack/stack';
|
||||
import { Text } from '/@/shared/components/text/text';
|
||||
import { toast } from '/@/shared/components/toast/toast';
|
||||
import {
|
||||
AnyLibraryItem,
|
||||
AnyLibraryItems,
|
||||
|
|
@ -113,6 +94,7 @@ function RatingIcon({ rating }: { rating: number }) {
|
|||
readOnly
|
||||
style={{
|
||||
pointerEvents: 'none',
|
||||
size: 'var(--theme-font-size-md)',
|
||||
}}
|
||||
value={rating}
|
||||
/>
|
||||
|
|
@ -292,7 +274,7 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
|
|||
{ctx.data.map((item) => (
|
||||
<li key={item.id}>
|
||||
<Group>
|
||||
—<Text $secondary>{item.name}</Text>
|
||||
—<Text isMuted>{item.name}</Text>
|
||||
</Group>
|
||||
</li>
|
||||
))}
|
||||
|
|
@ -750,13 +732,13 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
|
|||
addToFavorites: {
|
||||
id: 'addToFavorites',
|
||||
label: t('page.contextMenu.addToFavorites', { postProcess: 'sentenceCase' }),
|
||||
leftIcon: <RiHeartFill size="1.1rem" />,
|
||||
leftIcon: <Icon icon="favorite" />,
|
||||
onClick: handleAddToFavorites,
|
||||
},
|
||||
addToPlaylist: {
|
||||
id: 'addToPlaylist',
|
||||
label: t('page.contextMenu.addToPlaylist', { postProcess: 'sentenceCase' }),
|
||||
leftIcon: <RiPlayListAddFill size="1.1rem" />,
|
||||
leftIcon: <Icon icon="playlistAdd" />,
|
||||
onClick: handleAddToPlaylist,
|
||||
},
|
||||
createPlaylist: {
|
||||
|
|
@ -767,86 +749,86 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
|
|||
deletePlaylist: {
|
||||
id: 'deletePlaylist',
|
||||
label: t('page.contextMenu.deletePlaylist', { postProcess: 'sentenceCase' }),
|
||||
leftIcon: <RiDeleteBinFill size="1.1rem" />,
|
||||
leftIcon: <Icon icon="playlistDelete" />,
|
||||
onClick: openDeletePlaylistModal,
|
||||
},
|
||||
deselectAll: {
|
||||
id: 'deselectAll',
|
||||
label: t('page.contextMenu.deselectAll', { postProcess: 'sentenceCase' }),
|
||||
leftIcon: <RiCloseCircleLine size="1.1rem" />,
|
||||
leftIcon: <Icon icon="remove" />,
|
||||
onClick: handleDeselectAll,
|
||||
},
|
||||
download: {
|
||||
disabled: ctx.data?.length !== 1,
|
||||
id: 'download',
|
||||
label: t('page.contextMenu.download', { postProcess: 'sentenceCase' }),
|
||||
leftIcon: <RiDownload2Line size="1.1rem" />,
|
||||
leftIcon: <Icon icon="download" />,
|
||||
onClick: handleDownload,
|
||||
},
|
||||
moveToBottomOfQueue: {
|
||||
id: 'moveToBottomOfQueue',
|
||||
label: t('page.contextMenu.moveToBottom', { postProcess: 'sentenceCase' }),
|
||||
leftIcon: <RiArrowDownLine size="1.1rem" />,
|
||||
leftIcon: <Icon icon="arrowDownToLine" />,
|
||||
onClick: handleMoveToBottom,
|
||||
},
|
||||
moveToNextOfQueue: {
|
||||
id: 'moveToNext',
|
||||
label: t('page.contextMenu.moveToNext', { postProcess: 'sentenceCase' }),
|
||||
leftIcon: <RiArrowGoForwardLine size="1.1rem" />,
|
||||
leftIcon: <Icon icon="mediaPlayNext" />,
|
||||
onClick: handleMoveToNext,
|
||||
},
|
||||
moveToTopOfQueue: {
|
||||
id: 'moveToTopOfQueue',
|
||||
label: t('page.contextMenu.moveToTop', { postProcess: 'sentenceCase' }),
|
||||
leftIcon: <RiArrowUpLine size="1.1rem" />,
|
||||
leftIcon: <Icon icon="arrowUpToLine" />,
|
||||
onClick: handleMoveToTop,
|
||||
},
|
||||
play: {
|
||||
id: 'play',
|
||||
label: t('page.contextMenu.play', { postProcess: 'sentenceCase' }),
|
||||
leftIcon: <RiPlayFill size="1.1rem" />,
|
||||
leftIcon: <Icon icon="mediaPlay" />,
|
||||
onClick: () => handlePlay(Play.NOW),
|
||||
},
|
||||
playLast: {
|
||||
id: 'playLast',
|
||||
label: t('page.contextMenu.addLast', { postProcess: 'sentenceCase' }),
|
||||
leftIcon: <RiAddBoxFill size="1.1rem" />,
|
||||
leftIcon: <Icon icon="mediaPlayLast" />,
|
||||
onClick: () => handlePlay(Play.LAST),
|
||||
},
|
||||
playNext: {
|
||||
id: 'playNext',
|
||||
label: t('page.contextMenu.addNext', { postProcess: 'sentenceCase' }),
|
||||
leftIcon: <RiAddCircleFill size="1.1rem" />,
|
||||
leftIcon: <Icon icon="mediaPlayNext" />,
|
||||
onClick: () => handlePlay(Play.NEXT),
|
||||
},
|
||||
playShuffled: {
|
||||
id: 'playShuffled',
|
||||
label: t('page.contextMenu.playShuffled', { postProcess: 'sentenceCase' }),
|
||||
leftIcon: <RiShuffleFill size="1.1rem" />,
|
||||
leftIcon: <Icon icon="mediaShuffle" />,
|
||||
onClick: () => handlePlay(Play.SHUFFLE),
|
||||
},
|
||||
playSimilarSongs: {
|
||||
id: 'playSimilarSongs',
|
||||
label: t('page.contextMenu.playSimilarSongs', { postProcess: 'sentenceCase' }),
|
||||
leftIcon: <RiRadio2Fill size="1.1rem" />,
|
||||
leftIcon: <Icon icon="radio" />,
|
||||
onClick: handleSimilar,
|
||||
},
|
||||
removeFromFavorites: {
|
||||
id: 'removeFromFavorites',
|
||||
label: t('page.contextMenu.removeFromFavorites', { postProcess: 'sentenceCase' }),
|
||||
leftIcon: <RiDislikeFill size="1.1rem" />,
|
||||
leftIcon: <Icon icon="unfavorite" />,
|
||||
onClick: handleRemoveFromFavorites,
|
||||
},
|
||||
removeFromPlaylist: {
|
||||
id: 'removeFromPlaylist',
|
||||
label: t('page.contextMenu.removeFromPlaylist', { postProcess: 'sentenceCase' }),
|
||||
leftIcon: <RiDeleteBinFill size="1.1rem" />,
|
||||
leftIcon: <Icon icon="playlistDelete" />,
|
||||
onClick: handleRemoveFromPlaylist,
|
||||
},
|
||||
removeFromQueue: {
|
||||
id: 'removeSongs',
|
||||
label: t('page.contextMenu.removeFromQueue', { postProcess: 'sentenceCase' }),
|
||||
leftIcon: <RiDeleteBinFill size="1.1rem" />,
|
||||
leftIcon: <Icon icon="delete" />,
|
||||
onClick: handleRemoveSelected,
|
||||
},
|
||||
setRating: {
|
||||
|
|
@ -884,22 +866,22 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
|
|||
],
|
||||
id: 'setRating',
|
||||
label: t('action.setRating', { postProcess: 'sentenceCase' }),
|
||||
leftIcon: <RiStarFill size="1.1rem" />,
|
||||
leftIcon: <Icon icon="star" />,
|
||||
onClick: () => {},
|
||||
rightIcon: <RiArrowRightSFill size="1.2rem" />,
|
||||
rightIcon: <Icon icon="arrowRightS" />,
|
||||
},
|
||||
shareItem: {
|
||||
disabled: !hasFeature(server, ServerFeature.SHARING_ALBUM_SONG),
|
||||
id: 'shareItem',
|
||||
label: t('page.contextMenu.shareItem', { postProcess: 'sentenceCase' }),
|
||||
leftIcon: <RiShareForwardFill size="1.1rem" />,
|
||||
leftIcon: <Icon icon="share" />,
|
||||
onClick: handleShareItem,
|
||||
},
|
||||
showDetails: {
|
||||
disabled: ctx.data?.length !== 1 || !ctx.data[0].itemType,
|
||||
id: 'showDetails',
|
||||
label: t('page.contextMenu.showDetails', { postProcess: 'sentenceCase' }),
|
||||
leftIcon: <RiInformationFill />,
|
||||
leftIcon: <Icon icon="info" />,
|
||||
onClick: handleOpenItemDetails,
|
||||
},
|
||||
};
|
||||
|
|
@ -946,10 +928,10 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
|
|||
xPos={ctx.xPos}
|
||||
yPos={ctx.yPos}
|
||||
>
|
||||
<Stack spacing={0}>
|
||||
<Stack gap={0}>
|
||||
<Stack
|
||||
gap={0}
|
||||
onClick={closeContextMenu}
|
||||
spacing={0}
|
||||
>
|
||||
{ctx.menuItems?.map((item) => {
|
||||
return (
|
||||
|
|
@ -957,7 +939,7 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
|
|||
<Fragment key={`context-menu-${item.id}`}>
|
||||
{item.children ? (
|
||||
<HoverCard
|
||||
offset={5}
|
||||
offset={0}
|
||||
position="right"
|
||||
>
|
||||
<HoverCard.Target>
|
||||
|
|
@ -982,7 +964,7 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
|
|||
</ContextMenuButton>
|
||||
</HoverCard.Target>
|
||||
<HoverCard.Dropdown>
|
||||
<Stack spacing={0}>
|
||||
<Stack gap={0}>
|
||||
{contextMenuItems[
|
||||
item.id
|
||||
].children?.map((child) => (
|
||||
|
|
@ -1020,9 +1002,7 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
|
|||
|
||||
{item.divider && (
|
||||
<Divider
|
||||
color="rgb(62, 62, 62)"
|
||||
key={`context-menu-divider-${item.id}`}
|
||||
size="sm"
|
||||
/>
|
||||
)}
|
||||
</Fragment>
|
||||
|
|
@ -1030,10 +1010,6 @@ export const ContextMenuProvider = ({ children }: ContextMenuProviderProps) => {
|
|||
);
|
||||
})}
|
||||
</Stack>
|
||||
<Divider
|
||||
color="rgb(62, 62, 62)"
|
||||
size="sm"
|
||||
/>
|
||||
<ContextMenuButton disabled>
|
||||
{t('page.contextMenu.numberSelected', {
|
||||
count: ctx.data?.length || 0,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue