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
79 changes: 0 additions & 79 deletions frontend/src/ts/controllers/profile-search-controller.ts

This file was deleted.

5 changes: 5 additions & 0 deletions frontend/src/ts/controllers/route-controller.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import { isFunboxActive } from "../test/funbox/list";
import * as TestState from "../test/test-state";
import * as Notifications from "../elements/notifications";
import { LoadingOptions } from "../pages/page";
import * as NavigationEvent from "../observables/navigation-event";

//source: https://www.youtube.com/watch?v=OstALBk-jTc
// https://www.youtube.com/watch?v=OstALBk-jTc
Expand Down Expand Up @@ -249,3 +250,7 @@ document.addEventListener("DOMContentLoaded", () => {
}
});
});

NavigationEvent.subscribe((it) => {
void navigate(it.url, { data: it.data });
});
1 change: 0 additions & 1 deletion frontend/src/ts/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ import { egVideoListener } from "./popups/video-ad-popup";
import "./states/connection";
import "./test/tts";
import "./elements/fps-counter";
import "./controllers/profile-search-controller";
import { isDevEnvironment, addToGlobal } from "./utils/misc";
import * as VersionButton from "./elements/version-button";
import * as Focus from "./test/focus";
Expand Down
23 changes: 23 additions & 0 deletions frontend/src/ts/observables/navigation-event.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
type NavigationEvent = {
url: string;
data?: unknown;
};

type SubscribeFunction = (event: NavigationEvent) => void;

const subscribers: SubscribeFunction[] = [];

export function subscribe(fn: SubscribeFunction): void {
subscribers.push(fn);
}

export function dispatch(event: NavigationEvent): void {
subscribers.forEach((fn) => {
try {
fn(event);
} catch (e) {
console.error("Navigation event subscriber threw an error");
console.error(e);
}
});
}
66 changes: 65 additions & 1 deletion frontend/src/ts/pages/profile-search.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
import Page from "./page";
import * as Skeleton from "../utils/skeleton";
import Ape from "../ape";
import {
ValidatedHtmlInputElement,
validateWithIndicator,
} from "../elements/input-validation";
import { UserNameSchema, UserProfile } from "@monkeytype/schemas/users";
import { remoteValidation } from "../utils/remote-validation";
import * as NavigationEvent from "../observables/navigation-event";

let nameInputEl: ValidatedHtmlInputElement | null = null;
let lastProfile: UserProfile | null = null;

function enableButton(): void {
$('.page.pageProfileSearch button[type="submit"]').prop("disabled", false);
}

function disableButton(): void {
$('.page.pageProfileSearch button[type="submit"]').prop("disabled", true);
}

export const page = new Page({
id: "profileSearch",
Expand All @@ -10,9 +29,54 @@ export const page = new Page({
},
beforeShow: async (): Promise<void> => {
Skeleton.append("pageProfileSearch", "main");
$(".page.pageProfileSearch input").val("");

if (nameInputEl === null) {
nameInputEl = validateWithIndicator(
document.querySelector(
".page.pageProfileSearch input"
) as HTMLInputElement,
{
schema: UserNameSchema,
isValid: remoteValidation(
async (name) =>
Ape.users.getProfile({ params: { uidOrName: name } }),
{
check: (data) => {
lastProfile = data;
return true;
},
on4xx: () => "Unknown user",
}
),
callback: (result) => {
if (result.status === "success") {
enableButton();
} else {
disableButton();
lastProfile = null;
}
},
}
);
}

nameInputEl.setValue(null);
disableButton();
},
afterShow: async (): Promise<void> => {
$(".page.pageProfileSearch input").trigger("focus");
},
});

$(".page.pageProfileSearch form").on("submit", (e) => {
e.preventDefault();
if (lastProfile === null) return;
NavigationEvent.dispatch({
url: `/profile/${lastProfile.name}`,
data: lastProfile,
});
});

$(() => {
Skeleton.save("pageProfileSearch");
});