Advertisement
Guest User

Untitled

a guest
May 7th, 2024
58
0
147 days
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 6.47 KB | None | 0 0
  1. import React, { useEffect, useState, useRef } from 'react';
  2. import style from './filteredSuggestions.scss';
  3. import axios from 'axios';
  4. import { AppendToLog } from 'Utils/Helper';
  5. import { HandleError, HandleResponse } from 'Handlers/Response';
  6.  
  7. function FilteredList({ suggestionsList, language, filterValue, index, handleSuggestionClick, inputRef }) {
  8. const [suggestions, setSuggestions] = useState([]);
  9. const [filteredSuggestions, setFilteredSuggestions] = useState([]);
  10. const [selectedIndex, setSelectedIndex] = useState(-1);
  11. const selectedIndexRef = useRef(selectedIndex);
  12. selectedIndexRef.current = selectedIndex;
  13.  
  14. const [showSuggestion, setShowSuggestion] = useState(false);
  15.  
  16. const [exception, setException] = useState(null);
  17. const [isFetching, setIsFetching] = useState(false);
  18. const axiosCancelSource = axios.CancelToken.source();
  19.  
  20. const fetchSpecializations = async () => {
  21. if (isFetching) return; // Semaphor zapobiegający równoczesnym żądaniom
  22. setIsFetching(true);
  23. const url = `/?do=TAJNE.ZRODLO.DANYCH`;
  24.  
  25. try {
  26. const response = await axios({
  27. method: 'post',
  28. url: url,
  29. cancelToken: axiosCancelSource.token,
  30. });
  31. handleSpecializationsResponse(response);
  32. } catch (error) {
  33. if (axios.isCancel(error)) {
  34. AppendToLog(error.message);
  35. } else {
  36. HandleError(error, true);
  37. }
  38. } finally {
  39. setIsFetching(false); // Zwolnienie semafora po zakończeniu żądania
  40. }
  41. };
  42.  
  43. const handleSpecializationsResponse = (response) => {
  44. try {
  45. if (HandleResponse(response, true)) {
  46. setSuggestions(response?.data?.result?.specializations);
  47. }
  48. } catch (error) {
  49. setException(error);
  50. }
  51. };
  52.  
  53. useEffect(() => {
  54. fetchSpecializations();
  55. }, []); // Wywołanie funkcji po montażu komponentu
  56.  
  57. useEffect(() => {
  58. if (suggestionsList) {
  59. setSuggestions(suggestionsList);
  60. } else {
  61. setSuggestions([
  62. { 'en': 'Artificial Intelligence', 'pl': 'Sztuczna Inteligencja' },
  63. { 'en': 'Machine Learning', 'pl': 'Uczenie Maszynowe' },
  64. { 'en': 'Deep Learning', 'pl': 'Głębokie Uczenie' },
  65. { 'en': 'Neural Networks', 'pl': 'Sieci Neuronowe' },
  66. { 'en': 'Data Mining', 'pl': 'Zbieranie Danych' },
  67. { 'en': 'Big Data', 'pl': 'Duże Dane' },
  68. ]);
  69. }
  70. }, [suggestionsList]);
  71.  
  72. useEffect(() => {
  73. if (filterValue) {
  74. const filtered = suggestions.filter(item => item[language]?.toLowerCase().includes(filterValue.toLowerCase()));
  75. setFilteredSuggestions(filtered);
  76. //setShowSuggestion(true);
  77. } else {
  78. setFilteredSuggestions([]);
  79. }
  80. }, [filterValue, suggestions, language]);
  81.  
  82. useEffect(() => {
  83. const handleKeyDown = (e) => {
  84. let newIndex = selectedIndexRef.current;
  85. if (e.keyCode === 40) { // down arrow
  86. newIndex = newIndex < filteredSuggestions.length - 1 ? newIndex + 1 : newIndex;
  87. setSelectedIndex(newIndex);
  88. } else if (e.keyCode === 38) { // up arrow
  89. newIndex = newIndex > 0 ? newIndex - 1 : 0;
  90. setSelectedIndex(newIndex);
  91. } else if (e.keyCode === 13) { // ENTER
  92. simulateEnter(newIndex); // Passing the current index as an argument
  93. }
  94. };
  95.  
  96. window.addEventListener('keydown', handleKeyDown);
  97.  
  98. return () => {
  99. window.removeEventListener('keydown', handleKeyDown);
  100. };
  101. }, [filteredSuggestions.length]);
  102.  
  103. const simulateEnter = (currentIndex) => {
  104. if (currentIndex >= 0 && currentIndex < filteredSuggestions.length) {
  105. handleSuggestionClick(filteredSuggestions[currentIndex], index);
  106. }
  107. };
  108.  
  109. const handleMouseEnter = (currentIndex) => {
  110. if (currentIndex >= 0 && currentIndex < filteredSuggestions.length) {
  111. handleSuggestionClick(filteredSuggestions[currentIndex], index);
  112. }
  113. };
  114.  
  115. useEffect(() => {
  116. let isMounted = true;
  117. let timeoutId = null;
  118.  
  119. // const checkIfFocused = () => {
  120. // if (inputRef.current === document.activeElement) {
  121. // if (isMounted) {
  122. // console.log(`Input ${language} is focused`);
  123. // setShowSuggestion(true);
  124. // }
  125. // }
  126. // else {
  127. // console.log(`Input ${language} is not focused`);
  128. // timeoutId = setTimeout(() => {
  129. // if (isMounted) setShowSuggestion(false); // Aktualizacja stanu tylko jeśli komponent jest zamontowany
  130. // }, 0);
  131. // }
  132. // };
  133. // checkIfFocused();
  134.  
  135. const focusListener = () => setShowSuggestion(true);
  136. const blurListener = async () => {
  137. //console.log('blurListener');
  138. await new Promise(resolve => timeoutId = setTimeout(resolve, 200));
  139. if (isMounted) setShowSuggestion(false);
  140. };
  141.  
  142. inputRef.current?.addEventListener('focus', focusListener);
  143. inputRef.current?.addEventListener('blur', blurListener);
  144.  
  145. return () => {
  146. isMounted = false;
  147. inputRef.current?.removeEventListener('focus', focusListener);
  148. inputRef.current?.removeEventListener('blur', blurListener);
  149.  
  150. // Czyszczenie dla setTimeout
  151. if (timeoutId) {
  152. clearTimeout(timeoutId);
  153. }
  154. };
  155. }, [inputRef]);
  156.  
  157. return (
  158. showSuggestion && (
  159. <div className={style['suggestions-list']}>
  160. {filteredSuggestions.map((item, _index) => (
  161. <div key={_index}
  162. onClick={() => { handleMouseEnter(_index); }}
  163. //onMouseEnter={() => handleMouseEnter(_index)}
  164. className={`${style['suggestion-item']} ${selectedIndex === _index ? style['selected'] : ''}`}
  165. >
  166. {item[language]}
  167. </div>
  168. ))}
  169. </div>
  170. )
  171. );
  172. }
  173. export default FilteredList;
  174.  
  175.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement