+ {t('Last active: {{date}}', { date: new Date(latest * 1000).toLocaleString() })}
+
+ );
}, [playerData, t]);
const achievementColumns = useMemo(
() => [
{
Header: () => (
- currentWipe.start ? ' current-wipe-achievement' : ''}`}>
+
currentWipe.start ? ' current-wipe-achievement' : ''}`}
+ >
{new Date(props.value * 1000).toLocaleString()}
);
@@ -330,7 +350,10 @@ function Player() {
let rowAr = raritySort[rowA.original.normalizedRarity];
let rowBr = raritySort[rowB.original.normalizedRarity];
if (rowAr === rowBr) {
- return rowB.original.playersCompletedPercent - rowA.original.playersCompletedPercent
+ return (
+ rowB.original.playersCompletedPercent -
+ rowA.original.playersCompletedPercent
+ );
}
return rowAr - rowBr;
},
@@ -340,25 +363,25 @@ function Player() {
);
const achievementsData = useMemo(() => {
- return achievements?.map(a => {
- if (!playerData.achievements[a.id]) {
- return false;
- }
- return {
- ...a,
- completionDate: playerData.achievements[a.id],
- }
- }).filter(Boolean) || [];
+ return (
+ achievements
+ ?.map((a) => {
+ if (!playerData.achievements[a.id]) {
+ return false;
+ }
+ return {
+ ...a,
+ completionDate: playerData.achievements[a.id],
+ };
+ })
+ .filter(Boolean) || []
+ );
}, [achievements, playerData]);
const raidsColumns = useMemo(
() => [
{
- Header: (
-
- {t('Side')}
-
- ),
+ Header:
{t('Side')}
,
id: 'side',
accessor: 'side',
Cell: (props) => {
@@ -366,28 +389,20 @@ function Player() {
},
},
{
- Header: (
-
- {t('Raids')}
-
- ),
+ Header:
{t('Raids')}
,
id: 'raids',
accessor: 'raids',
},
{
Header: (
-
- {t('Survived')}
-
+
{t('Survived')}
),
id: 'survived',
accessor: 'survived',
},
{
Header: (
-
- {t('Runthrough')}
-
+
{t('Runthrough')}
),
id: 'runthrough',
accessor: 'runthrough',
@@ -396,11 +411,7 @@ function Player() {
},
},
{
- Header: (
-
- {t('MIA')}
-
- ),
+ Header:
{t('MIA')}
,
id: 'mia',
accessor: 'mia',
Cell: (props) => {
@@ -408,11 +419,7 @@ function Player() {
},
},
{
- Header: (
-
- {t('KIA')}
-
- ),
+ Header:
{t('KIA')}
,
id: 'kia',
accessor: 'kia',
Cell: (props) => {
@@ -420,11 +427,7 @@ function Player() {
},
},
{
- Header: (
-
- {t('Kills')}
-
- ),
+ Header:
{t('Kills')}
,
id: 'kills',
accessor: 'kills',
Cell: (props) => {
@@ -445,9 +448,7 @@ function Player() {
},
{
Header: (
-
- {t('Win Streak')}
-
+
{t('Win Streak')}
),
id: 'streak',
accessor: 'streak',
@@ -463,7 +464,7 @@ function Player() {
if (!playerData.pmcStats?.eft) {
return [];
}
- const statSides = { 'scavStats': 'Scav', 'pmcStats': 'PMC' };
+ const statSides = { scavStats: 'Scav', pmcStats: 'PMC' };
const statTypes = [
{
name: 'raids',
@@ -491,8 +492,8 @@ function Player() {
},
{
name: 'streak',
- key: ['LongestWinStreak']
- }
+ key: ['LongestWinStreak'],
+ },
];
const getStats = (side) => {
return {
@@ -500,7 +501,7 @@ function Player() {
...statTypes.reduce((all, s) => {
all[s.name] = 0;
return all;
- }, {})
+ }, {}),
};
};
const totalStats = getStats('Total');
@@ -510,7 +511,9 @@ function Player() {
const stats = playerData[sideKey].eft.overAllCounters.Items;
const currentData = getStats(sideLabel);
for (const st of statTypes) {
- const foundStat = stats.find(s => !st.key.some(keyPart => !s.Key.includes(keyPart)));
+ const foundStat = stats.find(
+ (s) => !st.key.some((keyPart) => !s.Key.includes(keyPart)),
+ );
currentData[st.name] = foundStat?.Value || 0;
totalStats[st.name] += currentData[st.name];
}
@@ -522,11 +525,7 @@ function Player() {
const skillsColumns = useMemo(
() => [
{
- Header: (
-
- {t('Skill')}
-
- ),
+ Header:
{t('Skill')}
,
id: 'skill',
accessor: 'skill',
Cell: (props) => {
@@ -534,11 +533,7 @@ function Player() {
},
},
{
- Header: (
-
- {t('Level')}
-
- ),
+ Header:
{t('Level')}
,
id: 'progress',
accessor: 'progress',
Cell: (props) => {
@@ -547,9 +542,7 @@ function Player() {
},
{
Header: (
-
- {t('Last Access')}
-
+
{t('Last Access')}
),
id: 'lastAccess',
accessor: 'lastAccess',
@@ -562,27 +555,26 @@ function Player() {
);
const skillsData = useMemo(() => {
- return playerData.skills?.Common?.map(s => {
- if (!s.Progress || s.LastAccess <= 0) {
- return false;
- }
- const skill = metaData.skills.find(skill => skill.id === s.Id);
- return {
- skill: skill?.name || s.Id,
- progress: s.Progress,
- lastAccess: s.LastAccess,
- }
- }).filter(Boolean) || [];
+ return (
+ playerData.skills?.Common?.map((s) => {
+ if (!s.Progress || s.LastAccess <= 0) {
+ return false;
+ }
+ const skill = metaData.skills.find((skill) => skill.id === s.Id);
+ return {
+ skill: skill?.name || s.Id,
+ progress: s.Progress,
+ lastAccess: s.LastAccess,
+ };
+ }).filter(Boolean) || []
+ );
}, [playerData, metaData]);
const masteringColumns = useMemo(
() => [
{
id: 'expander',
- Header: ({
- getToggleAllRowsExpandedProps,
- isAllRowsExpanded,
- }) =>
+ Header: ({ getToggleAllRowsExpandedProps, isAllRowsExpanded }) =>
//
// {isAllRowsExpanded ? 'v' : '>'}
//
@@ -610,30 +602,19 @@ function Player() {
) : null,
},
{
- Header: (
-
- {t('Weapon')}
-
- ),
+ Header:
{t('Weapon')}
,
id: 'name',
accessor: 'name',
Cell: (props) => {
if (props.row.original.shortName) {
- return (
-
- );
+ return
;
}
return props.value;
},
},
{
Header: (
-
- {t('Progress')}
-
+
{t('Progress')}
),
id: 'Progress',
accessor: 'Progress',
@@ -658,37 +639,45 @@ function Player() {
);
const masteringData = useMemo(() => {
- return playerData.skills?.Mastering?.map(masteringProgress => {
- const mastering = metaData.mastering.find(m => m.id === String(masteringProgress.Id));
- if (!mastering) {
- return false;
- }
- let level = 1;
- if (masteringProgress.Progress > mastering.level3) {
- level = 3;
- } else if (masteringProgress.Progress > mastering.level2) {
- level = 2;
- }
- return {
- ...masteringProgress,
- name: masteringProgress.Id,
- level,
- subRows: mastering.weapons.map(w => {
- const baseItem = items.find(i => i.id === w.id);
- if (!baseItem) {
- return false;
- }
- const preset = items.find (i => i.id === baseItem.properties.defaultPreset?.id);
- return {
- ...baseItem,
- itemLink: `/item/${baseItem.normalizedName}`,
- iconLink: preset ? preset.iconLink : baseItem.iconLink,
- Progress: masteringProgress.Progress,
- level,
- };
- }).filter(Boolean),
- };
- }).filter(Boolean) || [];
+ return (
+ playerData.skills?.Mastering?.map((masteringProgress) => {
+ const mastering = metaData.mastering.find(
+ (m) => m.id === String(masteringProgress.Id),
+ );
+ if (!mastering) {
+ return false;
+ }
+ let level = 1;
+ if (masteringProgress.Progress > mastering.level3) {
+ level = 3;
+ } else if (masteringProgress.Progress > mastering.level2) {
+ level = 2;
+ }
+ return {
+ ...masteringProgress,
+ name: masteringProgress.Id,
+ level,
+ subRows: mastering.weapons
+ .map((w) => {
+ const baseItem = items.find((i) => i.id === w.id);
+ if (!baseItem) {
+ return false;
+ }
+ const preset = items.find(
+ (i) => i.id === baseItem.properties.defaultPreset?.id,
+ );
+ return {
+ ...baseItem,
+ itemLink: `/item/${baseItem.normalizedName}`,
+ iconLink: preset ? preset.iconLink : baseItem.iconLink,
+ Progress: masteringProgress.Progress,
+ level,
+ };
+ })
+ .filter(Boolean),
+ };
+ }).filter(Boolean) || []
+ );
}, [playerData, metaData, items]);
const totalTimeInGame = useMemo(() => {
@@ -701,175 +690,224 @@ function Player() {
days,
hours,
minutes,
- seconds
+ seconds,
});
- return (
{`${t('Total account time in game')}: ${formattedTime}`}
);
+ return
{`${t('Total account time in game')}: ${formattedTime}`}
;
}, [playerData, t]);
- const getItemDisplay = useCallback((loadoutItem, imageOptions = {}) => {
- let item = items.find(i => i.id === loadoutItem._tpl);
- if (!item) {
- return undefined;
- }
- if (item.properties?.defaultPreset) {
- const preset = items.find(i => i.id === item.properties.defaultPreset.id);
- item = {
- ...item,
- width: preset.width,
- height: preset.height,
- baseImageLink: preset.baseImageLink,
- };
- }
- let countLabel;
+ const getItemDisplay = useCallback(
+ (loadoutItem, imageOptions = {}) => {
+ let item = items.find((i) => i.id === loadoutItem._tpl);
+ if (!item) {
+ return undefined;
+ }
+ if (item.properties?.defaultPreset) {
+ const preset = items.find((i) => i.id === item.properties.defaultPreset.id);
+ item = {
+ ...item,
+ width: preset.width,
+ height: preset.height,
+ inspectImageLink: preset.inspectImageLink,
+ };
+ }
+ let countLabel;
- let label = '';
- if (loadoutItem.upd?.StackObjectsCount > 1) {
- countLabel = loadoutItem.upd?.StackObjectsCount;
- }
- if (loadoutItem.upd?.Dogtag) {
- const tag = loadoutItem.upd.Dogtag;
- const weapon = items.find(i => i.id === tag.WeaponName?.split(' ')[0]);
- countLabel = tag.Level;
- let killerInfo =
{tag.KillerName};
- if (tag.KillerAccountId) {
- killerInfo =
{tag.KillerName};
+ let label = '';
+ if (loadoutItem.upd?.StackObjectsCount > 1) {
+ countLabel = loadoutItem.upd?.StackObjectsCount;
}
- let victimInfo = (
-
{tag.Nickname}
- );
- if (tag.AccountId !== '0') {
- victimInfo = (
-
{tag.Nickname}
+ if (loadoutItem.upd?.Dogtag) {
+ const tag = loadoutItem.upd.Dogtag;
+ const weapon = items.find((i) => i.id === tag.WeaponName?.split(' ')[0]);
+ countLabel = tag.Level;
+ let killerInfo =
{tag.KillerName};
+ if (tag.KillerAccountId) {
+ killerInfo = (
+
+ {tag.KillerName}
+
+ );
+ }
+ let victimInfo =
{tag.Nickname};
+ if (tag.AccountId !== '0') {
+ victimInfo = (
+
{tag.Nickname}
+ );
+ }
+ label = (
+
+ {victimInfo}
+ {` ${t(tag.Status)} `}
+ {killerInfo}
+ {weapon !== undefined && [
+ {` ${t('using')} `},
+
+ {weapon.shortName}
+ ,
+ ]}
+ {` ${new Date(tag.Time).toLocaleString()}`}
+
);
}
- label = (
-
- {victimInfo}
- {` ${t(tag.Status)} `}
- {killerInfo}
- {weapon !== undefined && [
- {` ${t('using')} `},
- {weapon.shortName}
- ]}
- {` ${new Date(tag.Time).toLocaleString()}`}
-
- );
- }
- if (loadoutItem.upd?.Key) {
- const key = items.find(i => i.id === loadoutItem._tpl);
- if (key) {
- if (key.properties.uses) {
- countLabel = `${key.properties.uses - loadoutItem.upd.Key.NumberOfUsages}/${key.properties.uses}`;
- } else {
- countLabel = loadoutItem.upd.Key.NumberOfUsages;
+ if (loadoutItem.upd?.Key) {
+ const key = items.find((i) => i.id === loadoutItem._tpl);
+ if (key) {
+ if (key.properties.uses) {
+ countLabel = `${key.properties.uses - loadoutItem.upd.Key.NumberOfUsages}/${key.properties.uses}`;
+ } else {
+ countLabel = loadoutItem.upd.Key.NumberOfUsages;
+ }
}
-
}
- }
- if (loadoutItem.upd?.Repairable) {
- countLabel = `${loadoutItem.upd.Repairable.Durability.toFixed(2)}/${loadoutItem.upd.Repairable.MaxDurability}`
- }
- if (loadoutItem.upd?.MedKit) {
- const item = items.find(i => i.id === loadoutItem._tpl);
- if (item?.properties?.uses || item?.properties?.hitpoints) {
- countLabel = `${loadoutItem.upd.MedKit.HpResource}/${item.properties?.uses || item.properties?.hitpoints}`;
+ if (loadoutItem.upd?.Repairable) {
+ countLabel = `${loadoutItem.upd.Repairable.Durability.toFixed(2)}/${loadoutItem.upd.Repairable.MaxDurability}`;
+ }
+ if (loadoutItem.upd?.MedKit) {
+ const item = items.find((i) => i.id === loadoutItem._tpl);
+ if (item?.properties?.uses || item?.properties?.hitpoints) {
+ countLabel = `${loadoutItem.upd.MedKit.HpResource}/${item.properties?.uses || item.properties?.hitpoints}`;
+ }
}
- }
- const itemImage = (
-
- );
- return { image: itemImage, label };
- }, [items, t, gameMode]);
+ const itemImage = (
+
+ );
+ return { image: itemImage, label };
+ },
+ [items, t, gameMode],
+ );
- const getLoadoutContents = useCallback((parentItem, itemType = 'loadout') => {
- const itemSource = itemType === 'loadout' ? playerData?.equipment?.Items : playerData?.favoriteItems;
- return itemSource?.reduce((contents, loadoutItem) => {
- if (loadoutItem.parentId !== parentItem._id) {
- return contents;
- }
- const itemDisplay = getItemDisplay(loadoutItem);
- if (!itemDisplay) {
+ const getLoadoutContents = useCallback(
+ (parentItem, itemType = 'loadout') => {
+ const itemSource =
+ itemType === 'loadout' ? playerData?.equipment?.Items : playerData?.favoriteItems;
+ return itemSource?.reduce((contents, loadoutItem) => {
+ if (loadoutItem.parentId !== parentItem._id) {
+ return contents;
+ }
+ const itemDisplay = getItemDisplay(loadoutItem);
+ if (!itemDisplay) {
+ return contents;
+ }
+ contents.push(
+
{
+ return itemDisplay.image;
+ },
+ }}
+ label={itemDisplay.label}
+ >
+ {getLoadoutContents(loadoutItem, itemType)}
+ ,
+ );
return contents;
- }
- contents.push((
-
{ return itemDisplay.image}}} label={itemDisplay.label}>
- {getLoadoutContents(loadoutItem, itemType)}
-
- ));
- return contents;
- }, []);
- }, [playerData, getItemDisplay]);
+ }, []);
+ },
+ [playerData, getItemDisplay],
+ );
- const getLoadoutInSlot = useCallback((slot) => {
- if (playerData?.equipment?.Id === undefined) {
- return "None";
- }
+ const getLoadoutInSlot = useCallback(
+ (slot) => {
+ if (playerData?.equipment?.Id === undefined) {
+ return 'None';
+ }
- let loadoutRoot = playerData.equipment.Items.find(i => i._id === playerData.equipment.Id);
- let loadoutItem = playerData.equipment.Items.find(i => i.slotId === slot && i.parentId === loadoutRoot._id);
+ let loadoutRoot = playerData.equipment.Items.find(
+ (i) => i._id === playerData.equipment.Id,
+ );
+ let loadoutItem = playerData.equipment.Items.find(
+ (i) => i.slotId === slot && i.parentId === loadoutRoot._id,
+ );
- if (loadoutItem === undefined) {
- return "None";
- }
+ if (loadoutItem === undefined) {
+ return 'None';
+ }
- let itemImage = undefined;
- let itemLabel = '';
- let contents = [];
- let itemDisplay = getItemDisplay(loadoutItem);
- if (itemDisplay) {
- itemImage = itemDisplay.image;
- }
- else {
- itemLabel = slot;
- }
- contents.push((
-
{ return itemImage}}} label={itemLabel}>
- {getLoadoutContents(loadoutItem)}
-
- ));
+ let itemImage = undefined;
+ let itemLabel = '';
+ let contents = [];
+ let itemDisplay = getItemDisplay(loadoutItem);
+ if (itemDisplay) {
+ itemImage = itemDisplay.image;
+ } else {
+ itemLabel = slot;
+ }
+ contents.push(
+
{
+ return itemImage;
+ },
+ }}
+ label={itemLabel}
+ >
+ {getLoadoutContents(loadoutItem)}
+ ,
+ );
- return
- {contents}
-
- }, [playerData, getItemDisplay, getLoadoutContents]);
+ return
{contents};
+ },
+ [playerData, getItemDisplay, getLoadoutContents],
+ );
const favoriteItemsContent = useMemo(() => {
if (!playerData?.favoriteItems?.length) {
return '';
}
- return ([
-
{t('Favorite Items')}
,
+ return [
+
+
+ {t('Favorite Items')}
+
,
- {playerData.favoriteItems.map(itemData => {
- if (itemData.parentId) {
- return false;
- }
+ {playerData.favoriteItems
+ .map((itemData) => {
+ if (itemData.parentId) {
+ return false;
+ }
- let itemImage = undefined;
- let itemLabel = '';
- let itemDisplay = getItemDisplay(itemData);
- if (itemDisplay) {
- itemImage = itemDisplay.image;
- itemLabel = itemDisplay.label;
- }
- return (
- -
-
- { return itemImage}}} label={itemLabel}>
- {getLoadoutContents(itemData, 'favorite')}
-
-
-
- );
- }).filter(Boolean)}
-
- ])
+ let itemImage = undefined;
+ let itemLabel = '';
+ let itemDisplay = getItemDisplay(itemData);
+ if (itemDisplay) {
+ itemImage = itemDisplay.image;
+ itemLabel = itemDisplay.label;
+ }
+ return (
+
+
+ {
+ return itemImage;
+ },
+ }}
+ label={itemLabel}
+ >
+ {getLoadoutContents(itemData, 'favorite')}
+
+
+
+ );
+ })
+ .filter(Boolean)}
+ ,
+ ];
}, [playerData, getItemDisplay, getLoadoutContents, t]);
useEffect(() => {
@@ -882,19 +920,36 @@ function Player() {
if (playerData.saved) {
return;
}
- fetchProfile();
- }, [playerData, accountId, turnstileToken, fetchProfile])
+ /*
+ *-----Commented out to prevent any unneccesary fetches to CloudFlare workers and/or Tarkov scanners, using the load profile feature to populate page ISSUE #1000 ------
+ *fetchProfile();
+ */
+ }, [playerData, accountId, turnstileToken, fetchProfile]);
const playerSearchDiv = (
@@ -923,10 +978,17 @@ function Player() {
{pageTitle}
{playerData.aid !== 0 && (
-
-
+
+
)}
@@ -934,10 +996,16 @@ function Player() {
{typeof playerBanned === 'undefined' && (
-
+
)}
{playerBanned === false && (
@@ -949,42 +1017,49 @@ function Player() {
)}
-
{
// https://developers.cloudflare.com/turnstile/reference/client-side-errors#error-codes
if (errorCode === '110200') {
- setProfileError(`Turnstile error: ${window.location.hostname} is not a valid hostname`);
+ setProfileError(
+ `Turnstile error: ${window.location.hostname} is not a valid hostname`,
+ );
} else {
setProfileError(`Turnstile error code ${errorCode}`);
}
}}
- options={{appearance: 'interaction-only'}}
- />
+ options={{ appearance: 'interaction-only' }}
+ /> */}