Skip to content

Commit 4759497

Browse files
committed
Add update screens
1 parent b32e165 commit 4759497

File tree

13 files changed

+290
-81
lines changed

13 files changed

+290
-81
lines changed

App.tsx

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ import Test from '@screens/Test'
2727
import RandomColor from '@screens/Try/RandomColor'
2828
import RandomPassword from '@screens/Try/RandomPassword'
2929
import YourAge from '@screens/Try/YourAge'
30-
import Update from '@screens/Update/Update'
30+
import ForceUpdate, { type ForceUpdateParamList } from '@screens/Update/ForceUpdate'
31+
import Update, { type UpdateParamList } from '@screens/Update/Update'
3132
import type { ConfirmCityParamList } from '@screens/Weather/ConfirmCity'
3233
import ConfirmCity from '@screens/Weather/ConfirmCity'
3334
import WeatherScreen from '@screens/Weather/Main/Weather'
@@ -140,7 +141,8 @@ export type RootStackParamList = {
140141
AppLock: undefined
141142
RandomPassword: undefined
142143
GlobalSearch: undefined
143-
Update: undefined
144+
Update: UpdateParamList
145+
ForceUpdate: ForceUpdateParamList
144146
}
145147

146148
const Stack = createStackNavigator<RootStackParamList>()
@@ -215,6 +217,7 @@ function Navigation() {
215217
<Stack.Screen name='RandomPassword' component={RandomPassword} options={GestureEnabled} />
216218
<Stack.Screen name='GlobalSearch' component={GlobalSearch} options={IOS_BOTTOM_STYLE} />
217219
<Stack.Screen name='Update' component={Update} options={IOS_BOTTOM_STYLE} />
220+
<Stack.Screen name='ForceUpdate' component={ForceUpdate} />
218221
</Stack.Navigator>
219222
</>
220223
)

src/assets/icons/icons.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,3 +125,6 @@ export { default as HumiditySolidIcon } from '@icons/humidity-solid-rounded.svg'
125125

126126
export { default as EyeSolidIcon } from '@icons/eye-solid-rounded.svg'
127127
export { default as NaturalFoodSolidIcon } from '@icons/natural-food-solid-rounded.svg'
128+
export { default as AndroidSolidIcon } from '@icons/android-solid-rounded.svg'
129+
130+
export { default as GithubSolidIcon } from '@icons/github-solid-rounded.svg'
Lines changed: 9 additions & 0 deletions
Loading
Lines changed: 4 additions & 0 deletions
Loading

src/components/BackHeader.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ type BackHeaderProps = ViewProps & {
1111
title?: string
1212
Title?: React.ReactNode
1313
Right?: React.ReactNode
14+
onBackPress?: () => void
1415
}
1516

16-
export default function BackHeader({ navigation, Right, title, Title }: BackHeaderProps) {
17+
export default function BackHeader({ navigation, Right, title, Title, onBackPress }: BackHeaderProps) {
1718
const scheme = useColorScheme()
1819
return (
1920
<View className='bg-white px-5 pb-0.5 pl-1 pr-6 dark:bg-zinc-950'>
@@ -23,7 +24,7 @@ export default function BackHeader({ navigation, Right, title, Title }: BackHead
2324
<View className='flex-row items-center' style={{ gap: 10 }}>
2425
<TouchableOpacity
2526
className='p-3 pr-0.5'
26-
onPress={() => navigation && navigation.goBack()}
27+
onPress={() => (onBackPress ? onBackPress() : navigation && navigation.goBack())}
2728
activeOpacity={0.7}
2829
>
2930
<ArrowLeft01Icon width={26} height={26} color={scheme === 'dark' ? Colors.zinc[200] : Colors.zinc[800]} />
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
import { SemiBold } from '@utils/fonts'
2+
import React from 'react'
3+
import { View } from 'react-native'
4+
5+
export default function RoundNotification({ n }: { n: number }) {
6+
if (n === 0) return null
7+
return (
8+
<View className='items-center justify-center rounded-full bg-red-500' style={{ height: 22, width: 22 }}>
9+
<SemiBold className='text-xs text-white' style={{ paddingTop: 2 }} numberOfLines={1}>
10+
{n}
11+
</SemiBold>
12+
</View>
13+
)
14+
}

src/screens/Home/HomeScreen.tsx

Lines changed: 42 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -4,14 +4,55 @@ import { useNavigation } from '@react-navigation/native'
44
import WeatherWidget from '@screens/Weather/Widget/WeatherWidget'
55
import { Medium, PoppinsMedium, PoppinsSemiBold } from '@utils/fonts'
66
import type { StackNav } from '@utils/types'
7-
import React, { useMemo } from 'react'
7+
import React, { useEffect, useMemo } from 'react'
88
import { Alert, Dimensions, Text, TouchableOpacity, View } from 'react-native'
99
import { ScrollView } from 'react-native-gesture-handler'
1010
import styles, { hw as height_weight } from './style'
1111
import Search from '@components/Search'
1212

1313
const { width } = Dimensions.get('window')
1414

15+
export default function HomeScreen({ navigation }: { navigation: StackNav }) {
16+
useEffect(() => {
17+
setTimeout(() => {
18+
navigation.navigate('Update', {
19+
version: '1.0.0',
20+
size: '10MB',
21+
whatsNew: ['New Features', 'Bug Fixes'],
22+
})
23+
}, 1000)
24+
}, [navigation])
25+
26+
return (
27+
<>
28+
<View className='bg-zinc-50 px-5 pt-1 dark:bg-black'>
29+
<PaddingTop />
30+
</View>
31+
<ScrollView className='flex-1 bg-zinc-50 dark:bg-black' showsVerticalScrollIndicator={false}>
32+
<View style={{ gap: 10 }} className='pb-10'>
33+
<View className=''>
34+
<TopArea />
35+
<View className='px-5 pt-1'>
36+
<Search
37+
onPress={() => {
38+
navigation.navigate('GlobalSearch')
39+
}}
40+
// editable={false}
41+
selectTextOnFocus={false}
42+
contextMenuHidden
43+
placeholder='Search for anything...'
44+
/>
45+
</View>
46+
</View>
47+
<Elements />
48+
<Shortcuts />
49+
<Graph />
50+
</View>
51+
<PaddingBottom />
52+
</ScrollView>
53+
</>
54+
)
55+
}
1556
function Elements() {
1657
const navigation = useNavigation<StackNav>()
1758

@@ -93,35 +134,3 @@ function Graph() {
93134
</View>
94135
)
95136
}
96-
97-
export default function HomeScreen({ navigation }: { navigation: StackNav }) {
98-
return (
99-
<>
100-
<View className='bg-zinc-50 px-5 pt-1 dark:bg-black'>
101-
<PaddingTop />
102-
</View>
103-
<ScrollView className='flex-1 bg-zinc-50 dark:bg-black' showsVerticalScrollIndicator={false}>
104-
<View style={{ gap: 10 }} className='pb-10'>
105-
<View className=''>
106-
<TopArea />
107-
<View className='px-5 pt-1'>
108-
<Search
109-
onPress={() => {
110-
navigation.navigate('GlobalSearch')
111-
}}
112-
// editable={false}
113-
selectTextOnFocus={false}
114-
contextMenuHidden
115-
placeholder='Search for anything...'
116-
/>
117-
</View>
118-
</View>
119-
<Elements />
120-
<Shortcuts />
121-
<Graph />
122-
</View>
123-
<PaddingBottom />
124-
</ScrollView>
125-
</>
126-
)
127-
}

src/screens/Settings/Settings.tsx

Lines changed: 23 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {
2121
} from '@assets/icons/icons'
2222
import { Gap12, Gap20 } from '@components/Gap'
2323
import RoundedIcon from '@components/RoundedIcon'
24+
import RoundNotification from '@components/RoundNotification'
2425
import { PaddingBottom, PaddingTop } from '@components/SafePadding'
2526
import Search from '@components/Search'
2627
import { SettGroup, SettOption, SettText } from '@components/Settings'
@@ -90,22 +91,34 @@ export default function Settings({ navigation }: NavProp) {
9091
Go to each section to customize your experience. All settings are saved automatically.
9192
</SettText>
9293
<SettGroup title='General'>
94+
{/* <SettOption
95+
title='App Update'
96+
Icon={<RoundedIcon Icon={Setting07SolidIcon} className='bg-slate-500' />}
97+
arrow
98+
Right={<RoundNotification n={4} />}
99+
onPress={() =>
100+
navigation.navigate('Update', {
101+
version: '2.7.3',
102+
size: '10MB',
103+
whatsNew: ['New features', 'Bug fixes', 'Performance improvements'],
104+
})
105+
}
106+
/> */}
93107
<SettOption
94108
title='App Update'
95109
Icon={<RoundedIcon Icon={Setting07SolidIcon} className='bg-slate-500' />}
96110
arrow
97-
Right={
98-
<View
99-
className='items-center justify-center rounded-full bg-red-500'
100-
style={{ height: 22, width: 22 }}
101-
>
102-
<SemiBold className='text-xs text-white' style={{ paddingTop: 2 }}>
103-
1
104-
</SemiBold>
105-
</View>
111+
Right={<RoundNotification n={1} />}
112+
onPress={() =>
113+
navigation.navigate('ForceUpdate', {
114+
shouldGoBack: true,
115+
version: '2.7.3',
116+
size: '10MB',
117+
whatsNew: ['New features', 'Bug fixes', 'Performance improvements'],
118+
})
106119
}
107-
onPress={() => navigation.navigate('Update')}
108120
/>
121+
109122
<SettOption
110123
title='Your Profile'
111124
Icon={<RoundedIcon Icon={UserSolidIcon} className='bg-green-500' />}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import { Medium, Regular, SemiBold } from '@utils/fonts'
2+
import React from 'react'
3+
import { View } from 'react-native'
4+
import AppIcon from '@assets/icons/icon.svg'
5+
6+
export default function UpdateAvailableUI({
7+
version,
8+
size,
9+
whatsNew,
10+
}: {
11+
version: string
12+
size: string
13+
whatsNew: Array<string>
14+
}) {
15+
return (
16+
<View className='flex-1 rounded-3xl bg-appIconBg p-8 pb-12'>
17+
<AppIcon width={80} height={80} className='mt-8' />
18+
<SemiBold style={{ fontSize: 24 }} className='mt-5 text-white'>
19+
Update Available
20+
</SemiBold>
21+
<Medium style={{ fontSize: 15 }} className='mt-1 text-white opacity-80'>
22+
{`v${version}`}{size && `${size}`}
23+
</Medium>
24+
<Regular className='mt-5 text-white opacity-80' style={{ fontSize: 11 }}>
25+
We bring you the latest features and improvements. Update now to enjoy the best experience.
26+
</Regular>
27+
<Regular className='mt-5 text-white opacity-80' style={{ fontSize: 11 }}>
28+
Download size may vary. The Download Update button will redirect you to the GitHub and you can download the
29+
latest.
30+
</Regular>
31+
<View className='mt-5' style={{ gap: 5 }}>
32+
{whatsNew.map((item, index) => (
33+
<Regular key={index} className='text-white opacity-80' style={{ fontSize: 11 }}>
34+
{' '}
35+
{item}
36+
</Regular>
37+
))}
38+
</View>
39+
</View>
40+
)
41+
}

src/screens/Update/ForceUpdate.tsx

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import { AndroidSolidIcon, CodeSolidIcon, GithubSolidIcon } from '@assets/icons/icons'
2+
import BackHeader from '@components/BackHeader'
3+
import Btn from '@components/Button'
4+
import { Gap12 } from '@components/Gap'
5+
import RoundedIcon from '@components/RoundedIcon'
6+
import { SettGroup, SettOption, SettText, SettWrapper } from '@components/Settings'
7+
import type { RouteProp } from '@react-navigation/native'
8+
import { GITHUB_LATEST_RELEASE, GITHUB_REPO, LATEST_APK_FILE } from '@utils/constants'
9+
import type { StackNav } from '@utils/types'
10+
import React, { useEffect } from 'react'
11+
import { BackHandler, Linking, ToastAndroid, View } from 'react-native'
12+
import UpdateAvailableUI from './Components/UpdateAvailableUI'
13+
14+
type ParamList = {
15+
ForceUpdate: ForceUpdateParamList
16+
}
17+
18+
export type ForceUpdateParamList = {
19+
shouldGoBack: boolean
20+
version: string
21+
size: string
22+
whatsNew: Array<string>
23+
}
24+
25+
export default function ForceUpdate({
26+
navigation,
27+
route,
28+
}: {
29+
navigation: StackNav
30+
route: RouteProp<ParamList, 'ForceUpdate'>
31+
}) {
32+
const shouldGoBack = route.params?.shouldGoBack
33+
const version = route.params.version
34+
const size = route.params.size
35+
const whatsNew = route.params.whatsNew
36+
// Disable Back button
37+
useEffect(() => {
38+
const backHandler = BackHandler.addEventListener('hardwareBackPress', () => {
39+
if (shouldGoBack === undefined || shouldGoBack) {
40+
navigation.goBack()
41+
return true
42+
}
43+
ToastAndroid.show('You cannot skip this update', ToastAndroid.SHORT)
44+
return true
45+
})
46+
return () => backHandler.remove()
47+
}, [navigation, shouldGoBack])
48+
49+
return (
50+
<SettWrapper
51+
navigation={navigation}
52+
title='App Update'
53+
Header={
54+
<BackHeader
55+
title='App Update'
56+
navigation={navigation}
57+
onBackPress={() => {
58+
if (shouldGoBack === undefined || shouldGoBack) {
59+
navigation.goBack()
60+
return
61+
}
62+
ToastAndroid.show('You cannot skip this update', ToastAndroid.SHORT)
63+
}}
64+
/>
65+
}
66+
>
67+
<Gap12>
68+
<View className='mt-5 flex-1 px-5'>
69+
<UpdateAvailableUI version={version} size={size} whatsNew={whatsNew} />
70+
</View>
71+
<View className='mt-2 px-10'>
72+
<Btn title='Download Update' onPress={() => Linking.openURL(LATEST_APK_FILE)} />
73+
</View>
74+
<SettGroup title='Download Options' className='mt-3'>
75+
<SettOption
76+
title='Download From Github'
77+
Icon={<RoundedIcon Icon={GithubSolidIcon} className='bg-black' />}
78+
arrow
79+
onPress={() => Linking.openURL(GITHUB_LATEST_RELEASE)}
80+
/>
81+
<SettOption
82+
title='Source on Github'
83+
Icon={<RoundedIcon Icon={CodeSolidIcon} className='bg-accent' />}
84+
onPress={() => Linking.openURL(GITHUB_REPO)}
85+
arrow
86+
/>
87+
<SettOption
88+
title='Download APK'
89+
Icon={<RoundedIcon Icon={AndroidSolidIcon} className='bg-green-500' />}
90+
arrow
91+
onPress={() => Linking.openURL(LATEST_APK_FILE)}
92+
/>
93+
</SettGroup>
94+
<SettText>
95+
Download size may vary. The Download Now button will redirect you to the GitHub and you can download the
96+
latest.
97+
</SettText>
98+
</Gap12>
99+
</SettWrapper>
100+
)
101+
}

0 commit comments

Comments
 (0)