mirror of
https://github.com/jeffvli/feishin.git
synced 2026-07-21 18:06:30 +02:00
Add global context modal for song edit and move album fetch to it
This commit is contained in:
@@ -1,11 +1,8 @@
|
|||||||
import { openModal } from '@mantine/modals';
|
import { openContextModal } from '@mantine/modals';
|
||||||
import isElectron from 'is-electron';
|
import isElectron from 'is-electron';
|
||||||
import { useCallback, useMemo } from 'react';
|
import { useCallback, useMemo } from 'react';
|
||||||
import { useTranslation } from 'react-i18next';
|
import { useTranslation } from 'react-i18next';
|
||||||
|
|
||||||
import { controller } from '/@/renderer/api/controller';
|
|
||||||
import { SongEditModal } from '/@/renderer/features/tag-editor/components/song-edit-modal';
|
|
||||||
import { useCurrentServer } from '/@/renderer/store';
|
|
||||||
import { ContextMenu } from '/@/shared/components/context-menu/context-menu';
|
import { ContextMenu } from '/@/shared/components/context-menu/context-menu';
|
||||||
import { Song } from '/@/shared/types/domain-types';
|
import { Song } from '/@/shared/types/domain-types';
|
||||||
|
|
||||||
@@ -16,44 +13,20 @@ interface EditMetadataActionProps {
|
|||||||
|
|
||||||
const utils = isElectron() ? window.api.utils : null;
|
const utils = isElectron() ? window.api.utils : null;
|
||||||
|
|
||||||
const getAlbumSongs = async (albumIds: string[], serverId: string): Promise<Song[]> => {
|
|
||||||
const albumDetails = await Promise.all(
|
|
||||||
albumIds.map((id) =>
|
|
||||||
controller.getAlbumDetail({
|
|
||||||
apiClientProps: { serverId },
|
|
||||||
query: { id },
|
|
||||||
}),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return albumDetails.flatMap((album) => album?.songs ?? []).filter((s) => s.path);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const EditMetadataAction = ({ albumIds, songs: songItems }: EditMetadataActionProps) => {
|
export const EditMetadataAction = ({ albumIds, songs: songItems }: EditMetadataActionProps) => {
|
||||||
const { t } = useTranslation();
|
const { t } = useTranslation();
|
||||||
const server = useCurrentServer();
|
|
||||||
const songs = useMemo(() => songItems?.filter((s) => s.path) ?? [], [songItems]);
|
const songs = useMemo(() => songItems?.filter((s) => s.path) ?? [], [songItems]);
|
||||||
const count = albumIds?.length ?? songs.length;
|
const count = albumIds?.length ?? songs.length;
|
||||||
|
|
||||||
const onSelect = useCallback(async () => {
|
const onSelect = useCallback(() => {
|
||||||
let resolvedSongs: Song[];
|
openContextModal({
|
||||||
|
innerProps: { albumIds, songs },
|
||||||
if (albumIds) {
|
modal: 'editMetadata',
|
||||||
resolvedSongs = server?.id ? await getAlbumSongs(albumIds, server.id) : [];
|
|
||||||
} else {
|
|
||||||
resolvedSongs = songs;
|
|
||||||
}
|
|
||||||
|
|
||||||
const trackCount = resolvedSongs.length;
|
|
||||||
openModal({
|
|
||||||
children: <SongEditModal songs={resolvedSongs} />,
|
|
||||||
size: 'xl',
|
size: 'xl',
|
||||||
styles: { body: { paddingBottom: 'var(--theme-spacing-xl)' } },
|
styles: { body: { paddingBottom: 'var(--theme-spacing-xl)' } },
|
||||||
title:
|
title: t('page.contextMenu.editMetadata'),
|
||||||
trackCount > 1
|
|
||||||
? `${t('page.contextMenu.editMetadata')} (${trackCount} ${t('common.tracks', 'tracks')})`
|
|
||||||
: t('page.contextMenu.editMetadata'),
|
|
||||||
});
|
});
|
||||||
}, [albumIds, server, songs, t]);
|
}, [albumIds, songs, t]);
|
||||||
|
|
||||||
if (!utils) return null;
|
if (!utils) return null;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,52 @@
|
|||||||
|
import { ContextModalProps } from '@mantine/modals';
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
|
||||||
|
import { controller } from '/@/renderer/api/controller';
|
||||||
|
import { SongEditModal } from '/@/renderer/features/tag-editor/components/song-edit-modal';
|
||||||
|
import { useCurrentServer } from '/@/renderer/store';
|
||||||
|
import { Spinner } from '/@/shared/components/spinner/spinner';
|
||||||
|
import { Stack } from '/@/shared/components/stack/stack';
|
||||||
|
import { Song } from '/@/shared/types/domain-types';
|
||||||
|
|
||||||
|
type SongEditInnerProps = {
|
||||||
|
albumIds?: string[];
|
||||||
|
songs?: Song[];
|
||||||
|
};
|
||||||
|
|
||||||
|
export const SongEditContextModal = ({ innerProps }: ContextModalProps<SongEditInnerProps>) => {
|
||||||
|
const server = useCurrentServer();
|
||||||
|
const [resolvedSongs, setResolvedSongs] = useState<Song[] | null>(null);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (innerProps.albumIds) {
|
||||||
|
if (!server?.id) {
|
||||||
|
setResolvedSongs([]);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Promise.all(
|
||||||
|
innerProps.albumIds.map((id) =>
|
||||||
|
controller.getAlbumDetail({
|
||||||
|
apiClientProps: { serverId: server.id },
|
||||||
|
query: { id },
|
||||||
|
}),
|
||||||
|
),
|
||||||
|
).then((albums) => {
|
||||||
|
setResolvedSongs(
|
||||||
|
albums.flatMap((album) => album?.songs ?? []).filter((s) => s.path),
|
||||||
|
);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
setResolvedSongs((innerProps.songs ?? []).filter((s) => s.path));
|
||||||
|
}
|
||||||
|
}, [innerProps.albumIds, innerProps.songs, server?.id]);
|
||||||
|
|
||||||
|
if (resolvedSongs === null) {
|
||||||
|
return (
|
||||||
|
<Stack align="center" p="xl">
|
||||||
|
<Spinner />
|
||||||
|
</Stack>
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <SongEditModal songs={resolvedSongs} />;
|
||||||
|
};
|
||||||
@@ -175,9 +175,22 @@ const VisualizerSettingsContextModal = (props: any) => (
|
|||||||
</Suspense>
|
</Suspense>
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const LazySongEditContextModal = lazy(() =>
|
||||||
|
import('/@/renderer/features/tag-editor/components/song-edit-context-modal').then((module) => ({
|
||||||
|
default: module.SongEditContextModal,
|
||||||
|
})),
|
||||||
|
);
|
||||||
|
|
||||||
|
const SongEditContextModal = (props: any) => (
|
||||||
|
<Suspense fallback={<Spinner container />}>
|
||||||
|
<LazySongEditContextModal {...props} />
|
||||||
|
</Suspense>
|
||||||
|
);
|
||||||
|
|
||||||
const appRouterModals = {
|
const appRouterModals = {
|
||||||
addToPlaylist: AddToPlaylistContextModal,
|
addToPlaylist: AddToPlaylistContextModal,
|
||||||
base: BaseContextModal,
|
base: BaseContextModal,
|
||||||
|
editMetadata: SongEditContextModal,
|
||||||
lyricsSettings: LyricsSettingsContextModal,
|
lyricsSettings: LyricsSettingsContextModal,
|
||||||
saveAndReplace: SaveAndReplaceContextModal,
|
saveAndReplace: SaveAndReplaceContextModal,
|
||||||
settings: SettingsContextModal,
|
settings: SettingsContextModal,
|
||||||
|
|||||||
Reference in New Issue
Block a user