From c47478bbf6b21973419f25234c68efb59466b368 Mon Sep 17 00:00:00 2001 From: Erika <3019731+Princesseuh@users.noreply.github.com> Date: Fri, 1 Dec 2023 11:20:24 +0100 Subject: [PATCH] fix(overlay): Fix notification setting not working immediately (#9243) --- .../runtime/client/dev-overlay/entrypoint.ts | 14 +--- .../src/runtime/client/dev-overlay/overlay.ts | 79 +++++++++++++------ .../client/dev-overlay/plugins/settings.ts | 6 ++ 3 files changed, 65 insertions(+), 34 deletions(-) diff --git a/packages/astro/src/runtime/client/dev-overlay/entrypoint.ts b/packages/astro/src/runtime/client/dev-overlay/entrypoint.ts index 32fca3759a..70b310fd0b 100644 --- a/packages/astro/src/runtime/client/dev-overlay/entrypoint.ts +++ b/packages/astro/src/runtime/client/dev-overlay/entrypoint.ts @@ -1,6 +1,5 @@ import type { DevOverlayPlugin as DevOverlayPluginDefinition } from '../../../@types/astro.js'; import { type AstroDevOverlay, type DevOverlayPlugin } from './overlay.js'; - import { settings } from './settings.js'; let overlay: AstroDevOverlay; @@ -23,7 +22,6 @@ document.addEventListener('DOMContentLoaded', async () => { DevOverlayBadge, DevOverlayIcon, }, - { getIconElement, isDefinedIcon }, ] = await Promise.all([ // @ts-expect-error import('astro:dev-overlay'), @@ -33,7 +31,6 @@ document.addEventListener('DOMContentLoaded', async () => { import('./plugins/settings.js'), import('./overlay.js'), import('./ui-library/index.js'), - import('./ui-library/icons.js'), ]); // Register custom elements @@ -76,9 +73,7 @@ document.addEventListener('DOMContentLoaded', async () => { plugin.notification.state = newState; - if (settings.config.disablePluginNotification === false) { - target.querySelector('.notification')?.toggleAttribute('data-active', newState); - } + target.querySelector('.notification')?.toggleAttribute('data-active', newState); }); eventTarget.addEventListener('toggle-plugin', async (evt) => { @@ -133,7 +128,7 @@ document.addEventListener('DOMContentLoaded', async () => { background: #B33E66; } - .notification[data-active] { + #dropdown:not([data-no-notification]) .notification[data-active] { display: block; } @@ -179,6 +174,7 @@ document.addEventListener('DOMContentLoaded', async () => { const dropdown = document.createElement('div'); dropdown.id = 'dropdown'; + dropdown.toggleAttribute('data-no-notification', settings.config.disablePluginNotification); for (const plugin of hiddenPlugins) { const buttonContainer = document.createElement('div'); @@ -209,9 +205,7 @@ document.addEventListener('DOMContentLoaded', async () => { plugin.eventTarget.addEventListener('toggle-notification', (evt) => { if (!(evt instanceof CustomEvent)) return; - if (settings.config.disablePluginNotification === false) { - notification.toggleAttribute('data-active', evt.detail.state ?? true); - } + notification.toggleAttribute('data-active', evt.detail.state ?? true); eventTarget.dispatchEvent( new CustomEvent('toggle-notification', { diff --git a/packages/astro/src/runtime/client/dev-overlay/overlay.ts b/packages/astro/src/runtime/client/dev-overlay/overlay.ts index b6a0095cdf..798be5e7d8 100644 --- a/packages/astro/src/runtime/client/dev-overlay/overlay.ts +++ b/packages/astro/src/runtime/client/dev-overlay/overlay.ts @@ -1,5 +1,8 @@ /* eslint-disable no-console */ -import type { DevOverlayPlugin as DevOverlayPluginDefinition } from '../../../@types/astro.js'; +import type { + DevOverlayMetadata, + DevOverlayPlugin as DevOverlayPluginDefinition, +} from '../../../@types/astro.js'; import { settings } from './settings.js'; import { getIconElement, isDefinedIcon, type Icon } from './ui-library/icons.js'; @@ -35,7 +38,7 @@ export class AstroDevOverlay extends HTMLElement { */ init() { this.shadowRoot.innerHTML = ` - -
+
@@ -291,6 +299,7 @@ export class AstroDevOverlay extends HTMLElement { this.init(); this.hasBeenInitialized = true; } + // Run this every time to make sure the correct plugin is open. this.plugins.forEach(async (plugin) => { await this.setPluginStatus(plugin, plugin.active); @@ -402,11 +411,16 @@ export class AstroDevOverlay extends HTMLElement { async togglePluginStatus(plugin: DevOverlayPlugin) { const activePlugin = this.getActivePlugin(); if (activePlugin) { - await this.setPluginStatus(activePlugin, false); + const closePlugin = await this.setPluginStatus(activePlugin, false); + + // If the plugin returned false, don't open the new plugin, the old plugin didn't want to close + if (!closePlugin) return; } + // TODO(fks): Handle a plugin that hasn't loaded yet. // Currently, this will just do nothing. if (plugin.status !== 'ready') return; + // Open the selected plugin. If the selected plugin was // already the active plugin then the desired outcome // was to close that plugin, so no action needed. @@ -417,13 +431,13 @@ export class AstroDevOverlay extends HTMLElement { async setPluginStatus(plugin: DevOverlayPlugin, newStatus: boolean) { const pluginCanvas = this.getPluginCanvasById(plugin.id); - if (!pluginCanvas) return; + if (!pluginCanvas) return false; if (plugin.active && !newStatus && plugin.beforeTogglingOff) { const shouldToggleOff = await plugin.beforeTogglingOff(pluginCanvas.shadowRoot!); // If the plugin returned false, don't toggle it off, maybe the plugin showed a confirmation dialog or similar - if (!shouldToggleOff) return; + if (!shouldToggleOff) return false; } plugin.active = newStatus ?? !plugin.active; @@ -460,17 +474,23 @@ export class AstroDevOverlay extends HTMLElement { if (import.meta.hot) { import.meta.hot.send(`${WS_EVENT_NAME}:${plugin.id}:toggled`, { state: plugin.active }); } + + return true; } + isHidden(): boolean { return this.devOverlay?.hasAttribute('data-hidden') ?? true; } + getActivePlugin(): DevOverlayPlugin | undefined { return this.plugins.find((plugin) => plugin.active); } + clearDelayedHide() { window.clearTimeout(this.delayedHideTimeout); this.delayedHideTimeout = undefined; } + triggerDelayedHide() { this.clearDelayedHide(); this.delayedHideTimeout = window.setTimeout(() => { @@ -478,6 +498,7 @@ export class AstroDevOverlay extends HTMLElement { this.delayedHideTimeout = undefined; }, HOVER_DELAY); } + setOverlayVisible(newStatus: boolean) { const barContainer = this.shadowRoot.querySelector('#bar-container'); const devBar = this.shadowRoot.querySelector('#dev-bar'); @@ -494,6 +515,16 @@ export class AstroDevOverlay extends HTMLElement { return; } } + + setNotificationVisible(newStatus: boolean) { + const devOverlayElement = this.shadowRoot.querySelector('#dev-overlay'); + devOverlayElement?.toggleAttribute('data-no-notification', !newStatus); + + const moreCanvas = this.getPluginCanvasById('astro:more'); + moreCanvas?.shadowRoot + ?.querySelector('#dropdown') + ?.toggleAttribute('data-no-notification', !newStatus); + } } export class DevOverlayCanvas extends HTMLElement { diff --git a/packages/astro/src/runtime/client/dev-overlay/plugins/settings.ts b/packages/astro/src/runtime/client/dev-overlay/plugins/settings.ts index ecca71f223..15d18d1615 100644 --- a/packages/astro/src/runtime/client/dev-overlay/plugins/settings.ts +++ b/packages/astro/src/runtime/client/dev-overlay/plugins/settings.ts @@ -18,6 +18,12 @@ const settingsRows = [ settingKey: 'disablePluginNotification', changeEvent: (evt: Event) => { if (evt.currentTarget instanceof HTMLInputElement) { + const devOverlay = document.querySelector('astro-dev-overlay'); + + if (devOverlay) { + devOverlay.setNotificationVisible(!evt.currentTarget.checked); + } + settings.updateSetting('disablePluginNotification', evt.currentTarget.checked); } },