Authentication-Results: mail-b.sr.ht; dkim=pass header.d=gmail.com header.i=@gmail.com Received: from mail-lf1-f53.google.com (mail-lf1-f53.google.com [209.85.167.53]) by mail-b.sr.ht (Postfix) with ESMTPS id 3B48711EFF3 for <~avery/public-inbox@lists.sr.ht>; Thu, 1 Sep 2022 16:58:04 +0000 (UTC) Received: by mail-lf1-f53.google.com with SMTP id w8so16261348lft.12 for <~avery/public-inbox@lists.sr.ht>; Thu, 01 Sep 2022 09:58:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date; bh=Zvt27UpUFZWn0eYWpT6Cvv5wCAmkrTyxrrWsmtvnRbM=; b=FNB/XAeBoXAsShHaiVCcGcF1k3CR8RGMBZn79/+lauQKCn5l6XtQTiZqS5KbJ6jK1G XALWfkOMBZsxVjOFEH87nVMyHvXfJuoTrliIt6eUF64rpLezTcObQ2PLsTVnltUM+zA9 i2FVxatTxkHTEV4jXOqmCBSa7wP1JtRRsth72Uy76KN0CyWpwNXu4iDHPrZA/gCYPBH3 kugOm3k5Hdk1TgvKWu/KcDPlZBIpvCY+HYiyWfwGLuBIaiSwqzEu3Epxeh32ESy4WBVU +LEOx7sLyJguShwWAmyaJU/rm7iQhe1ZiTEWem9+3Exc+o6EFheeTzPDDM/t4OMFz3X5 1AUw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date; bh=Zvt27UpUFZWn0eYWpT6Cvv5wCAmkrTyxrrWsmtvnRbM=; b=bk/K/RxiaC1aJvpLgw7h6IKlagMPy/GbfuW/Legvy3hZZR6s4zVh4+OOgvRy7bxoMd zfG4gyjQkyR1rO8onFblLgZiSaNWU3qaO2WMbdGnQ4mj4hwHWV0m33wLb+/+yVKHIlct +j7QmimiaVplfbBm7OXlMwnWC4Ji2TTGoHCNwrXrGbl40RYNtRP88ND46t1CKS9cHbhJ tGA4wWRdNxRJ8gdAszKfuJ4H0qlc5qLYi60FrYGhKZ7lZgevjSKqXITy8PcCJNP9KXdh HiFs6kTqXdjvB21EZjNFHn/gXd37Ami8N+2u56Usjxx3wS7Qc0ctlgKkSsUQPya5TE+j rFXw== X-Gm-Message-State: ACgBeo3EENNtjGL2ik4lSP6ml0d+jfKeTb6G6cDhY4yDEf2ehluNtR69 gMb+v2czgUyeTNeC+HR+Kq4bE58lOYd0NQ== X-Google-Smtp-Source: AA6agR5r1RviN61Z0NOveUzhMCk5Vc5DSJl1l8EaQaKa5PKy18pi+AGqeQDU2A/1OmqLIk6X3m4lBw== X-Received: by 2002:a05:6512:1154:b0:48b:3020:b29 with SMTP id m20-20020a056512115400b0048b30200b29mr10420873lfg.338.1662051482464; Thu, 01 Sep 2022 09:58:02 -0700 (PDT) Received: from localhost.localdomain (c188-151-223-206.bredband.tele2.se. [188.151.223.206]) by smtp.gmail.com with ESMTPSA id b7-20020a056512070700b004948b667d95sm688343lfs.265.2022.09.01.09.58.01 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 01 Sep 2022 09:58:01 -0700 (PDT) From: =?UTF-8?q?Jaras=C5=82a=C5=AD=20Viktor=C4=8Dyk?= To: ~avery/public-inbox@lists.sr.ht Cc: =?UTF-8?q?Jaras=C5=82a=C5=AD=20Viktor=C4=8Dyk?= Subject: [PATCH crankshaft v2 3/3] Add types for events and callbacks Date: Thu, 1 Sep 2022 18:57:45 +0200 Message-Id: <20220901165745.197501-3-ugzuzg@gmail.com> X-Mailer: git-send-email 2.37.3 In-Reply-To: <20220901165745.197501-1-ugzuzg@gmail.com> References: <20220901165745.197501-1-ugzuzg@gmail.com> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit smm.addEventListener can now automatically determine the event arg type based on the string supplied to it. --- .../menu-manager/deck/menu-injector-deck.tsx | 12 +- injected/src/smm.ts | 124 ++++++++++-------- injected/src/tab-observer.ts | 7 +- 3 files changed, 82 insertions(+), 61 deletions(-) diff --git a/injected/src/menu-manager/deck/menu-injector-deck.tsx b/injected/src/menu-manager/deck/menu-injector-deck.tsx index f8a82a8..0cdef73 100644 --- a/injected/src/menu-manager/deck/menu-injector-deck.tsx +++ b/injected/src/menu-manager/deck/menu-injector-deck.tsx @@ -1,7 +1,7 @@ import { dcCreateElement } from '../../dom-chef'; import { GamepadHandler } from '../../gamepad'; import { DECK_SELECTORS } from '../../selectors'; -import { SMM } from '../../smm'; +import { eventTypeSwitchToLocation, SMM } from '../../smm'; import { deleteAll } from '../../util'; import { MenuInjector, MenuItem, MenuManager } from '../menu-manager'; import styles from './menu-injector-deck.css'; @@ -89,8 +89,12 @@ export class MenuInjectorDeck implements MenuInjector { } private listenToNavigationChanges() { - this.smm.addEventListener('switchToPlugins', () => { - this.openPluginsPage(); + this.smm.addEventListener(eventTypeSwitchToLocation, (e) => { + if (e.detail.pathname === '/routes/blank/cs-plugins') { + this.openPluginsPage(); + } else { + this.closeActivePage(); + } }); } @@ -122,6 +126,8 @@ export class MenuInjectorDeck implements MenuInjector { } private async closePluginsPage(forward = false) { + if (!this.pageContainer.isConnected) return; + this.activePluginId = undefined; this.activePluginEl = undefined; // Clear active menu item diff --git a/injected/src/smm.ts b/injected/src/smm.ts index 2689405..32d255a 100644 --- a/injected/src/smm.ts +++ b/injected/src/smm.ts @@ -19,52 +19,28 @@ import { info } from './util'; type PluginId = string; -type AddEventListenerArgs = Parameters; - -// TODO: there's probably a better way to do these EventTarget types - -type SMMEventType = - | typeof eventTypeSwitchToUnknownPage - | typeof eventTypeSwitchToHome - | typeof eventTypeSwitchToCollections - | typeof eventTypeSwitchToAppDetails - | typeof eventTypeSwitchToAppProperties - | typeof eventTypeSwitchToPlugins - | typeof eventTypeLockScreenOpened - | typeof eventTypeLockScreenClosed; - -type SMMEvent = - | EventSwitchToUnknownPage - | EventSwitchToHome - | EventSwitchToCollections - | EventSwitchToAppDetails - | EventSwitchToAppProperties - | EventSwitchToPlugins - | EventLockScreenOpened - | EventLockScreenClosed; - -const eventTypeSwitchToUnknownPage = 'switchToUnknownPage' as const; +export const eventTypeSwitchToUnknownPage = 'switchToUnknownPage' as const; class EventSwitchToUnknownPage extends CustomEvent { constructor() { super(eventTypeSwitchToUnknownPage); } } -const eventTypeSwitchToHome = 'switchToHome' as const; +export const eventTypeSwitchToHome = 'switchToHome' as const; class EventSwitchToHome extends CustomEvent { constructor() { super(eventTypeSwitchToHome); } } -const eventTypeSwitchToCollections = 'switchToCollections' as const; +export const eventTypeSwitchToCollections = 'switchToCollections' as const; class EventSwitchToCollections extends CustomEvent { constructor() { super(eventTypeSwitchToCollections); } } -const eventTypeSwitchToAppDetails = 'switchToAppDetails' as const; +export const eventTypeSwitchToAppDetails = 'switchToAppDetails' as const; type eventDetailsSwitchToAppDetails = { appId: string; appName: string }; class EventSwitchToAppDetails extends CustomEvent { constructor(detail: eventDetailsSwitchToAppDetails) { @@ -72,34 +48,79 @@ class EventSwitchToAppDetails extends CustomEvent { constructor(detail: AppPropsApp) { super(eventTypeSwitchToAppProperties, { detail }); } } -const eventTypeSwitchToPlugins = 'switchToPlugins' as const; -class EventSwitchToPlugins extends CustomEvent { - constructor() { - super(eventTypeSwitchToPlugins); +export const eventTypeSwitchToLocation = 'switchToLocation' as const; +type eventDetailsSwitchToLocation = Location; +class EventSwitchToLocation extends CustomEvent { + constructor(detail: eventDetailsSwitchToLocation) { + super(eventTypeSwitchToLocation, { detail }); } } -const eventTypeLockScreenOpened = 'lockScreenOpened' as const; +export const eventTypeLockScreenOpened = 'lockScreenOpened' as const; class EventLockScreenOpened extends CustomEvent { constructor() { super(eventTypeLockScreenOpened); } } -const eventTypeLockScreenClosed = 'lockScreenClosed' as const; +export const eventTypeLockScreenClosed = 'lockScreenClosed' as const; class EventLockScreenClosed extends CustomEvent { constructor() { super(eventTypeLockScreenClosed); } } +interface EventListenerObjectFor { + handleEvent(evt: T): void; +} +interface EventListenerFor { + (evt: T): void; +} +type EventListenerOrEventListenerObjectFor = + | EventListenerFor + | EventListenerObjectFor; + +type SMMEventGroup = { + type: T; + event: E; +}; + +type SMMEvent = + | SMMEventGroup + | SMMEventGroup + | SMMEventGroup + | SMMEventGroup + | SMMEventGroup< + typeof eventTypeSwitchToAppProperties, + EventSwitchToAppProperties + > + | SMMEventGroup + | SMMEventGroup + | SMMEventGroup; + +type MapToCallbacks = U extends any + ? { + type: U['type']; + callback: EventListenerOrEventListenerObjectFor | null; + options: Parameters[2]; + } + : never; +type SMMEventCallback = MapToCallbacks; + +type SMMCallbackMap = { + [P in SMMEventCallback['type']]: Extract< + SMMEventCallback, + { type: P } + >['callback']; +}; + /** * @public */ @@ -141,14 +162,7 @@ export class SMM extends EventTarget { // that plugin. private currentPlugin?: string; // Events attached by plugins - private attachedEvents: Record< - PluginId, - { - type: AddEventListenerArgs[0]; - callback: AddEventListenerArgs[1]; - options: AddEventListenerArgs[2]; - }[] - >; + private attachedEvents: Record; constructor(entry: Entry) { super(); @@ -287,10 +301,10 @@ export class SMM extends EventTarget { /** * @internal */ - switchToPlugins() { - info('Switched to plugins'); + switchToLocation(loc: Location) { + info('Switched to location'); - this.dispatchEvent(new EventSwitchToPlugins()); + this.dispatchEvent(new EventSwitchToLocation(loc)); } /** @@ -383,15 +397,15 @@ export class SMM extends EventTarget { if (this.attachedEvents[pluginId]) { for (const { type, callback, options } of this.attachedEvents[pluginId]) { - this.removeEventListener(type, callback, options); + this.removeEventListener(type, callback as EventListener, options); } delete this.attachedEvents[pluginId]; } } - addEventListener( - type: SMMEventType, - callback: EventListenerOrEventListenerObject | null, + addEventListener( + type: K, + callback: SMMCallbackMap[K], options?: boolean | AddEventListenerOptions ): void { if (this.currentPlugin) { @@ -399,13 +413,17 @@ export class SMM extends EventTarget { this.attachedEvents[this.currentPlugin] = []; } - this.attachedEvents[this.currentPlugin].push({ type, callback, options }); + this.attachedEvents[this.currentPlugin].push({ + type, + callback, + options, + } as SMMEventCallback); } - super.addEventListener(type, callback, options); + super.addEventListener(type, callback as EventListener, options); } - dispatchEvent(event: SMMEvent): boolean { + dispatchEvent(event: SMMEvent['event']): boolean { return super.dispatchEvent(event); } diff --git a/injected/src/tab-observer.ts b/injected/src/tab-observer.ts index d8ea9ee..d9bfad9 100644 --- a/injected/src/tab-observer.ts +++ b/injected/src/tab-observer.ts @@ -14,6 +14,8 @@ export const createTabObserver = (smm: SMM, mainLibraryEl: HTMLElement) => { } const observer = new MutationObserver((_mutationsList) => { + smm.switchToLocation({ ...location }); + if (window.smmUIMode === 'deck') { if (document.querySelector(DECK_SELECTORS.lockScreenContainer)) { if (!smm.onLockScreen) { @@ -81,11 +83,6 @@ export const createTabObserver = (smm: SMM, mainLibraryEl: HTMLElement) => { } } - if (location.pathname === '/routes/blank/cs-plugins') { - smm.switchToPlugins(); - return; - } - smm.switchToUnknownPage(); }); -- 2.37.3