mirror of https://github.com/cocosolos/ixion.git
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:
parent
5d3d823c34
commit
11cb35d0ac
|
|
@ -38,7 +38,7 @@ export default function Header({
|
||||||
const { progress, setProgress, showAlert } = useLoadingContext();
|
const { progress, setProgress, showAlert } = useLoadingContext();
|
||||||
const [showSearchServer, setShowSearchServer] = useState(false);
|
const [showSearchServer, setShowSearchServer] = useState(false);
|
||||||
const [filtersApplied, setFiltersApplied] = useState(false);
|
const [filtersApplied, setFiltersApplied] = useState(false);
|
||||||
const [initialFetch, setInitialFetch] = useState(false);
|
const [initialFetch, setInitialFetch] = useState(true);
|
||||||
const toggleShowSearchServer = () => {
|
const toggleShowSearchServer = () => {
|
||||||
setShowSearchServer((prev) => !prev);
|
setShowSearchServer((prev) => !prev);
|
||||||
};
|
};
|
||||||
|
|
@ -69,9 +69,10 @@ export default function Header({
|
||||||
}, [showAlert, setServers, setProgress]);
|
}, [showAlert, setServers, setProgress]);
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
if (!initialFetch) {
|
// TODO: Check if there's a better way to do this than "initialFetch" state, see also SearchServers
|
||||||
|
if (initialFetch) {
|
||||||
fetchServerData();
|
fetchServerData();
|
||||||
setInitialFetch(true);
|
setInitialFetch(false);
|
||||||
}
|
}
|
||||||
setFiltersApplied(
|
setFiltersApplied(
|
||||||
JSON.stringify(searchState) !== JSON.stringify(SearchStateDefaults)
|
JSON.stringify(searchState) !== JSON.stringify(SearchStateDefaults)
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,32 @@ type SearchServersProps = {
|
||||||
setSearchState: React.Dispatch<React.SetStateAction<SearchState>>;
|
setSearchState: React.Dispatch<React.SetStateAction<SearchState>>;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
function parseSearchParams(searchParams: string): SearchState {
|
||||||
|
const params = new URLSearchParams(searchParams);
|
||||||
|
const parsedState = { ...SearchStateDefaults };
|
||||||
|
|
||||||
|
const keys = Object.keys(SearchStateDefaults) as Array<keyof SearchState>;
|
||||||
|
|
||||||
|
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({
|
export default function SearchServers({
|
||||||
showSearchServer,
|
showSearchServer,
|
||||||
searchState,
|
searchState,
|
||||||
|
|
@ -31,48 +57,33 @@ export default function SearchServers({
|
||||||
const location = useLocation();
|
const location = useLocation();
|
||||||
const [initialPath] = useState(location.pathname);
|
const [initialPath] = useState(location.pathname);
|
||||||
const [contentHeight, setContentHeight] = useState(0);
|
const [contentHeight, setContentHeight] = useState(0);
|
||||||
|
const [initialLoad, setInitialLoad] = useState(true);
|
||||||
function parseSearchParams(searchParams: string): SearchState {
|
|
||||||
const params = new URLSearchParams(searchParams);
|
|
||||||
const parsedState = SearchStateDefaults;
|
|
||||||
|
|
||||||
const keys = Object.keys(SearchStateDefaults) as Array<keyof SearchState>;
|
|
||||||
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
// Populate search state with URL params only if loading the home page
|
// Populate search state with URL params only if loading the home page
|
||||||
// Home page manages updating URL params
|
// Home page manages updating URL params
|
||||||
if (initialPath === '/') {
|
// TODO: Check if there's a better way to do this than "initialLoad" state, see also Header
|
||||||
const params = parseSearchParams(location.search);
|
if (initialLoad) {
|
||||||
if (params !== SearchStateDefaults) {
|
if (initialPath === '/') {
|
||||||
setSearchState(params);
|
const params = parseSearchParams(location.search);
|
||||||
|
if (JSON.stringify(params) !== JSON.stringify(SearchStateDefaults)) {
|
||||||
|
setSearchState(params);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
setInitialLoad(false);
|
||||||
}
|
}
|
||||||
if (showSearchServer && containerRef.current) {
|
if (showSearchServer && containerRef.current) {
|
||||||
setContentHeight(containerRef.current.scrollHeight);
|
setContentHeight(containerRef.current.scrollHeight);
|
||||||
} else {
|
} else {
|
||||||
setContentHeight(0);
|
setContentHeight(0);
|
||||||
}
|
}
|
||||||
}, [showSearchServer, location.search, setSearchState, initialPath]);
|
}, [
|
||||||
|
showSearchServer,
|
||||||
|
location.search,
|
||||||
|
setSearchState,
|
||||||
|
initialPath,
|
||||||
|
initialLoad,
|
||||||
|
]);
|
||||||
|
|
||||||
const handleChange = (
|
const handleChange = (
|
||||||
name: string,
|
name: string,
|
||||||
|
|
@ -141,11 +152,11 @@ export default function SearchServers({
|
||||||
theme.palette.mode === 'dark'
|
theme.palette.mode === 'dark'
|
||||||
? 'rgba(255, 255, 255, .06)'
|
? 'rgba(255, 255, 255, .06)'
|
||||||
: 'rgba(0, 0, 0, .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>
|
<Container className="my-2">
|
||||||
<Grid container spacing={2} className="py-2">
|
<Grid container spacing={2}>
|
||||||
{/* Name */}
|
{/* Name */}
|
||||||
<Grid item xs={12}>
|
<Grid item xs={12}>
|
||||||
<TextField
|
<TextField
|
||||||
|
|
@ -686,9 +697,6 @@ export default function SearchServers({
|
||||||
>
|
>
|
||||||
<IconButton
|
<IconButton
|
||||||
onClick={() => {
|
onClick={() => {
|
||||||
if (location.pathname === '/') {
|
|
||||||
window.history.replaceState({}, '', '/');
|
|
||||||
}
|
|
||||||
setSearchState(SearchStateDefaults);
|
setSearchState(SearchStateDefaults);
|
||||||
}}
|
}}
|
||||||
>
|
>
|
||||||
|
|
|
||||||
|
|
@ -6,37 +6,42 @@ import SettingsChipCloud from '../components/Server/SettingsChipCloud';
|
||||||
import { SearchState, SearchStateDefaults } from '../data/SearchState';
|
import { SearchState, SearchStateDefaults } from '../data/SearchState';
|
||||||
import { ServerData } from '../data/ServerData';
|
import { ServerData } from '../data/ServerData';
|
||||||
|
|
||||||
export default function Home({
|
function serializeSearchState(search: SearchState): string {
|
||||||
servers,
|
const params = new URLSearchParams();
|
||||||
searchState,
|
|
||||||
}: {
|
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[];
|
servers: ServerData[];
|
||||||
searchState: SearchState;
|
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(() => {
|
useEffect(() => {
|
||||||
// Update URL params whenever search state changes
|
// Update URL params whenever search state changes
|
||||||
const searchParams = serializeSearchState(searchState);
|
const searchParams = serializeSearchState(searchState);
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue