mirror of
https://github.com/monkeytypegame/monkeytype.git
synced 2025-10-09 23:25:53 +08:00
removed navigate event
removed any types added generic parameter which describes the type of options data
This commit is contained in:
parent
79b0c37dee
commit
20a08d27ea
13 changed files with 100 additions and 126 deletions
|
@ -1,4 +1,4 @@
|
|||
import { navigate } from "../../observables/navigate-event";
|
||||
import { navigate } from "../../controllers/route-controller";
|
||||
import * as ChallengeController from "../../controllers/challenge-controller";
|
||||
import * as TestLogic from "../../test/test-logic";
|
||||
import { capitalizeFirstLetterOfEachWord } from "../../utils/misc";
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
import { navigate } from "../../observables/navigate-event";
|
||||
import { navigate } from "../../controllers/route-controller";
|
||||
import { toggleFullscreen } from "../../utils/misc";
|
||||
|
||||
const commands: MonkeyTypes.Command[] = [
|
||||
|
|
|
@ -43,9 +43,9 @@ import {
|
|||
hideFavoriteQuoteLength,
|
||||
showFavoriteQuoteLength,
|
||||
} from "../test/test-config";
|
||||
import { navigate } from "../observables/navigate-event";
|
||||
import { update as updateTagsCommands } from "../commandline/lists/tags";
|
||||
import * as ConnectionState from "../states/connection";
|
||||
import { navigate } from "./route-controller";
|
||||
|
||||
let signedOutThisSession = false;
|
||||
|
||||
|
|
|
@ -27,12 +27,12 @@ import * as TestInput from "../test/test-input";
|
|||
import * as TestWords from "../test/test-words";
|
||||
import * as Hangul from "hangul-js";
|
||||
import * as CustomTextState from "../states/custom-text-name";
|
||||
import { navigate } from "../observables/navigate-event";
|
||||
import * as FunboxList from "../test/funbox/funbox-list";
|
||||
import * as Settings from "../pages/settings";
|
||||
import * as KeymapEvent from "../observables/keymap-event";
|
||||
import { IgnoredKeys } from "../constants/ignored-keys";
|
||||
import { ModifierKeys } from "../constants/modifier-keys";
|
||||
import { navigate } from "./route-controller";
|
||||
|
||||
let dontInsertSpace = false;
|
||||
let correctShiftUsed = true;
|
||||
|
|
|
@ -10,14 +10,13 @@ import * as PageProfile from "../pages/profile";
|
|||
import * as PageProfileSearch from "../pages/profile-search";
|
||||
import * as Page404 from "../pages/404";
|
||||
import * as PageTransition from "../states/page-transition";
|
||||
import type Page from "../pages/page";
|
||||
import * as AdController from "../controllers/ad-controller";
|
||||
import * as Focus from "../test/focus";
|
||||
|
||||
interface ChangeOptions {
|
||||
force?: boolean;
|
||||
params?: { [key: string]: string };
|
||||
data?: any;
|
||||
data?: unknown;
|
||||
}
|
||||
|
||||
export async function change(
|
||||
|
@ -45,7 +44,7 @@ export async function change(
|
|||
console.log(`changing page ${pageName}`);
|
||||
}
|
||||
|
||||
const pages: Record<MonkeyTypes.PageName, Page> = {
|
||||
const pages = {
|
||||
loading: PageLoading.page,
|
||||
test: PageTest.page,
|
||||
settings: Settings.page,
|
||||
|
@ -80,6 +79,7 @@ export async function change(
|
|||
previousPage?.afterHide();
|
||||
await nextPage?.beforeShow({
|
||||
params: options.params,
|
||||
// @ts-expect-error
|
||||
data: options.data,
|
||||
});
|
||||
}
|
||||
|
|
76
frontend/src/ts/controllers/profile-search-controller.ts
Normal file
76
frontend/src/ts/controllers/profile-search-controller.ts
Normal file
|
@ -0,0 +1,76 @@
|
|||
import { InputIndicator } from "../elements/input-indicator";
|
||||
import { sleep } from "../utils/misc";
|
||||
import Ape from "../ape";
|
||||
import { navigate } from "../controllers/route-controller";
|
||||
import * as Skeleton from "../popups/skeleton";
|
||||
|
||||
const searchIndicator = new InputIndicator(
|
||||
$(".page.pageProfileSearch .search input"),
|
||||
{
|
||||
notFound: {
|
||||
icon: "fa-user-slash",
|
||||
level: -1,
|
||||
},
|
||||
error: {
|
||||
icon: "fa-times",
|
||||
level: -1,
|
||||
},
|
||||
checking: {
|
||||
icon: "fa-circle-notch",
|
||||
spinIcon: true,
|
||||
level: 1,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
function disableInputs(): void {
|
||||
$(".page.pageProfileSearch .search .button").addClass("disabled");
|
||||
$(".page.pageProfileSearch .search input").attr("disabled", "disabled");
|
||||
}
|
||||
|
||||
function enableInputs(): void {
|
||||
$(".page.pageProfileSearch .search .button").removeClass("disabled");
|
||||
$(".page.pageProfileSearch .search input").removeAttr("disabled");
|
||||
}
|
||||
|
||||
function areInputsDisabled(): boolean {
|
||||
return (
|
||||
$(".page.pageProfileSearch .search input").attr("disabled") !== undefined
|
||||
);
|
||||
}
|
||||
|
||||
async function lookupProfile(): Promise<void> {
|
||||
searchIndicator.hide();
|
||||
const name = $(".page.pageProfileSearch .search input").val() as string;
|
||||
if (name === "") return;
|
||||
|
||||
searchIndicator.show("checking");
|
||||
disableInputs();
|
||||
|
||||
await sleep(500);
|
||||
|
||||
const response = await Ape.users.getProfileByName(name);
|
||||
enableInputs();
|
||||
if (response.status === 404) {
|
||||
searchIndicator.show("notFound", "User not found");
|
||||
return;
|
||||
} else if (response.status !== 200) {
|
||||
searchIndicator.show("error", `Error: ${response.message}`);
|
||||
return;
|
||||
}
|
||||
searchIndicator.hide();
|
||||
navigate(`/profile/${name}`, {
|
||||
data: response.data,
|
||||
});
|
||||
}
|
||||
|
||||
$(".page.pageProfileSearch .search input").on("keyup", (e) => {
|
||||
if (e.key === "Enter" && !areInputsDisabled()) lookupProfile();
|
||||
});
|
||||
|
||||
$(".page.pageProfileSearch .search .button").on("click", () => {
|
||||
if (areInputsDisabled()) return;
|
||||
lookupProfile();
|
||||
});
|
||||
|
||||
Skeleton.save("pageProfileSearch");
|
|
@ -2,7 +2,6 @@ import * as PageController from "./page-controller";
|
|||
import * as Leaderboards from "../elements/leaderboards";
|
||||
import * as TestUI from "../test/test-ui";
|
||||
import * as PageTransition from "../states/page-transition";
|
||||
import * as NavigateEvent from "../observables/navigate-event";
|
||||
import { Auth } from "../firebase";
|
||||
|
||||
//source: https://www.youtube.com/watch?v=OstALBk-jTc
|
||||
|
@ -11,7 +10,7 @@ import { Auth } from "../firebase";
|
|||
//this will be used in tribe
|
||||
interface NavigateOptions {
|
||||
empty?: boolean;
|
||||
data?: any;
|
||||
data?: unknown;
|
||||
}
|
||||
|
||||
function pathToRegex(path: string): RegExp {
|
||||
|
@ -84,11 +83,11 @@ const routes: Route[] = [
|
|||
path: "/login",
|
||||
load: (): void => {
|
||||
if (!Auth) {
|
||||
nav("/");
|
||||
navigate("/");
|
||||
return;
|
||||
}
|
||||
if (Auth.currentUser) {
|
||||
nav("/account");
|
||||
navigate("/account");
|
||||
return;
|
||||
}
|
||||
PageController.change("login");
|
||||
|
@ -98,7 +97,7 @@ const routes: Route[] = [
|
|||
path: "/account",
|
||||
load: (_params, options): void => {
|
||||
if (!Auth) {
|
||||
nav("/");
|
||||
navigate("/");
|
||||
return;
|
||||
}
|
||||
PageController.change("account", {
|
||||
|
@ -126,7 +125,7 @@ const routes: Route[] = [
|
|||
},
|
||||
];
|
||||
|
||||
function nav(
|
||||
export function navigate(
|
||||
url = window.location.pathname + window.location.search,
|
||||
options = {} as NavigateOptions
|
||||
): void {
|
||||
|
@ -173,19 +172,15 @@ document.addEventListener("DOMContentLoaded", () => {
|
|||
const target = e?.target as HTMLLinkElement;
|
||||
if (target.matches("[router-link]") && target?.href) {
|
||||
e.preventDefault();
|
||||
nav(target.href);
|
||||
navigate(target.href);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
$("#top .logo").on("click", () => {
|
||||
nav("/");
|
||||
navigate("/");
|
||||
});
|
||||
|
||||
$("#popups").on("click", "#leaderboards a.entryName", () => {
|
||||
Leaderboards.hide();
|
||||
});
|
||||
|
||||
NavigateEvent.subscribe((url, options) => {
|
||||
nav(url, options);
|
||||
});
|
||||
|
|
|
@ -10,7 +10,7 @@ import formatDistanceToNowStrict from "date-fns/formatDistanceToNowStrict";
|
|||
|
||||
type ProfileViewPaths = "profile" | "account";
|
||||
|
||||
interface ProfileData extends MonkeyTypes.Snapshot {
|
||||
export interface ProfileData extends MonkeyTypes.Snapshot {
|
||||
allTimeLbs: MonkeyTypes.LeaderboardMemory;
|
||||
uid: string;
|
||||
}
|
||||
|
|
|
@ -40,6 +40,7 @@ import { egVideoListener } from "./popups/video-ad-popup";
|
|||
import "./states/connection";
|
||||
import "./test/tts";
|
||||
import "./elements/fps-counter";
|
||||
import "./controllers/profile-search-controller";
|
||||
|
||||
type ExtendedGlobal = typeof globalThis & MonkeyTypes.Global;
|
||||
|
||||
|
|
|
@ -1,23 +0,0 @@
|
|||
type SubscribeFunction = (url?: string, options?: NavigateOptions) => void;
|
||||
|
||||
const subscribers: SubscribeFunction[] = [];
|
||||
|
||||
export function subscribe(fn: SubscribeFunction): void {
|
||||
subscribers.push(fn);
|
||||
}
|
||||
|
||||
interface NavigateOptions {
|
||||
empty?: boolean;
|
||||
data?: any;
|
||||
}
|
||||
|
||||
export function navigate(url?: string, options?: NavigateOptions): void {
|
||||
subscribers.forEach((fn) => {
|
||||
try {
|
||||
fn(url, options);
|
||||
} catch (e) {
|
||||
console.error("Navigate event subscriber threw an error");
|
||||
console.error(e);
|
||||
}
|
||||
});
|
||||
}
|
|
@ -1,15 +1,15 @@
|
|||
interface Options {
|
||||
interface Options<T> {
|
||||
params?: Record<string, string>;
|
||||
data?: any;
|
||||
data?: T;
|
||||
}
|
||||
|
||||
export default class Page {
|
||||
export default class Page<T> {
|
||||
public name: MonkeyTypes.PageName;
|
||||
public element: JQuery;
|
||||
public pathname: string;
|
||||
public beforeHide: () => Promise<void>;
|
||||
public afterHide: () => Promise<void>;
|
||||
public beforeShow: (options: Options) => Promise<void>;
|
||||
public beforeShow: (options: Options<T>) => Promise<void>;
|
||||
public afterShow: () => Promise<void>;
|
||||
constructor(
|
||||
name: MonkeyTypes.PageName,
|
||||
|
@ -17,7 +17,7 @@ export default class Page {
|
|||
pathname: string,
|
||||
beforeHide: () => Promise<void>,
|
||||
afterHide: () => Promise<void>,
|
||||
beforeShow: (options: Options) => Promise<void>,
|
||||
beforeShow: (options: Options<T>) => Promise<void>,
|
||||
afterShow: () => Promise<void>
|
||||
) {
|
||||
this.name = name;
|
||||
|
|
|
@ -1,78 +1,6 @@
|
|||
import Page from "./page";
|
||||
import { InputIndicator } from "../elements/input-indicator";
|
||||
import { sleep } from "../utils/misc";
|
||||
import Ape from "../ape";
|
||||
import { navigate } from "../observables/navigate-event";
|
||||
import * as Skeleton from "../popups/skeleton";
|
||||
|
||||
const searchIndicator = new InputIndicator(
|
||||
$(".page.pageProfileSearch .search input"),
|
||||
{
|
||||
notFound: {
|
||||
icon: "fa-user-slash",
|
||||
level: -1,
|
||||
},
|
||||
error: {
|
||||
icon: "fa-times",
|
||||
level: -1,
|
||||
},
|
||||
checking: {
|
||||
icon: "fa-circle-notch",
|
||||
spinIcon: true,
|
||||
level: 1,
|
||||
},
|
||||
}
|
||||
);
|
||||
|
||||
function disableInputs(): void {
|
||||
$(".page.pageProfileSearch .search .button").addClass("disabled");
|
||||
$(".page.pageProfileSearch .search input").attr("disabled", "disabled");
|
||||
}
|
||||
|
||||
function enableInputs(): void {
|
||||
$(".page.pageProfileSearch .search .button").removeClass("disabled");
|
||||
$(".page.pageProfileSearch .search input").removeAttr("disabled");
|
||||
}
|
||||
|
||||
function areInputsDisabled(): boolean {
|
||||
return (
|
||||
$(".page.pageProfileSearch .search input").attr("disabled") !== undefined
|
||||
);
|
||||
}
|
||||
|
||||
async function lookupProfile(): Promise<void> {
|
||||
searchIndicator.hide();
|
||||
const name = $(".page.pageProfileSearch .search input").val() as string;
|
||||
if (name === "") return;
|
||||
|
||||
searchIndicator.show("checking");
|
||||
disableInputs();
|
||||
|
||||
await sleep(500);
|
||||
|
||||
const response = await Ape.users.getProfileByName(name);
|
||||
enableInputs();
|
||||
if (response.status === 404) {
|
||||
searchIndicator.show("notFound", "User not found");
|
||||
return;
|
||||
} else if (response.status !== 200) {
|
||||
searchIndicator.show("error", `Error: ${response.message}`);
|
||||
return;
|
||||
}
|
||||
navigate(`/profile/${name}`, {
|
||||
data: response.data,
|
||||
});
|
||||
}
|
||||
|
||||
$(".page.pageProfileSearch .search input").on("keyup", (e) => {
|
||||
if (e.key === "Enter" && !areInputsDisabled()) lookupProfile();
|
||||
});
|
||||
|
||||
$(".page.pageProfileSearch .search .button").on("click", () => {
|
||||
if (areInputsDisabled()) return;
|
||||
lookupProfile();
|
||||
});
|
||||
|
||||
export const page = new Page(
|
||||
"profileSearch",
|
||||
$(".page.pageProfileSearch"),
|
||||
|
@ -86,11 +14,8 @@ export const page = new Page(
|
|||
async () => {
|
||||
Skeleton.append("pageProfileSearch", "middle");
|
||||
$(".page.pageProfileSearch input").val("");
|
||||
searchIndicator.hide();
|
||||
},
|
||||
async () => {
|
||||
$(".page.pageProfileSearch input").focus();
|
||||
}
|
||||
);
|
||||
|
||||
Skeleton.save("pageProfileSearch");
|
||||
|
|
|
@ -151,7 +151,7 @@ function reset(): void {
|
|||
|
||||
interface UpdateOptions {
|
||||
uidOrName?: string;
|
||||
data?: any;
|
||||
data?: undefined | Profile.ProfileData;
|
||||
}
|
||||
|
||||
async function update(options: UpdateOptions): Promise<void> {
|
||||
|
@ -199,7 +199,7 @@ $(".page.pageProfile").on("click", ".profile .userReportButton", () => {
|
|||
UserReportPopup.show({ uid, name });
|
||||
});
|
||||
|
||||
export const page = new Page(
|
||||
export const page = new Page<undefined | Profile.ProfileData>(
|
||||
"profile",
|
||||
$(".page.pageProfile"),
|
||||
"/profile",
|
||||
|
@ -220,7 +220,7 @@ export const page = new Page(
|
|||
reset();
|
||||
update({
|
||||
uidOrName,
|
||||
data: options?.["data"],
|
||||
data: options?.data,
|
||||
});
|
||||
} else {
|
||||
$(".page.pageProfile .preloader").addClass("hidden");
|
||||
|
|
Loading…
Add table
Reference in a new issue