From 7437f454de84be814d2a15e96692d3e4a62addcb Mon Sep 17 00:00:00 2001 From: Nicolas Carlier Date: Mon, 16 Sep 2024 19:39:19 +0000 Subject: [PATCH] fix(ui): improve PWA install support --- ui/src/App.tsx | 33 +++++++++-------- ui/src/contexts/DeviceContext.tsx | 36 +++++++++++++++++++ ui/src/contexts/index.ts | 1 + ui/src/hooks/useAddToHomeScreenPrompt.ts | 4 +-- .../settings/preferences/InstallationBox.tsx | 18 ++-------- 5 files changed, 60 insertions(+), 32 deletions(-) create mode 100644 ui/src/contexts/DeviceContext.tsx diff --git a/ui/src/App.tsx b/ui/src/App.tsx index 2fbf38c3d..c25e00d48 100755 --- a/ui/src/App.tsx +++ b/ui/src/App.tsx @@ -7,6 +7,7 @@ import { Store } from 'redux' import { CurrentUserProvider, + DeviceProvider, GraphQLProvider, LocalConfigurationProvider, MessageProvider, @@ -37,21 +38,23 @@ export default function App({ store, history /*, theme*/ }: Props) { - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + diff --git a/ui/src/contexts/DeviceContext.tsx b/ui/src/contexts/DeviceContext.tsx new file mode 100644 index 000000000..25c628a2e --- /dev/null +++ b/ui/src/contexts/DeviceContext.tsx @@ -0,0 +1,36 @@ +import React, { createContext, FC, PropsWithChildren, useContext, useState } from 'react' +import { useAddToHomescreenPrompt } from '../hooks' +import { isDisplayMode } from '../helpers' + +interface DeviceContextType { + isInstalled: boolean + isInstallable: boolean + promptToInstall: () => void +} + +const DeviceContext = createContext({ + isInstalled: false, + isInstallable: false, + promptToInstall: () => {return}, +}) + +const DeviceProvider: FC = ({ children }) => { + const [prompt, promptToInstall] = useAddToHomescreenPrompt() + const [isInstalled] = useState(isDisplayMode('standalone')) + const [isInstallable, setInstallableState] = useState(false) + + React.useEffect( + () => { + if (prompt) { + setInstallableState(true) + } + }, + [prompt] + ) + + return {children} +} + +export { DeviceProvider } + +export const useDevice = () => useContext(DeviceContext) diff --git a/ui/src/contexts/index.ts b/ui/src/contexts/index.ts index 31a946198..245fd2eac 100644 --- a/ui/src/contexts/index.ts +++ b/ui/src/contexts/index.ts @@ -1,4 +1,5 @@ export * from './CurrentUserContext' +export * from './DeviceContext' export * from './GraphQLContext' export * from './LocalConfigurationContext' export * from './MessageContext' diff --git a/ui/src/hooks/useAddToHomeScreenPrompt.ts b/ui/src/hooks/useAddToHomeScreenPrompt.ts index 3cd222568..09e26e75c 100644 --- a/ui/src/hooks/useAddToHomeScreenPrompt.ts +++ b/ui/src/hooks/useAddToHomeScreenPrompt.ts @@ -17,7 +17,7 @@ export function useAddToHomescreenPrompt(): [ null ) - const promptToInstall = () => { + const promptToInstall = React.useCallback(() => { if (prompt) { return prompt.prompt() } @@ -26,7 +26,7 @@ export function useAddToHomescreenPrompt(): [ 'Tried installing before browser sent "beforeinstallprompt" event' ) ) - } + }, [prompt]) React.useEffect(() => { const ready = (e: IBeforeInstallPromptEvent) => { diff --git a/ui/src/settings/preferences/InstallationBox.tsx b/ui/src/settings/preferences/InstallationBox.tsx index 5d7571ab8..f36052a04 100644 --- a/ui/src/settings/preferences/InstallationBox.tsx +++ b/ui/src/settings/preferences/InstallationBox.tsx @@ -1,8 +1,7 @@ -import React, { useState } from 'react' +import React from 'react' import { Box, Button } from '../../components' -import { isDisplayMode } from '../../helpers' -import { useAddToHomescreenPrompt } from '../../hooks' +import { useDevice } from '../../contexts' interface InstallProps { onClick?: (e: any) => void @@ -38,18 +37,7 @@ const Uninstallable = () => ( ) const InstallationBox = () => { - const [prompt, promptToInstall] = useAddToHomescreenPrompt() - const [isInstalled] = useState(isDisplayMode('standalone')) - const [isInstallable, setInstallableState] = useState(false) - - React.useEffect( - () => { - if (prompt) { - setInstallableState(true) - } - }, - [prompt] - ) + const {isInstalled, isInstallable, promptToInstall} = useDevice() return (