fix(app): keep the guild verification timer stable across switches (#1738)

This commit is contained in:
Hampus authored and GitHub committed 2026-08-19 12:40:55 +02:00
1 parent a1b595d52f
commit 8836565c32
2 files changed
+26 -20

No files matched your search

@@ -32,14 +32,18 @@ export const VerificationBarrier = observer(({channel}: Props) => {
case VerificationFailureReason.ACCOUNT_TOO_NEW:
return (
<AccountTooNewBarrier
initialTimeRemaining={verificationStatus.timeRemaining || 0}
initialTimeRemaining={
verificationStatus.verificationEndsAt ? Math.max(0, verificationStatus.verificationEndsAt - Date.now()) : 0
}
data-flx="channel.verification-barrier.account-too-new-barrier"
/>
);
case VerificationFailureReason.NOT_MEMBER_LONG_ENOUGH:
return (
<NotMemberLongEnoughBarrier
initialTimeRemaining={verificationStatus.timeRemaining || 0}
initialTimeRemaining={
verificationStatus.verificationEndsAt ? Math.max(0, verificationStatus.verificationEndsAt - Date.now()) : 0
}
data-flx="channel.verification-barrier.not-member-long-enough-barrier"
/>
);
@@ -50,7 +54,9 @@ export const VerificationBarrier = observer(({channel}: Props) => {
case VerificationFailureReason.TIMED_OUT:
return (
<TimeoutBarrier
initialTimeRemaining={verificationStatus.timeRemaining || 0}
initialTimeRemaining={
verificationStatus.verificationEndsAt ? Math.max(0, verificationStatus.verificationEndsAt - Date.now()) : 0
}
data-flx="channel.verification-barrier.timeout-barrier"
/>
);
@@ -30,7 +30,7 @@ export type VerificationFailureReason = ValueOf<typeof VerificationFailureReason
interface VerificationStatus {
canAccess: boolean;
reason?: VerificationFailureReason;
timeRemaining?: number;
verificationEndsAt?: number;
}
class GuildVerification {
@@ -81,10 +81,11 @@ class GuildVerification {
for (const guild of guilds) {
const status = this.computeVerificationStatus(guild);
newVerificationStatus[guild.id] = status;
if (!status.canAccess && status.timeRemaining && status.timeRemaining > 0) {
const delay = status.verificationEndsAt ? status.verificationEndsAt - Date.now() : undefined;
if (!status.canAccess && delay && delay > 0) {
newTimers[guild.id] = setTimeout(() => {
this.recomputeGuild(guild.id);
}, status.timeRemaining);
}, delay);
}
}
this.verificationStatus = Object.freeze(newVerificationStatus);
@@ -106,10 +107,11 @@ class GuildVerification {
}
const newTimers = {...this.timers};
delete newTimers[guildId];
if (!status.canAccess && status.timeRemaining && status.timeRemaining > 0) {
const delay = status.verificationEndsAt ? status.verificationEndsAt - Date.now() : undefined;
if (!status.canAccess && delay && delay > 0) {
newTimers[guildId] = setTimeout(() => {
this.recomputeGuild(guildId);
}, status.timeRemaining);
}, delay);
}
this.verificationStatus = Object.freeze(newVerificationStatus);
this.timers = newTimers;
@@ -124,12 +126,11 @@ class GuildVerification {
const now = Date.now();
if (member?.communicationDisabledUntil) {
const timeoutUntil = member.communicationDisabledUntil;
const timeRemaining = timeoutUntil.getTime() - now;
if (timeRemaining > 0) {
if (timeoutUntil.getTime() > now) {
return {
canAccess: false,
reason: VerificationFailureReason.TIMED_OUT,
timeRemaining,
verificationEndsAt: timeoutUntil.getTime(),
};
}
}
@@ -164,18 +165,16 @@ class GuildVerification {
}
}
if (verificationLevel >= GuildVerificationLevel.MEDIUM) {
const accountAge = Date.now() - user.createdAt.getTime();
if (accountAge < FIVE_MINUTES_MS) {
const timeRemaining = FIVE_MINUTES_MS - accountAge;
return {canAccess: false, reason: VerificationFailureReason.ACCOUNT_TOO_NEW, timeRemaining};
const verificationEndsAt = user.createdAt.getTime() + FIVE_MINUTES_MS;
if (verificationEndsAt > now) {
return {canAccess: false, reason: VerificationFailureReason.ACCOUNT_TOO_NEW, verificationEndsAt};
}
}
if (verificationLevel >= GuildVerificationLevel.HIGH) {
if (member?.joinedAt) {
const membershipDuration = Date.now() - member.joinedAt.getTime();
if (membershipDuration < TEN_MINUTES_MS) {
const timeRemaining = TEN_MINUTES_MS - membershipDuration;
return {canAccess: false, reason: VerificationFailureReason.NOT_MEMBER_LONG_ENOUGH, timeRemaining};
const verificationEndsAt = member.joinedAt.getTime() + TEN_MINUTES_MS;
if (verificationEndsAt > now) {
return {canAccess: false, reason: VerificationFailureReason.NOT_MEMBER_LONG_ENOUGH, verificationEndsAt};
}
}
}
@@ -196,7 +195,8 @@ class GuildVerification {
}
getTimeRemaining(guildId: string): number | null {
return this.verificationStatus[guildId]?.timeRemaining ?? null;
const verificationEndsAt = this.verificationStatus[guildId]?.verificationEndsAt;
return verificationEndsAt ? Math.max(0, verificationEndsAt - Date.now()) : null;
}
}