fix jamtrack autocomplete component
add debouncing technique to fetch data when fetching the data move the FingerprintJS initialization to the appDataContext so it is not instantiate eveytime
This commit is contained in:
parent
1e623e77de
commit
bd2d9410b5
|
|
@ -1,9 +1,8 @@
|
||||||
import React, { useEffect, useCallback, useState, useRef } from 'react';
|
import React, { useEffect, useState, useRef } from 'react';
|
||||||
import { Row, Col, FormGroup, Input, InputGroup, InputGroupText, ListGroup, ListGroupItem } from 'reactstrap';
|
import { Row, Col, FormGroup, Input, InputGroup, InputGroupText, ListGroup, ListGroupItem } from 'reactstrap';
|
||||||
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
|
||||||
import { useTranslation } from 'react-i18next';
|
|
||||||
import { autocompleteJamTracks } from '../../helpers/rest';
|
|
||||||
import PropTypes from 'prop-types';
|
import PropTypes from 'prop-types';
|
||||||
|
import useDebouncedValue from '../../hooks/useDebounceValue';
|
||||||
|
|
||||||
const JKJamTracksAutoComplete = ({
|
const JKJamTracksAutoComplete = ({
|
||||||
fetchFunc,
|
fetchFunc,
|
||||||
|
|
@ -19,54 +18,54 @@ const JKJamTracksAutoComplete = ({
|
||||||
const [songs, setSongs] = useState([]);
|
const [songs, setSongs] = useState([]);
|
||||||
const [loading, setLoading] = useState(false);
|
const [loading, setLoading] = useState(false);
|
||||||
const inputRef = useRef(null);
|
const inputRef = useRef(null);
|
||||||
const { t } = useTranslation();
|
|
||||||
const MIN_FILTER_SIZE = 3;
|
|
||||||
const MIN_FETCH_LIMIT = 5;
|
const MIN_FETCH_LIMIT = 5;
|
||||||
|
const DELAY = 400;
|
||||||
|
|
||||||
const fetchAutoCompleteResults = useCallback(() => {
|
const debouncedValue = useDebouncedValue(inputValue, DELAY);
|
||||||
|
|
||||||
|
const fetchAutoCompleteResults = () => {
|
||||||
// fetch tracks
|
// fetch tracks
|
||||||
setLoading(true);
|
setLoading(true);
|
||||||
fetchFunc(inputValue, MIN_FETCH_LIMIT)
|
fetchFunc(debouncedValue, MIN_FETCH_LIMIT)
|
||||||
.then(resp => {
|
.then(resp => {
|
||||||
return resp.json();
|
return resp.json();
|
||||||
})
|
})
|
||||||
.then(data => {
|
.then(data => {
|
||||||
console.log('tracks', data);
|
console.log('tracks', data);
|
||||||
if (data.songs) {
|
if (data.songs) {
|
||||||
const updatedSongs = data.songs.map(song => {
|
const updatedSongs = data.songs.map(song => {
|
||||||
song.type = 'song';
|
song.type = 'song';
|
||||||
return song;
|
return song;
|
||||||
});
|
});
|
||||||
setSongs(updatedSongs);
|
setSongs(updatedSongs);
|
||||||
}
|
}
|
||||||
if (data.artists) {
|
if (data.artists) {
|
||||||
const updatedArtists = data.artists.map(artist => {
|
const updatedArtists = data.artists.map(artist => {
|
||||||
artist.type = 'artist';
|
artist.type = 'artist';
|
||||||
return artist;
|
return artist;
|
||||||
});
|
});
|
||||||
setArtists(updatedArtists);
|
setArtists(updatedArtists);
|
||||||
}
|
}
|
||||||
if (data.jamtracks) {
|
if (data.jamtracks) {
|
||||||
const updatedSongs = data.jamtracks.map(song => {
|
const updatedSongs = data.jamtracks.map(song => {
|
||||||
song.type = 'song';
|
song.type = 'song';
|
||||||
return song;
|
return song;
|
||||||
});
|
});
|
||||||
setSongs(updatedSongs);
|
setSongs(updatedSongs);
|
||||||
}
|
}
|
||||||
setShowDropdown(true);
|
setShowDropdown(true);
|
||||||
})
|
})
|
||||||
.finally(() => {
|
.finally(() => {
|
||||||
setLoading(false);
|
setLoading(false);
|
||||||
});
|
});
|
||||||
}, [inputValue]);
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (inputValue && inputValue.length >= MIN_FILTER_SIZE) {
|
console.log('debounced value', debouncedValue)
|
||||||
fetchAutoCompleteResults();
|
if(debouncedValue && debouncedValue.length > 0){
|
||||||
} else {
|
fetchAutoCompleteResults()
|
||||||
setShowDropdown(false);
|
|
||||||
}
|
}
|
||||||
}, [inputValue]);
|
}, [debouncedValue]);
|
||||||
|
|
||||||
const handleInputChange = e => {
|
const handleInputChange = e => {
|
||||||
const val = e.target.value;
|
const val = e.target.value;
|
||||||
|
|
|
||||||
|
|
@ -82,6 +82,7 @@ const JKJamTracksFilter = () => {
|
||||||
const handleOnSelect = async selected => {
|
const handleOnSelect = async selected => {
|
||||||
page.current = 1;
|
page.current = 1;
|
||||||
setJamTracks([]);
|
setJamTracks([]);
|
||||||
|
setNextOffset(null)
|
||||||
setSearchTerm('');
|
setSearchTerm('');
|
||||||
setSelected(selected);
|
setSelected(selected);
|
||||||
const params = queryOptions(selected);
|
const params = queryOptions(selected);
|
||||||
|
|
@ -91,6 +92,7 @@ const JKJamTracksFilter = () => {
|
||||||
const handleOnEnter = async queryStr => {
|
const handleOnEnter = async queryStr => {
|
||||||
page.current = 1;
|
page.current = 1;
|
||||||
setJamTracks([]);
|
setJamTracks([]);
|
||||||
|
setNextOffset(null);
|
||||||
setSelected(x => null);
|
setSelected(x => null);
|
||||||
setSearchTerm(queryStr);
|
setSearchTerm(queryStr);
|
||||||
const params = queryOptions(queryStr);
|
const params = queryOptions(queryStr);
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import useUserProfile from '../hooks/useUserProfile';
|
import useUserProfile from '../hooks/useUserProfile';
|
||||||
import { useAuth } from './UserAuth';
|
import { useAuth } from './UserAuth';
|
||||||
//import { useShoppingCart } from '../hooks/useShoppingCart';
|
import FingerprintJS from '@fingerprintjs/fingerprintjs';
|
||||||
|
|
||||||
// AppDataContext.js
|
// AppDataContext.js
|
||||||
// this context is used to store app data that is shared across the app
|
// this context is used to store app data that is shared across the app
|
||||||
|
|
@ -11,16 +11,13 @@ export const AppDataProvider = ({ children }) => {
|
||||||
const [appData, setAppData] = React.useState({});
|
const [appData, setAppData] = React.useState({});
|
||||||
const { currentUser } = useAuth();
|
const { currentUser } = useAuth();
|
||||||
const { userProfile, photoUrl } = useUserProfile({ user: currentUser, useCache: false });
|
const { userProfile, photoUrl } = useUserProfile({ user: currentUser, useCache: false });
|
||||||
//const { shoppingCart, getCartItems } = useShoppingCart();
|
const fpPromise = FingerprintJS.load();
|
||||||
|
|
||||||
// React.useEffect(() => {
|
|
||||||
// getCartItems();
|
|
||||||
// }, [currentUser]);
|
|
||||||
|
|
||||||
React.useEffect(() => {
|
React.useEffect(() => {
|
||||||
setAppData({
|
setAppData({
|
||||||
userProfile, currentUserPhotoUrl:
|
userProfile, currentUserPhotoUrl:
|
||||||
photoUrl,
|
photoUrl,
|
||||||
|
fpPromise
|
||||||
});
|
});
|
||||||
}, [currentUser, userProfile, photoUrl]);
|
}, [currentUser, userProfile, photoUrl]);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
import { useEffect, useState } from "react";
|
||||||
|
const DEFAULT_DELAY = 500;
|
||||||
|
|
||||||
|
const useDebouncedValue = (
|
||||||
|
value = "",
|
||||||
|
delay = DEFAULT_DELAY
|
||||||
|
) => {
|
||||||
|
const [debouncedValue, setDebouncedValue] = useState(value);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
const timer = setTimeout(() => {
|
||||||
|
setDebouncedValue(value);
|
||||||
|
}, delay);
|
||||||
|
|
||||||
|
return () => clearTimeout(timer);
|
||||||
|
}, [value, delay]);
|
||||||
|
|
||||||
|
return debouncedValue;
|
||||||
|
};
|
||||||
|
|
||||||
|
export default useDebouncedValue;
|
||||||
|
|
@ -10,7 +10,7 @@ import {
|
||||||
import { SAMPLE_RATE } from '../helpers/jamTracks';
|
import { SAMPLE_RATE } from '../helpers/jamTracks';
|
||||||
import { createAlert } from '../helpers/rest';
|
import { createAlert } from '../helpers/rest';
|
||||||
import { useAuth } from '../context/UserAuth';
|
import { useAuth } from '../context/UserAuth';
|
||||||
import FingerprintJS from '@fingerprintjs/fingerprintjs';
|
import { useAppData } from '../context/AppDataContext';
|
||||||
|
|
||||||
export const useJamTrack = () => {
|
export const useJamTrack = () => {
|
||||||
|
|
||||||
|
|
@ -26,7 +26,7 @@ export const useJamTrack = () => {
|
||||||
const watchedMixdowns = useSelector(state => state.jamTrack.watchedMixdowns);
|
const watchedMixdowns = useSelector(state => state.jamTrack.watchedMixdowns);
|
||||||
|
|
||||||
const { currentUser } = useAuth();
|
const { currentUser } = useAuth();
|
||||||
const fpPromise = FingerprintJS.load();
|
const { fpPromise } = useAppData();
|
||||||
const dispatch = useDispatch();
|
const dispatch = useDispatch();
|
||||||
|
|
||||||
const [showQueueTime, setShowQueueTime] = useState(false);
|
const [showQueueTime, setShowQueueTime] = useState(false);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue