diff --git a/client/src/components/Header/Header.tsx b/client/src/components/Header/Header.tsx index 199ebdf..2f0e00d 100644 --- a/client/src/components/Header/Header.tsx +++ b/client/src/components/Header/Header.tsx @@ -38,7 +38,7 @@ export default function Header({ const { progress, setProgress, showAlert } = useLoadingContext(); const [showSearchServer, setShowSearchServer] = useState(false); const [filtersApplied, setFiltersApplied] = useState(false); - const [initialFetch, setInitialFetch] = useState(false); + const [initialFetch, setInitialFetch] = useState(true); const toggleShowSearchServer = () => { setShowSearchServer((prev) => !prev); }; @@ -69,9 +69,10 @@ export default function Header({ }, [showAlert, setServers, setProgress]); useEffect(() => { - if (!initialFetch) { + // TODO: Check if there's a better way to do this than "initialFetch" state, see also SearchServers + if (initialFetch) { fetchServerData(); - setInitialFetch(true); + setInitialFetch(false); } setFiltersApplied( JSON.stringify(searchState) !== JSON.stringify(SearchStateDefaults) diff --git a/client/src/components/Header/SearchServers.tsx b/client/src/components/Header/SearchServers.tsx index 1be7eee..8eb2684 100644 --- a/client/src/components/Header/SearchServers.tsx +++ b/client/src/components/Header/SearchServers.tsx @@ -22,6 +22,32 @@ type SearchServersProps = { setSearchState: React.Dispatch>; }; +function parseSearchParams(searchParams: string): SearchState { + const params = new URLSearchParams(searchParams); + const parsedState = { ...SearchStateDefaults }; + + const keys = Object.keys(SearchStateDefaults) as Array; + + keys.forEach((key) => { + if (params.has(key)) { + const value = params.get(key) as string; + const decodedValue = decodeURIComponent(value); + + if (key === 'maxLevel') { + const maxLevelArray = decodedValue.split(' ').map(Number); + parsedState[key] = + maxLevelArray.length === 1 ? [1, maxLevelArray[0]] : maxLevelArray; + } else if (key === 'expansionsEnabled') { + parsedState[key] = decodedValue.split(' ') as string[]; + } else { + parsedState[key] = decodedValue; + } + } + }); + + return parsedState as SearchState; +} + export default function SearchServers({ showSearchServer, searchState, @@ -31,48 +57,33 @@ export default function SearchServers({ const location = useLocation(); const [initialPath] = useState(location.pathname); const [contentHeight, setContentHeight] = useState(0); - - function parseSearchParams(searchParams: string): SearchState { - const params = new URLSearchParams(searchParams); - const parsedState = SearchStateDefaults; - - const keys = Object.keys(SearchStateDefaults) as Array; - - keys.forEach((key) => { - if (params.has(key)) { - const value = params.get(key) as string; - const decodedValue = decodeURIComponent(value); - - if (key === 'maxLevel') { - const maxLevelArray = decodedValue.split(',').map(Number); - parsedState[key] = - maxLevelArray.length === 1 ? [1, maxLevelArray[0]] : maxLevelArray; - } else if (key === 'expansionsEnabled') { - parsedState[key] = decodedValue.split(',') as string[]; - } else { - parsedState[key] = decodedValue; - } - } - }); - - return parsedState as SearchState; - } + const [initialLoad, setInitialLoad] = useState(true); useEffect(() => { // Populate search state with URL params only if loading the home page // Home page manages updating URL params - if (initialPath === '/') { - const params = parseSearchParams(location.search); - if (params !== SearchStateDefaults) { - setSearchState(params); + // TODO: Check if there's a better way to do this than "initialLoad" state, see also Header + if (initialLoad) { + if (initialPath === '/') { + const params = parseSearchParams(location.search); + if (JSON.stringify(params) !== JSON.stringify(SearchStateDefaults)) { + setSearchState(params); + } } + setInitialLoad(false); } if (showSearchServer && containerRef.current) { setContentHeight(containerRef.current.scrollHeight); } else { setContentHeight(0); } - }, [showSearchServer, location.search, setSearchState, initialPath]); + }, [ + showSearchServer, + location.search, + setSearchState, + initialPath, + initialLoad, + ]); const handleChange = ( name: string, @@ -141,11 +152,11 @@ export default function SearchServers({ theme.palette.mode === 'dark' ? 'rgba(255, 255, 255, .06)' : 'rgba(0, 0, 0, .06)', - boxShadow: 'inset 0em 3em 5em -5em black,inset 0em -3em 5em -6em black', + boxShadow: 'inset 0em 3em 5em -6em black,inset 0em -3em 5em -7em black', }} > - - + + {/* Name */} { - if (location.pathname === '/') { - window.history.replaceState({}, '', '/'); - } setSearchState(SearchStateDefaults); }} > diff --git a/client/src/pages/Home.tsx b/client/src/pages/Home.tsx index c440461..f229edd 100644 --- a/client/src/pages/Home.tsx +++ b/client/src/pages/Home.tsx @@ -6,37 +6,42 @@ import SettingsChipCloud from '../components/Server/SettingsChipCloud'; import { SearchState, SearchStateDefaults } from '../data/SearchState'; import { ServerData } from '../data/ServerData'; -export default function Home({ - servers, - searchState, -}: { +function serializeSearchState(search: SearchState): string { + const params = new URLSearchParams(); + + Object.entries(search).forEach(([key, value]) => { + if ( + value !== null && + value !== undefined && + !(key === 'name' && value === SearchStateDefaults.name) && + !( + key === 'maxLevel' && + JSON.stringify(value) === JSON.stringify(SearchStateDefaults.maxLevel) + ) + ) { + if (Array.isArray(value)) { + if (key === 'maxLevel') { + if (value[0] === value[1]) { + params.append(key, JSON.stringify(value[0])); + return; + } + } + params.append(key, value.join(' ')); + } else { + params.append(key, value); + } + } + }); + + return params.toString(); +} + +type HomeProps = { servers: ServerData[]; searchState: SearchState; -}) { - function serializeSearchState(search: SearchState): string { - const params = new URLSearchParams(); - - Object.entries(search).forEach(([key, value]) => { - if ( - value !== null && - value !== undefined && - !(key === 'name' && value === '') && - !( - key === 'maxLevel' && - JSON.stringify(value) === JSON.stringify(SearchStateDefaults.maxLevel) - ) - ) { - if (Array.isArray(value)) { - params.append(key, value.join(',')); - } else { - params.append(key, value); - } - } - }); - - return params.toString(); - } +}; +export default function Home({ servers, searchState }: HomeProps) { useEffect(() => { // Update URL params whenever search state changes const searchParams = serializeSearchState(searchState);