mirror of
https://github.com/Jellify-Music/App.git
synced 2026-03-17 10:40:38 -05:00
fullscreen modal, filter out current owner of playlist, callbacks for functionality
This commit is contained in:
@@ -8,10 +8,15 @@ import { useInfiniteQuery, useMutation, useQuery } from '@tanstack/react-query'
|
||||
import { fetchUserPlaylists, fetchPublicPlaylists, fetchPlaylistTracks } from './utils'
|
||||
import { ApiLimits } from '../../../configs/query.config'
|
||||
import { getApi, getUser, useJellifyLibrary } from '../../../stores'
|
||||
import { BaseItemDto } from '@jellyfin/sdk/lib/generated-client'
|
||||
import { BaseItemDto, PlaylistUserPermissions, UserDto } from '@jellyfin/sdk/lib/generated-client'
|
||||
import { QueryKeys } from '../../../enums/query-keys'
|
||||
import { addPlaylistUser, getPlaylistUsers, removePlaylistUser } from './utils/users'
|
||||
import { ONE_MINUTE } from '../../../constants/query-client'
|
||||
import { ONE_MINUTE, queryClient } from '../../../constants/query-client'
|
||||
import { User } from '@sentry/react-native'
|
||||
import { triggerHaptic } from '@/src/hooks/use-haptic-feedback'
|
||||
import { previous } from '@/src/hooks/player/functions/controls'
|
||||
import { userEvent } from '@testing-library/react-native'
|
||||
import Toast from 'react-native-toast-message'
|
||||
|
||||
export const useUserPlaylists = () => {
|
||||
const api = getApi()
|
||||
@@ -73,8 +78,8 @@ export const usePlaylistUsers = (playlist: BaseItemDto) => {
|
||||
}
|
||||
|
||||
interface addPlaylistUserMutation {
|
||||
playlistId: string
|
||||
userId: string
|
||||
playlist: BaseItemDto
|
||||
user: UserDto
|
||||
CanEdit: boolean
|
||||
}
|
||||
|
||||
@@ -84,18 +89,53 @@ export const useAddPlaylistUser = () => {
|
||||
return useMutation({
|
||||
//playlistId: string, userId: string, CanEdit: boolean
|
||||
mutationFn: (variables: addPlaylistUserMutation) =>
|
||||
addPlaylistUser(variables.playlistId, variables.userId, variables.CanEdit),
|
||||
addPlaylistUser(variables.playlist.Id!, variables.user.Id!, variables.CanEdit),
|
||||
|
||||
onSuccess: (data, variables) => {
|
||||
triggerHaptic('notificationSuccess')
|
||||
queryClient.setQueryData(
|
||||
PlaylistUsersQueryKey(variables.playlist),
|
||||
(previous: PlaylistUserPermissions[] | undefined) => {
|
||||
if (previous == undefined) {
|
||||
//return
|
||||
return [{ userId: variables.user.Id, canEdit: true }]
|
||||
} else {
|
||||
return [...previous, { userId: variables.user.Id, canEdit: true }]
|
||||
}
|
||||
},
|
||||
)
|
||||
},
|
||||
|
||||
onError: (error, variables) => {
|
||||
console.log(error)
|
||||
Toast.show({ type: 'error', text1: 'Unable to add user to playlist.' })
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
interface removePlaylistUser {
|
||||
playlistId: string
|
||||
userId: string
|
||||
playlist: BaseItemDto
|
||||
user: UserDto
|
||||
}
|
||||
|
||||
//remove user as playlist collaborator
|
||||
export const useRemovePlaylistUser = () => {
|
||||
return useMutation({
|
||||
mutationFn: (variables: removePlaylistUser) =>
|
||||
removePlaylistUser(variables.playlistId, variables.userId),
|
||||
removePlaylistUser(variables.playlist.Id!, variables.user.Id!),
|
||||
onSuccess: (data, variables) => {
|
||||
triggerHaptic('notificationSuccess')
|
||||
queryClient.setQueryData(
|
||||
PlaylistUsersQueryKey(variables.playlist),
|
||||
(previous: PlaylistUserPermissions[] | undefined) => {
|
||||
if (previous == undefined) {
|
||||
//return
|
||||
return []
|
||||
} else {
|
||||
return previous.filter((user) => user.UserId != variables.user.Id)
|
||||
}
|
||||
},
|
||||
)
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import { useQuery } from '@tanstack/react-query'
|
||||
import { UserQueryKey } from './keys'
|
||||
import { getApi } from '../../../stores'
|
||||
import { getApi, getUser } from '../../../stores'
|
||||
import { getUserApi } from '@jellyfin/sdk/lib/utils/api'
|
||||
|
||||
//hook to get users on server
|
||||
@@ -14,11 +14,17 @@ const fetchUsers = async () => {
|
||||
//use api (only get api when this function is called to get users)
|
||||
const api = getApi()
|
||||
|
||||
//get owner of playlist (self)
|
||||
const owner = getUser()
|
||||
|
||||
//check set
|
||||
if (!api) {
|
||||
throw new Error('API Instance not set')
|
||||
}
|
||||
|
||||
const usersResponse = await getUserApi(api).getUsers()
|
||||
|
||||
//return users where there isn't a user with owner id in array
|
||||
//return users from api
|
||||
return (await getUserApi(api).getUsers()).data
|
||||
return usersResponse.data.filter((user) => user.Id != owner?.id)
|
||||
}
|
||||
|
||||
@@ -1,7 +1,11 @@
|
||||
import { NativeStackNavigationProp } from '@react-navigation/native-stack'
|
||||
import LibraryStackParamList, { LibraryAddPlaylistUsers } from './types'
|
||||
import { Paragraph, Text, View, XStack, YStack } from 'tamagui'
|
||||
import { usePlaylistUsers } from '../../../src/api/queries/playlist'
|
||||
import {
|
||||
useAddPlaylistUser,
|
||||
usePlaylistUsers,
|
||||
useRemovePlaylistUser,
|
||||
} from '../../../src/api/queries/playlist'
|
||||
import { useUsers } from '../../../src/api/queries/users'
|
||||
import ItemImage from '../../../src/components/Global/components/image'
|
||||
import TextTicker from 'react-native-text-ticker'
|
||||
@@ -23,6 +27,12 @@ export default function addPlaylistUsers({
|
||||
} = usePlaylistUsers(playlist) //make this playlist an easy access variable (with const variable above)
|
||||
const { data: users, isPending: useUsersIsPending, refetch: refetchUseUsers } = useUsers()
|
||||
|
||||
//invoke mutations on icon press
|
||||
//add
|
||||
const addUser = useAddPlaylistUser()
|
||||
//remove
|
||||
const removeUser = useRemovePlaylistUser()
|
||||
|
||||
//get string array of all playlist user IDs
|
||||
const playlistUserIds = playlistUsers?.map((playlistUser) => playlistUser.UserId) ?? []
|
||||
|
||||
@@ -89,10 +99,27 @@ export default function addPlaylistUsers({
|
||||
imageOptions={{ maxWidth: 85, maxHeight: 85, quality: 90 }}
|
||||
/>
|
||||
<Paragraph>{user.Name ?? 'Unknown User'}</Paragraph>
|
||||
{playlistUserIds.includes(user.Id) ? (
|
||||
<Icon name='account-remove' color='$warning' />
|
||||
{playlistUserIds.includes(user.Id) ? ( //send playlist id and user id (with bang! because it likely won't be undefined)
|
||||
<Icon
|
||||
onPress={() =>
|
||||
removeUser.mutate({ playlist: playlist, user: user })
|
||||
}
|
||||
name='account-remove'
|
||||
color='$warning'
|
||||
/>
|
||||
) : (
|
||||
<Icon name='account-plus' color='$borderColor' />
|
||||
//same stuff and canEdit as true bcs you know anyone you're sharing with
|
||||
<Icon
|
||||
onPress={() =>
|
||||
addUser.mutate({
|
||||
playlist: playlist,
|
||||
user: user,
|
||||
CanEdit: true,
|
||||
})
|
||||
}
|
||||
name='account-plus'
|
||||
color='$borderColor'
|
||||
/>
|
||||
)}
|
||||
</XStack>
|
||||
)}
|
||||
|
||||
@@ -89,7 +89,7 @@ export default function LibraryScreen(): React.JSX.Element {
|
||||
options={{
|
||||
title: 'Add Playlist Users',
|
||||
presentation: 'formSheet',
|
||||
sheetAllowedDetents: Platform.OS === 'ios' ? 'fitToContents' : [0.5],
|
||||
sheetAllowedDetents: Platform.OS === 'ios' ? 'fitToContents' : [1.0], //screen full size
|
||||
}}
|
||||
/>
|
||||
|
||||
|
||||
Reference in New Issue
Block a user