diff --git a/desktop-app/package.json b/desktop-app/package.json
index 9fd324d6..f4584711 100644
--- a/desktop-app/package.json
+++ b/desktop-app/package.json
@@ -151,7 +151,7 @@
"@types/howler": "^2.2.7",
"@types/jest": "^28.1.7",
"@types/mousetrap": "^1.6.10",
- "@types/node": "18.15.2",
+ "@types/node": "20.3.1",
"@types/react": "18.0.28",
"@types/react-dom": "18.0.10",
"@types/react-test-renderer": "^18.0.0",
diff --git a/desktop-app/src/renderer/components/Previewer/Device/index.tsx b/desktop-app/src/renderer/components/Previewer/Device/index.tsx
index ab26f8d2..a6ac9a79 100644
--- a/desktop-app/src/renderer/components/Previewer/Device/index.tsx
+++ b/desktop-app/src/renderer/components/Previewer/Device/index.tsx
@@ -37,6 +37,7 @@ import {
setAddress,
setIsInspecting,
setLayout,
+ setPageTitle,
} from 'renderer/store/features/renderer';
import { PREVIEW_LAYOUTS } from 'common/constants';
import { NAVIGATION_EVENTS } from '../../ToolBar/NavigationControls';
@@ -409,6 +410,22 @@ const Device = ({ isPrimary, device, setIndividualDevice }: Props) => {
};
}, [device.isMobileCapable]);
+ useEffect(() => {
+ const webview = ref.current;
+
+ if (isPrimary && webview) {
+ webview.addEventListener('dom-ready', () => {
+ const pageTitle = webview.getTitle();
+ dispatch(setPageTitle(pageTitle));
+ });
+ }
+
+ // eslint-disable-next-line consistent-return
+ return () => {
+ webview?.removeEventListener('dom-ready', () => {});
+ };
+ }, [dispatch, isPrimary]);
+
const scaledHeight = height * zoomfactor;
const scaledWidth = width * zoomfactor;
@@ -452,6 +469,8 @@ const Device = ({ isPrimary, device, setIndividualDevice }: Props) => {
data-scale-factor={zoomfactor}
/* eslint-disable-next-line react/no-unknown-property */
allowpopups={isPrimary ? ('true' as any) : undefined}
+ /* eslint-disable-next-line react/no-unknown-property */
+ useragent={device.userAgent}
/>
{screenshotInProgress ? (
{
+const BookmarkButton = ({ currentAddress, pageTitle }: Props) => {
const [openFlyout, setOpenFlyout] = useState
(false);
- const [bookmark, setBookmark] = useState({
+ const initbookmark = {
id: '',
- name: '',
+ name: pageTitle,
address: currentAddress,
- });
+ };
+
const bookmarks = useSelector(selectBookmarks);
+ const bookmarkFound = useMemo(
+ () => bookmarks.find((bm: IBookmarks) => bm.address === currentAddress),
+ [currentAddress, bookmarks]
+ );
- const handleFlyout = () => setOpenFlyout(!openFlyout);
+ const isPageBookmarked = !!bookmarkFound;
- useEffect(() => {
- const bookmarkFound = bookmarks.find(
- (bm: IBookmarks) => bm.address === currentAddress
- );
- setBookmark(
- bookmarkFound || {
- id: '',
- name: '',
- address: currentAddress,
- }
- );
- }, [bookmarks, currentAddress]);
-
- const isPageBookmarked = Boolean(bookmark.name);
+ const handleFlyout = () => {
+ setOpenFlyout(!openFlyout);
+ };
return (
<>
@@ -54,7 +49,10 @@ const BookmarkButton = ({ currentAddress }: Props) => {
{openFlyout && (
-
+
)}
>
diff --git a/desktop-app/src/renderer/components/ToolBar/AddressBar/index.tsx b/desktop-app/src/renderer/components/ToolBar/AddressBar/index.tsx
index 30ad444e..8e3e3981 100644
--- a/desktop-app/src/renderer/components/ToolBar/AddressBar/index.tsx
+++ b/desktop-app/src/renderer/components/ToolBar/AddressBar/index.tsx
@@ -13,7 +13,11 @@ import {
import { useDispatch, useSelector } from 'react-redux';
import Button from 'renderer/components/Button';
import { webViewPubSub } from 'renderer/lib/pubsub';
-import { selectAddress, setAddress } from 'renderer/store/features/renderer';
+import {
+ selectAddress,
+ selectPageTitle,
+ setAddress,
+} from 'renderer/store/features/renderer';
import AuthModal from './AuthModal';
import SuggestionList from './SuggestionList';
import Bookmark from './BookmarkButton';
@@ -40,6 +44,7 @@ const AddressBar = () => {
useState(null);
const [authRequest, setAuthRequest] = useState(null);
const address = useSelector(selectAddress);
+ const pageTitle = useSelector(selectPageTitle);
const dispatch = useDispatch();
useEffect(() => {
@@ -241,7 +246,7 @@ const AddressBar = () => {
>
-
+
{isSuggesting ? (
diff --git a/desktop-app/src/renderer/store/features/renderer/index.ts b/desktop-app/src/renderer/store/features/renderer/index.ts
index 6249dc34..761cf0e1 100644
--- a/desktop-app/src/renderer/store/features/renderer/index.ts
+++ b/desktop-app/src/renderer/store/features/renderer/index.ts
@@ -9,6 +9,7 @@ import type { RootState } from '../..';
export interface RendererState {
address: string;
+ pageTitle: string;
individualZoomFactor: number;
zoomFactor: number;
rotate: boolean;
@@ -32,6 +33,7 @@ const urlFromQueryParam = () => {
const initialState: RendererState = {
address: urlFromQueryParam() ?? window.electron.store.get('homepage'),
+ pageTitle: '',
individualZoomFactor:
zoomSteps[window.electron.store.get('renderer.individualZoomStepIndex')],
zoomFactor: zoomSteps[window.electron.store.get('renderer.zoomStepIndex')],
@@ -65,6 +67,11 @@ export const rendererSlice = createSlice({
state.address = action.payload;
}
},
+ setPageTitle: (state, action: PayloadAction) => {
+ if (action.payload !== state.pageTitle) {
+ state.pageTitle = action.payload;
+ }
+ },
zoomIn: (state) => {
const index =
state.layout === PREVIEW_LAYOUTS.INDIVIDUAL
@@ -131,6 +138,7 @@ export const {
setIsInspecting,
setLayout,
setIsCapturingScreenshot,
+ setPageTitle,
} = rendererSlice.actions;
// Use different zoom factor based on state's current layout
@@ -141,6 +149,7 @@ export const selectZoomFactor = (state: RootState) => {
return state.renderer.zoomFactor;
};
export const selectAddress = (state: RootState) => state.renderer.address;
+export const selectPageTitle = (state: RootState) => state.renderer.pageTitle;
export const selectRotate = (state: RootState) => state.renderer.rotate;
export const selectIsInspecting = (state: RootState) =>
state.renderer.isInspecting;
diff --git a/desktop-app/yarn.lock b/desktop-app/yarn.lock
index 8f8a809a..be0f2449 100644
--- a/desktop-app/yarn.lock
+++ b/desktop-app/yarn.lock
@@ -2346,10 +2346,10 @@
resolved "https://registry.yarnpkg.com/@types/ms/-/ms-0.7.31.tgz#31b7ca6407128a3d2bbc27fe2d21b345397f6197"
integrity sha512-iiUgKzV9AuaEkZqkOLDIvlQiL6ltuZd9tGcW3gwpnX8JbuiuhFlEGmmFXEXkN50Cvq7Os88IY2v0dkDqXYWVgA==
-"@types/node@*", "@types/node@18.15.2", "@types/node@>=10.0.0":
- version "18.15.2"
- resolved "https://registry.yarnpkg.com/@types/node/-/node-18.15.2.tgz#0407ceb15647f186318101546d5ae40725b73810"
- integrity sha512-sDPHm2wfx2QhrMDK0pOt2J4KLJMAcerqWNvnED0itPRJWvI+bK+uNHzcH1dFsBlf7G3u8tqXmRF3wkvL9yUwMw==
+"@types/node@*", "@types/node@20.3.1", "@types/node@>=10.0.0":
+ version "20.3.1"
+ resolved "https://registry.yarnpkg.com/@types/node/-/node-20.3.1.tgz#e8a83f1aa8b649377bb1fb5d7bac5cb90e784dfe"
+ integrity sha512-EhcH/wvidPy1WeML3TtYFGR83UzjxeWRen9V402T8aUGYsCHOmfoisV3ZSg03gAFIbLq8TnWOJ0f4cALtnSEUg==
"@types/node@^18.11.18":
version "18.16.7"