diff --git a/src/App.tsx b/src/App.tsx index ec1e16e..88d1162 100644 --- a/src/App.tsx +++ b/src/App.tsx @@ -9,6 +9,7 @@ import RegistrationPage from "./pages/RegistrationPage"; import { reaction } from "mobx"; import Loader from "./components/Loader"; import { UnauthenticatedGuard } from "./components/guards/UnauthenticatedGuard"; +import useLogger from "./hooks/useLogger"; import AppPage from "./pages/AppPage"; import LogoutPage from "./pages/LogoutPage"; import ChannelPage from "./pages/subpages/ChannelPage"; @@ -17,6 +18,7 @@ import { Globals } from "./utils/Globals"; function App() { const app = useAppStore(); + const logger = useLogger("App"); const navigate = useNavigate(); React.useEffect(() => { @@ -30,12 +32,12 @@ function App() { app.setGatewayReady(false); app.gateway.connect(Globals.routeSettings.gateway); } else { - console.debug( + logger.debug( "Gateway connect called but socket is not closed", ); } } else { - console.debug("user no longer authenticated"); + logger.debug("user no longer authenticated"); if (app.gateway.readyState === WebSocket.OPEN) { app.gateway.disconnect( 1000, @@ -51,7 +53,7 @@ function App() { Globals.load(); app.loadToken(); - console.debug("Loading complete"); + logger.debug("Loading complete"); app.setAppLoading(false); return dispose; diff --git a/src/components/MessageInput.tsx b/src/components/MessageInput.tsx index 19d0790..b11b96f 100644 --- a/src/components/MessageInput.tsx +++ b/src/components/MessageInput.tsx @@ -1,9 +1,10 @@ import React from "react"; import styled from "styled-components"; -import Channel from "../stores/objects/Channel"; -import Snowflake from "../utils/Snowflake"; +import useLogger from "../hooks/useLogger"; import { useAppStore } from "../stores/AppStore"; +import Channel from "../stores/objects/Channel"; import User from "../stores/objects/User"; +import Snowflake from "../utils/Snowflake"; const Container = styled.div` margin-top: -8px; @@ -37,6 +38,7 @@ interface Props { function MessageInput(props: Props) { const app = useAppStore(); + const logger = useLogger("MessageInput"); const wrapperRef = React.useRef(null); const placeholderRef = React.useRef(null); const inputRef = React.useRef(null); @@ -95,20 +97,20 @@ function MessageInput(props: Props) { function onKeyDown(e: React.KeyboardEvent) { if (!props.channel) { - console.warn("No channel selected, cannot send message"); + logger.warn("No channel selected, cannot send message"); return; } if (e.key === "Enter") { e.preventDefault(); const shouldFail = app.experiments.isTreatmentEnabled( - 'message_queue', - 2, - ); - const shouldSend = !app.experiments.isTreatmentEnabled( - 'message_queue', - 1, - ); + "message_queue", + 2, + ); + const shouldSend = !app.experiments.isTreatmentEnabled( + "message_queue", + 1, + ); if (!props.channel.canSendMessage(content) && !shouldFail) return; @@ -120,7 +122,7 @@ function MessageInput(props: Props) { channel: props.channel.id, }); - if(shouldSend) { + if (shouldSend) { props.channel.sendMessage({ content, nonce }).catch((error) => { app.queue.error(nonce, error as string); }); diff --git a/src/components/modals/CreateServerModal.tsx b/src/components/modals/CreateServerModal.tsx index f3b9b38..a683a89 100644 --- a/src/components/modals/CreateServerModal.tsx +++ b/src/components/modals/CreateServerModal.tsx @@ -4,6 +4,7 @@ import React from "react"; import { useForm } from "react-hook-form"; import { useNavigate } from "react-router-dom"; import styled from "styled-components"; +import useLogger from "../../hooks/useLogger"; import { useAppStore } from "../../stores/AppStore"; import { messageFromFieldError } from "../../utils/messageFromFieldError"; import { @@ -74,6 +75,7 @@ type FormValues = { function CreateServerModal() { const app = useAppStore(); + const logger = useLogger("CreateServerModal"); const { openModal, closeModal } = useModals(); const [selectedFile, setSelectedFile] = React.useState(); const fileInputRef = React.useRef(null); @@ -132,7 +134,7 @@ function CreateServerModal() { } } else { // unknown error - console.error(r); + logger.error(r); setError("name", { type: "manual", message: "Unknown Error", diff --git a/src/hooks/useLogger.ts b/src/hooks/useLogger.ts new file mode 100644 index 0000000..404a898 --- /dev/null +++ b/src/hooks/useLogger.ts @@ -0,0 +1,5 @@ +import Logger from "../utils/Logger"; + +export default function (name: string) { + return new Logger(name); +} diff --git a/src/pages/LoginPage.tsx b/src/pages/LoginPage.tsx index f8267a1..8f297ec 100644 --- a/src/pages/LoginPage.tsx +++ b/src/pages/LoginPage.tsx @@ -25,6 +25,7 @@ import { import { Divider } from "../components/Divider"; import HCaptcha, { HeaderContainer } from "../components/HCaptcha"; import ForgotPasswordModal from "../components/modals/ForgotPasswordModal"; +import useLogger from "../hooks/useLogger"; import { AUTH_NO_BRANDING, useAppStore } from "../stores/AppStore"; import { Globals, RouteSettings } from "../utils/Globals"; import REST from "../utils/REST"; @@ -46,6 +47,7 @@ type FormValues = { function LoginPage() { const app = useAppStore(); + const logger = useLogger("LoginPage"); const navigate = useNavigate(); const [loading, setLoading] = React.useState(false); const [captchaSiteKey, setCaptchaSiteKey] = React.useState(); @@ -97,12 +99,12 @@ function LoginPage() { return; } else if ("ticket" in r) { // mfa - console.log("MFA Required", r); + logger.info("MFA Required", r); setMfaData(r); return; } else { // unknown error - console.error(r); + logger.error(r); setError("login", { type: "manual", message: "Unknown Error", @@ -157,7 +159,7 @@ function LoginPage() { resetCaptcha(); } else { // unknown error - console.error(r); + logger.error(r); setError("login", { type: "manual", message: "Unknown Error", @@ -201,7 +203,7 @@ function LoginPage() { }); } - console.debug(`Instance lookup has set routes to`, endpoints); + logger.debug(`Instance lookup has set routes to`, endpoints); Globals.routeSettings = endpoints; // hmm Globals.save(); setCheckingInstance(false); diff --git a/src/pages/RegistrationPage.tsx b/src/pages/RegistrationPage.tsx index e9a2d37..707b9dc 100644 --- a/src/pages/RegistrationPage.tsx +++ b/src/pages/RegistrationPage.tsx @@ -24,6 +24,7 @@ import { import DOBInput from "../components/DOBInput"; import { Divider } from "../components/Divider"; import HCaptcha from "../components/HCaptcha"; +import useLogger from "../hooks/useLogger"; import { AUTH_NO_BRANDING, useAppStore } from "../stores/AppStore"; import { IAPILoginResponseSuccess, @@ -42,6 +43,7 @@ type FormValues = { function RegistrationPage() { const app = useAppStore(); + const logger = useLogger("RegistrationPage"); const navigate = useNavigate(); const [loading, setLoading] = React.useState(false); const [captchaSiteKey, setCaptchaSiteKey] = React.useState(); @@ -89,7 +91,7 @@ function RegistrationPage() { return; } else { // unknown error - console.error(r); + logger.error(r); setError("email", { type: "manual", message: "Unknown Error", @@ -144,7 +146,7 @@ function RegistrationPage() { resetCaptcha(); } else { // unknown error - console.error(r); + logger.error(r); setError("email", { type: "manual", message: "Unknown Error", diff --git a/src/pages/subpages/MFA.tsx b/src/pages/subpages/MFA.tsx index dbf4351..bf1baf4 100644 --- a/src/pages/subpages/MFA.tsx +++ b/src/pages/subpages/MFA.tsx @@ -20,6 +20,7 @@ import { Wrapper, } from "../../components/AuthComponents"; import { Divider } from "../../components/Divider"; +import useLogger from "../../hooks/useLogger"; import { useAppStore } from "../../stores/AppStore"; import { IAPIError, @@ -35,6 +36,7 @@ type FormValues = { function MFA(props: IAPILoginResponseMFARequired) { const app = useAppStore(); + const logger = useLogger("MFA"); const navigate = useNavigate(); const [loading, setLoading] = React.useState(false); @@ -81,7 +83,7 @@ function MFA(props: IAPILoginResponseMFARequired) { } } else { // unknown error - console.error(r); + logger.error(r); setError("code", { type: "manual", message: "Unknown Error", diff --git a/src/stores/AppStore.ts b/src/stores/AppStore.ts index 71d2b00..88ff591 100644 --- a/src/stores/AppStore.ts +++ b/src/stores/AppStore.ts @@ -1,6 +1,7 @@ import type { APIUser } from "@spacebarchat/spacebar-api-types/v9"; import { action, computed, makeAutoObservable, observable } from "mobx"; import secureLocalStorage from "react-secure-storage"; +import Logger from "../utils/Logger"; import REST from "../utils/REST"; import AccountStore from "./AccountStore"; import ExperimentsStore from "./ExperimentsStore"; @@ -16,6 +17,8 @@ import UserStore from "./UserStore"; export const AUTH_NO_BRANDING = false; export default class AppStore { + private readonly logger: Logger = new Logger("AppStore"); + // whether the gateway is ready @observable isGatewayReady = false; // whether the app is still loading @@ -57,7 +60,7 @@ export default class AppStore { this.tokenLoaded = true; if (save) { secureLocalStorage.setItem("token", token); - console.log("Token saved to storage"); + this.logger.info("Token saved to storage"); } } @@ -73,10 +76,10 @@ export default class AppStore { this.tokenLoaded = true; if (token) { - console.debug("Loaded token from storage."); + this.logger.debug("Loaded token from storage."); this.setToken(token); } else { - console.debug("No token found in storage."); + this.logger.debug("No token found in storage."); this.setGatewayReady(true); } } diff --git a/src/stores/GatewayConnectionStore.ts b/src/stores/GatewayConnectionStore.ts index 2986795..981eea4 100644 --- a/src/stores/GatewayConnectionStore.ts +++ b/src/stores/GatewayConnectionStore.ts @@ -28,12 +28,14 @@ import { Snowflake, } from "@spacebarchat/spacebar-api-types/v9"; import { action, makeObservable, observable, runInAction } from "mobx"; +import Logger from "../utils/Logger"; import AppStore from "./AppStore"; const GATEWAY_VERSION = "9"; const GATEWAY_ENCODING = "json"; export default class GatewayConnectionStore { + private readonly logger: Logger = new Logger("GatewayConnectionStore"); @observable private socket: WebSocket | null = null; @observable private sessionId: string | null = null; @observable public readyState: number = WebSocket.CLOSED; @@ -65,7 +67,7 @@ export default class GatewayConnectionStore { newUrl.searchParams.append("v", GATEWAY_VERSION); newUrl.searchParams.append("encoding", GATEWAY_ENCODING); this.url = newUrl.href; - console.debug(`[Connect] ${this.url}`); + this.logger.debug(`[Connect] ${this.url}`); this.connectionStartTime = Date.now(); this.socket = new WebSocket(this.url); this.readyState = WebSocket.CONNECTING; @@ -81,7 +83,7 @@ export default class GatewayConnectionStore { } this.readyState = WebSocket.CLOSING; - console.debug(`[Disconnect] ${this.url}`); + this.logger.debug(`[Disconnect] ${this.url}`); this.socket?.close(code, reason); } @@ -144,7 +146,7 @@ export default class GatewayConnectionStore { } private onopen = () => { - console.debug( + this.logger.debug( `[Connected] ${this.url} (took ${ Date.now() - this.connectionStartTime! }ms)`, @@ -158,7 +160,7 @@ export default class GatewayConnectionStore { private onmessage = (e: MessageEvent) => { const payload: GatewayReceivePayload = JSON.parse(e.data); if (payload.op !== GatewayOpcodes.Dispatch) { - console.debug(`[Gateway] -> ${payload.op}`, payload); + this.logger.debug(`[Gateway] -> ${payload.op}`, payload); } switch (payload.op) { @@ -181,13 +183,13 @@ export default class GatewayConnectionStore { this.handleHeartbeatAck(); break; default: - console.debug("Received unknown opcode"); + this.logger.debug("Received unknown opcode"); break; } }; private onerror = (e: Event) => { - console.error("[Gateway] Socket Error", e); + this.logger.error("[Gateway] Socket Error", e); }; private onclose = (e: CloseEvent) => { @@ -197,17 +199,17 @@ export default class GatewayConnectionStore { private sendJson = (payload: GatewaySendPayload) => { if (!this.socket) { - console.error("Socket is not open"); + this.logger.error("Socket is not open"); return; } if (this.socket.readyState !== WebSocket.OPEN) { - console.error( + this.logger.error( `Socket is not open; readyState: ${this.socket.readyState}`, ); return; } - console.debug(`[Gateway] <- ${payload.op}`, payload); + this.logger.debug(`[Gateway] <- ${payload.op}`, payload); this.socket.send(JSON.stringify(payload)); }; @@ -215,9 +217,9 @@ export default class GatewayConnectionStore { * Sends Identify payload to gateway */ private handleIdentify = () => { - console.debug("handleIdentify called"); + this.logger.debug("handleIdentify called"); if (!this.app.token) { - return console.error("Token shouldn't be null here"); + return this.logger.error("Token shouldn't be null here"); } this.identifyStartTime = Date.now(); @@ -250,7 +252,7 @@ export default class GatewayConnectionStore { private handleInvalidSession = (resumable: boolean) => { this.cleanup(); - console.debug(`Received invalid session; Can Resume: ${resumable}`); + this.logger.debug(`Received invalid session; Can Resume: ${resumable}`); if (!resumable) { return; } @@ -263,13 +265,13 @@ export default class GatewayConnectionStore { */ private handleReconnect() { this.cleanup(); - console.debug("Received reconnect"); + this.logger.debug("Received reconnect"); } private handleResume() { - console.debug("handleResume called"); + this.logger.debug("handleResume called"); if (!this.app.token) { - return console.error("Token shouldn't be null here"); + return this.logger.error("Token shouldn't be null here"); } this.sendJson({ @@ -284,7 +286,7 @@ export default class GatewayConnectionStore { private handleHello = (data: GatewayHelloData) => { this.heartbeatInterval = data.heartbeat_interval; - console.info( + this.logger.info( `[Hello] heartbeat interval: ${data.heartbeat_interval} (took ${ Date.now() - this.connectionStartTime! }ms)`, @@ -314,7 +316,7 @@ export default class GatewayConnectionStore { this.cleanup(); if (code === 4004) { - console.warn("closed because of authentication failure."); + this.logger.warn("closed because of authentication failure."); // remove token, this will send us back to the login screen // TODO: maybe we could show a toast here so the user knows why they got logged out this.app.logout(); @@ -382,7 +384,7 @@ export default class GatewayConnectionStore { * Handles a heartbeat timeout */ private handleHeartbeatTimeout = () => { - console.warn( + this.logger.warn( `[Heartbeat ACK Timeout] should reconnect in ${( this.heartbeatInterval! / 1000 ).toFixed(2)} seconds`, @@ -403,7 +405,7 @@ export default class GatewayConnectionStore { op: GatewayOpcodes.Heartbeat, d: this.sequence, }; - console.debug("Sending heartbeat"); + this.logger.debug("Sending heartbeat"); this.sendJson(payload); }; @@ -411,7 +413,7 @@ export default class GatewayConnectionStore { * Stops heartbeat interval and removes socket */ private cleanup = () => { - console.debug("Cleaning up"); + this.logger.debug("Cleaning up"); this.stopHeartbeater(); this.socket = null; }; @@ -420,7 +422,7 @@ export default class GatewayConnectionStore { * Processes a heartbeat ack opcode */ private handleHeartbeatAck = () => { - console.debug("Received heartbeat ack"); + this.logger.debug("Received heartbeat ack"); this.heartbeatAck = true; }; @@ -429,11 +431,11 @@ export default class GatewayConnectionStore { */ private handleDispatch = (data: GatewayDispatchPayload) => { const { d, t, s } = data; - console.debug(`[Gateway] -> ${t}`, d); + this.logger.debug(`[Gateway] -> ${t}`, d); this.sequence = s; const handler = this.dispatchHandlers.get(t); if (!handler) { - console.debug(`No handler for dispatch event ${t}`); + this.logger.debug(`No handler for dispatch event ${t}`); return; } @@ -444,14 +446,14 @@ export default class GatewayConnectionStore { * Processes a resumed dispatch event */ private onResumed = () => { - console.debug("Resumed"); + this.logger.debug("Resumed"); }; /** * Processes a ready dispatch event */ private onReady = (data: GatewayReadyDispatchData) => { - console.info( + this.logger.info( `[Ready] took ${Date.now() - this.connectionStartTime!}ms`, ); const { session_id, guilds, users, user, private_channels } = data; @@ -517,7 +519,7 @@ export default class GatewayConnectionStore { // Start dispatch handlers private onGuildCreate = (data: GatewayGuildCreateDispatchData) => { - console.debug("Received guild create event"); + this.logger.debug("Received guild create event"); runInAction(() => { this.app.guilds.add({ ...data, @@ -527,12 +529,12 @@ export default class GatewayConnectionStore { }; private onGuildUpdate = (data: GatewayGuildModifyDispatchData) => { - console.debug("Received guild update event"); + this.logger.debug("Received guild update event"); this.app.guilds.get(data.id)?.update(data); }; private onGuildDelete = (data: GatewayGuildDeleteDispatchData) => { - console.debug("Received guild delete event"); + this.logger.debug("Received guild delete event"); runInAction(() => { this.app.guilds.remove(data.id); }); @@ -541,12 +543,14 @@ export default class GatewayConnectionStore { private onGuildMemberListUpdate = ( data: GatewayGuildMemberListUpdateDispatchData, ) => { - console.debug("Received GuildMemberListUpdate event"); + this.logger.debug("Received GuildMemberListUpdate event"); const { guild_id } = data; const guild = this.app.guilds.get(guild_id); if (!guild) { - console.warn(`[GuildMemberListUpdate] Guild ${guild_id} not found`); + this.logger.warn( + `[GuildMemberListUpdate] Guild ${guild_id} not found`, + ); return; } @@ -561,7 +565,7 @@ export default class GatewayConnectionStore { const guild = this.app.guilds.get(data.guild_id!); if (!guild) { - console.warn( + this.logger.warn( `[ChannelCreate] Guild ${data.guild_id} not found for channel ${data.id}`, ); return; @@ -577,7 +581,7 @@ export default class GatewayConnectionStore { const guild = this.app.guilds.get(data.guild_id!); if (!guild) { - console.warn( + this.logger.warn( `[ChannelDelete] Guild ${data.guild_id} not found for channel ${data.id}`, ); return; @@ -588,14 +592,14 @@ export default class GatewayConnectionStore { private onMessageCreate = (data: GatewayMessageCreateDispatchData) => { const guild = this.app.guilds.get(data.guild_id!); if (!guild) { - console.warn( + this.logger.warn( `[MessageCreate] Guild ${data.guild_id} not found for channel ${data.id}`, ); return; } const channel = guild.channels.get(data.channel_id); if (!channel) { - console.warn( + this.logger.warn( `[MessageCreate] Channel ${data.channel_id} not found for message ${data.id}`, ); return; @@ -608,14 +612,14 @@ export default class GatewayConnectionStore { private onMessageUpdate = (data: GatewayMessageUpdateDispatchData) => { const guild = this.app.guilds.get(data.guild_id!); if (!guild) { - console.warn( + this.logger.warn( `[MessageUpdate] Guild ${data.guild_id} not found for channel ${data.id}`, ); return; } const channel = guild.channels.get(data.channel_id); if (!channel) { - console.warn( + this.logger.warn( `[MessageUpdate] Channel ${data.channel_id} not found for message ${data.id}`, ); return; @@ -627,14 +631,14 @@ export default class GatewayConnectionStore { private onMessageDelete = (data: GatewayMessageDeleteDispatchData) => { const guild = this.app.guilds.get(data.guild_id!); if (!guild) { - console.warn( + this.logger.warn( `[MessageDelete] Guild ${data.guild_id} not found for channel ${data.id}`, ); return; } const channel = guild.channels.get(data.channel_id); if (!channel) { - console.warn( + this.logger.warn( `[MessageDelete] Channel ${data.channel_id} not found for message ${data.id}`, ); return; diff --git a/src/stores/GuildMemberListStore.ts b/src/stores/GuildMemberListStore.ts index 9d74272..677cd09 100644 --- a/src/stores/GuildMemberListStore.ts +++ b/src/stores/GuildMemberListStore.ts @@ -4,11 +4,13 @@ import { GatewayGuildMemberListUpdateOperation, } from "@spacebarchat/spacebar-api-types/v9"; import { action, observable } from "mobx"; +import Logger from "../utils/Logger"; import AppStore from "./AppStore"; import Guild from "./objects/Guild"; import GuildMember from "./objects/GuildMember"; export default class GuildMemberListStore { + private readonly logger: Logger = new Logger("GuildMemberListStore"); private readonly app: AppStore; id: string; @@ -151,11 +153,11 @@ export default class GuildMemberListStore { // ); // } // } - console.debug("DELETE", item); + this.logger.debug("DELETE", item); break; } case GatewayGuildMemberListUpdateOperation.UPDATE: { - console.debug("UPDATE", item); + this.logger.debug("UPDATE", item); // for (const item of items) { // if ("group" in item) { // // this.listData[range[0]].title = item.group.id; @@ -195,7 +197,7 @@ export default class GuildMemberListStore { break; } default: { - console.warn(`Uknown OP: ${op}`); + this.logger.warn(`Uknown OP: ${op}`); break; } } diff --git a/src/stores/GuildStore.ts b/src/stores/GuildStore.ts index 7586d12..ff1273f 100644 --- a/src/stores/GuildStore.ts +++ b/src/stores/GuildStore.ts @@ -1,9 +1,11 @@ import type { GatewayGuild } from "@spacebarchat/spacebar-api-types/v9"; import { action, computed, observable, ObservableMap } from "mobx"; +import Logger from "../utils/Logger"; import AppStore from "./AppStore"; import Guild from "./objects/Guild"; export default class GuildStore { + private readonly logger: Logger = new Logger("GuildStore"); private readonly app: AppStore; @observable initialGuildsLoaded = false; @observable readonly guilds = new ObservableMap(); @@ -15,7 +17,7 @@ export default class GuildStore { @action setInitialGuildsLoaded() { this.initialGuildsLoaded = true; - console.debug("Initial guilds loaded"); + this.logger.debug("Initial guilds loaded"); } @action diff --git a/src/stores/objects/Channel.ts b/src/stores/objects/Channel.ts index cdd2337..3a2269f 100644 --- a/src/stores/objects/Channel.ts +++ b/src/stores/objects/Channel.ts @@ -15,11 +15,13 @@ import type { } from "@spacebarchat/spacebar-api-types/v9"; import { ChannelType, Routes } from "@spacebarchat/spacebar-api-types/v9"; import { action, computed, makeObservable, observable } from "mobx"; +import Logger from "../../utils/Logger"; +import { APIError } from "../../utils/interfaces/api"; import AppStore from "../AppStore"; import MessageStore from "../MessageStore"; -import { APIError } from "../../utils/interfaces/api"; export default class Channel { + private readonly logger: Logger = new Logger("Channel"); private readonly app: AppStore; id: SnowflakeType; @@ -170,7 +172,7 @@ export default class Channel { } this.hasFetchedMessages = true; - console.log(`Fetching messags for ${this.id}`); + this.logger.info(`Fetching messags for ${this.id}`); app.rest .get( Routes.channelMessages(this.id), @@ -178,7 +180,7 @@ export default class Channel { ) .then((res) => { if ("code" in res) { - console.error(res); + this.logger.error(res); return; } this.messages.addAll( @@ -191,7 +193,7 @@ export default class Channel { ); }) .catch((err) => { - console.error(err); + this.logger.error(err); }); } diff --git a/src/utils/Globals.ts b/src/utils/Globals.ts index efa6938..86005a0 100644 --- a/src/utils/Globals.ts +++ b/src/utils/Globals.ts @@ -1,3 +1,5 @@ +import Logger from "./Logger"; + export interface RouteSettings { api: string; cdn: string; @@ -12,21 +14,15 @@ export const DefaultRouteSettings: RouteSettings = { wellknown: "https://spacebar.chat", }; +const logger = new Logger("Globals"); + export const Globals: { - // logger: { - // debug: (...args: unknown[]) => void; - // info: (...args: unknown[]) => void; - // warn: (...args: unknown[]) => void; - // error: (...args: unknown[]) => void; - // }; load: () => void; save: () => void; routeSettings: RouteSettings; } = { - // logger: useLogger('Globals'), load: () => { - // Globals.logger.info('Initializing Globals'); - console.log("Initializing Globals"); + logger.info("Initializing Globals"); const settings = localStorage.getItem("routeSettings"); if (!settings) { @@ -34,8 +30,7 @@ export const Globals: { } Globals.routeSettings = JSON.parse(settings); - // Globals.logger.info('Loaded route settings from storage'); - console.log("Loaded route settings from storage"); + logger.info("Loaded route settings from storage"); }, save: () => { localStorage.setItem( diff --git a/src/utils/Logger.ts b/src/utils/Logger.ts new file mode 100644 index 0000000..81128cd --- /dev/null +++ b/src/utils/Logger.ts @@ -0,0 +1,39 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ + +export default class Logger { + constructor(public readonly name: string) { + this.name = name; + } + + debug(...args: any[]) { + console.debug( + `%c${new Date().toLocaleTimeString()} | ${this.name} | DEBUG |`, + `color: LimeGreen`, + ...args, + ); + } + + info(...args: any[]) { + console.debug( + `%c${new Date().toLocaleTimeString()} | ${this.name} | DEBUG |`, + `color: DodgerBlue`, + ...args, + ); + } + + warn(...args: any[]) { + console.debug( + `%c${new Date().toLocaleTimeString()} | ${this.name} | DEBUG |`, + `color: Tomato`, + ...args, + ); + } + + error(...args: any[]) { + console.debug( + `%c${new Date().toLocaleTimeString()} | ${this.name} | DEBUG |`, + `color: Red`, + ...args, + ); + } +} diff --git a/src/utils/REST.ts b/src/utils/REST.ts index 82f310e..64105a2 100644 --- a/src/utils/REST.ts +++ b/src/utils/REST.ts @@ -4,8 +4,10 @@ import AppStore from "../stores/AppStore"; import { Globals, RouteSettings } from "./Globals"; +import Logger from "./Logger"; export default class REST { + private readonly logger = new Logger("REST"); private app: AppStore; private headers: Record; @@ -52,7 +54,7 @@ export default class REST { const endpoints = await fetch( `${url.toString()}${ url.pathname.includes("api") ? "" : "api" - }/policies/instance/domains` + }/policies/instance/domains`, ).then((x) => x.json()); return { api: endpoints.apiEndpoint, @@ -112,7 +114,7 @@ export default class REST { ): Promise { return new Promise((resolve, reject) => { const url = REST.makeAPIUrl(path, queryParams); - console.debug(`POST ${url}; payload:`, body); + this.logger.debug(`POST ${url}; payload:`, body); return fetch(url, { method: "POST", headers: this.headers,