Skip to content

Commit

Permalink
Add Android update wall
Browse files Browse the repository at this point in the history
  • Loading branch information
lubej committed May 21, 2024
1 parent 07306d4 commit d9d73ed
Show file tree
Hide file tree
Showing 9 changed files with 140 additions and 24 deletions.
21 changes: 0 additions & 21 deletions src/app/components/Ionic/IonicProvider.tsx

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import { FC, PropsWithChildren } from 'react'
import { Capacitor } from '@capacitor/core'
import { IonicContextProvider } from '../../providers/IonicProvider'
import { RequiresUpdate } from '../RequiresUpdate'

export const IonicNativePlatformProvider: FC<PropsWithChildren> = ({ children }) => {
if (Capacitor.isNativePlatform()) {
return <IonicContextProvider>

Check warning on line 8 in src/app/components/Ionic/components/IonicNativePlatformProvider/index.tsx

View workflow job for this annotation

GitHub Actions / lint

Insert `(⏎······`
<RequiresUpdate>

Check warning on line 9 in src/app/components/Ionic/components/IonicNativePlatformProvider/index.tsx

View workflow job for this annotation

GitHub Actions / lint

Replace `<RequiresUpdate>⏎········{children}⏎······` with `··<RequiresUpdate>{children}`
{children}
</RequiresUpdate>
</IonicContextProvider>

Check warning on line 12 in src/app/components/Ionic/components/IonicNativePlatformProvider/index.tsx

View workflow job for this annotation

GitHub Actions / lint

Replace `</IonicContextProvider>` with `··</IonicContextProvider>⏎····)`
}

return children
}
29 changes: 29 additions & 0 deletions src/app/components/Ionic/components/RequiresUpdate/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React, { FC, PropsWithChildren, useContext } from 'react'
import { IonicContext } from '../../providers/IonicContext'
import { Box } from 'grommet/es6/components/Box'
import { Button } from 'grommet/es6/components/Button'
import { navigateToAppStore } from '../../utils/capacitor-app-update'

export const RequiresUpdate: FC<PropsWithChildren> = ({ children }) => {
const { state: { requiresUpdate } } = useContext(IonicContext)

Check warning on line 8 in src/app/components/Ionic/components/RequiresUpdate/index.tsx

View workflow job for this annotation

GitHub Actions / lint

Replace `·state:·{·requiresUpdate·}` with `⏎····state:·{·requiresUpdate·},⏎·`

if (requiresUpdate === false) return children

const handleNavigateToAppStore = () => {
navigateToAppStore()
}

return (
<Box direction="row-responsive" background="background-back" fill style={{ minHeight: '100dvh' }}>
{requiresUpdate === undefined && <>Loading...</>}

Check failure on line 18 in src/app/components/Ionic/components/RequiresUpdate/index.tsx

View workflow job for this annotation

GitHub Actions / lint

Conditional plain text nodes could break React if used with Google Translate. Wrap text into an element
{requiresUpdate === true && <>

Check warning on line 19 in src/app/components/Ionic/components/RequiresUpdate/index.tsx

View workflow job for this annotation

GitHub Actions / lint

Insert `(⏎········`

Check failure on line 19 in src/app/components/Ionic/components/RequiresUpdate/index.tsx

View workflow job for this annotation

GitHub Actions / lint

Conditional plain text nodes could break React if used with Google Translate. Wrap text into an element
This app requires an update to the latest version in order to operate correctly.

Check warning on line 20 in src/app/components/Ionic/components/RequiresUpdate/index.tsx

View workflow job for this annotation

GitHub Actions / lint

Insert `··`
<Button

Check warning on line 21 in src/app/components/Ionic/components/RequiresUpdate/index.tsx

View workflow job for this annotation

GitHub Actions / lint

Replace `<Button⏎··········fill="horizontal"⏎··········label="Update·application"⏎··········onClick={handleNavigateToAppStore}` with `··<Button·fill="horizontal"·label="Update·application"·onClick={handleNavigateToAppStore}·/>`
fill="horizontal"
label="Update application"
onClick={handleNavigateToAppStore}
/>

Check warning on line 25 in src/app/components/Ionic/components/RequiresUpdate/index.tsx

View workflow job for this annotation

GitHub Actions / lint

Insert `<`
</>}

Check warning on line 26 in src/app/components/Ionic/components/RequiresUpdate/index.tsx

View workflow job for this annotation

GitHub Actions / lint

Replace `</>` with `)`
</Box>
)
}
23 changes: 23 additions & 0 deletions src/app/components/Ionic/hooks/useIonicRequiresUpdate.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { useEffect } from 'react'
import { IonicProviderState } from '../providers/IonicContext'
import { updateAvailable } from '../utils/capacitor-app-update'

export const useIonicRequiresUpdate = (setState: (state: IonicProviderState) => void) => {
useEffect(() => {
let inProgress = true

const init = async () => {
const requiresUpdate = await updateAvailable()

if (inProgress) {
setState({ requiresUpdate })
}
}

init()

return () => {
inProgress = false
}
}, [])

Check warning on line 22 in src/app/components/Ionic/hooks/useIonicRequiresUpdate.ts

View workflow job for this annotation

GitHub Actions / lint

React Hook useEffect has a missing dependency: 'setState'. Either include it or remove the dependency array. If 'setState' changes too often, find the parent component that defines it and wrap that definition in useCallback
}
17 changes: 17 additions & 0 deletions src/app/components/Ionic/providers/IonicContext.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
import { createContext } from 'react'

export interface IonicProviderState {
/**
* Indicates whether an update is required.
* In an undefined state, it indicates that the application is currently in loading phase.
*
* @type {boolean | undefined}
*/
requiresUpdate: boolean | undefined
}

export interface IonicProviderContext {
readonly state: IonicProviderState
}

export const IonicContext = createContext<IonicProviderContext>({} as IonicProviderContext)
23 changes: 23 additions & 0 deletions src/app/components/Ionic/providers/IonicProvider.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
import { FC, PropsWithChildren, useState } from 'react'
import { useIonicBackButtonListener } from '../hooks/useIonicBackButtonListener'
import { useIonicAppStateChangeListener } from '../hooks/useIonicAppStateChangeListener'
import { IonicContext, IonicProviderContext, IonicProviderState } from './IonicContext'
import { useIonicRequiresUpdate } from '../hooks/useIonicRequiresUpdate'

const ionicProviderInitialState: IonicProviderState = {
requiresUpdate: undefined,
}

export const IonicContextProvider: FC<PropsWithChildren> = ({ children }) => {
const [state, setState] = useState<IonicProviderState>({ ...ionicProviderInitialState })

useIonicRequiresUpdate(setState)
useIonicAppStateChangeListener()
useIonicBackButtonListener()

const providerState: IonicProviderContext = {
state,
}

return <IonicContext.Provider value={providerState}>{children}</IonicContext.Provider>
}
29 changes: 29 additions & 0 deletions src/app/components/Ionic/utils/capacitor-app-update.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { AppUpdate, AppUpdateAvailability } from '@capawesome/capacitor-app-update'
import { Capacitor } from '@capacitor/core'

export const updateAvailable = async () => {
const result = await AppUpdate.getAppUpdateInfo()
const { updateAvailability, currentVersionCode, availableVersionCode } = result

if (updateAvailability === AppUpdateAvailability.UPDATE_IN_PROGRESS) {
return undefined
}

// TODO: Skips in case there is no internet connection
if (updateAvailability !== AppUpdateAvailability.UPDATE_AVAILABLE) {
return false
}

if (Capacitor.getPlatform() === 'android') {
// Example of version code -> "1", "2", ...
return parseInt(availableVersionCode ?? `${Number.MAX_SAFE_INTEGER}`, 10) > parseInt(currentVersionCode ?? '0', 10)
}

// TODO: Add for iOS
// Compare semVer between currentVersionName and availableVersionName
throw new Error('Unknown Capacitor platform!')
}

export const navigateToAppStore = async () => {
await AppUpdate.openAppStore()
}
6 changes: 3 additions & 3 deletions src/app/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import { useRouteRedirects } from './useRouteRedirects'
import { PersistLoadingGate } from 'app/components/Persist/PersistLoadingGate'
import { UnlockGate } from 'app/components/Persist/UnlockGate'
import { BuildBanner } from 'app/components/BuildBanner'
import { IonicProvider } from './components/Ionic/IonicProvider'
import { IonicNativePlatformProvider } from './components/Ionic/components/IonicNativePlatformProvider'

export function App() {
useRouteRedirects()
Expand All @@ -31,7 +31,7 @@ export function App() {

return (
<FatalErrorHandler>
<IonicProvider>
<IonicNativePlatformProvider>
<ModalProvider>
<Helmet
titleTemplate="%s - ROSE Wallet"
Expand All @@ -57,7 +57,7 @@ export function App() {
</PersistLoadingGate>
</Box>
</ModalProvider>
</IonicProvider>
</IonicNativePlatformProvider>
</FatalErrorHandler>
)
}

0 comments on commit d9d73ed

Please sign in to comment.