diff --git a/App.tsx b/App.tsx index 9e66199..68d76cf 100644 --- a/App.tsx +++ b/App.tsx @@ -15,8 +15,7 @@ import MyStatusBar from '@app/features/commons/components/StatusBar'; import {BottomSheetHomeProvider} from '@app/containers/BottomSheetHomeContext'; import GlobalContext from '@app/containers'; - -export const queryClient = new QueryClient(); +import {queryClient} from '@app/lib/react-query'; const App = () => { return ( diff --git a/android/fastlane/Fastfile b/android/fastlane/Fastfile index e338621..990cced 100644 --- a/android/fastlane/Fastfile +++ b/android/fastlane/Fastfile @@ -23,17 +23,6 @@ platform :android do desc "Deploy a new version to the Google Play" lane :deploy do |options| - # Convertir el tipo de versión a número - version_map = { - 'major' => '1', - 'minor' => '2', - 'patch' => '3' - } - version_type = version_map[options[:version_type]] || '3' - - # Ejecutar el script con el tipo de versión como argumento - sh "echo #{version_type} | ./bump-release-numbers.sh" - # Leer las variables de GitHub Secrets directamente store_file = ENV["MYAPP_UPLOAD_STORE_FILE"] store_password = ENV["MYAPP_UPLOAD_STORE_PASSWORD"] @@ -68,5 +57,26 @@ platform :android do skip_upload_images: true, skip_upload_screenshots: true ) + + # --- AHORA ACTUALIZAMOS LA VERSIÓN PARA LA SIGUIENTE BUILD --- + version_map = { + 'major' => '1', + 'minor' => '2', + 'patch' => '3' + } + version_type = version_map[options[:version_type]] || '3' + + # Ejecutar el script con el tipo de versión como argumento + sh "echo #{version_type} | ./bump-release-numbers.sh" + + # --- SUBIR LOS CAMBIOS A GIT --- + commit_message = "🔖 Bump versión de desarrollo automática después de release" + branch_name = sh("git rev-parse --abbrev-ref HEAD").strip + + sh "git add ." + sh "git commit -m '#{commit_message}'" + sh "git push origin #{branch_name}" + + puts "✅ Versión subida a Google Play y número de versión actualizado en Git." end end diff --git a/android/fastlane/bump-release-numbers.sh b/android/fastlane/bump-release-numbers.sh index b5028e2..89bb9a9 100755 --- a/android/fastlane/bump-release-numbers.sh +++ b/android/fastlane/bump-release-numbers.sh @@ -30,6 +30,10 @@ fi IFS='.' read -r MAJOR MINOR PATCH <<< "$CURRENT_VERSION_NAME" # Lee la opción desde stdin +echo "Seleccione el tipo de incremento:" +echo "1) Major" +echo "2) Minor" +echo "3) Patch" read -r CHOICE # Valida y procesa la opción @@ -57,14 +61,18 @@ esac # Forma la nueva versión NEW_VERSION_NAME="$MAJOR.$MINOR.$PATCH" -NEW_VERSION_CODE=$((CURRENT_VERSION_CODE + 1)) +NEW_VERSION_CODE="$MAJOR$MINOR$PATCH" # Crea un archivo temporal TMP_FILE=$(mktemp) -# Actualiza el archivo build.gradle usando sed con un archivo temporal +# Actualiza el archivo build.gradle usando sed con compatibilidad universal sed "s/versionCode $CURRENT_VERSION_CODE/versionCode $NEW_VERSION_CODE/" "$GRADLE_FILE" > "$TMP_FILE" -sed -i "s/versionName \"$CURRENT_VERSION_NAME\"/versionName \"$NEW_VERSION_NAME\"/" "$TMP_FILE" +if [[ "$OSTYPE" == "darwin"* ]]; then + sed -i '' "s/versionName \"$CURRENT_VERSION_NAME\"/versionName \"$NEW_VERSION_NAME\"/" "$TMP_FILE" +else + sed -i "s/versionName \"$CURRENT_VERSION_NAME\"/versionName \"$NEW_VERSION_NAME\"/" "$TMP_FILE" +fi # Mueve el archivo temporal al original mv "$TMP_FILE" "$GRADLE_FILE" @@ -72,4 +80,4 @@ mv "$TMP_FILE" "$GRADLE_FILE" echo "versionCode actualizado de $CURRENT_VERSION_CODE a $NEW_VERSION_CODE" echo "versionName actualizado de $CURRENT_VERSION_NAME a $NEW_VERSION_NAME" -exit 0 +exit 0 \ No newline at end of file diff --git a/app/features/commons/components/Header/NotifyMeButton/hooks/useNotifyMeButton.ts b/app/features/commons/components/Header/NotifyMeButton/hooks/useNotifyMeButton.ts index e8eab03..2329849 100644 --- a/app/features/commons/components/Header/NotifyMeButton/hooks/useNotifyMeButton.ts +++ b/app/features/commons/components/Header/NotifyMeButton/hooks/useNotifyMeButton.ts @@ -1,42 +1,15 @@ -import React, {useEffect, useMemo, useState} from 'react'; - +import {useMemo} from 'react'; import {useUserContext} from '@app/containers/UserContext'; import {useTheme} from '@app/features/commons/theme/hooks/useTheme'; import {usePlaylistAllTracks} from '@app/features/commons/hooks/usePlaylistAllTracks'; -import { - isSavedPlaylistForNotify, - removePlaylistForNotify, - savePlaylistForNotify, -} from '@app/services/playlist'; -import {queryClient} from '../../../../../../../App'; +import {useToggleNotify} from '@app/features/commons/hooks/useToggleNotify'; export const useNotifyMeButton = (playlistId: string) => { const {isDarkMode} = useTheme(); - - const [isSaved, setIsSaved] = useState(false); - const [loadingToggle, setLoadingToggle] = useState(false); - const [checkingSaved, setCheckingSaved] = useState(false); const {tracks, hasNextPage} = usePlaylistAllTracks(playlistId); - const {user} = useUserContext(); - - const checkPlaylistForNotify = async () => { - if (user) { - setCheckingSaved(true); - const isSaved = await isSavedPlaylistForNotify(playlistId, user?.id); - setIsSaved(isSaved ?? false); - setCheckingSaved(false); - return isSaved; - } - }; - useEffect(() => { - const init = async () => { - const isSaved = await checkPlaylistForNotify(); - setIsSaved(isSaved ?? false); - }; - - init(); - }, []); + const {toggleNotify, isSaved, checkingSaved, loadingToggle} = + useToggleNotify(playlistId); const iconProps = useMemo(() => { if (isSaved) @@ -49,29 +22,10 @@ export const useNotifyMeButton = (playlistId: string) => { color: 'gray', iconName: 'material-symbols:notifications-off-outline-rounded', }; - }, [isSaved]); + }, [isSaved, isDarkMode]); const togglePlaylistSave = async () => { - if (user) { - setLoadingToggle(true); // Show loading indicator - - try { - if (!isSaved) { - // Always save the playlist, regardless of hasNextPage - await savePlaylistForNotify(playlistId, tracks, user?.id); - queryClient.invalidateQueries({queryKey: ['userPlaylists']}); - setIsSaved(true); - } else { - await removePlaylistForNotify(playlistId, user?.id); - queryClient.invalidateQueries({queryKey: ['userPlaylists']}); - setIsSaved(false); - } - } catch (error) { - console.error('Error saving/removing playlist:', error); - } - - setLoadingToggle(false); // Hide loading indicator - } + toggleNotify(tracks); }; return { @@ -79,7 +33,7 @@ export const useNotifyMeButton = (playlistId: string) => { checkingSaved, iconProps, canSavePlaylist: hasNextPage, - checkPlaylistForNotify, + isSaved, togglePlaylistSave, }; }; diff --git a/app/features/commons/components/Header/NotifyMeButton/index.tsx b/app/features/commons/components/Header/NotifyMeButton/index.tsx index 4423e9e..8bd828b 100644 --- a/app/features/commons/components/Header/NotifyMeButton/index.tsx +++ b/app/features/commons/components/Header/NotifyMeButton/index.tsx @@ -24,17 +24,20 @@ const NotifyMeButton = ({id}: Props) => { checkingSaved, } = useNotifyMeButton(id); - if (checkingSaved) + const showLoading = checkingSaved || canSavePlaylist; + const showSavingLoading = loadingToggle || checkingSaved || canSavePlaylist; + + if (showLoading) return ( ); return ( - {loadingToggle && } + {showSavingLoading && } + disabled={showSavingLoading} + onPress={togglePlaylistSave}> diff --git a/app/features/commons/hooks/useNotifyPlaylist.ts b/app/features/commons/hooks/useNotifyPlaylist.ts new file mode 100644 index 0000000..fb3a652 --- /dev/null +++ b/app/features/commons/hooks/useNotifyPlaylist.ts @@ -0,0 +1,89 @@ +import {useMutation, useQuery, useQueryClient} from '@tanstack/react-query'; +import { + removePlaylistForNotify, + savePlaylistForNotify, + isSavedPlaylistForNotify, +} from '@app/services/playlist'; +import {PlaylistItem, UserAddedPlaylistsResponse} from '@app/services/types'; +import {QUERY_KEYS} from '@app/lib/queryKeys'; +import {useUserContext} from '@app/containers/UserContext'; + +export const useNotifyStatus = (playlistId: string) => { + const {user} = useUserContext(); + + return useQuery({ + queryKey: QUERY_KEYS.NOTIFY.playlist(playlistId, user?.id), + queryFn: () => isSavedPlaylistForNotify(playlistId, user?.id ?? ''), + enabled: !!user?.id, + staleTime: 5 * 60 * 1000, // 5 minutos + }); +}; + +export const useSaveNotify = (playlistId: string) => { + const {user} = useUserContext(); + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: async ({tracks}: {tracks: PlaylistItem[]}) => { + if (!user?.id) throw new Error('User ID is required'); + // Actualización optimista inmediata + return savePlaylistForNotify(playlistId, tracks, user?.id); + }, + onSuccess: () => { + queryClient.setQueryData( + QUERY_KEYS.NOTIFY.playlist(playlistId, user?.id), + true, + ); + queryClient.refetchQueries([QUERY_KEYS.USER_NOTIFIED_PLAYLISTS]); + }, + onError: () => { + queryClient.setQueryData( + QUERY_KEYS.NOTIFY.playlist(playlistId, user?.id), + false, + ); + }, + }); +}; + +export const useRemoveNotify = (playlistId: string) => { + const {user} = useUserContext(); + const queryClient = useQueryClient(); + + return useMutation({ + mutationFn: async () => { + if (!user?.id) throw new Error('User ID is required'); + queryClient.setQueryData( + QUERY_KEYS.NOTIFY.playlist(playlistId, user?.id), + false, + ); + + return removePlaylistForNotify(playlistId, user?.id); + }, + onSuccess: () => { + console.log( + 'onsuccedss', + queryClient.getQueryData([QUERY_KEYS.USER_NOTIFIED_PLAYLISTS]), + ); + + queryClient.setQueryData( + [QUERY_KEYS.USER_NOTIFIED_PLAYLISTS], + oldData => + oldData?.filter(item => item.playlistId !== playlistId) ?? [], + ); + }, + onError: () => { + console.log('onError'); + + queryClient.setQueryData( + QUERY_KEYS.NOTIFY.playlist(playlistId, user?.id), + true, + ); + + queryClient.setQueryData( + [QUERY_KEYS.USER_NOTIFIED_PLAYLISTS], + oldData => + oldData?.filter(item => item.playlistId !== playlistId) ?? [], + ); + }, + }); +}; diff --git a/app/features/commons/hooks/usePlaylist.ts b/app/features/commons/hooks/usePlaylist.ts index 11829f1..d0c6ef7 100644 --- a/app/features/commons/hooks/usePlaylist.ts +++ b/app/features/commons/hooks/usePlaylist.ts @@ -1,5 +1,6 @@ import {useQuery} from '@tanstack/react-query'; import {getPlaylist} from '../../../services/playlist'; +import {QUERY_KEYS} from '@app/lib/queryKeys'; interface Props { playlistId: string; @@ -7,9 +8,11 @@ interface Props { export const usePlaylist = ({playlistId}: Props) => { const playlistReq = useQuery({ - queryKey: ['playlist', playlistId], + queryKey: [QUERY_KEYS.PLAYLIST_DETAIL, playlistId], queryFn: () => getPlaylist(playlistId), retry: 3, + staleTime: 5 * 60 * 1000, // 5 minutos + cacheTime: 30 * 60 * 1000, // 30 minutos }); return playlistReq; diff --git a/app/features/commons/hooks/usePlaylistAllTracks.ts b/app/features/commons/hooks/usePlaylistAllTracks.ts index 729b70c..c5d0613 100644 --- a/app/features/commons/hooks/usePlaylistAllTracks.ts +++ b/app/features/commons/hooks/usePlaylistAllTracks.ts @@ -1,12 +1,10 @@ import {useInfiniteQuery} from '@tanstack/react-query'; import {getPlaylistTracks} from '../../../services/playlist'; -export const usePlaylistAllTracks = (playlistId: string) => { - const fetchTracks = async ({pageParam = ''}) => { - const res = await getPlaylistTracks(playlistId, pageParam); - return res; - }; +import React, {useEffect} from 'react'; +import {QUERY_KEYS} from '@app/lib/queryKeys'; +export const usePlaylistAllTracks = (playlistId: string) => { const { data, fetchNextPage, @@ -16,18 +14,26 @@ export const usePlaylistAllTracks = (playlistId: string) => { error, refetch, } = useInfiniteQuery({ - queryKey: ['playlistAllTracks', playlistId], - queryFn: fetchTracks, - getNextPageParam: (lastPage, allPages) => { - return lastPage?.next; - }, + queryKey: QUERY_KEYS.playlistTracks(playlistId), + queryFn: ({pageParam = ''}) => getPlaylistTracks(playlistId, pageParam), + getNextPageParam: lastPage => lastPage?.next || undefined, keepPreviousData: true, + staleTime: 5 * 60 * 1000, // 5 minutos + cacheTime: 30 * 60 * 1000, // 30 minutos }); - if (hasNextPage) fetchNextPage(); + // Memoizar el flatMap para evitar recálculos innecesarios + const tracks = React.useMemo( + () => data?.pages.flatMap(page => page?.items ?? []) ?? [], + [data?.pages], + ); - //flatMapping data for getting only tracks items - const tracks = data?.pages.flatMap(page => page?.items ?? []) ?? []; + // Cargar siguiente página solo si hay más y no estamos ya cargando + useEffect(() => { + if (hasNextPage && !isFetching) { + fetchNextPage(); + } + }, [hasNextPage, isFetching, fetchNextPage]); return { tracks, diff --git a/app/features/commons/hooks/useToggleNotify.ts b/app/features/commons/hooks/useToggleNotify.ts new file mode 100644 index 0000000..8e298a1 --- /dev/null +++ b/app/features/commons/hooks/useToggleNotify.ts @@ -0,0 +1,32 @@ +import { + useNotifyStatus, + useSaveNotify, + useRemoveNotify, +} from './useNotifyPlaylist'; +import {PlaylistItem} from '@app/services/types'; + +export const useToggleNotify = (playlistId: string) => { + const {data: isSaved = false, isLoading: checkingSaved} = + useNotifyStatus(playlistId); + + const {mutate: saveNotify, isLoading: loadingSave} = + useSaveNotify(playlistId); + + const {mutate: removeNotify, isLoading: loadingRemove} = + useRemoveNotify(playlistId); + + const toggleNotify = (tracks: PlaylistItem[]) => { + if (isSaved) { + removeNotify(); + } else { + saveNotify({tracks}); + } + }; + + return { + toggleNotify, + isSaved, + checkingSaved, + loadingToggle: loadingSave, + }; +}; diff --git a/app/features/commons/hooks/useUserNotifiedPlaylists.ts b/app/features/commons/hooks/useUserNotifiedPlaylists.ts index 701d4d9..c9f4a77 100644 --- a/app/features/commons/hooks/useUserNotifiedPlaylists.ts +++ b/app/features/commons/hooks/useUserNotifiedPlaylists.ts @@ -2,6 +2,7 @@ import {useQuery} from '@tanstack/react-query'; import {useUserContext} from '../../../containers/UserContext'; import {getUserNotifiedPlaylists} from '../../../services/user'; import {useEffect} from 'react'; +import {QUERY_KEYS} from '@app/lib/queryKeys'; export const useUserNotifiedPlaylists = () => { const {user} = useUserContext(); @@ -12,16 +13,18 @@ export const useUserNotifiedPlaylists = () => { if (fetchedPlaylists) return fetchedPlaylists; } + + return []; }; const {data, refetch, isRefetching, isLoading} = useQuery({ - queryKey: ['userPlaylists'], + queryKey: [QUERY_KEYS.USER_NOTIFIED_PLAYLISTS], queryFn: getNotifiedPlaylists, enabled: !!user, // Start the query only when user is available - keepPreviousData: true, retry: 3, - cacheTime: 600000, - refetchOnWindowFocus: 'always', + staleTime: 5 * 60 * 1000, // 5 minutos + cacheTime: 30 * 60 * 1000, // 30 minutos + // refetchOnWindowFocus: true, }); return { diff --git a/app/lib/queryKeys.ts b/app/lib/queryKeys.ts new file mode 100644 index 0000000..c44963c --- /dev/null +++ b/app/lib/queryKeys.ts @@ -0,0 +1,30 @@ +export const QUERY_KEYS = { + // User related keys + USER_PROFILE: 'userProfile', + USER_PLAYLISTS: 'userPlaylists', + USER_NOTIFIED_PLAYLISTS: 'userNotifiedPlaylists', + + // Track related keys + TRACK_DETAIL: 'trackDetail', + + // Search related keys + SEARCH_PLAYLISTS: 'searchPlaylists', + + // Playlist related keys + PLAYLIST_DETAIL: 'playlistDetail', + PLAYLIST_TRACKS: 'playlistTracks', + PLAYLIST_IS_SAVED: 'playlistIsSaved', + + // Notify related keys + NOTIFY: { + all: ['notify'], + playlist: (playlistId: string, userId?: string) => [ + 'notify', + playlistId, + userId, + ], + }, + + playlistTracks: (playlistId: string) => + ['playlist', playlistId, 'tracks'] as const, +} as const; diff --git a/app/lib/react-query.ts b/app/lib/react-query.ts new file mode 100644 index 0000000..42015f5 --- /dev/null +++ b/app/lib/react-query.ts @@ -0,0 +1,11 @@ +import {QueryClient} from '@tanstack/react-query'; + +export const queryClient = new QueryClient({ + defaultOptions: { + queries: { + retry: 2, + staleTime: 1000 * 60 * 5, // 5 minutes + cacheTime: 1000 * 60 * 30, // 30 minutes + }, + }, +}); \ No newline at end of file diff --git a/app/screens/playlists-for-notify/components/PlaylistList/index.tsx b/app/screens/playlists-for-notify/components/PlaylistList/index.tsx index b42bc1d..de0a8fd 100644 --- a/app/screens/playlists-for-notify/components/PlaylistList/index.tsx +++ b/app/screens/playlists-for-notify/components/PlaylistList/index.tsx @@ -1,26 +1,27 @@ import React, {useEffect, useState} from 'react'; import {useTranslation} from 'react-i18next'; -import Animated, {Layout} from 'react-native-reanimated'; +import Animated from 'react-native-reanimated'; import { + ActivityIndicator, Alert, FlatList, Image, RefreshControl, + ScrollView, StyleSheet, TouchableOpacity, View, } from 'react-native'; -import {RootStackParamList, RootTabsParamList} from '@app/navigation'; -import {useNavigation} from '@react-navigation/native'; -import {removePlaylistForNotify} from '@app/services/playlist'; -import {NativeStackNavigationProp} from '@react-navigation/native-stack'; - import PlaylistListItem from '../PlaylistListItem'; import SwipeableItem from '../PlaylistListItem/components/SwipableItem'; import {UserAddedPlaylistsResponse} from '../../../../services/types'; import Text from '@app/features/commons/layout/Text'; +import {useUserNotifiedPlaylists} from '@app/features/commons/hooks/useUserNotifiedPlaylists'; +import Layout from '@app/features/commons/layout/TabLayout'; +import Monicon from '@monicon/native'; +import {PoweredBySpotify} from '@app/features/commons/components/PoweredBySpotify'; const defaultPlaylist = { id: '4OYwdvuAT2msLdqmNVUQD4', @@ -28,54 +29,17 @@ const defaultPlaylist = { name: 'holAloh', }; -type Props = { - isLoading: boolean; - isRefetching: boolean; - refetch: () => void; - userNotifiedPlaylists: UserAddedPlaylistsResponse[]; -}; - -const PlaylistList = ({ - isLoading, - isRefetching, - refetch, - userNotifiedPlaylists, -}: Props) => { - const {t} = useTranslation(); - const navigation = - useNavigation>(); - const tabNavigation = - useNavigation>(); - - const showAlert = (item: UserAddedPlaylistsResponse) => - Alert.alert( - 'Confirmar Acción', - '¿Estás seguro de que deseas realizar esta acción?', - [ - { - text: 'Cancelar', - onPress: () => console.log('Acción cancelada'), - style: 'cancel', - }, - { - text: 'Eliminar', - onPress: async () => { - await removePlaylistForNotify(item.playlistId, item.userId); - refetch(); - // swipableRef?.current?.close(); - }, - style: 'destructive', - }, - ], - { - cancelable: true, - }, - ); +const PlaylistList = () => { + const { + userNotifiedPlaylists, + isLoading, + isRefetching, + refetchUserNotifiesPlaylists, + } = useUserNotifiedPlaylists(); - useEffect(() => { - if (userNotifiedPlaylists) - userNotifiedPlaylists.map(item => console.log(item.playlistId)); - }, [userNotifiedPlaylists]); + if (isLoading) { + return ; + } return ( item.id} refreshControl={ - + } renderItem={({ item, @@ -96,14 +63,92 @@ const PlaylistList = ({ index: number; }) => { return ( - showAlert(item)}> - - + + ); + }} + ListEmptyComponent={() => { + return ( + + + } + contentContainerStyle={{ + flex: 1, + justifyContent: 'center', + alignItems: 'center', + marginVertical: 12, + marginHorizontal: 20, + rowGap: 48, + }} + style={styles.nodataContainer}> + + + ¿Todavía no has seleccionado ninguna lista para que te + notifiquemos? + + + + Para poder notificarte sobre la actualización de una lista de + reproducción, primero deberás de seleccionar alguna. + + + Accede desde tu foto de perfil a tus playlists, en la parte + superior derecha, o utiliza el buscador para encontrar una en + concreto. + + {/* + Puedes probar con esta: + { + navigation.navigate('Playlist', {id: defaultPlaylist.id}); + }}> + + + */} + + + Marca el icono de notificación en la cabecera de las listas + de reproducción. + + + + + + + + + + + ); }} /> diff --git a/app/screens/playlists-for-notify/components/PlaylistListItem/index.tsx b/app/screens/playlists-for-notify/components/PlaylistListItem/index.tsx index 32f1d24..283c96d 100644 --- a/app/screens/playlists-for-notify/components/PlaylistListItem/index.tsx +++ b/app/screens/playlists-for-notify/components/PlaylistListItem/index.tsx @@ -1,7 +1,7 @@ import React, {useEffect, useMemo} from 'react'; import {useTranslation} from 'react-i18next'; -import {Image, StyleSheet, TouchableOpacity, View} from 'react-native'; +import {Alert, Image, StyleSheet, TouchableOpacity, View} from 'react-native'; import Animated, { FadeInLeft, FadeOutRight, @@ -17,6 +17,10 @@ import {usePlaylist} from '../../../../features/commons/hooks/usePlaylist'; import {useBottomSheetContext} from '../../../../containers/BottomSheetHomeContext'; import {usePlaylistAllTracks} from '../../../../features/commons/hooks/usePlaylistAllTracks'; import Monicon from '@monicon/native'; +import {QUERY_KEYS} from '@app/lib/queryKeys'; +import {queryClient} from '@app/lib/react-query'; +import SwipeableItem from './components/SwipableItem'; +import {useRemoveNotify} from '@app/features/commons/hooks/useNotifyPlaylist'; interface Props { playlistId: string; @@ -31,15 +35,45 @@ const PlaylistListItem = ({ index, isRefetching, }: Props) => { - const {tracks, hasNextPage, refetch} = usePlaylistAllTracks(playlistId); + const {tracks, hasNextPage} = usePlaylistAllTracks(playlistId); const {data: playlist, isLoading} = usePlaylist({playlistId: playlistId}); const {t} = useTranslation(); const {isDarkMode} = useTheme(); const {handlePresentModalPress, compareAllData} = useBottomSheetContext(); + const {mutateAsync: removePlaylistForNotify} = useRemoveNotify(playlistId); + useEffect(() => { - refetch(); - }, [isRefetching]); + if (isRefetching) { + queryClient.refetchQueries({ + queryKey: QUERY_KEYS.playlistTracks(playlistId), + exact: true, + }); + } + }, [isRefetching, playlistId]); + + const showAlert = () => + Alert.alert( + 'Confirmar Acción', + '¿Estás seguro de que deseas realizar esta acción?', + [ + { + text: 'Cancelar', + onPress: () => console.log('Acción cancelada'), + style: 'cancel', + }, + { + text: 'Eliminar', + onPress: async () => { + await removePlaylistForNotify(); + }, + style: 'destructive', + }, + ], + { + cancelable: true, + }, + ); const onPress = () => { if (playlist && tracksUpdate) { @@ -61,12 +95,20 @@ const PlaylistListItem = ({ if (!hasNextPage) { const resultNew = tracks.filter(item1 => { return !savedPlaylistTracksIds.some(item2 => { + if (!item2 || !item1.track) { + return true; + } + return item1.track.id === item2; }); }); const resultDeleted = savedPlaylistTracksIds.filter(item1 => { return !tracks.some(item2 => { + if (!item1 || !item2.track) { + return true; + } + return item1 === item2.track.id; }); }); @@ -94,62 +136,65 @@ const PlaylistListItem = ({ if (!tracksUpdate) return ; return ( - - - - - - - - - {playlist.name} - - - {tracksUpdate.resultNew.length === 0 && - tracksUpdate.resultDeleted.length === 0 ? ( - - {t('no_tracks_new_or_deleted')} - - ) : ( + + + + + + + + + {playlist.name} + + + {tracksUpdate.resultNew.length === 0 && + tracksUpdate.resultDeleted.length === 0 ? ( - - - {tracksUpdate.resultNew.length}{' '} - {t('tracks_added').toLowerCase()} - + {t('no_tracks_new_or_deleted')} - - - - {tracksUpdate.resultDeleted.length}{' '} - {t('tracks_deleted').toLowerCase()} - + ) : ( + + + + + {tracksUpdate.resultNew.length}{' '} + {t('tracks_added').toLowerCase()} + + + + + + {tracksUpdate.resultDeleted.length}{' '} + {t('tracks_deleted').toLowerCase()} + + - - )} + )} + - - - + + + ); }; diff --git a/app/screens/playlists-for-notify/index.tsx b/app/screens/playlists-for-notify/index.tsx index a766ca3..ceea920 100644 --- a/app/screens/playlists-for-notify/index.tsx +++ b/app/screens/playlists-for-notify/index.tsx @@ -25,150 +25,14 @@ import Animated, {FadeIn} from 'react-native-reanimated'; import Monicon from '@monicon/native'; import {PoweredBySpotify} from '@app/features/commons/components/PoweredBySpotify'; -type Props = { - isLoading: boolean; - isRefetching: boolean; - refetch: () => void; - userNotifiedPlaylists: UserAddedPlaylistsResponse[]; -}; - const PlaylistsForNotifyScreen = () => { - const {isLoading, isRefetching, refetch, userNotifiedPlaylists} = useHome(); - const {ref} = useBottomSheetContext(); const snapPoints = useMemo(() => ['50%'], []); - const {t} = useTranslation(); - const navigation = - useNavigation>(); - - const showAlert = (item: UserAddedPlaylistsResponse) => - Alert.alert( - 'Confirmar Acción', - '¿Estás seguro de que deseas realizar esta acción?', - [ - { - text: 'Cancelar', - onPress: () => console.log('Acción cancelada'), - style: 'cancel', - }, - { - text: 'Eliminar', - onPress: async () => { - await removePlaylistForNotify(item.playlistId, item.userId); - refetch(); - // swipableRef?.current?.close(); - }, - style: 'destructive', - }, - ], - { - cancelable: true, - }, - ); - - useEffect(() => { - if (userNotifiedPlaylists) - userNotifiedPlaylists.map(item => console.log(item.playlistId)); - }, [userNotifiedPlaylists]); - - if (isLoading) - return ( - - - {t('loading_notified_playlists')} - - - - ); - - if (!userNotifiedPlaylists) { - return null; - } - - if (userNotifiedPlaylists?.length === 0) - return ( - - - } - contentContainerStyle={{ - flex: 1, - justifyContent: 'center', - alignItems: 'center', - marginVertical: 12, - marginHorizontal: 20, - rowGap: 48, - }} - style={styles.nodataContainer}> - - - ¿Todavía no has seleccionado ninguna lista para que te - notifiquemos? - - - - Para poder notificarte sobre la actualización de una lista de - reproducción, primero deberás de seleccionar alguna. - - - Accede desde tu foto de perfil a tus playlists, en la parte - superior derecha, o utiliza el buscador para encontrar una en - concreto. - - {/* - Puedes probar con esta: - { - navigation.navigate('Playlist', {id: defaultPlaylist.id}); - }}> - - - */} - - - Marca el icono de notificación en la cabecera de las listas de - reproducción. - - - - - - - - - - - - ); - return ( - + => { - try { - const data = await HttpClient({ - baseURL: API_URL, - url: '/playlist/add', - method: 'post', - data: { - playlistId: playlistId, - tracks: tracks, - userId: userId, - }, - }); - // .then(({data}) => { - // console.log(data); - // return data; - // }) - // .catch((error: AxiosError) => console.log(error.response?.data)); + console.log('## Adding playlist for notify: ' + playlistId + ' ##'); - return data.data; - } catch { - return false; - } + const data = await HttpClient({ + baseURL: API_URL, + url: '/playlist/add', + method: 'post', + data: { + playlistId: playlistId, + tracks: tracks, + userId: userId, + }, + }); + + return data.data; }; export const removePlaylistForNotify = async (