Skip to content

Commit

Permalink
chore(ui): improve installation support
Browse files Browse the repository at this point in the history
  • Loading branch information
ncarlier committed Sep 20, 2024
1 parent 7437f45 commit 46efdf4
Show file tree
Hide file tree
Showing 4 changed files with 40 additions and 70 deletions.
48 changes: 29 additions & 19 deletions ui/src/contexts/DeviceContext.tsx
Original file line number Diff line number Diff line change
@@ -1,34 +1,44 @@
import React, { createContext, FC, PropsWithChildren, useContext, useState } from 'react'
import { useAddToHomescreenPrompt } from '../hooks'
import { isDisplayMode } from '../helpers'

interface IBeforeInstallPromptEvent extends Event {
readonly platforms: string[]
readonly userChoice: Promise<{
outcome: 'accepted' | 'dismissed'
platform: string
}>
prompt(): Promise<void>
}

interface DeviceContextType {
isInstalled: boolean
isInstallable: boolean
promptToInstall: () => void
beforeInstallPromptEvent: IBeforeInstallPromptEvent | null
}

const DeviceContext = createContext<DeviceContextType>({
isInstalled: false,
isInstallable: false,
promptToInstall: () => {return},
beforeInstallPromptEvent: null,
})

const DeviceProvider: FC<PropsWithChildren> = ({ children }) => {
const [prompt, promptToInstall] = useAddToHomescreenPrompt()
const [isInstalled] = useState(isDisplayMode('standalone'))
const [isInstallable, setInstallableState] = useState(false)

React.useEffect(
() => {
if (prompt) {
setInstallableState(true)
}
},
[prompt]
)

return <DeviceContext.Provider value={{ isInstalled, isInstallable, promptToInstall }}>{children}</DeviceContext.Provider>
const [beforeInstallPromptEvent, setBeforeInstallPromptEventState] = useState<IBeforeInstallPromptEvent | null>(null)
const [isInstalled, setInstalledState] = useState(isDisplayMode('standalone'))

React.useEffect(() => {
const ready = (e: IBeforeInstallPromptEvent) => {
e.preventDefault()
setBeforeInstallPromptEventState(e)
}
const installed = () => setInstalledState(true)
window.addEventListener('beforeinstallprompt', ready as any)
window.addEventListener('appinstalled', installed)
return () => {
window.removeEventListener('beforeinstallprompt', ready as any)
window.removeEventListener('appinstalled', installed)
}
}, [])

return <DeviceContext.Provider value={{ isInstalled, beforeInstallPromptEvent }}>{children}</DeviceContext.Provider>
}

export { DeviceProvider }
Expand Down
1 change: 0 additions & 1 deletion ui/src/hooks/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
export * from './useAddToHomeScreenPrompt'
export * from './useApi'
export * from './useConfirmModal'
export * from './useDeviceSubcriptionStatus'
Expand Down
45 changes: 0 additions & 45 deletions ui/src/hooks/useAddToHomeScreenPrompt.ts

This file was deleted.

16 changes: 11 additions & 5 deletions ui/src/settings/preferences/InstallationBox.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,21 +30,27 @@ const Installed = () => (

const Uninstallable = () => (
<p>
Oh! readflow can&apos;t be installed on this device.
Sadness! readflow can&apos;t be installed on this device from here.
<br />
Maybe your device device configuration does not allow it. Sad.
Maybe your device&apos;s browser allows you to do this, but only by using the built-in application menu.
</p>
)

const InstallationBox = () => {
const {isInstalled, isInstallable, promptToInstall} = useDevice()
const { isInstalled, beforeInstallPromptEvent } = useDevice()

const install = React.useCallback(() => {
if (beforeInstallPromptEvent) {
beforeInstallPromptEvent.prompt()
}
}, [beforeInstallPromptEvent])

return (
<Box title="Installation">
{(() => {
switch (true) {
case !isInstalled && isInstallable:
return <Install onClick={promptToInstall} />
case !isInstalled && beforeInstallPromptEvent != null:
return <Install onClick={install} />
case isInstalled:
return <Installed />
default:
Expand Down

0 comments on commit 46efdf4

Please sign in to comment.