Improve shadows in search box and fix url param parsing

SearchServers component useEffect wasn't getting an updated location.search value, so give it the same treatment as Header and keep state of initial load.
This commit is contained in:
Corey 2024-05-13 04:14:20 -04:00
parent 5d3d823c34
commit 11cb35d0ac
Signed by: coco
GPG Key ID: 051138DA6AEE3E60
3 changed files with 82 additions and 68 deletions

View File

@ -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)

View File

@ -22,19 +22,9 @@ type SearchServersProps = {
setSearchState: React.Dispatch<React.SetStateAction<SearchState>>;
};
export default function SearchServers({
showSearchServer,
searchState,
setSearchState,
}: SearchServersProps) {
const containerRef = useRef<HTMLDivElement>(null);
const location = useLocation();
const [initialPath] = useState(location.pathname);
const [contentHeight, setContentHeight] = useState(0);
function parseSearchParams(searchParams: string): SearchState {
function parseSearchParams(searchParams: string): SearchState {
const params = new URLSearchParams(searchParams);
const parsedState = SearchStateDefaults;
const parsedState = { ...SearchStateDefaults };
const keys = Object.keys(SearchStateDefaults) as Array<keyof SearchState>;
@ -44,11 +34,11 @@ export default function SearchServers({
const decodedValue = decodeURIComponent(value);
if (key === 'maxLevel') {
const maxLevelArray = decodedValue.split(',').map(Number);
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[];
parsedState[key] = decodedValue.split(' ') as string[];
} else {
parsedState[key] = decodedValue;
}
@ -56,23 +46,44 @@ export default function SearchServers({
});
return parsedState as SearchState;
}
}
export default function SearchServers({
showSearchServer,
searchState,
setSearchState,
}: SearchServersProps) {
const containerRef = useRef<HTMLDivElement>(null);
const location = useLocation();
const [initialPath] = useState(location.pathname);
const [contentHeight, setContentHeight] = useState(0);
const [initialLoad, setInitialLoad] = useState(true);
useEffect(() => {
// Populate search state with URL params only if loading the home page
// Home page manages updating URL 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 (params !== SearchStateDefaults) {
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',
}}
>
<Container>
<Grid container spacing={2} className="py-2">
<Container className="my-2">
<Grid container spacing={2}>
{/* Name */}
<Grid item xs={12}>
<TextField
@ -686,9 +697,6 @@ export default function SearchServers({
>
<IconButton
onClick={() => {
if (location.pathname === '/') {
window.history.replaceState({}, '', '/');
}
setSearchState(SearchStateDefaults);
}}
>

View File

@ -6,28 +6,27 @@ import SettingsChipCloud from '../components/Server/SettingsChipCloud';
import { SearchState, SearchStateDefaults } from '../data/SearchState';
import { ServerData } from '../data/ServerData';
export default function Home({
servers,
searchState,
}: {
servers: ServerData[];
searchState: SearchState;
}) {
function serializeSearchState(search: SearchState): string {
function serializeSearchState(search: SearchState): string {
const params = new URLSearchParams();
Object.entries(search).forEach(([key, value]) => {
if (
value !== null &&
value !== undefined &&
!(key === 'name' && value === '') &&
!(key === 'name' && value === SearchStateDefaults.name) &&
!(
key === 'maxLevel' &&
JSON.stringify(value) === JSON.stringify(SearchStateDefaults.maxLevel)
)
) {
if (Array.isArray(value)) {
params.append(key, value.join(','));
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);
}
@ -35,8 +34,14 @@ export default function Home({
});
return params.toString();
}
}
type HomeProps = {
servers: ServerData[];
searchState: SearchState;
};
export default function Home({ servers, searchState }: HomeProps) {
useEffect(() => {
// Update URL params whenever search state changes
const searchParams = serializeSearchState(searchState);