height adjuster (#94)

This hook observes and returns the current height of a component.
This commit is contained in:
Red J Adaya 2024-07-05 00:07:06 +08:00 committed by GitHub
parent cbd8512ed6
commit d8ff2cb806
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 49 additions and 28 deletions

View File

@ -0,0 +1,40 @@
// Copyright 2024, Command Line Inc.
// SPDX-License-Identifier: Apache-2.0
import debounce from "lodash.debounce";
import { useCallback, useEffect, useState } from "react";
const useParentHeight = (ref: React.RefObject<HTMLElement>) => {
const [height, setHeight] = useState<number | null>(null);
const updateHeight = useCallback(() => {
if (ref.current) {
const parentHeight = ref.current.getBoundingClientRect().height || 0;
setHeight(parentHeight);
}
}, []);
const debouncedUpdateHeight = useCallback(debounce(updateHeight, 100), [updateHeight]);
useEffect(() => {
const resizeObserver = new ResizeObserver(() => {
debouncedUpdateHeight();
});
if (ref.current) {
resizeObserver.observe(ref.current);
updateHeight();
}
return () => {
if (ref.current) {
resizeObserver.unobserve(ref.current);
}
debouncedUpdateHeight.cancel();
};
}, [debouncedUpdateHeight, updateHeight]);
return height;
};
export { useParentHeight };

View File

@ -2,6 +2,7 @@
// SPDX-License-Identifier: Apache-2.0 // SPDX-License-Identifier: Apache-2.0
import { Button } from "@/app/element/button"; import { Button } from "@/app/element/button";
import { useParentHeight } from "@/app/hook/useParentHeight";
import { getApi } from "@/app/store/global"; import { getApi } from "@/app/store/global";
import { WebviewTag } from "electron"; import { WebviewTag } from "electron";
import React, { memo, useEffect, useRef, useState } from "react"; import React, { memo, useEffect, useRef, useState } from "react";
@ -16,26 +17,19 @@ interface WebViewProps {
const WebView = memo(({ parentRef, initialUrl }: WebViewProps) => { const WebView = memo(({ parentRef, initialUrl }: WebViewProps) => {
const [url, setUrl] = useState(initialUrl); const [url, setUrl] = useState(initialUrl);
const [inputUrl, setInputUrl] = useState(initialUrl); // Separate state for the input field const [inputUrl, setInputUrl] = useState(initialUrl); // Separate state for the input field
const [webViewHeight, setWebViewHeight] = useState(0);
const [isLoading, setIsLoading] = useState(false); const [isLoading, setIsLoading] = useState(false);
const webviewRef = useRef<WebviewTag>(null); const webviewRef = useRef<WebviewTag>(null);
const inputRef = useRef<HTMLInputElement>(null); const inputRef = useRef<HTMLInputElement>(null);
const historyStack = useRef<string[]>([]); const historyStack = useRef<string[]>([]);
const historyIndex = useRef<number>(-1); const historyIndex = useRef<number>(-1);
const recentUrls = useRef<{ [key: string]: number }>({}); const recentUrls = useRef<{ [key: string]: number }>({});
const getWebViewHeight = () => { const parentHeight = useParentHeight(parentRef);
const inputHeight = inputRef.current?.getBoundingClientRect().height; const inputHeight = inputRef.current?.getBoundingClientRect().height || 0;
const parentHeight = parentRef.current?.getBoundingClientRect().height; const webViewHeight = parentHeight - (inputHeight + 35);
return parentHeight - (inputHeight + 35);
};
useEffect(() => { useEffect(() => {
const webviewHeight = getWebViewHeight();
setWebViewHeight(webviewHeight);
historyStack.current.push(initialUrl); historyStack.current.push(initialUrl);
historyIndex.current = 0; historyIndex.current = 0;
@ -99,6 +93,10 @@ const WebView = memo(({ parentRef, initialUrl }: WebViewProps) => {
} }
}, [initialUrl]); }, [initialUrl]);
// useEffect(() => {
// setWebViewHeight(getWebViewHeight());
// }, [parentHeight, getWebViewHeight]);
useEffect(() => { useEffect(() => {
const handleKeyDown = (event: KeyboardEvent) => { const handleKeyDown = (event: KeyboardEvent) => {
if ((event.ctrlKey || event.metaKey) && event.key === "l") { if ((event.ctrlKey || event.metaKey) && event.key === "l") {
@ -115,34 +113,17 @@ const WebView = memo(({ parentRef, initialUrl }: WebViewProps) => {
} }
}; };
const handleResize = () => {
const webviewHeight = getWebViewHeight();
setWebViewHeight(webviewHeight);
};
const parentElement = parentRef.current; const parentElement = parentRef.current;
if (parentElement) { if (parentElement) {
parentElement.addEventListener("keydown", handleKeyDown); parentElement.addEventListener("keydown", handleKeyDown);
} }
// Use ResizeObserver to observe changes in the height of parentRef
const resizeObserver = new ResizeObserver((entries) => {
for (let entry of entries) {
if (entry.target === parentElement) {
handleResize();
}
}
});
resizeObserver.observe(parentElement);
return () => { return () => {
if (parentElement) { if (parentElement) {
parentElement.removeEventListener("keydown", handleKeyDown); parentElement.removeEventListener("keydown", handleKeyDown);
} }
resizeObserver.disconnect();
}; };
}, []); }, [parentRef]);
const ensureUrlScheme = (url: string) => { const ensureUrlScheme = (url: string) => {
if (/^(localhost|(\d{1,3}\.){3}\d{1,3})(:\d+)?/.test(url)) { if (/^(localhost|(\d{1,3}\.){3}\d{1,3})(:\d+)?/.test(url)) {