2022-01-06 13:04:03 +01:00
|
|
|
import React from "react";
|
|
|
|
|
|
|
|
import { Accordion, AccordionSummary, AccordionDetails, Box, Typography } from "@mui/material";
|
|
|
|
|
|
|
|
import { AchievementEntry } from "./AchievementEntry";
|
2022-04-07 01:30:08 +02:00
|
|
|
import { Achievement, PlayerAchievement } from "./Achievements";
|
|
|
|
import { Settings } from "../Settings/Settings";
|
2022-01-06 13:04:03 +01:00
|
|
|
import { getFiltersFromHex } from "../ThirdParty/colorUtils";
|
|
|
|
import { CorruptableText } from "../ui/React/CorruptableText";
|
|
|
|
|
|
|
|
interface IProps {
|
|
|
|
achievements: Achievement[];
|
|
|
|
playerAchievements: PlayerAchievement[];
|
|
|
|
}
|
|
|
|
|
|
|
|
export function AchievementList({ achievements, playerAchievements }: IProps): JSX.Element {
|
|
|
|
// Need to transform the primary color into css filters to change the color of the SVG.
|
|
|
|
const cssPrimary = getFiltersFromHex(Settings.theme.primary);
|
|
|
|
const cssSecondary = getFiltersFromHex(Settings.theme.secondary);
|
|
|
|
|
2022-04-07 01:30:08 +02:00
|
|
|
const data = achievements
|
|
|
|
.map((achievement) => ({
|
|
|
|
achievement,
|
|
|
|
unlockedOn: playerAchievements.find((playerAchievement) => playerAchievement.ID === achievement.ID)?.unlockedOn,
|
|
|
|
}))
|
|
|
|
.sort((a, b) => (b.unlockedOn ?? 0) - (a.unlockedOn ?? 0));
|
2022-01-06 13:04:03 +01:00
|
|
|
|
2022-04-07 01:30:08 +02:00
|
|
|
const unlocked = data.filter((entry) => entry.unlockedOn);
|
2022-01-06 13:04:03 +01:00
|
|
|
|
|
|
|
// Hidden achievements
|
2022-04-07 01:30:08 +02:00
|
|
|
const secret = data.filter((entry) => !entry.unlockedOn && entry.achievement.Secret);
|
2022-01-06 13:04:03 +01:00
|
|
|
|
|
|
|
// Locked behind locked content (bitnode x)
|
2022-04-07 01:30:08 +02:00
|
|
|
const unavailable = data.filter(
|
|
|
|
(entry) =>
|
|
|
|
!entry.unlockedOn && !entry.achievement.Secret && entry.achievement.Visible && !entry.achievement.Visible(),
|
|
|
|
);
|
2022-01-06 13:04:03 +01:00
|
|
|
|
|
|
|
// Remaining achievements
|
|
|
|
const locked = data
|
2022-04-07 01:30:08 +02:00
|
|
|
.filter((entry) => !unlocked.map((u) => u.achievement.ID).includes(entry.achievement.ID))
|
|
|
|
.filter((entry) => !secret.map((u) => u.achievement.ID).includes(entry.achievement.ID))
|
|
|
|
.filter((entry) => !unavailable.map((u) => u.achievement.ID).includes(entry.achievement.ID));
|
2022-01-06 13:04:03 +01:00
|
|
|
|
|
|
|
return (
|
|
|
|
<Box sx={{ pr: 18, my: 2 }}>
|
2022-04-07 01:30:08 +02:00
|
|
|
<Box
|
|
|
|
sx={{
|
|
|
|
display: "flex",
|
|
|
|
flexDirection: "column",
|
|
|
|
flexWrap: "wrap",
|
|
|
|
}}
|
|
|
|
>
|
2022-01-06 13:04:03 +01:00
|
|
|
{unlocked.length > 0 && (
|
|
|
|
<Accordion defaultExpanded disableGutters square>
|
|
|
|
<AccordionSummary>
|
|
|
|
<Typography variant="h5" sx={{ my: 1 }}>
|
|
|
|
Acquired ({unlocked.length}/{data.length})
|
|
|
|
</Typography>
|
|
|
|
</AccordionSummary>
|
|
|
|
<AccordionDetails sx={{ pt: 2 }}>
|
2022-04-07 01:30:08 +02:00
|
|
|
{unlocked.map((item) => (
|
|
|
|
<AchievementEntry
|
|
|
|
key={`unlocked_${item.achievement.ID}`}
|
2022-01-06 13:04:03 +01:00
|
|
|
achievement={item.achievement}
|
|
|
|
unlockedOn={item.unlockedOn}
|
|
|
|
cssFiltersUnlocked={cssPrimary}
|
2022-04-07 01:30:08 +02:00
|
|
|
cssFiltersLocked={cssSecondary}
|
|
|
|
/>
|
2022-01-06 13:04:03 +01:00
|
|
|
))}
|
|
|
|
</AccordionDetails>
|
|
|
|
</Accordion>
|
|
|
|
)}
|
|
|
|
|
|
|
|
{locked.length > 0 && (
|
|
|
|
<Accordion disableGutters square>
|
|
|
|
<AccordionSummary>
|
|
|
|
<Typography variant="h5" color="secondary">
|
|
|
|
Locked ({locked.length} remaining)
|
|
|
|
</Typography>
|
|
|
|
</AccordionSummary>
|
|
|
|
<AccordionDetails sx={{ pt: 2 }}>
|
2022-04-07 01:30:08 +02:00
|
|
|
{locked.map((item) => (
|
|
|
|
<AchievementEntry
|
|
|
|
key={`locked_${item.achievement.ID}`}
|
2022-01-06 13:04:03 +01:00
|
|
|
achievement={item.achievement}
|
|
|
|
cssFiltersUnlocked={cssPrimary}
|
2022-04-07 01:30:08 +02:00
|
|
|
cssFiltersLocked={cssSecondary}
|
|
|
|
/>
|
2022-01-06 13:04:03 +01:00
|
|
|
))}
|
|
|
|
</AccordionDetails>
|
|
|
|
</Accordion>
|
|
|
|
)}
|
|
|
|
|
|
|
|
{unavailable.length > 0 && (
|
|
|
|
<Accordion disableGutters square>
|
|
|
|
<AccordionSummary>
|
|
|
|
<Typography variant="h5" color="secondary">
|
|
|
|
Unavailable ({unavailable.length} remaining)
|
|
|
|
</Typography>
|
|
|
|
</AccordionSummary>
|
|
|
|
<AccordionDetails>
|
2022-04-07 01:30:08 +02:00
|
|
|
<Typography sx={{ mt: 1 }}>
|
2022-01-06 13:04:03 +01:00
|
|
|
{unavailable.length} additional achievements hidden behind content you don't have access to.
|
|
|
|
</Typography>
|
|
|
|
</AccordionDetails>
|
|
|
|
</Accordion>
|
|
|
|
)}
|
|
|
|
|
|
|
|
{secret.length > 0 && (
|
|
|
|
<Accordion disableGutters square>
|
|
|
|
<AccordionSummary>
|
|
|
|
<Typography variant="h5" color="secondary">
|
|
|
|
Secret ({secret.length} remaining)
|
|
|
|
</Typography>
|
|
|
|
</AccordionSummary>
|
|
|
|
<AccordionDetails>
|
|
|
|
<Typography color="secondary" sx={{ mt: 1 }}>
|
2022-04-07 01:30:08 +02:00
|
|
|
{secret.map((item) => (
|
2022-01-10 00:02:22 +01:00
|
|
|
<span key={`secret_${item.achievement.ID}`}>
|
2022-01-06 13:04:03 +01:00
|
|
|
<CorruptableText content={item.achievement.ID}></CorruptableText>
|
|
|
|
<br />
|
2022-01-10 00:02:22 +01:00
|
|
|
</span>
|
2022-01-06 13:04:03 +01:00
|
|
|
))}
|
|
|
|
</Typography>
|
|
|
|
</AccordionDetails>
|
|
|
|
</Accordion>
|
|
|
|
)}
|
|
|
|
</Box>
|
|
|
|
</Box>
|
|
|
|
);
|
|
|
|
}
|