diff --git a/src/SEQTA.ts b/src/SEQTA.ts index e7e2adca..d899fd7e 100644 --- a/src/SEQTA.ts +++ b/src/SEQTA.ts @@ -29,6 +29,7 @@ import { onError } from './seqta/utils/onError' import stringToHTML from './seqta/utils/stringToHTML' import { updateAllColors } from './seqta/ui/colors/Manager' import { updateBgDurations } from './seqta/ui/Animation' +import { SettingsResizer } from "./seqta/ui/SettingsResizer"; declare global { interface Window { @@ -890,11 +891,13 @@ function addExtensionSettings() { extensionIframe.setAttribute('allowTransparency', 'true') extensionIframe.setAttribute('excludeDarkCheck', 'true') extensionIframe.style.width = '384px' - extensionIframe.style.height = '600px' + extensionIframe.style.height = '100%' extensionIframe.style.border = 'none' extensionPopup.appendChild(extensionIframe) const container = document.getElementById('container') + + new SettingsResizer(); const closeExtensionPopup = () => { const ExtensionIframe = document.getElementById('ExtensionIframe') as HTMLIFrameElement diff --git a/src/interface/SettingsPage.tsx b/src/interface/SettingsPage.tsx index 9f5a9dae..8e33d748 100644 --- a/src/interface/SettingsPage.tsx +++ b/src/interface/SettingsPage.tsx @@ -30,7 +30,7 @@ const SettingsPage = ({ standalone }: SettingsPage) => { ]; return ( -
+
diff --git a/src/seqta/ui/SettingsResizer.ts b/src/seqta/ui/SettingsResizer.ts new file mode 100644 index 00000000..2298714d --- /dev/null +++ b/src/seqta/ui/SettingsResizer.ts @@ -0,0 +1,26 @@ +import { debounce } from "../utils/debounce"; + +/** + * Automatically resizes the popup to fit the screen, checks on resize but is debounced to prevent intense utilisation. + */ +export class SettingsResizer { + constructor() { + this.adjustPopupHeight(); + window.addEventListener('resize', debounce(this.adjustPopupHeight, 250) as EventListener); + document.addEventListener('DOMContentLoaded', this.adjustPopupHeight); + } + + private adjustPopupHeight() { + const iframePopup = document.getElementById('ExtensionPopup'); + if (!iframePopup) return; + + const viewportHeight = window.innerHeight; + const idealHeight = viewportHeight - 80 - 15; // -80px for the top of the popup + + if (idealHeight > 600) { + iframePopup.style.height = '600px'; + } else { + iframePopup.style.height = `${idealHeight}px`; + } + } +} \ No newline at end of file diff --git a/src/seqta/utils/debounce.ts b/src/seqta/utils/debounce.ts new file mode 100644 index 00000000..affd641a --- /dev/null +++ b/src/seqta/utils/debounce.ts @@ -0,0 +1,25 @@ +/** + * Creates a debounced function that delays invoking the provided function until after `wait` milliseconds have elapsed + * since the last time it was invoked. The debounced function will only be invoked once during the `wait` period. + * + * @param func - The function to debounce. + * @param wait - The number of milliseconds to delay. + * @param immediate - If `true`, the function will be invoked immediately on the leading edge instead of the trailing edge. + * If not provided, it is disabled by default. + * @returns A debounced function. + */ +export function debounce(func: Function, wait: number, immediate?: boolean): Function { + let timeout: number | undefined; + return function(this: any) { + const context = this; + const args = arguments; + const later = function() { + timeout = undefined; + if (!immediate) func.apply(context, args); + }; + const callNow = immediate && !timeout; + clearTimeout(timeout); + timeout = setTimeout(later, wait); + if (callNow) func.apply(context, args); + }; +} \ No newline at end of file