mirror of
https://github.com/Sendouc/sendou.ink.git
synced 2026-09-07 03:35:40 -05:00
Fix scrim map my map locking too early
This commit is contained in:
@@ -219,7 +219,13 @@ async function loadMapByMapContext({
|
||||
ScrimMapListRepository.findMapListsByScrimPostId(post.id),
|
||||
]);
|
||||
|
||||
if (Scrim.isTrackingLocked(maps, mapLists)) {
|
||||
if (
|
||||
Scrim.isTrackingLocked({
|
||||
startTime: Scrim.getStartTime(post),
|
||||
maps,
|
||||
mapLists,
|
||||
})
|
||||
) {
|
||||
errorToast("Tracking is locked");
|
||||
}
|
||||
|
||||
|
||||
@@ -532,46 +532,78 @@ describe("sideOfUser", () => {
|
||||
describe("isTrackingLocked", () => {
|
||||
const ONE_HOUR_MS = 60 * 60 * 1000;
|
||||
const lockWindowMs = SCRIM_TRACKING_AUTO_LOCK_HOURS * ONE_HOUR_MS;
|
||||
const now = 1_000_000_000;
|
||||
const secondsAgo = (ms: number) => (now - ms) / 1000;
|
||||
|
||||
test("returns false when no map list submitted yet", () => {
|
||||
expect(isTrackingLocked([], [], Date.now())).toBe(false);
|
||||
expect(isTrackingLocked({ startTime: secondsAgo(ONE_HOUR_MS), now })).toBe(
|
||||
false,
|
||||
);
|
||||
});
|
||||
|
||||
test("returns false just inside the auto-lock window from list submission", () => {
|
||||
const now = 1_000_000_000;
|
||||
const updatedAt = (now - (lockWindowMs - ONE_HOUR_MS)) / 1000;
|
||||
expect(isTrackingLocked([], [{ updatedAt }], now)).toBe(false);
|
||||
const startTime = secondsAgo(lockWindowMs);
|
||||
const updatedAt = secondsAgo(lockWindowMs - ONE_HOUR_MS);
|
||||
expect(
|
||||
isTrackingLocked({ startTime, mapLists: [{ updatedAt }], now }),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
test("returns true just past the auto-lock window from list submission", () => {
|
||||
const now = 1_000_000_000;
|
||||
const updatedAt = (now - (lockWindowMs + ONE_HOUR_MS)) / 1000;
|
||||
expect(isTrackingLocked([], [{ updatedAt }], now)).toBe(true);
|
||||
const startTime = secondsAgo(lockWindowMs * 2);
|
||||
const updatedAt = secondsAgo(lockWindowMs + ONE_HOUR_MS);
|
||||
expect(
|
||||
isTrackingLocked({ startTime, mapLists: [{ updatedAt }], now }),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test("uses the most recent reported map as the reference point", () => {
|
||||
const now = 1_000_000_000;
|
||||
const oldUpdatedAt = (now - lockWindowMs * 2) / 1000;
|
||||
const recentMapSeconds = (now - ONE_HOUR_MS) / 1000;
|
||||
const startTime = secondsAgo(lockWindowMs * 2);
|
||||
expect(
|
||||
isTrackingLocked(
|
||||
[{ reportedAt: recentMapSeconds }],
|
||||
[{ updatedAt: oldUpdatedAt }],
|
||||
isTrackingLocked({
|
||||
startTime,
|
||||
maps: [{ reportedAt: secondsAgo(ONE_HOUR_MS) }],
|
||||
mapLists: [{ updatedAt: secondsAgo(lockWindowMs * 2) }],
|
||||
now,
|
||||
),
|
||||
}),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
test("uses the most recent list update when there are no reported maps", () => {
|
||||
const now = 1_000_000_000;
|
||||
const oldUpdatedAt = (now - lockWindowMs * 2) / 1000;
|
||||
const recentUpdatedAt = (now - ONE_HOUR_MS) / 1000;
|
||||
const startTime = secondsAgo(lockWindowMs * 2);
|
||||
expect(
|
||||
isTrackingLocked(
|
||||
[],
|
||||
[{ updatedAt: oldUpdatedAt }, { updatedAt: recentUpdatedAt }],
|
||||
isTrackingLocked({
|
||||
startTime,
|
||||
mapLists: [
|
||||
{ updatedAt: secondsAgo(lockWindowMs * 2) },
|
||||
{ updatedAt: secondsAgo(ONE_HOUR_MS) },
|
||||
],
|
||||
now,
|
||||
),
|
||||
}),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
test("returns false when the map list was submitted long before a scrim that just started", () => {
|
||||
const startTime = secondsAgo(ONE_HOUR_MS);
|
||||
const updatedAt = secondsAgo(lockWindowMs * 10);
|
||||
expect(
|
||||
isTrackingLocked({ startTime, mapLists: [{ updatedAt }], now }),
|
||||
).toBe(false);
|
||||
});
|
||||
|
||||
test("returns true once the auto-lock window has elapsed since the start time", () => {
|
||||
const startTime = secondsAgo(lockWindowMs + ONE_HOUR_MS);
|
||||
const updatedAt = secondsAgo(lockWindowMs * 10);
|
||||
expect(
|
||||
isTrackingLocked({ startTime, mapLists: [{ updatedAt }], now }),
|
||||
).toBe(true);
|
||||
});
|
||||
|
||||
test("returns false for a scrim that has not started yet", () => {
|
||||
const startTime = (now + lockWindowMs) / 1000;
|
||||
const updatedAt = secondsAgo(lockWindowMs * 10);
|
||||
expect(
|
||||
isTrackingLocked({ startTime, mapLists: [{ updatedAt }], now }),
|
||||
).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -157,23 +157,33 @@ export function sideOfUser(post: ScrimPost, userId: number): ScrimSide | null {
|
||||
/**
|
||||
* Returns true when map-by-map tracking is locked: the auto-lock window has
|
||||
* elapsed since the last activity (most recent reported map, falling back to
|
||||
* the most recently updated submitted map list). Returns false when no map
|
||||
* list has been submitted yet (tracking is not active).
|
||||
* the most recently updated submitted map list). Activity happening before the
|
||||
* scrim starts does not begin the window, it only starts running once the
|
||||
* scrim is under way. Returns false when no map list has been submitted yet
|
||||
* (tracking is not active).
|
||||
*/
|
||||
export function isTrackingLocked(
|
||||
maps: Pick<Tables["ScrimMap"], "reportedAt">[] = [],
|
||||
mapLists: Pick<Tables["ScrimMapList"], "updatedAt">[] = [],
|
||||
now: number = Date.now(),
|
||||
): boolean {
|
||||
export function isTrackingLocked({
|
||||
startTime,
|
||||
maps = [],
|
||||
mapLists = [],
|
||||
now = Date.now(),
|
||||
}: {
|
||||
startTime: number;
|
||||
maps?: Pick<Tables["ScrimMap"], "reportedAt">[];
|
||||
mapLists?: Pick<Tables["ScrimMapList"], "updatedAt">[];
|
||||
now?: number;
|
||||
}): boolean {
|
||||
const latestReported = R.firstBy(
|
||||
maps.filter((m) => m.reportedAt !== null),
|
||||
[(m) => m.reportedAt!, "desc"],
|
||||
);
|
||||
const latestList = R.firstBy(mapLists, [(l) => l.updatedAt, "desc"]);
|
||||
|
||||
const referenceSeconds =
|
||||
const latestActivitySeconds =
|
||||
latestReported?.reportedAt ?? latestList?.updatedAt ?? null;
|
||||
if (referenceSeconds === null) return false;
|
||||
if (latestActivitySeconds === null) return false;
|
||||
|
||||
const referenceSeconds = Math.max(latestActivitySeconds, startTime);
|
||||
|
||||
const elapsedHours = (now - referenceSeconds * 1000) / (60 * 60 * 1000);
|
||||
|
||||
|
||||
@@ -83,7 +83,11 @@ async function resolveMapByMap({
|
||||
const pool = mapLists.length > 0 ? ScrimMapByMap.unionPool(mapLists) : null;
|
||||
const currentMap = maps.find((m) => m.reportedAt === null) ?? null;
|
||||
const viewerSide = Scrim.sideOfUser(post, user.id);
|
||||
const locked = Scrim.isTrackingLocked(maps, mapLists);
|
||||
const locked = Scrim.isTrackingLocked({
|
||||
startTime: Scrim.getStartTime(post),
|
||||
maps,
|
||||
mapLists,
|
||||
});
|
||||
|
||||
const ownList = viewerSide
|
||||
? mapLists.find((l) => l.side === viewerSide)
|
||||
|
||||
Reference in New Issue
Block a user