Improve alert timer

This commit is contained in:
41666 2023-06-10 10:58:30 -04:00
parent 8b5ceaf599
commit 2314da4763
2 changed files with 141 additions and 57 deletions

View file

@ -99,7 +99,15 @@ export const contBars = style({
export const contBarTitle = style({
fontWeight: "bold",
fontSize: "0.7rem",
padding: "0.2rem 0.5rem",
padding: "0.15rem",
lineHeight: 0.8,
display: "flex",
justifyContent: "space-between",
});
export const barSeparator = style({
height: "0.5rem",
width: "100%",
});
export const contCircle = style({
@ -145,6 +153,24 @@ export const alertCont = style({
animation: `${alertFade} 1s ease-in-out 4 alternate`,
});
const alertDotBlink = keyframes({
from: {
backgroundColor: "#ff2d2d",
},
to: {
backgroundColor: "#662929",
},
});
export const alertDot = style({
display: "inline-block",
height: "0.5rem",
width: "0.5rem",
borderRadius: "50%",
background: "#ff2d2d",
animation: `${alertDotBlink} var(--speed) ease-in-out infinite alternate`,
});
export const nextCont = style({
display: "flex",
flexDirection: "row",

View file

@ -13,6 +13,7 @@ import { FactionBar } from "./faction-bar";
import type { MetagameWorld } from "~/utils/metagame";
import type { PopulationWorld } from "~/utils/population";
import { c } from "~/utils/classes";
import { ReactFragment, useEffect, useState } from "react";
export type IndexWorldProps = {
metagame: MetagameWorld;
@ -67,64 +68,10 @@ export const IndexWorld = ({ metagame, population }: IndexWorldProps) => {
return a.alert && !b.alert ? -1 : b.alert && !a.alert ? 1 : 0;
})
.map((zone) => {
let {
name,
colors: [upper, lower],
} = zones[zone.id];
return worldId !== 19 ? (
<div
key={zone.id}
className={c(styles.continent, zone.alert && styles.alertCont)}
>
<div className={styles.contName}>
<div
className={styles.contCircle}
style={
{
"--upper-color": upper,
"--lower-color": lower,
} as any
}
></div>
<div>{name}</div>
</div>
<div className={styles.contBars}>
<div>
<div className={styles.contBarTitle}>TERRITORY CONTROL</div>
<FactionBar population={zone.territory} />
</div>
{zone.alert && (
<div>
<div className={styles.contBarTitle}>
{snakeCaseToTitleCase(
zone.alert.alert_type
).toUpperCase()}{" "}
ALERT PROGRESS | STARTED{" "}
{humanTimeAgo(
Date.now() -
new Date(zone.alert.start_time).getTime(),
true
).toUpperCase()}{" "}
AGO
</div>
<FactionBar population={zone.alert.percentages} />
</div>
)}
</div>
</div>
<Continent key={zone.id} zone={zone} />
) : (
<div key={zone.id} className={styles.contName}>
<div
className={styles.contCircle}
style={
{
"--upper-color": upper,
"--lower-color": lower,
} as any
}
></div>
<div>{name}</div>
</div>
<JaegerContinent key={zone.id} zone={zone} />
);
})}
{worldId !== 19 && (
@ -148,3 +95,114 @@ export const IndexWorld = ({ metagame, population }: IndexWorldProps) => {
</div>
);
};
const JaegerContinent = ({ zone }: { zone: MetagameWorld["zones"][0] }) => {
const {
name,
colors: [upper, lower],
} = zones[zone.id];
return (
<div key={zone.id} className={styles.contName}>
<div
className={styles.contCircle}
style={
{
"--upper-color": upper,
"--lower-color": lower,
} as any
}
></div>
<div>{name}</div>
</div>
);
};
const endTime = (alert: Required<MetagameWorld["zones"][0]>["alert"]) => {
const alertDurationMins = alert.alert_type !== "sudden_death" ? 90 : 15;
return new Date(alert.start_time).getTime() + alertDurationMins * 60 * 1000;
};
const Continent = ({ zone }: { zone: MetagameWorld["zones"][0] }) => {
const {
name,
colors: [upper, lower],
} = zones[zone.id];
return (
<div key={zone.id} className={c(styles.continent)}>
<div className={styles.contName}>
<div
className={styles.contCircle}
style={
{
"--upper-color": upper,
"--lower-color": lower,
} as any
}
></div>
<div>{name}</div>
</div>
<div className={styles.contBars}>
<div>
<div className={styles.contBarTitle}>TERRITORY CONTROL</div>
<FactionBar population={zone.territory} />
</div>
{zone.alert && (
<>
<div className={styles.barSeparator}></div>
<div>
<div className={styles.contBarTitle}>
<div>
{snakeCaseToTitleCase(zone.alert.alert_type).toUpperCase()}{" "}
ALERT PROGRESS
</div>{" "}
<div>
<TimeLeft alert={zone.alert} />{" "}
</div>
</div>
<FactionBar population={zone.alert.percentages} />
</div>
</>
)}
</div>
</div>
);
};
const timeLeftString = (alert: MetagameWorld["zones"][0]["alert"]) => {
if (alert) {
const time = endTime(alert) - Date.now();
if (time < 2000) {
return <>JUST ENDED</>;
}
const speed = time < 1000 * 60 * 15 ? "1s" : "4s";
return (
<>
{humanTimeAgo(time, true).toUpperCase()} LEFT{" "}
<div
className={styles.alertDot}
style={{ "--speed": speed } as any}
></div>
</>
);
} else {
return <></>;
}
};
const TimeLeft = ({ alert }: { alert: MetagameWorld["zones"][0]["alert"] }) => {
const [timeLeft, setTimeLeft] = useState(timeLeftString(alert));
useEffect(() => {
if (alert) {
const interval = setInterval(() => {
setTimeLeft(timeLeftString(alert));
}, 1000);
return () => clearInterval(interval);
}
}, [alert]);
return <>{timeLeft}</>;
};