diff --git a/src/App.js b/src/App.js
index 10fc95141..a804e2381 100644
--- a/src/App.js
+++ b/src/App.js
@@ -78,6 +78,7 @@ const WipeLength = React.lazy(() => import('./pages/wipe-length/index.js'));
const Achievements = React.lazy(() => import('./pages/achievements/index.js'));
const Players = React.lazy(() => import('./pages/players/index.js'));
const Player = React.lazy(() => import('./pages/player/index.js'));
+const PlayerForward = React.lazy(() => import('./pages/player/player-forward.js'));
const Converter = React.lazy(() => import('./pages/converter/index.js'));
const About = React.lazy(() => import('./pages/about/index.js'));
@@ -924,7 +925,7 @@ function App() {
]}
/>
} key="suspense-player-wrapper">
@@ -933,6 +934,16 @@ function App() {
remoteControlSessionElement,
]}
/>
+ } key="suspense-player-forward-wrapper">
+
+ ,
+ remoteControlSessionElement,
+ ]}
+ />
{
+ request: async (path, gameMode, body) => {
try {
const method = body ? 'POST' : 'GET';
const response = await fetch(apiUrl + path, {
method,
body,
+ headers: {
+ 'game-mode': gameMode,
+ }
});
if (response.status !== 200) {
@@ -33,13 +36,14 @@ const playerStats = {
}
return json;
} catch (error) {
+ console.log(error);
if (error.message.includes('NetworkError')) {
return Promise.reject(new Error('Rate limited exceeded. Wait one minute to send another request.'));
}
return Promise.reject(error);
}
},
- searchPlayers: async (searchString, turnstileToken) => {
+ searchPlayers: async (searchString, gameMode = 'regular', turnstileToken) => {
// Create a form request to send the Turnstile token
// This avoids sending an extra pre-flight request
let body;
@@ -52,14 +56,14 @@ const playerStats = {
searchParams = `?token=${turnstileToken}`;
}
}
- return playerStats.request(`/name/${searchString}${searchParams}`, body).catch(error => {
+ return playerStats.request(`/name/${searchString}${searchParams}`, gameMode, body).catch(error => {
if (error.message.includes('Malformed')) {
return Promise.reject(new Error('Error searching player profile; try removing one character from the end until the search works.'));
}
return Promise.reject(error);
});
},
- getProfile: async (accountId, turnstileToken) => {
+ getProfile: async (accountId, gameMode = 'regular', turnstileToken) => {
let body;
let searchParams = '';
if (turnstileToken) {
@@ -70,7 +74,7 @@ const playerStats = {
searchParams = `?token=${turnstileToken}`;
}
}
- return playerStats.request(`/account/${accountId}${searchParams}`, body);
+ return playerStats.request(`/account/${accountId}${searchParams}`, gameMode, body);
},
};
diff --git a/src/pages/player/index.js b/src/pages/player/index.js
index 6e0e7306d..9333cd8e9 100644
--- a/src/pages/player/index.js
+++ b/src/pages/player/index.js
@@ -78,6 +78,8 @@ function Player() {
const params = useParams();
const navigate = useNavigate();
+ const gameMode = params.gameMode;
+
const [accountId, setAccountId] = useState(params.accountId);
useEffect(() => {
@@ -125,7 +127,7 @@ function Player() {
}
for (const result of searchResponse) {
if (result.name.toLowerCase() === accountId.toLowerCase()) {
- navigate('/player/'+result.aid);
+ navigate(`/players/${gameMode}/${result.aid}`);
return;
}
}
@@ -143,7 +145,7 @@ function Player() {
} catch (error) {
setProfileError(error.message);
}
- }, [accountId, setPlayerData, setProfileError, navigate, turnstileToken, turnstileRef]);
+ }, [accountId, setPlayerData, setProfileError, navigate, turnstileToken, turnstileRef, gameMode]);
const downloadProfile = useCallback(() => {
if (!playerData.aid) {
@@ -166,13 +168,13 @@ function Player() {
const data = JSON.parse(text);
data.saved = true;
setPlayerData(data);
- window.history.replaceState(null, null, `/player/${data.aid}`);
+ window.history.replaceState(null, null, `/players/${gameMode}/${data.aid}`);
} catch(error) {
setProfileError('Error reading profile');
}
};
reader.readAsText(e.target.files[0]);
- }, [setPlayerData, setProfileError]);
+ }, [setPlayerData, setProfileError, gameMode]);
const playerLevel = useMemo(() => {
if (playerData.info.experience === 0) {
@@ -708,11 +710,11 @@ function Player() {
countLabel = tag.Level;
let killerInfo = {tag.KillerName};
if (tag.KillerAccountId) {
- killerInfo = {tag.KillerName};
+ killerInfo = {tag.KillerName};
}
label = (
- {tag.Nickname}
+ {tag.Nickname}
{` ${t(tag.Status)} `}
{killerInfo}
{weapon !== undefined && [
@@ -753,7 +755,7 @@ function Player() {
/>
);
return { image: itemImage, label };
- }, [items, t]);
+ }, [items, t, gameMode]);
const getLoadoutContents = useCallback((parentItem, itemType = 'loadout') => {
const itemSource = itemType === 'loadout' ? playerData?.equipment?.Items : playerData?.favoriteItems;
diff --git a/src/pages/player/player-forward.js b/src/pages/player/player-forward.js
new file mode 100644
index 000000000..b1d44f66a
--- /dev/null
+++ b/src/pages/player/player-forward.js
@@ -0,0 +1,9 @@
+import { useParams, useNavigate } from 'react-router-dom';
+
+function PlayerForward() {
+ const params = useParams();
+ const navigate = useNavigate();
+ navigate('/players/regular/'+params.accountId);
+}
+
+export default PlayerForward;
diff --git a/src/pages/players/index.css b/src/pages/players/index.css
index a7079de4c..7a2df2d9f 100644
--- a/src/pages/players/index.css
+++ b/src/pages/players/index.css
@@ -30,3 +30,13 @@
grid-template-columns: repeat(3, 1fr);
grid-gap: 10px;
}
+
+.game-mode .select__control {
+ color: #1b1919;
+ background-color: #2d2c2e;
+ border-color: #9a8866;
+}
+
+.game-mode .select__single-value {
+ color: #fff;
+}
diff --git a/src/pages/players/index.js b/src/pages/players/index.js
index 3f4933f4e..b02bf92ad 100644
--- a/src/pages/players/index.js
+++ b/src/pages/players/index.js
@@ -1,8 +1,9 @@
import { useState, useCallback, useMemo, useEffect, useRef } from 'react';
+import { useSelector } from 'react-redux';
import { Link } from 'react-router-dom';
import { Trans, useTranslation } from 'react-i18next';
import { Turnstile } from '@marsidev/react-turnstile'
-
+import Select from 'react-select';
import { Icon } from '@mdi/react';
import { mdiAccountSearch } from '@mdi/js';
@@ -12,6 +13,7 @@ import SEO from '../../components/SEO.jsx';
import { InputFilter } from '../../components/filter/index.js';
import playerStats from '../../modules/player-stats.mjs';
+import gameModes from '../../data/game-modes.json';
import './index.css';
@@ -23,6 +25,9 @@ function Players() {
const enterPress = useKeyPress('Enter');
+ const gameModeSetting = useSelector((state) => state.settings.gameMode);
+ const [ gameMode, setGameMode ] = useState(gameModeSetting);
+
const [nameFilter, setNameFilter] = useState('');
const [nameResults, setNameResults] = useState([]);
const [nameResultsError, setNameResultsError] = useState(false);
@@ -56,7 +61,7 @@ function Players() {
try {
setNameResultsError(false);
setButtonDisabled(true);
- setNameResults((await playerStats.searchPlayers(nameFilter, turnstileToken.current)).sort((a, b) => a.name.localeCompare(b.name)));
+ setNameResults((await playerStats.searchPlayers(nameFilter, gameMode, turnstileToken.current)).sort((a, b) => a.name.localeCompare(b.name)));
setSearched(true);
} catch (error) {
setSearched(false);
@@ -67,7 +72,7 @@ function Players() {
if (turnstileRef.current?.reset) {
turnstileRef.current.reset();
}
- }, [nameFilter, searchTextValid, setNameResults, setNameResultsError, turnstileToken, turnstileRef]);
+ }, [nameFilter, searchTextValid, setNameResults, setNameResultsError, turnstileToken, turnstileRef, gameMode]);
const searchResults = useMemo(() => {
if (!searched) {
@@ -122,6 +127,25 @@ function Players() {
+