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
40 changes: 21 additions & 19 deletions frontend/__tests__/components/ScrollToTop.spec.tsx
Original file line number Diff line number Diff line change
@@ -1,19 +1,14 @@
import { describe, it, expect, vi, beforeEach } from "vitest";
import { render } from "@solidjs/testing-library";
import { userEvent } from "@testing-library/user-event";
import {
ScrollToTop,
__testing,
hideScrollToTop,
} from "../../src/ts/components/ScrollToTop";
import * as ActivePage from "../../src/ts/states/active-page";
import { ScrollToTop } from "../../src/ts/components/ScrollToTop";
import * as CoreSignals from "../../src/ts/signals/core";

describe("ScrollToTop", () => {
const getActivePageMock = vi.spyOn(ActivePage, "get");
const getActivePageMock = vi.spyOn(CoreSignals, "getActivePage");
beforeEach(() => {
getActivePageMock.mockClear().mockReturnValue("account");
Object.defineProperty(window, "scrollY", { value: 0, writable: true });
__testing.resetState();
});

function renderElement(): {
Expand Down Expand Up @@ -44,18 +39,34 @@ describe("ScrollToTop", () => {
expect(button).toHaveClass("invisible");
});

it("becomes visible when scrollY > 100", () => {
it("becomes visible when scrollY > 100 on non-test pages", () => {
const { button } = renderElement();
scrollTo(150);

expect(button).not.toHaveClass("invisible");
});

it("stays invisible on test page regardless of scroll", () => {
it("stays invisible on test page at scroll 0", () => {
getActivePageMock.mockReturnValue("test");
const { button } = renderElement();

expect(button).toHaveClass("invisible");
});

it("stays invisible on test page even with scroll > 100", () => {
getActivePageMock.mockReturnValue("test");
const { button } = renderElement();
scrollTo(150);

expect(button).toHaveClass("invisible");
});

it("becomes invisible when scroll < 100 on non-test pages", () => {
const { button } = renderElement();
scrollTo(150);
expect(button).not.toHaveClass("invisible");

scrollTo(50);
expect(button).toHaveClass("invisible");
});

Expand All @@ -74,15 +85,6 @@ describe("ScrollToTop", () => {
expect(button).toHaveClass("invisible");
});

it("hides button when hideScrollToTop is called", () => {
const { button } = renderElement();
scrollTo(150);

hideScrollToTop();

expect(button).toHaveClass("invisible");
});

it("cleans up scroll listener on unmount", () => {
const removeEventListenerSpy = vi.spyOn(window, "removeEventListener");
const { unmount } = render(() => <ScrollToTop />);
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/ts/commandline/commandline-metadata.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { areUnsortedArraysEqual } from "../utils/arrays";
import Config from "../config";
import { get as getTypingSpeedUnit } from "../utils/typing-speed-units";
import { Validation } from "../elements/input-validation";
import * as ActivePage from "../states/active-page";
import { getActivePage } from "../signals/core";
import { Fonts } from "../constants/fonts";
import { KnownFontName } from "@monkeytype/schemas/fonts";
import * as UI from "../ui";
Expand Down Expand Up @@ -278,7 +278,7 @@ export const commandlineConfigMetadata: CommandlineConfigMetadataObject = {
inputValueConvert: (val) =>
val.trim().split(" ") as ConfigSchemas.CustomPolyglot,
afterExec: () => {
if (ActivePage.get() === "test") {
if (getActivePage() === "test") {
TestLogic.restart();
}
},
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/ts/commandline/commandline.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { clearFontPreview } from "../ui";
import AnimatedModal, { ShowOptions } from "../utils/animated-modal";
import * as Notifications from "../elements/notifications";
import * as OutOfFocus from "../test/out-of-focus";
import * as ActivePage from "../states/active-page";
import { getActivePage } from "../signals/core";
import * as Loader from "../elements/loader";
import { Command, CommandsSubgroup, CommandWithValidation } from "./types";
import { areSortedArraysEqual, areUnsortedArraysEqual } from "../utils/arrays";
Expand Down Expand Up @@ -185,7 +185,7 @@ function hide(clearModalChain = false): void {
afterAnimation: async () => {
hideWarning();
addCommandlineBackground();
if (ActivePage.get() !== "test") {
if (getActivePage() !== "test") {
(document.activeElement as HTMLElement | undefined)?.blur();
}
isAnimating = false;
Expand Down
21 changes: 5 additions & 16 deletions frontend/src/ts/components/ScrollToTop.tsx
Original file line number Diff line number Diff line change
@@ -1,17 +1,12 @@
import { JSXElement, createSignal, onMount, onCleanup } from "solid-js";
import * as ActivePage from "../states/active-page";
import { getActivePage } from "../signals/core";
import "./ScrollToTop.scss";

const [visible, setVisible] = createSignal(false);

export function hideScrollToTop(): void {
setVisible(false);
}

export function ScrollToTop(): JSXElement {
const [visible, setVisible] = createSignal(false);

const handleScroll = (): void => {
const page = ActivePage.get();
if (page === "test") return;
if (getActivePage() === "test") return;

const scroll = window.scrollY;
setVisible(scroll > 100);
Expand All @@ -31,7 +26,7 @@ export function ScrollToTop(): JSXElement {
<div
class={`breakout button`}
classList={{
invisible: !visible(),
invisible: getActivePage() === "test" || !visible(),
}}
onClick={() => {
setVisible(false);
Expand All @@ -46,9 +41,3 @@ export function ScrollToTop(): JSXElement {
</div>
);
}

export const __testing = {
resetState: (): void => {
setVisible(false);
},
};
4 changes: 2 additions & 2 deletions frontend/src/ts/controllers/chart-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import chartAnnotation, {
} from "chartjs-plugin-annotation";
import chartTrendline from "chartjs-plugin-trendline";
import { get as getTypingSpeedUnit } from "../utils/typing-speed-units";
import * as ActivePage from "../states/active-page";
import { getActivePage } from "../signals/core";

Chart.register(
BarController,
Expand Down Expand Up @@ -1433,7 +1433,7 @@ export function updateAllChartColors(): void {
}

ConfigEvent.subscribe(({ key, newValue }) => {
if (key === "accountChart" && ActivePage.get() === "account") {
if (key === "accountChart" && getActivePage() === "account") {
updateResults();
updateAccuracy();
updateAverage10();
Expand Down
10 changes: 5 additions & 5 deletions frontend/src/ts/controllers/page-controller.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import * as Misc from "../utils/misc";
import * as Strings from "../utils/strings";
import * as ActivePage from "../states/active-page";
import { getActivePage, setActivePage } from "../signals/core";
import * as Settings from "../pages/settings";
import * as Account from "../pages/account";
import * as PageTest from "../pages/test";
Expand Down Expand Up @@ -174,7 +174,7 @@ export async function change(
return false;
}

if (!options.force && ActivePage.get() === pageName) {
if (!options.force && getActivePage() === pageName) {
console.debug(`change page ${pageName} stoped, page already active`);
return false;
} else {
Expand All @@ -196,7 +196,7 @@ export async function change(
leaderboards: PageLeaderboards.page,
};

const previousPage = pages[ActivePage.get()];
const previousPage = pages[getActivePage()];
const nextPage = pages[pageName];
const totalDuration = Misc.applyReducedMotion(250);

Expand Down Expand Up @@ -246,7 +246,7 @@ export async function change(
}

pages.loading.element.addClass("active");
ActivePage.set(pages.loading.id);
setActivePage(pages.loading.id);
Focus.set(false);
PageLoading.showError();
PageLoading.updateText(
Expand All @@ -260,7 +260,7 @@ export async function change(

//between
updateTitle(nextPage);
ActivePage.set(nextPage.id);
setActivePage(nextPage.id);
updateOpenGraphUrl();
Focus.set(false);

Expand Down
4 changes: 2 additions & 2 deletions frontend/src/ts/controllers/pw-ad-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
//@ts-nocheck too many errors from 3rd party ad code

import Config from "../config";
import * as ActivePage from "../states/active-page";
import { getActivePage } from "../signals/core";
import * as TestState from "../test/test-state";

// Step 1: Create the Ramp Object, NOTE: selector id needed for tagged units only
Expand Down Expand Up @@ -207,7 +207,7 @@ function getUnits(): unknown {

export async function reinstate(): boolean {
if (!rampReady) return;
if (ActivePage.get() === "test" && !TestState.resultVisible) {
if (getActivePage() === "test" && !TestState.resultVisible) {
ramp.destroyUnits("all");
return;
}
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/ts/elements/alerts.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import { updateXp as accountPageUpdateProfile } from "./profile";
import { MonkeyMail } from "@monkeytype/schemas/users";
import * as XPBar from "../elements/xp-bar";
import * as AuthEvent from "../observables/auth-event";
import * as ActivePage from "../states/active-page";
import { getActivePage } from "../signals/core";
import { animate } from "animejs";
import { qs, qsr } from "../utils/dom";

Expand Down Expand Up @@ -117,7 +117,7 @@ function hide(): void {
const snapxp = DB.getSnapshot()?.xp ?? 0;
void XPBar.update(snapxp, totalXpClaimed);

const activePage = ActivePage.get();
const activePage = getActivePage();
if (activePage === "account" || activePage === "profile") {
accountPageUpdateProfile(activePage, snapxp + totalXpClaimed, true);
}
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/ts/elements/keymap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import * as Misc from "../utils/misc";
import * as JSONData from "../utils/json-data";
import * as Hangul from "hangul-js";
import * as Notifications from "../elements/notifications";
import * as ActivePage from "../states/active-page";
import { getActivePage } from "../signals/core";
import * as TestWords from "../test/test-words";
import { capsState } from "../test/caps-warning";
import * as ShiftTracker from "../test/shift-tracker";
Expand Down Expand Up @@ -398,7 +398,7 @@ export async function refresh(): Promise<void> {
: Config.layout;

if (Config.keymapMode === "off") return;
if (ActivePage.get() !== "test") return;
if (getActivePage() !== "test") return;
if (!layoutName) return;
try {
let layoutNameDisplayString = layoutName;
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/ts/elements/profile.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import * as Levels from "../utils/levels";
import * as DateTime from "@monkeytype/util/date-and-time";
import { getHTMLById } from "../controllers/badge-controller";
import { throttle } from "throttle-debounce";
import * as ActivePage from "../states/active-page";
import { getActivePage } from "../signals/core";
import { formatDistanceToNowStrict } from "date-fns/formatDistanceToNowStrict";
import { getHtmlByUserFlags } from "../controllers/user-flag-controller";
import Format from "../utils/format";
Expand Down Expand Up @@ -457,7 +457,7 @@ export function updateFriendRequestButton(): void {
}
}
const throttledEvent = throttle(1000, () => {
const activePage = ActivePage.get();
const activePage = getActivePage();
if (activePage && ["account", "profile"].includes(activePage)) {
updateNameFontSize(activePage as ProfileViewPaths);
}
Expand Down
6 changes: 3 additions & 3 deletions frontend/src/ts/elements/settings/theme-picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import * as Loader from "../loader";
import * as DB from "../../db";
import * as ConfigEvent from "../../observables/config-event";
import { isAuthenticated } from "../../firebase";
import * as ActivePage from "../../states/active-page";
import { getActivePage } from "../../signals/core";
import { CustomThemeColors, ThemeName } from "@monkeytype/schemas/configs";
import { captureException } from "../../sentry";
import { ThemesListSorted } from "../../constants/themes";
Expand Down Expand Up @@ -487,10 +487,10 @@ $(".pageSettings #saveCustomThemeButton").on("click", async () => {
});

ConfigEvent.subscribe(({ key }) => {
if (key === "theme" && ActivePage.get() === "settings") {
if (key === "theme" && getActivePage() === "settings") {
updateActiveButton();
}
if (key === "favThemes" && ActivePage.get() === "settings") {
if (key === "favThemes" && getActivePage() === "settings") {
void fillPresetButtons();
}
});
6 changes: 3 additions & 3 deletions frontend/src/ts/event-handlers/global.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import Config from "../config";
import * as TestWords from "../test/test-words";
import * as Commandline from "../commandline/commandline";
import * as Notifications from "../elements/notifications";
import * as ActivePage from "../states/active-page";
import { getActivePage } from "../signals/core";
import { ModifierKeys } from "../constants/modifier-keys";
import { focusWords } from "../test/test-ui";
import * as TestLogic from "../test/test-logic";
Expand All @@ -17,7 +17,7 @@ document.addEventListener("keydown", (e) => {
if (PageTransition.get()) return;
if (e.key === undefined) return;

const pageTestActive: boolean = ActivePage.get() === "test";
const pageTestActive: boolean = getActivePage() === "test";
if (pageTestActive && !TestState.resultVisible && !isInputElementFocused()) {
const popupVisible: boolean = Misc.isAnyPopupVisible();
// this is nested because isAnyPopupVisible is a bit expensive
Expand Down Expand Up @@ -74,7 +74,7 @@ document.addEventListener("keydown", (e) => {
!isInteractiveElement)
) {
e.preventDefault();
if (ActivePage.get() === "test") {
if (getActivePage() === "test") {
if (e.shiftKey) {
ManualRestart.set();
}
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/ts/pages/account-settings.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { PageWithUrlParams } from "./page";
import * as Skeleton from "../utils/skeleton";
import { getAuthenticatedUser, isAuthenticated } from "../firebase";
import * as ActivePage from "../states/active-page";
import { getActivePage } from "../signals/core";
import { swapElements } from "../utils/misc";
import { getSnapshot } from "../db";
import Ape from "../ape";
Expand Down Expand Up @@ -147,7 +147,7 @@ function updateAccountSections(): void {
}

export function updateUI(): void {
if (ActivePage.get() !== "accountSettings") return;
if (getActivePage() !== "accountSettings") return;
updateAuthenticationSections();
updateIntegrationSections();
updateAccountSections();
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/ts/pages/account.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import * as ConnectionState from "../states/connection";
import * as Skeleton from "../utils/skeleton";
import type { ScaleChartOptions, LinearScaleOptions } from "chart.js";
import * as ConfigEvent from "../observables/config-event";
import * as ActivePage from "../states/active-page";
import { getActivePage } from "../signals/core";
import { getAuthenticatedUser } from "../firebase";
import * as Loader from "../elements/loader";
import * as ResultBatches from "../elements/result-batches";
Expand Down Expand Up @@ -1206,7 +1206,7 @@ qs(".pageAccount button.loadMoreResults")?.on("click", async () => {
});

ConfigEvent.subscribe(({ key }) => {
if (ActivePage.get() === "account" && key === "typingSpeedUnit") {
if (getActivePage() === "account" && key === "typingSpeedUnit") {
void update();
}
});
Expand Down
4 changes: 2 additions & 2 deletions frontend/src/ts/pages/leaderboards.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { z } from "zod";
import { LocalStorageWithSchema } from "../utils/local-storage-with-schema";
import { UTCDateMini } from "@date-fns/utc";
import * as ConfigEvent from "../observables/config-event";
import * as ActivePage from "../states/active-page";
import { getActivePage } from "../signals/core";
import {
PaginationQuery,
FriendsOnlyQuery,
Expand Down Expand Up @@ -1520,7 +1520,7 @@ onWindowLoad(async () => {
});

ConfigEvent.subscribe(({ key }) => {
if (ActivePage.get() === "leaderboards" && key === "typingSpeedUnit") {
if (getActivePage() === "leaderboards" && key === "typingSpeedUnit") {
updateContent();
fillUser();
}
Expand Down
Loading
Loading