mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2024-09-20 07:16:17 +08:00
chore: add more eslint rules (#5687)
* duplicate * no meaningless void * no-unnecessary-boolean-literal-compare * prefer includes * fixes * type cast * ignore rule * backend * duplicate * interface > type * no-confusing-void-expression * no-unnecessary-type-assertion * extend plugin * fix * ignore
This commit is contained in:
parent
6b9f4a0f18
commit
fe7a67d0fb
|
@ -54,7 +54,7 @@ async function getOrCreateUser(
|
|||
|
||||
if (existingUser !== undefined && existingUser !== null) {
|
||||
return existingUser;
|
||||
} else if (createUser === false) {
|
||||
} else if (!createUser) {
|
||||
throw new MonkeyError(404, `User ${username} does not exist.`);
|
||||
}
|
||||
|
||||
|
@ -256,7 +256,7 @@ async function updateUser(uid: string): Promise<void> {
|
|||
timeTyping: timeTyping,
|
||||
completedTests: completedTests,
|
||||
startedTests: Math.round(completedTests * 1.25),
|
||||
personalBests: personalBests as PersonalBests,
|
||||
personalBests: personalBests,
|
||||
lbPersonalBests: lbPersonalBests,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -472,7 +472,7 @@ export async function addResult(
|
|||
user.banned !== true &&
|
||||
user.lbOptOut !== true &&
|
||||
(isDevEnvironment() || (user.timeTyping ?? 0) > 7200) &&
|
||||
completedEvent.stopOnLetter !== true;
|
||||
!completedEvent.stopOnLetter;
|
||||
|
||||
const selectedBadgeId = user.inventory?.badges?.find((b) => b.selected)?.id;
|
||||
const isPremium =
|
||||
|
|
|
@ -79,7 +79,10 @@ function applyTsRestApiRoutes(app: IRouter): void {
|
|||
createExpressEndpoints(contract, router, app, {
|
||||
jsonQuery: true,
|
||||
requestValidationErrorHandler(err, req, res, next) {
|
||||
if (err.body?.issues === undefined) return next();
|
||||
if (err.body?.issues === undefined) {
|
||||
next();
|
||||
return;
|
||||
}
|
||||
const issues = err.body?.issues.map(prettyErrorMessage);
|
||||
res.status(422).json({
|
||||
message: "Invalid request data schema",
|
||||
|
@ -101,7 +104,7 @@ function applyDevApiRoutes(app: Application): void {
|
|||
//disable csp to allow assets to load from unsecured http
|
||||
app.use((req, res, next) => {
|
||||
res.setHeader("Content-Security-Policy", "");
|
||||
return next();
|
||||
next();
|
||||
});
|
||||
app.use("/configure", expressStatic(join(__dirname, "../../../private")));
|
||||
|
||||
|
|
|
@ -970,7 +970,7 @@ export async function updateInbox(
|
|||
//we don't need to read mails that are going to be deleted because
|
||||
//Rewards will be claimed on unread mails on deletion
|
||||
const readSet = [...new Set(mailToRead)].filter(
|
||||
(it) => deleteSet.includes(it) === false
|
||||
(it) => !deleteSet.includes(it)
|
||||
);
|
||||
|
||||
const update = await getUsersCollection().updateOne({ uid }, [
|
||||
|
@ -992,12 +992,12 @@ export async function updateInbox(
|
|||
);
|
||||
|
||||
const toBeRead = inbox.filter(
|
||||
(it) => readIds.includes(it.id) && it.read === false
|
||||
(it) => readIds.includes(it.id) && !it.read
|
||||
);
|
||||
|
||||
//flatMap rewards
|
||||
const rewards: AllRewards[] = [...toBeRead, ...toBeDeleted]
|
||||
.filter((it) => it.read === false)
|
||||
.filter((it) => !it.read)
|
||||
.reduce((arr, current) => {
|
||||
return [...arr, ...current.rewards];
|
||||
}, []);
|
||||
|
@ -1126,7 +1126,7 @@ export async function checkIfUserIsPremium(
|
|||
): Promise<boolean> {
|
||||
const premiumFeaturesEnabled = (await getCachedConfiguration(true)).users
|
||||
.premium.enabled;
|
||||
if (premiumFeaturesEnabled !== true) {
|
||||
if (!premiumFeaturesEnabled) {
|
||||
return false;
|
||||
}
|
||||
const user =
|
||||
|
|
|
@ -50,7 +50,7 @@ export async function connect(): Promise<void> {
|
|||
};
|
||||
|
||||
mongoClient = new MongoClient(
|
||||
(DB_URI as string) ?? global.__MONGO_URI__, // Set in tests only
|
||||
DB_URI ?? global.__MONGO_URI__, // Set in tests only
|
||||
connectionOptions
|
||||
);
|
||||
|
||||
|
|
|
@ -112,7 +112,8 @@ async function _authenticateRequestInternal(
|
|||
req
|
||||
);
|
||||
|
||||
return next(error);
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
recordAuthTime(
|
||||
token.type,
|
||||
|
@ -345,7 +346,8 @@ export function authenticateGithubWebhook(): Handler {
|
|||
}
|
||||
}
|
||||
} catch (e) {
|
||||
return next(e);
|
||||
next(e);
|
||||
return;
|
||||
}
|
||||
|
||||
next();
|
||||
|
|
|
@ -98,13 +98,14 @@ async function errorHandlingMiddleware(
|
|||
delete monkeyResponse.data.errorId;
|
||||
}
|
||||
|
||||
return handleMonkeyResponse(monkeyResponse, res);
|
||||
handleMonkeyResponse(monkeyResponse, res);
|
||||
return;
|
||||
} catch (e) {
|
||||
Logger.error("Error handling middleware failed.");
|
||||
Logger.error(e);
|
||||
}
|
||||
|
||||
return handleMonkeyResponse(
|
||||
handleMonkeyResponse(
|
||||
new MonkeyResponse(
|
||||
"Something went really wrong, please contact support.",
|
||||
undefined,
|
||||
|
|
|
@ -8,10 +8,12 @@ import { isDevEnvironment } from "../utils/misc";
|
|||
const REQUEST_MULTIPLIER = isDevEnvironment() ? 100 : 1;
|
||||
|
||||
const getKey = (req: MonkeyTypes.Request, _res: Response): string => {
|
||||
return ((req.headers["cf-connecting-ip"] as string) ||
|
||||
return (
|
||||
(req.headers["cf-connecting-ip"] as string) ||
|
||||
(req.headers["x-forwarded-for"] as string) ||
|
||||
(req.ip as string) ||
|
||||
"255.255.255.255") as string;
|
||||
"255.255.255.255"
|
||||
);
|
||||
};
|
||||
|
||||
const getKeyWithUid = (req: MonkeyTypes.Request, _res: Response): string => {
|
||||
|
@ -61,7 +63,8 @@ export async function badAuthRateLimiterHandler(
|
|||
const badAuthEnabled =
|
||||
req?.ctx?.configuration?.rateLimiting?.badAuthentication?.enabled;
|
||||
if (!badAuthEnabled) {
|
||||
return next();
|
||||
next();
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
|
@ -75,7 +78,8 @@ export async function badAuthRateLimiterHandler(
|
|||
);
|
||||
}
|
||||
} catch (error) {
|
||||
return next(error);
|
||||
next(error);
|
||||
return;
|
||||
}
|
||||
|
||||
next();
|
||||
|
|
|
@ -28,7 +28,7 @@ export function asyncHandler(handler: AsyncHandler): RequestHandler {
|
|||
) => {
|
||||
try {
|
||||
const handlerData = await handler(req, res);
|
||||
return handleMonkeyResponse(handlerData, res);
|
||||
handleMonkeyResponse(handlerData, res);
|
||||
} catch (error) {
|
||||
next(error);
|
||||
}
|
||||
|
|
|
@ -35,7 +35,8 @@ export function handleMonkeyResponse(
|
|||
//@ts-expect-error ignored so that we can see message in swagger stats
|
||||
res.monkeyMessage = message;
|
||||
if ([301, 302].includes(status)) {
|
||||
return res.redirect(data);
|
||||
res.redirect(data);
|
||||
return;
|
||||
}
|
||||
|
||||
res.json({ message, data });
|
||||
|
|
|
@ -102,7 +102,7 @@ export function getFontawesomeConfig(debug = false): FontawesomeConfig {
|
|||
throw new Error("unknown icons: " + leftOvers);
|
||||
}
|
||||
|
||||
if (debug === true) {
|
||||
if (debug) {
|
||||
console.debug(
|
||||
"Make sure fontawesome modules are active: ",
|
||||
Object.entries(modules2)
|
||||
|
|
|
@ -491,9 +491,7 @@ async function runActiveCommand(): Promise<void> {
|
|||
updateInput(inputModeParams.value as string);
|
||||
hideCommands();
|
||||
} else if (command.subgroup) {
|
||||
CommandlineLists.pushToStack(
|
||||
command.subgroup as MonkeyTypes.CommandsSubgroup
|
||||
);
|
||||
CommandlineLists.pushToStack(command.subgroup);
|
||||
updateInput("");
|
||||
await filterSubgroup();
|
||||
await showCommands();
|
||||
|
|
|
@ -246,9 +246,7 @@ export const commands: MonkeyTypes.CommandsSubgroup = {
|
|||
icon: "fa-tint",
|
||||
exec: ({ input }): void => {
|
||||
if (input === undefined) return;
|
||||
void UpdateConfig.setCustomLayoutfluid(
|
||||
input as MonkeyTypes.CustomLayoutFluidSpaces
|
||||
);
|
||||
void UpdateConfig.setCustomLayoutfluid(input);
|
||||
},
|
||||
},
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ function update(themes: MonkeyTypes.Theme[]): void {
|
|||
subgroup.list = [];
|
||||
const favs: MonkeyTypes.Command[] = [];
|
||||
themes.forEach((theme) => {
|
||||
if ((Config.favThemes as string[]).includes(theme.name)) {
|
||||
if (Config.favThemes.includes(theme.name)) {
|
||||
favs.push({
|
||||
id: "changeTheme" + capitalizeFirstLetterOfEachWord(theme.name),
|
||||
display: theme.name.replace(/_/g, " "),
|
||||
|
|
|
@ -1875,10 +1875,7 @@ export async function setCustomLayoutfluid(
|
|||
return false;
|
||||
}
|
||||
|
||||
const customLayoutfluid = trimmed.replace(
|
||||
/ /g,
|
||||
"#"
|
||||
) as ConfigSchemas.CustomLayoutFluid;
|
||||
const customLayoutfluid = trimmed.replace(/ /g, "#");
|
||||
|
||||
config.customLayoutfluid = customLayoutfluid;
|
||||
saveToLocalStorage("customLayoutfluid", nosave);
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
/* eslint-disable @typescript-eslint/no-unsafe-assignment */
|
||||
type Config = {
|
||||
backendUrl: string;
|
||||
isDevelopment: boolean;
|
||||
|
|
|
@ -215,10 +215,8 @@ export async function loadUser(user: UserType): Promise<void> {
|
|||
const response = await Ape.results.save(TestLogic.notSignedInLastResult);
|
||||
|
||||
if (response.status !== 200) {
|
||||
return Notifications.add(
|
||||
"Failed to save last result: " + response.message,
|
||||
-1
|
||||
);
|
||||
Notifications.add("Failed to save last result: " + response.message, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
TestLogic.clearNotSignedInResult();
|
||||
|
@ -491,7 +489,7 @@ async function signUp(): Promise<void> {
|
|||
});
|
||||
return;
|
||||
}
|
||||
await RegisterCaptchaModal.show();
|
||||
RegisterCaptchaModal.show();
|
||||
const captchaToken = await RegisterCaptchaModal.promise;
|
||||
if (captchaToken === undefined || captchaToken === "") {
|
||||
Notifications.add("Please complete the captcha", -1);
|
||||
|
|
|
@ -55,9 +55,7 @@ export function verify(result: Result<Mode>): string | null {
|
|||
for (const requirementType in TestState.activeChallenge.requirements) {
|
||||
if (!requirementsMet) return null;
|
||||
const requirementValue =
|
||||
TestState.activeChallenge.requirements[
|
||||
requirementType as keyof typeof TestState.activeChallenge.requirements
|
||||
];
|
||||
TestState.activeChallenge.requirements[requirementType];
|
||||
|
||||
if (requirementValue === undefined) {
|
||||
throw new Error("Requirement value is undefined");
|
||||
|
|
|
@ -746,7 +746,7 @@ function handleChar(
|
|||
document.querySelectorAll<HTMLElement>("#words .word")[
|
||||
TestUI.currentWordElementIndex - 1
|
||||
]?.offsetTop ?? 0
|
||||
) as number;
|
||||
);
|
||||
if (!Config.showAllLines) TestUI.lineJump(currentTop);
|
||||
} else {
|
||||
TestInput.input.current = TestInput.input.current.slice(0, -1);
|
||||
|
|
|
@ -35,12 +35,14 @@ export async function change(
|
|||
console.debug(
|
||||
`change page to ${pageName} stopped, page transition is true`
|
||||
);
|
||||
return resolve(false);
|
||||
resolve(false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!options.force && ActivePage.get() === pageName) {
|
||||
console.debug(`change page ${pageName} stoped, page already active`);
|
||||
return resolve(false);
|
||||
resolve(false);
|
||||
return;
|
||||
} else {
|
||||
console.log(`changing page ${pageName}`);
|
||||
}
|
||||
|
|
|
@ -990,6 +990,7 @@ function verifyResultFiltersStructure(filterIn: ResultFilters): ResultFilters {
|
|||
const key = entry[0] as keyof ResultFilters;
|
||||
const value = entry[1];
|
||||
if (filter[key] === undefined) {
|
||||
// @ts-expect-error key and value is based on default filter so this is safe to ignore
|
||||
filter[key] = value;
|
||||
}
|
||||
});
|
||||
|
|
|
@ -62,7 +62,7 @@ function hide(): void {
|
|||
|
||||
for (const r of rewardsClaimed) {
|
||||
if (r.type === "xp") {
|
||||
totalXpClaimed += r.item as number;
|
||||
totalXpClaimed += r.item;
|
||||
} else if (r.type === "badge") {
|
||||
const badge = BadgeController.getById(r.item.id);
|
||||
if (badge) {
|
||||
|
|
|
@ -133,11 +133,11 @@ export async function refresh(
|
|||
lts = layouts["qwerty"];
|
||||
layoutString = "default";
|
||||
} else {
|
||||
lts = layouts[Config.layout as keyof typeof layouts];
|
||||
lts = layouts[Config.layout];
|
||||
layoutString = Config.layout;
|
||||
}
|
||||
} else {
|
||||
lts = layouts[Config.keymapLayout as keyof typeof layouts];
|
||||
lts = layouts[Config.keymapLayout];
|
||||
layoutString = Config.keymapLayout;
|
||||
}
|
||||
|
||||
|
|
|
@ -198,9 +198,7 @@ function updateFooter(lb: LbKey): void {
|
|||
|
||||
let toppercent = "";
|
||||
if (currentTimeRange === "allTime" && lbRank !== undefined && lbRank?.rank) {
|
||||
const num = Numbers.roundTo2(
|
||||
(lbRank.rank / (currentRank[lb].count as number)) * 100
|
||||
);
|
||||
const num = Numbers.roundTo2((lbRank.rank / currentRank[lb].count) * 100);
|
||||
if (currentRank[lb].rank === 1) {
|
||||
toppercent = "GOAT";
|
||||
} else {
|
||||
|
@ -482,10 +480,11 @@ async function update(): Promise<void> {
|
|||
if (failedResponses.length > 0) {
|
||||
hideLoader("15");
|
||||
hideLoader("60");
|
||||
return Notifications.add(
|
||||
Notifications.add(
|
||||
"Failed to load leaderboards: " + failedResponses[0]?.message,
|
||||
-1
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const [lb15Data, lb60Data] = responses.map((response) => response.data);
|
||||
|
|
|
@ -90,8 +90,8 @@ function updateParticle(particle: Particle): void {
|
|||
particle.prev.x = particle.x;
|
||||
particle.prev.y = particle.y;
|
||||
// Update pos
|
||||
particle.x += particle.vel.x * (ctx.deltaTime as number);
|
||||
particle.y += particle.vel.y * (ctx.deltaTime as number);
|
||||
particle.x += particle.vel.x * ctx.deltaTime;
|
||||
particle.y += particle.vel.y * ctx.deltaTime;
|
||||
|
||||
if (particle.x > ctx.canvas.width) {
|
||||
particle.vel.x *= -particleBounceMod;
|
||||
|
|
|
@ -67,7 +67,7 @@ export default class SettingsGroup<T extends ConfigValue> {
|
|||
let typed = value as T;
|
||||
if (typed === "true") typed = true as T;
|
||||
if (typed === "false") typed = false as T;
|
||||
this.setValue(typed as T);
|
||||
this.setValue(typed);
|
||||
}
|
||||
);
|
||||
} else if (this.mode === "range") {
|
||||
|
@ -109,9 +109,9 @@ export default class SettingsGroup<T extends ConfigValue> {
|
|||
`.pageSettings .section[data-config-name='${this.configName}'] button`
|
||||
).removeClass("active");
|
||||
if (this.mode === "select") {
|
||||
const select = document.querySelector(
|
||||
const select = document.querySelector<HTMLSelectElement>(
|
||||
`.pageSettings .section[data-config-name='${this.configName}'] select`
|
||||
) as HTMLSelectElement | null;
|
||||
);
|
||||
|
||||
if (select === null) {
|
||||
return;
|
||||
|
@ -131,12 +131,12 @@ export default class SettingsGroup<T extends ConfigValue> {
|
|||
`.pageSettings .section[data-config-name='${this.configName}'] button[data-config-value='${this.configValue}']`
|
||||
).addClass("active");
|
||||
} else if (this.mode === "range") {
|
||||
const range = document.querySelector(
|
||||
const range = document.querySelector<HTMLInputElement>(
|
||||
`.pageSettings .section[data-config-name='${this.configName}'] input[type=range]`
|
||||
) as HTMLInputElement | null;
|
||||
);
|
||||
const rangeValue = document.querySelector(
|
||||
`.pageSettings .section[data-config-name='${this.configName}'] .value`
|
||||
) as HTMLSpanElement | null;
|
||||
);
|
||||
|
||||
if (range === null || rangeValue === null) {
|
||||
return;
|
||||
|
|
|
@ -20,7 +20,7 @@ function updateActiveButton(): void {
|
|||
Config.randomTheme !== "custom" &&
|
||||
ThemeController.randomTheme !== null
|
||||
) {
|
||||
activeThemeName = ThemeController.randomTheme as string;
|
||||
activeThemeName = ThemeController.randomTheme;
|
||||
}
|
||||
|
||||
document
|
||||
|
@ -169,7 +169,7 @@ export async function refreshButtons(): Promise<void> {
|
|||
Config.randomTheme !== "custom" &&
|
||||
ThemeController.randomTheme !== null
|
||||
) {
|
||||
activeThemeName = ThemeController.randomTheme as string;
|
||||
activeThemeName = ThemeController.randomTheme;
|
||||
}
|
||||
|
||||
let themes;
|
||||
|
|
|
@ -53,7 +53,7 @@ function addToGlobal(items: Record<string, unknown>): void {
|
|||
|
||||
void loadFromLocalStorage();
|
||||
void VersionButton.update();
|
||||
void Focus.set(true, true);
|
||||
Focus.set(true, true);
|
||||
|
||||
addToGlobal({
|
||||
snapshot: DB.getSnapshot,
|
||||
|
|
|
@ -47,7 +47,7 @@ function refreshList(): void {
|
|||
}
|
||||
</button>
|
||||
</td>
|
||||
<td onClick=${console.log(key)}>${key.name}</td>
|
||||
<td>${key.name}</td>
|
||||
<td>${format(new Date(key.createdOn), "dd MMM yyyy HH:mm")}</td>
|
||||
<td>${format(new Date(key.modifiedOn), "dd MMM yyyy HH:mm")}</td>
|
||||
<td>${
|
||||
|
@ -116,7 +116,8 @@ async function toggleActiveKey(keyId: string): Promise<void> {
|
|||
const response = await Ape.apeKeys.update(keyId, { enabled: !key.enabled });
|
||||
Loader.hide();
|
||||
if (response.status !== 200) {
|
||||
return Notifications.add("Failed to update key: " + response.message, -1);
|
||||
Notifications.add("Failed to update key: " + response.message, -1);
|
||||
return;
|
||||
}
|
||||
key.enabled = !key.enabled;
|
||||
refreshList();
|
||||
|
|
|
@ -109,17 +109,17 @@ const modal = new AnimatedModal({
|
|||
}
|
||||
});
|
||||
modalEl.querySelector(".acceptSelected")?.addEventListener("click", () => {
|
||||
const analytics = (
|
||||
const analyticsChecked = (
|
||||
modalEl.querySelector(".cookie.analytics input") as HTMLInputElement
|
||||
).checked;
|
||||
const accepted = {
|
||||
security: true,
|
||||
analytics,
|
||||
analytics: analyticsChecked,
|
||||
};
|
||||
setAcceptedObject(accepted);
|
||||
void hide();
|
||||
|
||||
if (analytics === true) {
|
||||
if (analyticsChecked) {
|
||||
activateAnalytics();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -8,7 +8,7 @@ function parseInput(input: string): number {
|
|||
const re = /((-\s*)?\d+(\.\d+)?\s*[hms]?)/g;
|
||||
const seconds = [...input.toLowerCase().matchAll(re)]
|
||||
.map((match) => {
|
||||
const part = match[0] as string;
|
||||
const part = match[0];
|
||||
const duration = parseFloat(part.replace(/\s+/g, ""));
|
||||
|
||||
if (part.includes("h")) {
|
||||
|
|
|
@ -121,10 +121,8 @@ async function save(): Promise<void> {
|
|||
state.tags = state.tags.filter((el) => el !== undefined);
|
||||
|
||||
if (response.status !== 200) {
|
||||
return Notifications.add(
|
||||
"Failed to update result tags: " + response.message,
|
||||
-1
|
||||
);
|
||||
Notifications.add("Failed to update result tags: " + response.message, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
//can do this because the response will not be null if the status is 200
|
||||
|
|
|
@ -59,15 +59,17 @@ async function hide(): Promise<void> {
|
|||
|
||||
async function apply(): Promise<void> {
|
||||
if (!signedInUser) {
|
||||
return Notifications.add(
|
||||
Notifications.add(
|
||||
"Missing user credential. Please close the popup and try again.",
|
||||
-1
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const captcha = CaptchaController.getResponse("googleSignUpModal");
|
||||
if (!captcha) {
|
||||
return Notifications.add("Please complete the captcha", 0);
|
||||
Notifications.add("Please complete the captcha", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
disableInput();
|
||||
|
@ -190,10 +192,11 @@ const checkNameDebounced = debounce(1000, async () => {
|
|||
|
||||
if (response.status !== 200) {
|
||||
nameIndicator.show("unavailable");
|
||||
return Notifications.add(
|
||||
Notifications.add(
|
||||
"Failed to check name availability: " + response.message,
|
||||
-1
|
||||
);
|
||||
return;
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -206,7 +209,8 @@ async function setup(modalEl: HTMLElement): Promise<void> {
|
|||
disableButton();
|
||||
const val = $("#googleSignUpModal input").val() as string;
|
||||
if (val === "") {
|
||||
return nameIndicator.hide();
|
||||
nameIndicator.hide();
|
||||
return;
|
||||
} else {
|
||||
nameIndicator.show("checking");
|
||||
void checkNameDebounced();
|
||||
|
|
|
@ -96,10 +96,8 @@ async function getQuotes(): Promise<void> {
|
|||
Loader.hide();
|
||||
|
||||
if (response.status !== 200) {
|
||||
return Notifications.add(
|
||||
"Failed to get new quotes: " + response.message,
|
||||
-1
|
||||
);
|
||||
Notifications.add("Failed to get new quotes: " + response.message, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
quotes = response.data ?? [];
|
||||
|
@ -158,10 +156,8 @@ async function approveQuote(index: number, dbid: string): Promise<void> {
|
|||
if (response.status !== 200) {
|
||||
resetButtons(index);
|
||||
quote.find("textarea, input").prop("disabled", false);
|
||||
return Notifications.add(
|
||||
"Failed to approve quote: " + response.message,
|
||||
-1
|
||||
);
|
||||
Notifications.add("Failed to approve quote: " + response.message, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
Notifications.add(`Quote approved. ${response.message ?? ""}`, 1);
|
||||
|
@ -182,7 +178,8 @@ async function refuseQuote(index: number, dbid: string): Promise<void> {
|
|||
if (response.status !== 200) {
|
||||
resetButtons(index);
|
||||
quote.find("textarea, input").prop("disabled", false);
|
||||
return Notifications.add("Failed to refuse quote: " + response.message, -1);
|
||||
Notifications.add("Failed to refuse quote: " + response.message, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
Notifications.add("Quote refused.", 1);
|
||||
|
@ -213,10 +210,8 @@ async function editQuote(index: number, dbid: string): Promise<void> {
|
|||
if (response.status !== 200) {
|
||||
resetButtons(index);
|
||||
quote.find("textarea, input").prop("disabled", false);
|
||||
return Notifications.add(
|
||||
"Failed to approve quote: " + response.message,
|
||||
-1
|
||||
);
|
||||
Notifications.add("Failed to approve quote: " + response.message, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
Notifications.add(`Quote edited and approved. ${response.message ?? ""}`, 1);
|
||||
|
|
|
@ -131,7 +131,8 @@ function hide(clearChain = false): void {
|
|||
|
||||
async function submit(): Promise<void> {
|
||||
if (rating === 0) {
|
||||
return Notifications.add("Please select a rating");
|
||||
Notifications.add("Please select a rating");
|
||||
return;
|
||||
}
|
||||
if (!currentQuote) {
|
||||
return;
|
||||
|
@ -143,10 +144,8 @@ async function submit(): Promise<void> {
|
|||
Loader.hide();
|
||||
|
||||
if (response.status !== 200) {
|
||||
return Notifications.add(
|
||||
"Failed to submit quote rating: " + response.message,
|
||||
-1
|
||||
);
|
||||
Notifications.add("Failed to submit quote rating: " + response.message, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
const snapshot = DB.getSnapshot();
|
||||
|
|
|
@ -52,10 +52,7 @@ export async function show(
|
|||
},
|
||||
});
|
||||
|
||||
new CharacterCounter(
|
||||
$("#quoteReportModal .comment") as JQuery<HTMLTextAreaElement>,
|
||||
250
|
||||
);
|
||||
new CharacterCounter($("#quoteReportModal .comment"), 250);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
@ -74,32 +71,37 @@ async function hide(clearChain = false): Promise<void> {
|
|||
async function submitReport(): Promise<void> {
|
||||
const captchaResponse = CaptchaController.getResponse("quoteReportModal");
|
||||
if (!captchaResponse) {
|
||||
return Notifications.add("Please complete the captcha");
|
||||
Notifications.add("Please complete the captcha");
|
||||
return;
|
||||
}
|
||||
|
||||
const quoteId = state.quoteToReport?.id.toString();
|
||||
const quoteLanguage = removeLanguageSize(Config.language);
|
||||
const reason = $("#quoteReportModal .reason").val() as string;
|
||||
const comment = $("#quoteReportModal .comment").val() as string;
|
||||
const captcha = captchaResponse as string;
|
||||
const captcha = captchaResponse;
|
||||
|
||||
if (quoteId === undefined || quoteId === "") {
|
||||
return Notifications.add("Please select a quote");
|
||||
Notifications.add("Please select a quote");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!reason) {
|
||||
return Notifications.add("Please select a valid report reason");
|
||||
Notifications.add("Please select a valid report reason");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!comment) {
|
||||
return Notifications.add("Please provide a comment");
|
||||
Notifications.add("Please provide a comment");
|
||||
return;
|
||||
}
|
||||
|
||||
const characterDifference = comment.length - 250;
|
||||
if (characterDifference > 0) {
|
||||
return Notifications.add(
|
||||
Notifications.add(
|
||||
`Report comment is ${characterDifference} character(s) too long`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
Loader.show();
|
||||
|
@ -113,7 +115,8 @@ async function submitReport(): Promise<void> {
|
|||
Loader.hide();
|
||||
|
||||
if (response.status !== 200) {
|
||||
return Notifications.add("Failed to report quote: " + response.message, -1);
|
||||
Notifications.add("Failed to report quote: " + response.message, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
Notifications.add("Report submitted. Thank you!", 1);
|
||||
|
|
|
@ -209,7 +209,7 @@ async function updateResults(searchText: string): Promise<void> {
|
|||
|
||||
const searchResults = modal
|
||||
.getModal()
|
||||
.querySelectorAll(".searchResult") as NodeListOf<HTMLElement>;
|
||||
.querySelectorAll<HTMLElement>(".searchResult");
|
||||
for (const searchResult of searchResults) {
|
||||
const quoteId = parseInt(searchResult.dataset["quoteId"] as string);
|
||||
searchResult
|
||||
|
@ -325,7 +325,7 @@ function hide(clearChain = false): void {
|
|||
function apply(val: number): void {
|
||||
if (isNaN(val)) {
|
||||
val = parseInt(
|
||||
(document.getElementById("searchBox") as HTMLInputElement).value as string
|
||||
(document.getElementById("searchBox") as HTMLInputElement).value
|
||||
);
|
||||
}
|
||||
if (val !== null && !isNaN(val) && val >= 0) {
|
||||
|
|
|
@ -32,7 +32,8 @@ async function submitQuote(): Promise<void> {
|
|||
const captcha = CaptchaController.getResponse("submitQuote");
|
||||
|
||||
if (!text || !source || !language) {
|
||||
return Notifications.add("Please fill in all fields", 0);
|
||||
Notifications.add("Please fill in all fields", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
Loader.show();
|
||||
|
@ -40,7 +41,8 @@ async function submitQuote(): Promise<void> {
|
|||
Loader.hide();
|
||||
|
||||
if (response.status !== 200) {
|
||||
return Notifications.add("Failed to submit quote: " + response.message, -1);
|
||||
Notifications.add("Failed to submit quote: " + response.message, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
Notifications.add("Quote submitted.", 1);
|
||||
|
@ -71,10 +73,7 @@ export async function show(showOptions: ShowOptions): Promise<void> {
|
|||
$("#quoteSubmitModal .newQuoteLanguage").trigger("change");
|
||||
$("#quoteSubmitModal input").val("");
|
||||
|
||||
new CharacterCounter(
|
||||
$("#quoteSubmitModal .newQuoteText") as JQuery<HTMLTextAreaElement>,
|
||||
250
|
||||
);
|
||||
new CharacterCounter($("#quoteSubmitModal .newQuoteText"), 250);
|
||||
},
|
||||
});
|
||||
}
|
||||
|
|
|
@ -111,7 +111,6 @@ type PopupKey =
|
|||
| "resetAccount"
|
||||
| "clearTagPb"
|
||||
| "optOutOfLeaderboards"
|
||||
| "clearTagPb"
|
||||
| "applyCustomFont"
|
||||
| "resetPersonalBests"
|
||||
| "resetSettings"
|
||||
|
@ -287,7 +286,7 @@ class SimpleModal {
|
|||
attributes["value"] = input.initVal?.toString() ?? "";
|
||||
attributes["type"] = input.type;
|
||||
}
|
||||
if (!input.hidden && !input.optional === true) {
|
||||
if (!input.hidden && !input.optional) {
|
||||
attributes["required"] = true;
|
||||
}
|
||||
if (input.disabled) {
|
||||
|
@ -1887,7 +1886,7 @@ export function showPopup(
|
|||
Notifications.add("Failed to show popup - popup is not defined", -1);
|
||||
return;
|
||||
}
|
||||
if (popup.onlineOnly === true && !ConnectionState.get()) {
|
||||
if (popup.onlineOnly && !ConnectionState.get()) {
|
||||
Notifications.add("You are offline", 0, { duration: 2 });
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -28,7 +28,8 @@ let select: SlimSelect | undefined = undefined;
|
|||
|
||||
export async function show(options: ShowOptions): Promise<void> {
|
||||
if (!isAuthenticated()) {
|
||||
return Notifications.add("You must be logged in to submit a report", 0);
|
||||
Notifications.add("You must be logged in to submit a report", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
void modal.show({
|
||||
|
@ -59,10 +60,7 @@ export async function show(options: ShowOptions): Promise<void> {
|
|||
},
|
||||
});
|
||||
|
||||
new CharacterCounter(
|
||||
$("#userReportModal .comment") as JQuery<HTMLTextAreaElement>,
|
||||
250
|
||||
);
|
||||
new CharacterCounter($("#userReportModal .comment"), 250);
|
||||
}
|
||||
|
||||
async function hide(): Promise<void> {
|
||||
|
@ -78,36 +76,41 @@ async function hide(): Promise<void> {
|
|||
async function submitReport(): Promise<void> {
|
||||
const captchaResponse = CaptchaController.getResponse("userReportModal");
|
||||
if (!captchaResponse) {
|
||||
return Notifications.add("Please complete the captcha");
|
||||
Notifications.add("Please complete the captcha");
|
||||
return;
|
||||
}
|
||||
|
||||
const reason = $("#userReportModal .reason").val() as string;
|
||||
const comment = $("#userReportModal .comment").val() as string;
|
||||
const captcha = captchaResponse as string;
|
||||
const captcha = captchaResponse;
|
||||
|
||||
if (!reason) {
|
||||
return Notifications.add("Please select a valid report reason");
|
||||
Notifications.add("Please select a valid report reason");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!comment) {
|
||||
return Notifications.add("Please provide a comment");
|
||||
Notifications.add("Please provide a comment");
|
||||
return;
|
||||
}
|
||||
|
||||
if (reason === "Suspected cheating" && state.lbOptOut) {
|
||||
return Notifications.add(
|
||||
Notifications.add(
|
||||
"You cannot report this user for suspected cheating as they have opted out of the leaderboards.",
|
||||
0,
|
||||
{
|
||||
duration: 10,
|
||||
}
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
const characterDifference = comment.length - 250;
|
||||
if (characterDifference > 0) {
|
||||
return Notifications.add(
|
||||
Notifications.add(
|
||||
`Report comment is ${characterDifference} character(s) too long`
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
Loader.show();
|
||||
|
@ -120,7 +123,8 @@ async function submitReport(): Promise<void> {
|
|||
Loader.hide();
|
||||
|
||||
if (response.status !== 200) {
|
||||
return Notifications.add("Failed to report user: " + response.message, -1);
|
||||
Notifications.add("Failed to report user: " + response.message, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
Notifications.add("Report submitted. Thank you!", 1);
|
||||
|
|
|
@ -220,8 +220,8 @@ async function fillContent(): Promise<void> {
|
|||
PbTables.update(snapshot.personalBests);
|
||||
void Profile.update("account", snapshot);
|
||||
|
||||
void TestActivity.init(snapshot.testActivity, new Date(snapshot.addedAt));
|
||||
void void ResultBatches.update();
|
||||
TestActivity.init(snapshot.testActivity, new Date(snapshot.addedAt));
|
||||
void ResultBatches.update();
|
||||
|
||||
chartData = [];
|
||||
accChartData = [];
|
||||
|
|
|
@ -260,7 +260,8 @@ $(".page.pageLogin .register.side .usernameInput").on("input", () => {
|
|||
".page.pageLogin .register.side .usernameInput"
|
||||
).val() as string;
|
||||
if (val === "") {
|
||||
return nameIndicator.hide();
|
||||
nameIndicator.hide();
|
||||
return;
|
||||
} else {
|
||||
nameIndicator.show("checking");
|
||||
void checkNameDebounced();
|
||||
|
|
|
@ -186,10 +186,8 @@ async function update(options: UpdateOptions): Promise<void> {
|
|||
$(".page.pageProfile .error .message").text(message);
|
||||
} else if (response.status !== 200) {
|
||||
// $(".page.pageProfile .failedToLoad").removeClass("hidden");
|
||||
return Notifications.add(
|
||||
"Failed to load profile: " + response.message,
|
||||
-1
|
||||
);
|
||||
Notifications.add("Failed to load profile: " + response.message, -1);
|
||||
return;
|
||||
} else {
|
||||
window.history.replaceState(null, "", `/profile/${response.data.name}`);
|
||||
await Profile.update("profile", response.data);
|
||||
|
|
|
@ -169,11 +169,15 @@ export function setCustomTextLongProgress(
|
|||
}
|
||||
|
||||
function getLocalStorage(): CustomTextObject {
|
||||
return JSON.parse(window.localStorage.getItem("customText") ?? "{}");
|
||||
return JSON.parse(
|
||||
window.localStorage.getItem("customText") ?? "{}"
|
||||
) as CustomTextObject;
|
||||
}
|
||||
|
||||
function getLocalStorageLong(): CustomTextLongObject {
|
||||
return JSON.parse(window.localStorage.getItem("customTextLong") ?? "{}");
|
||||
return JSON.parse(
|
||||
window.localStorage.getItem("customTextLong") ?? "{}"
|
||||
) as CustomTextLongObject;
|
||||
}
|
||||
|
||||
function setLocalStorage(data: CustomTextObject): void {
|
||||
|
|
|
@ -139,7 +139,7 @@ export function canSetConfigWithCurrentFunboxes(
|
|||
Notifications.add(
|
||||
`You can't set ${Strings.camelCaseToWords(
|
||||
key
|
||||
)} to ${value} with currently active funboxes.`,
|
||||
)} to ${value.toString()} with currently active funboxes.`,
|
||||
0,
|
||||
{
|
||||
duration: 5,
|
||||
|
@ -185,7 +185,7 @@ export function canSetFunboxWithConfig(
|
|||
errorStrings.push(
|
||||
`${Strings.capitalizeFirstLetter(
|
||||
Strings.camelCaseToWords(error.key)
|
||||
)} cannot be set to ${error.value}.`
|
||||
)} cannot be set to ${error.value.toString()}.`
|
||||
);
|
||||
}
|
||||
Notifications.add(
|
||||
|
|
|
@ -893,7 +893,7 @@ export async function finish(difficultyFailed = false): Promise<void> {
|
|||
dontSave = true;
|
||||
}
|
||||
|
||||
const completedEvent = JSON.parse(JSON.stringify(ce));
|
||||
const completedEvent = JSON.parse(JSON.stringify(ce)) as CompletedEvent;
|
||||
|
||||
///////// completed event ready
|
||||
|
||||
|
@ -1008,7 +1008,7 @@ export async function finish(difficultyFailed = false): Promise<void> {
|
|||
) {
|
||||
// They bailed out
|
||||
|
||||
const historyLength = TestInput.input.getHistory()?.length as number;
|
||||
const historyLength = TestInput.input.getHistory()?.length;
|
||||
const newProgress =
|
||||
CustomText.getCustomTextLongProgress(customTextName) + historyLength;
|
||||
CustomText.setCustomTextLongProgress(customTextName, newProgress);
|
||||
|
@ -1049,7 +1049,9 @@ export async function finish(difficultyFailed = false): Promise<void> {
|
|||
|
||||
$("#result .stats .dailyLeaderboard").addClass("hidden");
|
||||
|
||||
TestStats.setLastResult(JSON.parse(JSON.stringify(completedEvent)));
|
||||
TestStats.setLastResult(
|
||||
JSON.parse(JSON.stringify(completedEvent)) as CompletedEvent
|
||||
);
|
||||
|
||||
if (!ConnectionState.get()) {
|
||||
ConnectionState.showOfflineBanner();
|
||||
|
@ -1067,6 +1069,7 @@ export async function finish(difficultyFailed = false): Promise<void> {
|
|||
);
|
||||
|
||||
if (completedEvent.chartData !== "toolong") {
|
||||
// @ts-expect-error TODO: check if this is needed
|
||||
delete completedEvent.chartData.unsmoothedRaw;
|
||||
}
|
||||
|
||||
|
@ -1089,7 +1092,7 @@ export async function finish(difficultyFailed = false): Promise<void> {
|
|||
Result.updateRateQuote(TestWords.currentQuote);
|
||||
|
||||
AccountButton.loading(true);
|
||||
if (completedEvent.bailedOut !== true) {
|
||||
if (!completedEvent.bailedOut) {
|
||||
completedEvent.challenge = ChallengeContoller.verify(completedEvent);
|
||||
}
|
||||
|
||||
|
@ -1151,7 +1154,8 @@ async function saveResult(
|
|||
response.message =
|
||||
"Looks like your result data is using an incorrect schema. Please refresh the page to download the new update. If the problem persists, please contact support.";
|
||||
}
|
||||
return Notifications.add("Failed to save result: " + response.message, -1);
|
||||
Notifications.add("Failed to save result: " + response.message, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
$("#result .stats .tags .editTagsButton").attr(
|
||||
|
|
|
@ -69,13 +69,13 @@ export function getStats(): unknown {
|
|||
try {
|
||||
// @ts-expect-error
|
||||
ret.keypressTimings.spacing.average =
|
||||
(TestInput.keypressTimings.spacing.array as number[]).reduce(
|
||||
TestInput.keypressTimings.spacing.array.reduce(
|
||||
(previous, current) => (current += previous)
|
||||
) / TestInput.keypressTimings.spacing.array.length;
|
||||
|
||||
// @ts-expect-error
|
||||
ret.keypressTimings.spacing.sd = Numbers.stdDev(
|
||||
TestInput.keypressTimings.spacing.array as number[]
|
||||
TestInput.keypressTimings.spacing.array
|
||||
);
|
||||
} catch (e) {
|
||||
//
|
||||
|
@ -83,13 +83,13 @@ export function getStats(): unknown {
|
|||
try {
|
||||
// @ts-expect-error
|
||||
ret.keypressTimings.duration.average =
|
||||
(TestInput.keypressTimings.duration.array as number[]).reduce(
|
||||
TestInput.keypressTimings.duration.array.reduce(
|
||||
(previous, current) => (current += previous)
|
||||
) / TestInput.keypressTimings.duration.array.length;
|
||||
|
||||
// @ts-expect-error
|
||||
ret.keypressTimings.duration.sd = Numbers.stdDev(
|
||||
TestInput.keypressTimings.duration.array as number[]
|
||||
TestInput.keypressTimings.duration.array
|
||||
);
|
||||
} catch (e) {
|
||||
//
|
||||
|
@ -295,7 +295,7 @@ function countChars(): CharCount {
|
|||
correctChars += targetWord.length;
|
||||
if (
|
||||
i < inputWords.length - 1 &&
|
||||
Strings.getLastChar(inputWord as string) !== "\n"
|
||||
Strings.getLastChar(inputWord) !== "\n"
|
||||
) {
|
||||
correctspaces++;
|
||||
}
|
||||
|
|
|
@ -390,7 +390,7 @@ export function showWords(): void {
|
|||
let wordsHTML = "";
|
||||
if (Config.mode !== "zen") {
|
||||
for (let i = 0; i < TestWords.words.length; i++) {
|
||||
wordsHTML += getWordHTML(TestWords.words.get(i) as string);
|
||||
wordsHTML += getWordHTML(TestWords.words.get(i));
|
||||
}
|
||||
} else {
|
||||
wordsHTML =
|
||||
|
@ -421,9 +421,7 @@ export async function updateWordsInputPosition(initial = false): Promise<void> {
|
|||
const isLanguageRTL = currentLanguage.rightToLeft;
|
||||
|
||||
const el = document.querySelector("#wordsInput") as HTMLElement;
|
||||
const activeWord = document.querySelector(
|
||||
"#words .active"
|
||||
) as HTMLElement | null;
|
||||
const activeWord = document.querySelector<HTMLElement>("#words .active");
|
||||
|
||||
if (!activeWord) {
|
||||
el.style.top = "0px";
|
||||
|
@ -1385,7 +1383,7 @@ export async function applyBurstHeatmap(): Promise<void> {
|
|||
if (wordBurstAttr === undefined) {
|
||||
$(word).css("color", unreachedColor);
|
||||
} else {
|
||||
let wordBurstVal = parseInt(wordBurstAttr as string);
|
||||
let wordBurstVal = parseInt(wordBurstAttr);
|
||||
wordBurstVal = Math.round(
|
||||
getTypingSpeedUnit(Config.typingSpeedUnit).fromWpm(wordBurstVal)
|
||||
);
|
||||
|
@ -1503,7 +1501,8 @@ $(".pageTest #copyWordsListButton").on("click", async () => {
|
|||
if (Config.mode === "zen") {
|
||||
words = TestInput.input.history.join(" ");
|
||||
} else {
|
||||
words = (TestWords.words.get() as string[])
|
||||
words = TestWords.words
|
||||
.get()
|
||||
.slice(0, TestInput.input.history.length)
|
||||
.join(" ");
|
||||
}
|
||||
|
|
|
@ -672,18 +672,18 @@ export async function generateWords(
|
|||
}
|
||||
|
||||
ret.hasTab =
|
||||
ret.words.some((w) => /\t/.test(w)) ||
|
||||
currentWordset.words.some((w) => /\t/.test(w)) ||
|
||||
ret.words.some((w) => w.includes("\t")) ||
|
||||
currentWordset.words.some((w) => w.includes("\t")) ||
|
||||
(Config.mode === "quote" &&
|
||||
(quote as MonkeyTypes.QuoteWithTextSplit).textSplit.some((w) =>
|
||||
/\t/.test(w)
|
||||
w.includes("\t")
|
||||
));
|
||||
ret.hasNewline =
|
||||
ret.words.some((w) => /\n/.test(w)) ||
|
||||
currentWordset.words.some((w) => /\n/.test(w)) ||
|
||||
ret.words.some((w) => w.includes("\n")) ||
|
||||
currentWordset.words.some((w) => w.includes("\n")) ||
|
||||
(Config.mode === "quote" &&
|
||||
(quote as MonkeyTypes.QuoteWithTextSplit).textSplit.some((w) =>
|
||||
/\n/.test(w)
|
||||
w.includes("\n")
|
||||
));
|
||||
|
||||
sectionHistory = []; //free up a bit of memory? is that even a thing?
|
||||
|
|
|
@ -195,7 +195,10 @@ export default class AnimatedModal<
|
|||
async show(options?: ShowOptions<IncomingModalChainData>): Promise<void> {
|
||||
// eslint-disable-next-line no-async-promise-executor
|
||||
return new Promise(async (resolve) => {
|
||||
if (this.open) return resolve();
|
||||
if (this.open) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
Skeleton.append(this.dialogId, this.skeletonAppendParent);
|
||||
|
||||
if (!this.setupRan) {
|
||||
|
@ -203,7 +206,10 @@ export default class AnimatedModal<
|
|||
this.setupRan = true;
|
||||
}
|
||||
|
||||
if (isPopupVisible(this.dialogId)) return resolve();
|
||||
if (isPopupVisible(this.dialogId)) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
const modalAnimationDuration =
|
||||
(options?.customAnimation?.modal?.durationMs ??
|
||||
|
@ -316,7 +322,10 @@ export default class AnimatedModal<
|
|||
async hide(options?: HideOptions<OutgoingModalChainData>): Promise<void> {
|
||||
// eslint-disable-next-line no-async-promise-executor
|
||||
return new Promise(async (resolve) => {
|
||||
if (!isPopupVisible(this.dialogId)) return resolve();
|
||||
if (!isPopupVisible(this.dialogId)) {
|
||||
resolve();
|
||||
return;
|
||||
}
|
||||
|
||||
if (options?.clearModalChain) {
|
||||
this.previousModalInChain = undefined;
|
||||
|
|
|
@ -30,17 +30,13 @@ export async function linkDiscord(hashOverride: string): Promise<void> {
|
|||
Loader.hide();
|
||||
|
||||
if (response.status !== 200) {
|
||||
return Notifications.add(
|
||||
"Failed to link Discord: " + response.message,
|
||||
-1
|
||||
);
|
||||
Notifications.add("Failed to link Discord: " + response.message, -1);
|
||||
return;
|
||||
}
|
||||
|
||||
if (response.data === null) {
|
||||
return Notifications.add(
|
||||
"Failed to link Discord: data returned was null",
|
||||
-1
|
||||
);
|
||||
Notifications.add("Failed to link Discord: data returned was null", -1);
|
||||
return;
|
||||
}
|
||||
|
||||
Notifications.add(response.message, 1);
|
||||
|
@ -71,7 +67,8 @@ export function loadCustomThemeFromUrl(getOverride?: string): void {
|
|||
try {
|
||||
decoded = JSON.parse(atob(getValue));
|
||||
} catch (e) {
|
||||
return Notifications.add("Invalid custom theme ", 0);
|
||||
Notifications.add("Invalid custom theme ", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
let colorArray = [];
|
||||
|
@ -87,7 +84,8 @@ export function loadCustomThemeFromUrl(getOverride?: string): void {
|
|||
}
|
||||
|
||||
if (colorArray.length === 0) {
|
||||
return Notifications.add("Invalid custom theme ", 0);
|
||||
Notifications.add("Invalid custom theme ", 0);
|
||||
return;
|
||||
}
|
||||
|
||||
const oldCustomTheme = Config.customTheme;
|
||||
|
@ -213,7 +211,7 @@ export function loadChallengeFromUrl(getOverride?: string): void {
|
|||
Notifications.add("Loading challenge", 0);
|
||||
ChallengeController.setup(getValue)
|
||||
.then((result) => {
|
||||
if (result === true) {
|
||||
if (result) {
|
||||
Notifications.add("Challenge loaded", 1);
|
||||
restartTest({
|
||||
nosave: true,
|
||||
|
|
|
@ -54,9 +54,39 @@ module.exports = {
|
|||
"plugin:@typescript-eslint/eslint-recommended",
|
||||
"plugin:@typescript-eslint/recommended",
|
||||
"plugin:@typescript-eslint/strict",
|
||||
// "plugin:@typescript-eslint/recommended-requiring-type-checking"
|
||||
"plugin:@typescript-eslint/strict-type-checked",
|
||||
],
|
||||
rules: {
|
||||
//strict type checked
|
||||
"@typescript-eslint/require-await": "off",
|
||||
"@typescript-eslint/unbound-method": "off",
|
||||
"@typescript-eslint/await-thenable": "off",
|
||||
"@typescript-eslint/no-useless-template-literals": "off",
|
||||
"@typescript-eslint/prefer-promise-reject-errors": "off",
|
||||
"@typescript-eslint/no-this-alias": "off",
|
||||
"@typescript-eslint/no-unnecessary-type-arguments": "off",
|
||||
"@typescript-eslint/restrict-template-expressions": "off",
|
||||
"@typescript-eslint/no-redundant-type-constituents": "off",
|
||||
"@typescript-eslint/restrict-plus-operands": "off",
|
||||
|
||||
// TODO: enable at some point
|
||||
"@typescript-eslint/no-unsafe-return": "off", //~12
|
||||
"@typescript-eslint/no-unsafe-assignment": "off", //~63
|
||||
"@typescript-eslint/no-unsafe-argument": "off", //~37
|
||||
"@typescript-eslint/no-unsafe-call": "off", //~76
|
||||
"@typescript-eslint/no-unsafe-member-access": "off", //~105
|
||||
//
|
||||
|
||||
"@typescript-eslint/no-unnecessary-type-assertion": [
|
||||
"error",
|
||||
{
|
||||
typesToIgnore: ["HTMLElement", "Element"],
|
||||
},
|
||||
],
|
||||
"@typescript-eslint/no-confusing-void-expression": [
|
||||
"error",
|
||||
{ ignoreArrowShorthand: true },
|
||||
],
|
||||
"@typescript-eslint/explicit-function-return-type": ["error"],
|
||||
"@typescript-eslint/ban-ts-comment": "off",
|
||||
"@typescript-eslint/no-empty-function": "warn",
|
||||
|
|
|
@ -184,7 +184,6 @@ export type DBResult<T extends Mode> = Omit<
|
|||
| "customText"
|
||||
| "quoteLength"
|
||||
| "isPb"
|
||||
| "customText"
|
||||
> & {
|
||||
correctChars?: number; // --------------
|
||||
incorrectChars?: number; // legacy results
|
||||
|
@ -241,7 +240,7 @@ export type CustomTextDataWithTextLen = Omit<CustomTextData, "text"> & {
|
|||
textLen: number;
|
||||
};
|
||||
|
||||
export interface ResultFilters {
|
||||
export type ResultFilters = {
|
||||
_id: string;
|
||||
name: string;
|
||||
pb: {
|
||||
|
@ -300,7 +299,7 @@ export interface ResultFilters {
|
|||
funbox: {
|
||||
none?: boolean;
|
||||
} & Record<string, boolean>;
|
||||
}
|
||||
};
|
||||
|
||||
export type PSA = {
|
||||
_id: string;
|
||||
|
|
Loading…
Reference in a new issue