Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 25 additions & 0 deletions frontend/__tests__/test/british-english.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,5 +38,30 @@ describe("british-english", () => {
"armour-flavouring"
);
});

it("should convert double quotes to single quotes", async () => {
await expect(replace('"hello"', "")).resolves.toEqual("'hello'");
await expect(replace('"test"', "")).resolves.toEqual("'test'");
await expect(replace('"Hello World"', "")).resolves.toEqual(
"'Hello World'"
);
});

it("should convert double quotes and replace words", async () => {
await expect(replace('"color"', "")).resolves.toEqual("'colour'");
await expect(replace('"math"', "")).resolves.toEqual("'maths'");
await expect(replace('"Color"', "")).resolves.toEqual("'Colour'");
});

it("should handle multiple double quotes in a word", async () => {
await expect(
replace('He said "hello" and "goodbye"', "")
).resolves.toEqual("He said 'hello' and 'goodbye'");
});

it("should not affect words without double quotes", async () => {
await expect(replace("'hello'", "")).resolves.toEqual("'hello'");
await expect(replace("test", "")).resolves.toEqual("test");
});
});
});
12 changes: 9 additions & 3 deletions frontend/src/styles/core.scss
Original file line number Diff line number Diff line change
Expand Up @@ -350,14 +350,20 @@ key {
line-height: 1em;
font-size: var(--size);
border-radius: 100%;
background-position: center center;
background-size: contain;
background-repeat: no-repeat;
grid-column: 1/2;
grid-row: 1/2;
place-self: center center;
display: grid;
place-content: center center;
overflow: hidden;
display: inline-block;
z-index: 1; //place above the loading spinner
img {
width: 100%;
height: 100%;
object-fit: cover;
display: block;
}
}

.loading {
Expand Down
16 changes: 8 additions & 8 deletions frontend/src/ts/db.ts
Original file line number Diff line number Diff line change
Expand Up @@ -951,16 +951,16 @@ export function saveLocalResult(data: SaveLocalResultData): void {
startedTests: 0,
completedTests: 0,
};
}

const time =
data.result.testDuration +
data.result.incompleteTestSeconds -
data.result.afkDuration;
const time =
data.result.testDuration +
data.result.incompleteTestSeconds -
data.result.afkDuration;

snapshot.typingStats.timeTyping += time;
snapshot.typingStats.startedTests += data.result.restartCount + 1;
snapshot.typingStats.completedTests += 1;
}
snapshot.typingStats.timeTyping += time;
snapshot.typingStats.startedTests += data.result.restartCount + 1;
snapshot.typingStats.completedTests += 1;

if (data.isPb) {
saveLocalPB(
Expand Down
9 changes: 1 addition & 8 deletions frontend/src/ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ import "./states/connection";
import "./test/tts";
import "./elements/fps-counter";
import "./controllers/profile-search-controller";
import { isDevEnvironment } from "./utils/misc";
import { isDevEnvironment, addToGlobal } from "./utils/misc";
import * as VersionButton from "./elements/version-button";
import * as Focus from "./test/focus";
import { getDevOptionsModal } from "./utils/async-modules";
Expand Down Expand Up @@ -71,13 +71,6 @@ Object.defineProperty(window, "Math", {
enumerable: true,
});

function addToGlobal(items: Record<string, unknown>): void {
for (const [name, item] of Object.entries(items)) {
//@ts-expect-error dev
window[name] = item;
}
}

void loadFromLocalStorage();
void VersionButton.update();
Focus.set(true, true);
Expand Down
5 changes: 5 additions & 0 deletions frontend/src/ts/test/british-english.ts
Original file line number Diff line number Diff line change
Expand Up @@ -658,6 +658,11 @@ export async function replace(
word: string,
previousWord: string
): Promise<string> {
// Convert American-style double quotes to British-style single quotes
if (word.includes('"')) {
word = word.replace(/"/g, "'");
}

if (word.includes("-")) {
//this handles hyphenated words (for example "cream-colored") to make sure
//we don't have to add every possible combination to the list
Expand Down
89 changes: 37 additions & 52 deletions frontend/src/ts/utils/discord-avatar.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,41 @@
const cachedAvatarUrlByAvatarId: Map<string, string | null> = new Map();

type Options = { size?: number; userIcon?: string };

function buildElement(
url: string | null,
options?: { loading?: boolean } & Options
): HTMLElement {
const knownBadUrls = new Set();

function buildElement(url: string | null, options?: Options): HTMLElement {
const avatar = document.createElement("div");
avatar.classList.add("avatar");
if (url === null) {
if (options?.loading) {
avatar.innerHTML = `<div class="loading"><i class="fas fa-circle-notch fa-spin"><i></div>`;
} else {
avatar.innerHTML = `<div class="userIcon"><i class="${
options?.userIcon ?? "fas fa-user-circle"
}"><i></div>`;
}

if (url === null || knownBadUrls.has(url)) {
avatar.innerHTML = `<div class="userIcon"><i class="${
options?.userIcon ?? "fas fa-user-circle"
}"></i></div>`;
} else {
avatar.innerHTML = `<div class="discordImage" style="background-image:url(${url}?size=${
options?.size ?? 32
})"></div>`;
const loading = document.createElement("div");
loading.className = "loading";
loading.innerHTML = '<i class="fas fa-circle-notch fa-spin"></i>';

const imageContainer = document.createElement("div");
imageContainer.className = "discordImage";

const img = document.createElement("img");
img.src = `${url}?size=${options?.size ?? 32}`;

// Add event listeners directly to the img element
img.addEventListener("load", async () => {
loading.remove();
});

img.addEventListener("error", () => {
knownBadUrls.add(url);
avatar.replaceWith(buildElement(null, options));
});

imageContainer.appendChild(img);
avatar.appendChild(loading);
avatar.appendChild(imageContainer);
}

return avatar;
}

Expand All @@ -43,40 +58,10 @@ export function getAvatarElement(
return buildElement(null, options);
}

const cachedUrl = cachedAvatarUrlByAvatarId.get(discordAvatar);

if (cachedUrl !== undefined) {
return buildElement(cachedUrl, options);
} else {
const element = buildElement(null, { loading: true });

void getDiscordAvatarUrl({ discordId, discordAvatar }).then((url) => {
cachedAvatarUrlByAvatarId.set(discordAvatar, url);
element.replaceWith(buildElement(url, options));
});

return element;
}
}

async function getDiscordAvatarUrl({
discordId,
discordAvatar,
}: {
discordId: string;
discordAvatar: string;
}): Promise<string | null> {
// An invalid request to this URL will return a 404.
try {
const avatarUrl = `https://cdn.discordapp.com/avatars/${discordId}/${discordAvatar}.png`;

const response = await fetch(avatarUrl, { method: "HEAD" });
if (!response.ok) {
return null;
}

return avatarUrl;
} catch (error) {}
const element = buildElement(
`https://cdn.discordapp.com/avatars/${discordId}/${discordAvatar}.png`,
options
);

return null;
return element;
}
7 changes: 7 additions & 0 deletions frontend/src/ts/utils/misc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -761,4 +761,11 @@ export function scrollToCenterOrTop(el: HTMLElement | null): void {
});
}

export function addToGlobal(items: Record<string, unknown>): void {
for (const [name, item] of Object.entries(items)) {
//@ts-expect-error dev
window[name] = item;
}
}

// DO NOT ALTER GLOBAL OBJECTSONSTRUCTOR, IT WILL BREAK RESULT HASHES
Loading