From 20a403cedb634465fa4e68ce1a62a00189b33b9a Mon Sep 17 00:00:00 2001 From: Arthur Geron <3487334+arthurgeron@users.noreply.github.com> Date: Sun, 13 Oct 2024 12:46:14 -0300 Subject: [PATCH] fix: out of bounds error when opening extension makes sure modal always to top-right --- packages/app/manifest.config.ts | 9 +- .../app/src/systems/CRX/utils/position.ts | 109 ++++++++++++++++-- 2 files changed, 105 insertions(+), 13 deletions(-) diff --git a/packages/app/manifest.config.ts b/packages/app/manifest.config.ts index 7664ddb15..120c37822 100644 --- a/packages/app/manifest.config.ts +++ b/packages/app/manifest.config.ts @@ -42,7 +42,14 @@ export default defineManifest({ }, ], host_permissions: [''], - permissions: ['storage', 'alarms', 'tabs', 'clipboardWrite', 'scripting'], + permissions: [ + 'storage', + 'alarms', + 'tabs', + 'system.display', + 'clipboardWrite', + 'scripting', + ], content_security_policy: { extension_pages: "script-src 'self' 'wasm-unsafe-eval'; object-src 'self'", }, diff --git a/packages/app/src/systems/CRX/utils/position.ts b/packages/app/src/systems/CRX/utils/position.ts index 4448b4bf8..befccd077 100644 --- a/packages/app/src/systems/CRX/utils/position.ts +++ b/packages/app/src/systems/CRX/utils/position.ts @@ -1,21 +1,106 @@ -import { WALLET_WIDTH } from '~/config'; +import { WALLET_HEIGHT, WALLET_WIDTH } from '~/config'; export async function getPopUpPosition() { let left = 0; let top = 0; + try { - const { - top: windowTop = 0, - left: windowLeft = 0, - width: windowWidth = 0, - } = await chrome.windows.getLastFocused(); - top = windowTop; - left = windowLeft + (windowWidth - WALLET_WIDTH); - } catch (_) { - const { screenX, screenY, outerWidth } = window; - top = Math.max(screenY, 0); - left = Math.max(screenX + (outerWidth - WALLET_WIDTH), 0); + // Get information about all connected displays + const displays = await chrome.system.display.getInfo(); + + // Assume primary display is the first one marked as primary + const primaryDisplay = + displays.find((display) => display.isPrimary) || displays[0]; + + if (!primaryDisplay) { + throw new Error('No displays found'); + } + + const { bounds } = primaryDisplay; + const screenWidth = bounds.width; + const screenHeight = bounds.height; + + // Attempt to position at top-right Corner + left = bounds.left + screenWidth - WALLET_WIDTH; + top = bounds.top; + + // Ensure at least 50% within bounds + const isTopRightValid = + left + WALLET_WIDTH * 0.5 >= bounds.left && + top + WALLET_HEIGHT * 0.5 >= bounds.top && + left <= bounds.left + screenWidth - WALLET_WIDTH * 0.5 && + top <= bounds.top + screenHeight - WALLET_HEIGHT * 0.5; + + if (!isTopRightValid) { + // Fallback to centered position + left = bounds.left + (screenWidth - WALLET_WIDTH) / 2; + top = bounds.top + (screenHeight - WALLET_HEIGHT) / 2; + } + + // **Final adjustment to ensure full isibility + left = Math.max( + bounds.left, + Math.min(left, bounds.left + screenWidth - WALLET_WIDTH) + ); + top = Math.max( + bounds.top, + Math.min(top, bounds.top + screenHeight - WALLET_HEIGHT) + ); + } catch (error) { + console.error('Failed to get display info:', error); + try { + const focusedWindow = await chrome.windows.getLastFocused(); + const { + left: windowLeft = 0, + top: windowTop = 0, + width: windowWidth = 0, + } = focusedWindow; + + // Attempt top-Right relative to focused window + left = windowLeft + windowWidth - WALLET_WIDTH; + top = windowTop; + + // ensure at least 50% within bounds** + const { width: screenWidth, height: screenHeight } = + await getPrimaryDisplaySize(); + const isTopRightValid = + left + WALLET_WIDTH * 0.5 >= 0 && + top + WALLET_HEIGHT * 0.5 >= 0 && + left <= screenWidth - WALLET_WIDTH * 0.5 && + top <= screenHeight - WALLET_HEIGHT * 0.5; + + if (!isTopRightValid) { + // fallback to centered position** + left = (screenWidth - WALLET_WIDTH) / 2; + top = (screenHeight - WALLET_HEIGHT) / 2; + } + + // final adjustment + left = Math.max(0, Math.min(left, screenWidth - WALLET_WIDTH)); + top = Math.max(0, Math.min(top, screenHeight - WALLET_HEIGHT)); + } catch (fallbackError) { + console.error('Failed to get focused window:', fallbackError); + // bsolute fallback to top-left corner + left = 100; + top = 100; + } } return { left, top }; } + +// Helper function to get primary display size +async function getPrimaryDisplaySize() { + const displays = await chrome.system.display.getInfo(); + const primaryDisplay = + displays.find((display) => display.isPrimary) || displays[0]; + + if (!primaryDisplay) { + throw new Error('No displays found'); + } + + return { + width: primaryDisplay.bounds.width, + height: primaryDisplay.bounds.height, + }; +}