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"