Skip to content

Commit c0c4822

Browse files
Merge pull request #57 from binarapps/forcing-update
Forcing user to update app
2 parents 397efdb + 2ac17ae commit c0c4822

10 files changed

Lines changed: 1174 additions & 241 deletions

File tree

scripts/data/swagger-spec.json

Lines changed: 1049 additions & 219 deletions
Large diffs are not rendered by default.

src/api/query/system/system.msw.ts

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,17 +6,38 @@
66
* API documentation for the starter-kit project in NestJS by BinarApps. The API allows management of users, sessions and offers various functions for logged in users. Contains examples of authentication, authorization, and CRUD for selected resources.
77
* OpenAPI spec version: 1.0
88
*/
9+
import { faker } from '@faker-js/faker'
910
import { HttpResponse, delay, http } from 'msw'
1011

11-
export const getSystemControllerCheckForAppUpdateMockHandler = () => {
12+
import type { AppVersionStatusEntity } from '../../types'
13+
14+
export const getSystemControllerCheckForAppUpdateResponseMock = (
15+
overrideResponse: any = {}
16+
): AppVersionStatusEntity => ({
17+
appId: faker.word.sample(),
18+
currentVersionReleaseDate: `${faker.date.past().toISOString().split('.')[0]}Z`,
19+
latestVersion: faker.word.sample(),
20+
minimumVersion: faker.word.sample(),
21+
updateRequired: faker.datatype.boolean(),
22+
...overrideResponse,
23+
})
24+
25+
export const getSystemControllerCheckForAppUpdateMockHandler = (
26+
overrideResponse?: AppVersionStatusEntity
27+
) => {
1228
return http.post('*/api/v1/system/app-updates/check', async () => {
1329
await delay(1000)
14-
return new HttpResponse(null, {
15-
status: 200,
16-
headers: {
17-
'Content-Type': 'application/json',
18-
},
19-
})
30+
return new HttpResponse(
31+
JSON.stringify(
32+
overrideResponse ? overrideResponse : getSystemControllerCheckForAppUpdateResponseMock()
33+
),
34+
{
35+
status: 200,
36+
headers: {
37+
'Content-Type': 'application/json',
38+
},
39+
}
40+
)
2041
})
2142
}
2243
export const getSystemMock = () => [getSystemControllerCheckForAppUpdateMockHandler()]

src/api/query/system/system.ts

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,21 @@ import type { MutationFunction, UseMutationOptions } from '@tanstack/react-query
1111

1212
import { customInstance } from '../../axios/custom-instance'
1313
import type { ErrorType, BodyType } from '../../axios/custom-instance'
14-
import type { CheckUpdateDto } from '../../types'
14+
import type {
15+
AppVersionStatusEntity,
16+
CheckUpdateDto,
17+
ErrorServerEntity,
18+
ErrorTooManyRequestsEntity,
19+
ErrorValidationEntity,
20+
} from '../../types'
1521

1622
type SecondParameter<T extends (...args: any) => any> = Parameters<T>[1]
1723

1824
export const systemControllerCheckForAppUpdate = (
1925
checkUpdateDto: BodyType<CheckUpdateDto>,
2026
options?: SecondParameter<typeof customInstance>
2127
) => {
22-
return customInstance<void>(
28+
return customInstance<AppVersionStatusEntity>(
2329
{
2430
url: `/api/v1/system/app-updates/check`,
2531
method: 'POST',
@@ -31,7 +37,7 @@ export const systemControllerCheckForAppUpdate = (
3137
}
3238

3339
export const getSystemControllerCheckForAppUpdateMutationOptions = <
34-
TError = ErrorType<unknown>,
40+
TError = ErrorType<void | ErrorValidationEntity | ErrorTooManyRequestsEntity | ErrorServerEntity>,
3541
TContext = unknown
3642
>(options?: {
3743
mutation?: UseMutationOptions<
@@ -65,10 +71,12 @@ export type SystemControllerCheckForAppUpdateMutationResult = NonNullable<
6571
Awaited<ReturnType<typeof systemControllerCheckForAppUpdate>>
6672
>
6773
export type SystemControllerCheckForAppUpdateMutationBody = BodyType<CheckUpdateDto>
68-
export type SystemControllerCheckForAppUpdateMutationError = ErrorType<unknown>
74+
export type SystemControllerCheckForAppUpdateMutationError = ErrorType<
75+
void | ErrorValidationEntity | ErrorTooManyRequestsEntity | ErrorServerEntity
76+
>
6977

7078
export const useSystemControllerCheckForAppUpdate = <
71-
TError = ErrorType<unknown>,
79+
TError = ErrorType<void | ErrorValidationEntity | ErrorTooManyRequestsEntity | ErrorServerEntity>,
7280
TContext = unknown
7381
>(options?: {
7482
mutation?: UseMutationOptions<
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
/* eslint-disable @typescript-eslint/no-explicit-any */
2+
/**
3+
* Generated by orval 🍺
4+
* Do not edit manually.
5+
* API
6+
* API documentation for the starter-kit project in NestJS by BinarApps. The API allows management of users, sessions and offers various functions for logged in users. Contains examples of authentication, authorization, and CRUD for selected resources.
7+
* OpenAPI spec version: 1.0
8+
*/
9+
10+
export interface AppVersionStatusEntity {
11+
/** AppId of application in AppStore(AppStore Bundle ID) or PlayStore(Google Play Store app ID) */
12+
appId: string
13+
/** The current version of the app. */
14+
currentVersionReleaseDate: string
15+
/** The latest version of the app available in the app store. */
16+
latestVersion: string
17+
/** The minimum version of the app that still functions correctly without mandatory updates. */
18+
minimumVersion: string
19+
/** Indicates whether an update is required to continue using the app. */
20+
updateRequired: boolean
21+
}

src/api/types/index.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
* OpenAPI spec version: 1.0
88
*/
99

10+
export * from './appVersionStatusEntity'
1011
export * from './articleEntity'
1112
export * from './articlesControllerFindAllParams'
1213
export * from './articlesControllerFindDraftsParams'

src/components/AppLoading.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { Loader, Center } from '@baca/design-system/components'
22
import { useCachedResources, useNavigationTheme } from '@baca/hooks'
3+
import { useCheckForAppUpdate } from '@baca/hooks/useCheckForAppUpdate'
34
import { isSignedInAtom } from '@baca/store/auth'
45
import * as SplashScreen from 'expo-splash-screen'
56
import { useAtomValue } from 'jotai'
@@ -11,19 +12,18 @@ SplashScreen.preventAutoHideAsync()
1112

1213
export const AppLoading: FC<PropsWithChildren> = ({ children }) => {
1314
const { navigationTheme } = useNavigationTheme()
14-
1515
const isLoadingComplete = useCachedResources()
16-
1716
const isSignedIn = useAtomValue(isSignedInAtom)
18-
const [isLayoutReady, setIsLayoutReady] = useState<boolean>(false)
1917

18+
const [isLayoutReady, setIsLayoutReady] = useState<boolean>(false)
2019
const [isSplashHidden, setIsSplashHidden] = useState<boolean>(false)
20+
const isUpdateLoading = useCheckForAppUpdate()
2121

2222
const onLayout = useCallback(() => {
2323
setIsLayoutReady(true)
2424
}, [])
2525

26-
const isLoading = !isLoadingComplete || isSignedIn === null || !isLayoutReady
26+
const isLoading = !isLoadingComplete || isSignedIn === null || !isLayoutReady || isUpdateLoading
2727

2828
useEffect(() => {
2929
const hideSplashScreen = () => {

src/constants/links.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
export const APP_STORE_URL = `https://apps.apple.com/app/id`
2+
export const PLAY_STORE_URL = `https://play.google.com/store/apps/details?id=`

src/hooks/useCheckForAppUpdate.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import { useSystemControllerCheckForAppUpdate } from '@baca/api/query/system/system'
2+
import { APP_STORE_URL, PLAY_STORE_URL } from '@baca/constants/links'
3+
import { useTranslation } from '@baca/hooks'
4+
import * as Application from 'expo-application'
5+
import { useEffect, useState } from 'react'
6+
import { Platform, Alert, Linking } from 'react-native'
7+
8+
const currentVersion = Application.nativeApplicationVersion || 'unknown'
9+
const { OS } = Platform
10+
11+
export const useCheckForAppUpdate = () => {
12+
const { t } = useTranslation()
13+
const [isUpdateLoading, setIsUpdateLoading] = useState<boolean>(true)
14+
15+
const { mutate: checkForUpdate } = useSystemControllerCheckForAppUpdate()
16+
17+
useEffect(() => {
18+
if (OS === 'ios' || OS === 'android') {
19+
checkForUpdate(
20+
{
21+
data: {
22+
currentVersion,
23+
os: OS,
24+
},
25+
},
26+
{
27+
onSuccess: ({ updateRequired, appId }) => {
28+
if (updateRequired) {
29+
const storeUrl =
30+
OS === 'ios' ? `${APP_STORE_URL}${appId}` : `${PLAY_STORE_URL}${appId}`
31+
Alert.alert(t('update.alert_title'), t('update.alert_message'), [
32+
{ text: t('update.update_now'), onPress: () => Linking.openURL(storeUrl) },
33+
])
34+
}
35+
},
36+
onError: (error) => {
37+
console.error('Error checking for updates:', error)
38+
// CONFIG: Add log to your analytics service, for example - sentry o crashlytics
39+
},
40+
onSettled: () => {
41+
setIsUpdateLoading(false)
42+
},
43+
}
44+
)
45+
} else {
46+
setIsUpdateLoading(false)
47+
}
48+
}, [checkForUpdate, t])
49+
50+
return isUpdateLoading
51+
}

src/i18n/translations/en.json

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -116,9 +116,9 @@
116116
"update": {
117117
"alert_message": "You will have to restart the application to have better experiences while using it",
118118
"alert_title": "New version available",
119-
"restart": "Restart"
119+
"restart": "Restart",
120+
"update_now": "Update now"
120121
},
121-
122122
"application_info_screen": {
123123
"navigation_info": "When you will try to go back it will double ask if you really want to leave \n"
124124
},
@@ -143,7 +143,6 @@
143143
"tertiary_gray": "Button tertiary gray",
144144
"with_icons": "Button with icons"
145145
},
146-
147146
"loader_variants": {
148147
"bricks": "Bricks loader",
149148
"bubbles": "Bubbles loader",

src/i18n/translations/pl.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -114,11 +114,11 @@
114114
"warning": {}
115115
},
116116
"update": {
117-
"alert_message": "Będziesz musiał zrestartować aplikację, żeby mieć lepsze doświadczenia podczas jej używania",
117+
"alert_message": "Musisz zrestartować aplikację, żeby mieć lepsze doświadczenia podczas jej używania",
118118
"alert_title": "Aktualizacja",
119-
"restart": "Zrestartuj"
119+
"restart": "Zrestartuj",
120+
"update_now": "Aktualizuj teraz"
120121
},
121-
122122
"application_info_screen": {
123123
"navigation_info": "Kiedy będziesz próbował cofnąć to zostaniesz podwójnie zapytany, czy na pewno tego chcesz \n"
124124
},

0 commit comments

Comments
 (0)