Add owner to playlist update query

- Support smart playlist rules
- Add user list query
This commit is contained in:
jeffvli 2023-01-04 18:33:49 -08:00
parent 75ef43dffb
commit d63e5f5784
13 changed files with 309 additions and 59 deletions

View file

@ -1,6 +1,6 @@
import { Group, Stack } from '@mantine/core';
import { useForm } from '@mantine/form';
import { CreatePlaylistQuery, ServerType } from '/@/renderer/api/types';
import { CreatePlaylistBody, ServerType } from '/@/renderer/api/types';
import { Button, Switch, TextInput, toast } from '/@/renderer/components';
import { useCreatePlaylist } from '/@/renderer/features/playlists/mutations/create-playlist-mutation';
import { useCurrentServer } from '/@/renderer/store';
@ -13,18 +13,20 @@ export const CreatePlaylistForm = ({ onCancel }: CreatePlaylistFormProps) => {
const mutation = useCreatePlaylist();
const server = useCurrentServer();
const form = useForm<CreatePlaylistQuery>({
const form = useForm<CreatePlaylistBody>({
initialValues: {
comment: '',
name: '',
public: false,
rules: undefined,
ndParams: {
public: false,
rules: undefined,
},
},
});
const handleSubmit = form.onSubmit((values) => {
mutation.mutate(
{ query: values },
{ body: values },
{
onError: (err) => {
toast.error({ message: err.message, title: 'Error creating playlist' });
@ -56,7 +58,7 @@ export const CreatePlaylistForm = ({ onCancel }: CreatePlaylistFormProps) => {
{isPublicDisplayed && (
<Switch
label="Is Public?"
{...form.getInputProps('public')}
{...form.getInputProps('ndParams.public')}
/>
)}
<Group position="right">

View file

@ -1,6 +1,7 @@
import { forwardRef, Fragment, Ref } from 'react';
import { Group, Stack } from '@mantine/core';
import { closeAllModals, openModal } from '@mantine/modals';
import { forwardRef, Fragment, Ref } from 'react';
import { useQueryClient } from '@tanstack/react-query';
import { RiMoreFill } from 'react-icons/ri';
import { generatePath, useNavigate, useParams } from 'react-router';
import { Link } from 'react-router-dom';
@ -14,6 +15,10 @@ import { AppRoute } from '/@/renderer/router/routes';
import { usePlayButtonBehavior } from '/@/renderer/store/settings.store';
import { LibraryItem, Play } from '/@/renderer/types';
import { formatDurationString } from '/@/renderer/utils';
import { UserListSort, SortOrder, UserListQuery } from '/@/renderer/api/types';
import { useCurrentServer } from '/@/renderer/store';
import { api } from '/@/renderer/api';
import { queryKeys } from '/@/renderer/api/query-keys';
interface PlaylistDetailHeaderProps {
background: string;
@ -27,10 +32,12 @@ export const PlaylistDetailHeader = forwardRef(
ref: Ref<HTMLDivElement>,
) => {
const navigate = useNavigate();
const queryClient = useQueryClient();
const { playlistId } = useParams() as { playlistId: string };
const detailQuery = usePlaylistDetail({ id: playlistId });
const handlePlayQueueAdd = usePlayQueueAdd();
const playButtonBehavior = usePlayButtonBehavior();
const server = useCurrentServer();
const handlePlay = (playType?: Play) => {
handlePlayQueueAdd?.({
@ -42,7 +49,20 @@ export const PlaylistDetailHeader = forwardRef(
});
};
const openUpdatePlaylistModal = () => {
const openUpdatePlaylistModal = async () => {
const query: UserListQuery = {
sortBy: UserListSort.NAME,
sortOrder: SortOrder.ASC,
startIndex: 0,
};
const users = await queryClient.fetchQuery({
queryFn: ({ signal }) => api.controller.getUserList({ query, server, signal }),
queryKey: queryKeys.users.list(server?.id || '', query),
});
const normalizedUsers = api.normalize.userList(users, server);
openModal({
children: (
<UpdatePlaylistForm
@ -50,10 +70,16 @@ export const PlaylistDetailHeader = forwardRef(
comment: detailQuery?.data?.description || undefined,
genres: detailQuery?.data?.genres,
name: detailQuery?.data?.name,
public: detailQuery?.data?.public || false,
rules: detailQuery?.data?.rules || undefined,
ndParams: {
owner: detailQuery?.data?.owner || undefined,
ownerId: detailQuery?.data?.ownerId || undefined,
public: detailQuery?.data?.public || false,
rules: detailQuery?.data?.rules || undefined,
sync: detailQuery?.data?.sync || undefined,
},
}}
query={{ id: playlistId }}
users={normalizedUsers.items}
onCancel={closeAllModals}
/>
),

View file

@ -1,27 +1,37 @@
import { Group, Stack } from '@mantine/core';
import { useForm } from '@mantine/form';
import { ServerType, UpdatePlaylistBody, UpdatePlaylistQuery } from '/@/renderer/api/types';
import { Button, Switch, TextInput, toast } from '/@/renderer/components';
import { ServerType, UpdatePlaylistBody, UpdatePlaylistQuery, User } from '/@/renderer/api/types';
import { Button, Select, Switch, TextInput, toast } from '/@/renderer/components';
import { useUpdatePlaylist } from '/@/renderer/features/playlists/mutations/update-playlist-mutation';
import { useCurrentServer } from '/@/renderer/store';
interface CreatePlaylistFormProps {
interface UpdatePlaylistFormProps {
body: Partial<UpdatePlaylistBody>;
onCancel: () => void;
query: UpdatePlaylistQuery;
users?: User[];
}
export const UpdatePlaylistForm = ({ query, body, onCancel }: CreatePlaylistFormProps) => {
export const UpdatePlaylistForm = ({ users, query, body, onCancel }: UpdatePlaylistFormProps) => {
const mutation = useUpdatePlaylist();
const server = useCurrentServer();
const userList = users?.map((user) => ({
label: user.name,
value: user.id,
}));
const form = useForm<UpdatePlaylistBody>({
initialValues: {
comment: '',
name: '',
public: false,
rules: undefined,
...body,
comment: body?.comment || '',
name: body?.name || '',
ndParams: {
owner: body?.ndParams?.owner || '',
ownerId: body?.ndParams?.ownerId || '',
public: body?.ndParams?.public || false,
rules: undefined,
sync: body?.ndParams?.sync || false,
},
},
});
@ -56,6 +66,11 @@ export const UpdatePlaylistForm = ({ query, body, onCancel }: CreatePlaylistForm
label="Description"
{...form.getInputProps('comment')}
/>
<Select
data={userList || []}
{...form.getInputProps('ndParams.ownerId')}
label="Owner"
/>
{isPublicDisplayed && (
<Switch
label="Is Public?"

View file

@ -0,0 +1 @@
export * from './queries/user-list-query';

View file

@ -0,0 +1,22 @@
import { useQuery } from '@tanstack/react-query';
import { useCallback } from 'react';
import { queryKeys } from '/@/renderer/api/query-keys';
import type { RawUserListResponse, UserListQuery } from '/@/renderer/api/types';
import { useCurrentServer } from '/@/renderer/store';
import { api } from '/@/renderer/api';
import type { QueryOptions } from '/@/renderer/lib/react-query';
export const useUserList = (query: UserListQuery, options?: QueryOptions) => {
const server = useCurrentServer();
return useQuery({
enabled: !!server?.id,
queryFn: ({ signal }) => api.controller.getUserList({ query, server, signal }),
queryKey: queryKeys.users.list(server?.id || '', query),
select: useCallback(
(data: RawUserListResponse | undefined) => api.normalize.userList(data, server),
[server],
),
...options,
});
};