Change how search state is saved

This commit is contained in:
Corey 2024-05-01 22:51:08 +00:00
parent 9ff42ce914
commit 08094b8683
7 changed files with 105 additions and 94 deletions

View File

@ -9,6 +9,7 @@ services:
- /var/run/docker.sock:/var/run/docker-host.sock
- ixion-dev-node_modules:/workspace/client/node_modules
- ixion-dev-static:/workspace/api/static
- ixion-dev-database:/workspace/api/db
- ..:/workspace:cached
client:
image: ixion-dev:latest
@ -31,6 +32,7 @@ services:
environment:
- DEBUG=true
volumes:
- ixion-dev-database:/workspace/api/db
- ixion-dev-static:/workspace/api/static
- ../api:/workspace/api:cached
- ../client:/workspace/client:cached
@ -44,6 +46,7 @@ services:
working_dir: /workspace/api
command: celery -A api worker -l info
volumes:
- ixion-dev-database:/workspace/api/db
- ../api:/workspace/api:cached
depends_on:
- workspace
@ -63,3 +66,4 @@ services:
volumes:
ixion-dev-node_modules:
ixion-dev-static:
ixion-dev-database:

View File

@ -16,6 +16,8 @@ services:
build: .
command: celery -A api worker -l info
restart: always
volumes:
- database:/app/db
depends_on:
- api
celery-beat:

View File

@ -4,7 +4,7 @@ import { BrowserRouter, Route, Routes } from 'react-router-dom';
import AlertComponent from './components/Alert';
import Footer from './components/Footer';
import Header from './components/Header';
import SearchState from './data/SearchState';
import SearchState, { SearchStateDefaults } from './data/SearchState';
import ServerData from './data/ServerData';
import About from './pages/About';
import Home from './pages/Home';
@ -18,23 +18,8 @@ export function App() {
} | null>(null);
const [servers, setServers] = useState<ServerData[]>([]);
const [searchName, setSearchName] = useState('');
const [searchMultibox, setSearchMultibox] = useState<string[] | null>(null);
const [searchTrusts, setSearchTrusts] = useState<string[] | null>(null);
const [searchLevelSync, setSearchLevelSync] = useState<string[] | null>(null);
const [searchMaxLevel, setSearchMaxLevel] = useState<number[]>([1, 99]);
const [searchExpansions, setSearchExpansions] = useState<string[] | null>(
null
);
const searchState: SearchState = {
name: { value: searchName, setValue: setSearchName },
multibox: { value: searchMultibox, setValue: setSearchMultibox },
trusts: { value: searchTrusts, setValue: setSearchTrusts },
levelSync: { value: searchLevelSync, setValue: setSearchLevelSync },
maxLevel: { value: searchMaxLevel, setValue: setSearchMaxLevel },
expansions: { value: searchExpansions, setValue: setSearchExpansions },
};
const [searchState, setSearchState] =
useState<SearchState>(SearchStateDefaults);
return (
<div className="flex min-h-screen flex-col">
@ -43,6 +28,7 @@ export function App() {
servers={servers}
setServers={setServers}
searchState={searchState}
setSearchState={setSearchState}
/>
<AlertComponent alertInfo={alertInfo} setAlertInfo={setAlertInfo} />
<Container className="grow p-0">

View File

@ -22,11 +22,13 @@ export default function Header({
servers,
setServers,
searchState,
setSearchState,
}: {
setAlertInfo: React.Dispatch<React.SetStateAction<AlertResponse>>;
servers: ServerData[];
setServers: React.Dispatch<React.SetStateAction<ServerData[]>>;
searchState: SearchState;
setSearchState: React.Dispatch<React.SetStateAction<SearchState>>;
}) {
const [fetchLoading, setFetchLoading] = useState(0);
const [showSearchServer, setShowSearchServer] = useState(false);
@ -103,6 +105,7 @@ export default function Header({
<SearchServers
showSearchServer={showSearchServer}
searchState={searchState}
setSearchState={setSearchState}
/>
</Box>
);

View File

@ -15,9 +15,11 @@ import SearchState from '../data/SearchState';
export default function SearchServers({
showSearchServer,
searchState,
setSearchState,
}: {
showSearchServer: boolean;
searchState: SearchState;
setSearchState: React.Dispatch<React.SetStateAction<SearchState>>;
}) {
const containerRef = useRef<HTMLDivElement>(null);
const [contentHeight, setContentHeight] = useState(0);
@ -32,28 +34,28 @@ export default function SearchServers({
}, [showSearchServer]);
const handleSearchName = (event: React.ChangeEvent<HTMLInputElement>) => {
searchState.name.setValue(event.target.value);
setSearchState({ ...searchState, name: event.target.value });
};
const handleSearchMultibox = (
_event: React.MouseEvent<HTMLElement>,
newSearchMultibox: string[]
) => {
searchState.multibox.setValue(newSearchMultibox);
setSearchState({ ...searchState, multibox: newSearchMultibox });
};
const handleSearchTrusts = (
_event: React.MouseEvent<HTMLElement>,
newSearchTrusts: string[]
) => {
searchState.trusts.setValue(newSearchTrusts);
setSearchState({ ...searchState, trusts: newSearchTrusts });
};
const handleSearchLevelSync = (
_event: React.MouseEvent<HTMLElement>,
newSearchLevelSync: string[]
) => {
searchState.levelSync.setValue(newSearchLevelSync);
setSearchState({ ...searchState, levelSync: newSearchLevelSync });
};
const handleSearchMaxLevelMin = (
@ -65,10 +67,13 @@ export default function SearchServers({
} else if (newValue > 99) {
newValue = 99;
}
searchState.maxLevel.setValue([
Math.min(newValue, searchState.maxLevel.value[1] - minDistance),
searchState.maxLevel.value[1],
]);
setSearchState({
...searchState,
maxLevel: [
Math.min(newValue, searchState.maxLevel[1] - minDistance),
searchState.maxLevel[1],
],
});
};
const handleSearchMaxLevelMax = (
@ -80,10 +85,13 @@ export default function SearchServers({
} else if (newValue > 99) {
newValue = 99;
}
searchState.maxLevel.setValue([
searchState.maxLevel.value[0],
Math.max(newValue, searchState.maxLevel.value[0] + minDistance),
]);
setSearchState({
...searchState,
maxLevel: [
searchState.maxLevel[0],
Math.max(newValue, searchState.maxLevel[0] + minDistance),
],
});
};
const handleSearchMaxLevel = (
@ -95,15 +103,21 @@ export default function SearchServers({
return;
}
if (activeThumb === 0) {
searchState.maxLevel.setValue([
Math.min(newValue[0], searchState.maxLevel.value[1] - minDistance),
searchState.maxLevel.value[1],
]);
setSearchState({
...searchState,
maxLevel: [
Math.min(newValue[0], searchState.maxLevel[1] - minDistance),
searchState.maxLevel[1],
],
});
} else {
searchState.maxLevel.setValue([
searchState.maxLevel.value[0],
Math.max(newValue[1], searchState.maxLevel.value[0] + minDistance),
]);
setSearchState({
...searchState,
maxLevel: [
searchState.maxLevel[0],
Math.max(newValue[1], searchState.maxLevel[0] + minDistance),
],
});
}
};
@ -112,23 +126,24 @@ export default function SearchServers({
newSearchExpansions: string[]
) => {
if (newSearchExpansions.length === 0) {
searchState.expansions.setValue(null);
setSearchState({ ...searchState, expansions: null });
} else if (
searchState.expansions.value &&
searchState.expansions.value.includes('none') &&
searchState.expansions &&
searchState.expansions.includes('none') &&
newSearchExpansions.length > 1
) {
searchState.expansions.setValue(
newSearchExpansions.filter((item) => item !== 'none')
);
setSearchState({
...searchState,
expansions: newSearchExpansions.filter((item) => item !== 'none'),
});
} else if (
searchState.expansions.value &&
!searchState.expansions.value.includes('none') &&
searchState.expansions &&
!searchState.expansions.includes('none') &&
newSearchExpansions.includes('none')
) {
searchState.expansions.setValue(['none']);
setSearchState({ ...searchState, expansions: ['none'] });
} else {
searchState.expansions.setValue(newSearchExpansions);
setSearchState({ ...searchState, expansions: newSearchExpansions });
}
};
@ -149,7 +164,7 @@ export default function SearchServers({
{/* Name */}
<Grid item xs={12}>
<TextField
value={searchState.name.value}
value={searchState.name}
onChange={handleSearchName}
variant="standard"
autoComplete="false"
@ -174,7 +189,7 @@ export default function SearchServers({
</Grid>
<Grid item xs={12} className="flex pt-0">
<Input
value={searchState.maxLevel.value[0]}
value={searchState.maxLevel[0]}
size="small"
onChange={handleSearchMaxLevelMin}
// onBlur={handleBlur}
@ -188,7 +203,7 @@ export default function SearchServers({
/>
<Slider
aria-labelledby="max-level-slider"
value={searchState.maxLevel.value}
value={searchState.maxLevel}
onChange={handleSearchMaxLevel}
valueLabelDisplay="auto"
disableSwap
@ -198,7 +213,7 @@ export default function SearchServers({
max={99}
/>
<Input
value={searchState.maxLevel.value[1]}
value={searchState.maxLevel[1]}
size="small"
onChange={handleSearchMaxLevelMax}
// onBlur={handleBlur}
@ -230,7 +245,7 @@ export default function SearchServers({
</Typography>
</Tooltip>
<ToggleButtonGroup
value={searchState.expansions.value}
value={searchState.expansions}
onChange={handleSearchExpansions}
size="small"
aria-labelledby="expansions-button-group"
@ -307,7 +322,7 @@ export default function SearchServers({
Multiboxing
</Typography>
<ToggleButtonGroup
value={searchState.multibox.value}
value={searchState.multibox}
onChange={handleSearchMultibox}
size="small"
aria-labelledby="multibox-button-group"
@ -355,7 +370,7 @@ export default function SearchServers({
Trusts
</Typography>
<ToggleButtonGroup
value={searchState.trusts.value}
value={searchState.trusts}
onChange={handleSearchTrusts}
size="small"
aria-labelledby="trust-button-group"
@ -395,7 +410,7 @@ export default function SearchServers({
Level Sync
</Typography>
<ToggleButtonGroup
value={searchState.levelSync.value}
value={searchState.levelSync}
onChange={handleSearchLevelSync}
size="small"
aria-labelledby="level-sync-button-group"

View File

@ -1,13 +1,17 @@
interface SearchStateTemplate<T> {
value: T;
setValue: React.Dispatch<React.SetStateAction<T>>;
export default interface SearchState {
name: string;
multibox: string[] | null;
trusts: string[] | null;
levelSync: string[] | null;
maxLevel: number[];
expansions: string[] | null;
}
export default interface SearchState {
name: SearchStateTemplate<string>;
multibox: SearchStateTemplate<string[] | null>;
trusts: SearchStateTemplate<string[] | null>;
levelSync: SearchStateTemplate<string[] | null>;
maxLevel: SearchStateTemplate<number[]>;
expansions: SearchStateTemplate<string[] | null>;
}
export const SearchStateDefaults: SearchState = {
name: '',
multibox: null,
trusts: null,
levelSync: null,
maxLevel: [1, 99],
expansions: null,
};

View File

@ -43,28 +43,28 @@ export default function Home({
}, [setAlertInfo, setServers]);
const filterServers = (server: ServerData): boolean => {
if (searchState.name.value.length > 0) {
if (searchState.name.length > 0) {
const serverName = server.name.toLowerCase();
if (!serverName.includes(searchState.name.value.toLowerCase())) {
if (!serverName.includes(searchState.name.toLowerCase())) {
return false;
}
}
if (server.max_level < searchState.maxLevel.value[0]) {
if (server.max_level < searchState.maxLevel[0]) {
return false;
}
if (server.max_level > searchState.maxLevel.value[1]) {
if (server.max_level > searchState.maxLevel[1]) {
return false;
}
if (
searchState.trusts.value &&
searchState.trusts &&
typeof server.customizations['MAIN.ENABLE_TRUST_CASTING'] === 'number'
) {
const serverTrusts =
server.customizations['MAIN.ENABLE_TRUST_CASTING'] === 1;
const searchEnabled = searchState.trusts.value.includes('enabled');
const searchDisabled = searchState.trusts.value.includes('disabled');
const searchEnabled = searchState.trusts.includes('enabled');
const searchDisabled = searchState.trusts.includes('disabled');
if (serverTrusts && searchDisabled && !searchEnabled) {
return false;
}
@ -74,12 +74,12 @@ export default function Home({
}
if (
searchState.levelSync.value &&
searchState.levelSync &&
typeof server.customizations['MAP.LEVEL_SYNC_ENABLE'] === 'boolean'
) {
const serverLevelSync = server.customizations['MAP.LEVEL_SYNC_ENABLE'];
const searchEnabled = searchState.levelSync.value.includes('enabled');
const searchDisabled = searchState.levelSync.value.includes('disabled');
const searchEnabled = searchState.levelSync.includes('enabled');
const searchDisabled = searchState.levelSync.includes('disabled');
if (serverLevelSync && searchDisabled && !searchEnabled) {
return false;
}
@ -88,21 +88,21 @@ export default function Home({
}
}
if (searchState.expansions.value) {
const searchNoneEnabled = searchState.expansions.value.includes('none');
const searchRotzEnabled = searchState.expansions.value.includes('rotz');
if (searchState.expansions) {
const searchNoneEnabled = searchState.expansions.includes('none');
const searchRotzEnabled = searchState.expansions.includes('rotz');
const serverRotzEnabled =
server.customizations['LOGIN.RISE_OF_ZILART'] === true;
const searchCopEnabled = searchState.expansions.value.includes('cop');
const searchCopEnabled = searchState.expansions.includes('cop');
const serverCopEnabled =
server.customizations['LOGIN.CHAINS_OF_PROMATHIA'] === true;
const searchToauEnabled = searchState.expansions.value.includes('toau');
const searchToauEnabled = searchState.expansions.includes('toau');
const serverToauEnabled =
server.customizations['LOGIN.TREASURES_OF_AHT_URGHAN'] === true;
const searchWotgEnabled = searchState.expansions.value.includes('wotg');
const searchWotgEnabled = searchState.expansions.includes('wotg');
const serverWotgEnabled =
server.customizations['LOGIN.WINGS_OF_THE_GODDESS'] === true;
const searchSoaEnabled = searchState.expansions.value.includes('soa');
const searchSoaEnabled = searchState.expansions.includes('soa');
const serverSoaEnabled =
server.customizations['LOGIN.SEEKERS_OF_ADOULIN'] === true;
if (
@ -132,20 +132,17 @@ export default function Home({
}
}
if (searchState.multibox.value) {
if (searchState.multibox) {
const serverMultibox = server.login_limit;
if (searchState.multibox.value.includes('none') && serverMultibox !== 1) {
if (searchState.multibox.includes('none') && serverMultibox !== 1) {
return false;
}
if (searchState.multibox.includes('unlimited') && serverMultibox !== 0) {
return false;
}
if (
searchState.multibox.value.includes('unlimited') &&
serverMultibox !== 0
) {
return false;
}
if (
searchState.multibox.value.includes('limited') &&
!searchState.multibox.value.includes('unlimited') &&
searchState.multibox.includes('limited') &&
!searchState.multibox.includes('unlimited') &&
serverMultibox < 2
) {
return false;