diff --git a/src/components/AddressCard.tsx b/src/components/AddressCard.tsx
index 2e8ec621..686522e5 100644
--- a/src/components/AddressCard.tsx
+++ b/src/components/AddressCard.tsx
@@ -18,8 +18,9 @@ along with the library. If not, see .
import { calculateAmountWorth } from '@alephium/sdk'
import { colord } from 'colord'
+import { LinearGradient } from 'expo-linear-gradient'
import { Copy, SettingsIcon } from 'lucide-react-native'
-import { StyleProp, View, ViewStyle } from 'react-native'
+import { StyleProp, ViewStyle } from 'react-native'
import styled, { useTheme } from 'styled-components/native'
import AddressBadge from '~/components/AddressBadge'
@@ -60,7 +61,7 @@ const AddressCard = ({ style, addressHash }: AddressCardProps) => {
const textColor = themes[textColorTheme].font.primary
return (
-
+
{
Group {address.group}
-
+
)
}
diff --git a/src/components/AppText.tsx b/src/components/AppText.tsx
index 88e3e61b..5ebebf3d 100644
--- a/src/components/AppText.tsx
+++ b/src/components/AppText.tsx
@@ -27,7 +27,7 @@ export type AppTextProps = {
bold?: boolean
semiBold?: boolean
medium?: boolean
- color?: FontColor | GlobalColor
+ color?: FontColor | GlobalColor | string
colorTheme?: ThemeType
size?: number
}
@@ -36,7 +36,7 @@ export default styled.Text`
color: ${({ color, theme, colorTheme }) => {
const th = colorTheme ? themes[colorTheme] : theme
- return color ? th.font[color as FontColor] || th.global[color as GlobalColor] : th.font.primary
+ return color ? th.font[color as FontColor] || th.global[color as GlobalColor] || color : th.font.primary
}};
${({ bold }) =>
diff --git a/src/components/ConfirmWithAuthModal.tsx b/src/components/ConfirmWithAuthModal.tsx
index 023fdb92..7820de69 100644
--- a/src/components/ConfirmWithAuthModal.tsx
+++ b/src/components/ConfirmWithAuthModal.tsx
@@ -17,11 +17,14 @@ along with the library. If not, see .
*/
import { getHumanReadableError, walletOpenAsyncUnsafe } from '@alephium/sdk'
+import { XIcon } from 'lucide-react-native'
import { useCallback, useEffect, useState } from 'react'
import { Alert } from 'react-native'
import styled from 'styled-components/native'
+import Button from '~/components/buttons/Button'
import PinCodeInput from '~/components/inputs/PinCodeInput'
+import { ScreenSection } from '~/components/layout/Screen'
import ModalWithBackdrop from '~/components/ModalWithBackdrop'
import CenteredInstructions, { Instruction } from '~/components/text/CenteredInstructions'
import { getStoredActiveWallet, getStoredWalletById } from '~/persistent-storage/wallets'
@@ -31,6 +34,7 @@ import { mnemonicToSeed, pbkdf2 } from '~/utils/crypto'
interface ConfirmWithAuthModalProps {
onConfirm: (pin?: string, wallet?: ActiveWalletState) => void
+ onClose?: () => void
usePin?: boolean
walletId?: string
}
@@ -47,7 +51,7 @@ const errorInstructionSet: Instruction[] = [
{ text: 'Please try again 💪', type: 'secondary' }
]
-const ConfirmWithAuthModal = ({ onConfirm, walletId, usePin = false }: ConfirmWithAuthModalProps) => {
+const ConfirmWithAuthModal = ({ onConfirm, onClose, walletId, usePin = false }: ConfirmWithAuthModalProps) => {
const [shownInstructions, setShownInstructions] = useState(firstInstructionSet)
const [encryptedWallet, setEncryptedWallet] = useState()
// eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -99,9 +103,14 @@ const ConfirmWithAuthModal = ({ onConfirm, walletId, usePin = false }: ConfirmWi
return (
<>
-
+
{encryptedWallet && (
+ {onClose && (
+
+
+
+ )}
@@ -120,3 +129,7 @@ const ModalContent = styled.View`
background-color: ${({ theme }) => theme.bg.secondary};
padding-top: 40px;
`
+
+const HeaderSection = styled(ScreenSection)`
+ align-items: flex-end;
+`
diff --git a/src/components/ExpandableRow.tsx b/src/components/ExpandableRow.tsx
index 05e1be6f..4665c898 100644
--- a/src/components/ExpandableRow.tsx
+++ b/src/components/ExpandableRow.tsx
@@ -18,29 +18,26 @@ along with the library. If not, see .
import { ChevronDown } from 'lucide-react-native'
import { ReactNode, useState } from 'react'
-import { StyleProp, ViewStyle } from 'react-native'
+import { StyleProp, View, ViewStyle } from 'react-native'
import Animated, { useAnimatedStyle, withTiming } from 'react-native-reanimated'
import styled, { useTheme } from 'styled-components/native'
import AppText from '~/components/AppText'
-import HighlightRow from '~/components/HighlightRow'
interface ExpandableRowProps {
- // TODO: Find a better way to measure the height of the collapsable section
- expandedHeight: number
children: ReactNode
title?: string
style?: StyleProp
}
-const ExpandableRow = ({ expandedHeight, children, title = 'Advanced options', style }: ExpandableRowProps) => {
+const ExpandableRow = ({ children, title = 'Advanced options', style }: ExpandableRowProps) => {
const theme = useTheme()
const [isExpanded, setIsExpanded] = useState(false)
const toggleExpanded = () => setIsExpanded(!isExpanded)
const collapsableSectionStyle = useAnimatedStyle(() => ({
- height: withTiming(isExpanded ? expandedHeight : 0)
+ opacity: withTiming(isExpanded ? 1 : 0)
}))
const chevronStyle = useAnimatedStyle(() => ({
@@ -48,20 +45,19 @@ const ExpandableRow = ({ expandedHeight, children, title = 'Advanced options', s
}))
return (
-
+
- {children}
-
+ {children}
+
)
}
export default styled(ExpandableRow)`
- background-color: ${({ theme }) => theme.bg.secondary};
flex-direction: column;
justify-content: center;
padding-top: 0;
@@ -84,9 +80,3 @@ const Header = styled.TouchableOpacity`
width: 100%;
padding: 25px 0 25px 6px;
`
-
-const CollapsableSection = styled(Animated.View)`
- width: 100%;
- height: 0;
- overflow: hidden;
-`
diff --git a/src/components/HistoricWorthChart.tsx b/src/components/HistoricWorthChart.tsx
index 1d24cf7d..16c5089a 100644
--- a/src/components/HistoricWorthChart.tsx
+++ b/src/components/HistoricWorthChart.tsx
@@ -92,7 +92,7 @@ const HistoricWorthChart = ({
-
+
.
-*/
-
-import QRCode from 'react-qr-code'
-import { useTheme } from 'styled-components/native'
-
-import ModalWithBackdrop from '~/components/ModalWithBackdrop'
-import { AddressHash } from '~/types/addresses'
-
-interface QRCodeModalProps {
- addressHash: AddressHash
- isOpen: boolean
- onClose: () => void
-}
-
-const QRCodeModal = ({ addressHash, isOpen, onClose }: QRCodeModalProps) => {
- const theme = useTheme()
-
- return (
-
-
-
- )
-}
-
-export default QRCodeModal
diff --git a/src/components/buttons/Button.tsx b/src/components/buttons/Button.tsx
index 57e74c44..24b251c4 100644
--- a/src/components/buttons/Button.tsx
+++ b/src/components/buttons/Button.tsx
@@ -54,7 +54,7 @@ const Button = ({
const colors = {
bg: {
- default: theme.bg.primary,
+ default: theme.bg.secondary,
contrast: theme.font.primary,
accent: theme.global.accent,
valid: colord(theme.global.valid).alpha(0.1).toRgbString(),
diff --git a/src/components/headers/BottomModalHeader.tsx b/src/components/headers/BottomModalHeader.tsx
index 4af1bf35..d7e4c11c 100644
--- a/src/components/headers/BottomModalHeader.tsx
+++ b/src/components/headers/BottomModalHeader.tsx
@@ -16,10 +16,18 @@ You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see .
*/
+import { StackHeaderProps } from '@react-navigation/stack'
import { ReactNode } from 'react'
import { View } from 'react-native'
import { useTheme } from 'styled-components/native'
+import { BottomModalScreenTitle, ScreenSection } from '~/components/layout/Screen'
+
+interface BottomModalHeaderProps {
+ title?: StackHeaderProps['options']['title']
+ children?: ReactNode
+}
+
export const bottomModalHeights = {
pullTab: {
container: 20,
@@ -27,7 +35,7 @@ export const bottomModalHeights = {
}
}
-const BottomModalHeader = ({ children }: { children?: ReactNode }) => {
+const BottomModalHeader = ({ children, title }: BottomModalHeaderProps) => {
const theme = useTheme()
return (
@@ -42,6 +50,11 @@ const BottomModalHeader = ({ children }: { children?: ReactNode }) => {
>
+ {title && (
+
+ {title}
+
+ )}
{children && {children}}
)
diff --git a/src/components/inputs/AddressSelector.tsx b/src/components/inputs/AddressSelector.tsx
deleted file mode 100644
index b08b0e2c..00000000
--- a/src/components/inputs/AddressSelector.tsx
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
-Copyright 2018 - 2022 The Alephium Authors
-This file is part of the alephium project.
-
-The library is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-The library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with the library. If not, see .
-*/
-
-import AddressBadge from '~/components/AddressBadge'
-import Select, { SelectProps } from '~/components/inputs/Select'
-import { useAppSelector } from '~/hooks/redux'
-import { selectAllAddresses } from '~/store/addressesSlice'
-import { AddressHash } from '~/types/addresses'
-
-type AddressSelectorProps = Omit, 'options' | 'renderValue'>
-
-const AddressSelector = ({ label = 'Address', ...props }: AddressSelectorProps) => {
- const addressEntries = useAppSelector((s) => s.addresses.entities)
- const addresses = useAppSelector(selectAllAddresses)
-
- const addressesOptions = addresses.map((address) => ({
- value: address.hash,
- label:
- }))
-
- const renderValue = (addressHash: AddressHash) => {
- const address = addressEntries[addressHash]
-
- return address ? : null
- }
-
- return
-}
-
-export default AddressSelector
diff --git a/src/components/inputs/Select.tsx b/src/components/inputs/Select.tsx
deleted file mode 100644
index dfb452b5..00000000
--- a/src/components/inputs/Select.tsx
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
-Copyright 2018 - 2022 The Alephium Authors
-This file is part of the alephium project.
-
-The library is free software: you can redistribute it and/or modify
-it under the terms of the GNU Lesser General Public License as published by
-the Free Software Foundation, either version 3 of the License, or
-(at your option) any later version.
-
-The library is distributed in the hope that it will be useful,
-but WITHOUT ANY WARRANTY; without even the implied warranty of
-MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-GNU Lesser General Public License for more details.
-
-You should have received a copy of the GNU Lesser General Public License
-along with the library. If not, see .
-*/
-
-import { ChevronDown } from 'lucide-react-native'
-import { ReactNode, useState } from 'react'
-import styled, { useTheme } from 'styled-components/native'
-
-import AppText from '~/components/AppText'
-import HighlightRow from '~/components/HighlightRow'
-import Input, { InputProps, InputValue, RenderValueFunc } from '~/components/inputs/Input'
-import BoxSurface from '~/components/layout/BoxSurface'
-import ModalWithBackdrop from '~/components/ModalWithBackdrop'
-
-export type SelectOption = {
- value: T
- label: ReactNode
-}
-
-export interface SelectProps extends Omit, 'value'> {
- options: SelectOption[]
- value: T
- onValueChange: (value: T) => void
- renderValue?: RenderValueFunc
-}
-
-const Select = ({ options, onValueChange, value, renderValue }: SelectProps) => {
- const [isModalOpen, setIsModalOpen] = useState(false)
- const theme = useTheme()
-
- const handleOptionPress = (value: T) => {
- onValueChange(value)
- setIsModalOpen(false)
- }
-
- const openModal = () => setIsModalOpen(true)
- const closeModal = () => setIsModalOpen(false)
-
- return (
- <>
- }
- value={value}
- renderValue={renderValue}
- label=""
- />
-
-
- {options.map(({ label, value }, index) => (
- handleOptionPress(value)}
- key={JSON.stringify(value) + (label ?? '') + index}
- isLast={index === options.length - 1}
- >
- {typeof label === 'string' ? {label} : label}
-
- ))}
-
-
- >
- )
-}
-
-export default Select
-
-const ChevronRight = styled(ChevronDown)`
- transform: rotate(-90deg);
-`
diff --git a/src/contexts/NewAddressContext.tsx b/src/contexts/NewAddressContext.tsx
new file mode 100644
index 00000000..913f1a4e
--- /dev/null
+++ b/src/contexts/NewAddressContext.tsx
@@ -0,0 +1,39 @@
+/*
+Copyright 2018 - 2022 The Alephium Authors
+This file is part of the alephium project.
+
+The library is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+The library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the library. If not, see .
+*/
+
+import { createContext, ReactNode, useContext, useState } from 'react'
+
+interface NewAddressContextValue {
+ group?: number
+ setGroup: (group?: number) => void
+}
+
+const initialValues: NewAddressContextValue = {
+ group: undefined,
+ setGroup: () => null
+}
+
+const NewAddressContext = createContext(initialValues)
+
+export const NewAddressContextProvider = ({ children }: { children: ReactNode }) => {
+ const [group, setGroup] = useState(initialValues.group)
+
+ return {children}
+}
+
+export const useNewAddressContext = () => useContext(NewAddressContext)
diff --git a/src/contexts/ScrollContext.tsx b/src/contexts/ScrollContext.tsx
index 1d806f11..120694fe 100644
--- a/src/contexts/ScrollContext.tsx
+++ b/src/contexts/ScrollContext.tsx
@@ -20,29 +20,48 @@ import { createContext, ReactNode, useContext } from 'react'
import { NativeScrollEvent, NativeSyntheticEvent } from 'react-native'
import { SharedValue, useSharedValue } from 'react-native-reanimated'
-interface ScrollContextProps {
+interface ScrollContextValue {
scrollY?: SharedValue
- isScrolling?: SharedValue
+ scrollDirection?: SharedValue
}
-const ScrollContext = createContext({
- scrollY: undefined
+const scrollDirectionDeltaThreshold = 10
+
+export type ScrollDirection = 'up' | 'down' | undefined
+
+const ScrollContext = createContext({
+ scrollY: undefined,
+ scrollDirection: undefined
})
export const ScrollContextProvider = ({ children }: { children: ReactNode }) => {
const scrollY = useSharedValue(0)
+ const scrollDirection = useSharedValue(undefined as ScrollDirection)
- return {children}
+ return {children}
}
export const useScrollContext = () => useContext(ScrollContext)
export const useScrollEventHandler = () => {
- const { scrollY } = useScrollContext()
+ const { scrollY, scrollDirection } = useScrollContext()
const scrollHandler = (e: NativeSyntheticEvent) => {
- if (!scrollY) return
- scrollY.value = e.nativeEvent.contentOffset.y
+ if (!scrollY || !scrollDirection) return
+
+ const newScrollY = e.nativeEvent.contentOffset.y
+ const delta = scrollY.value - newScrollY
+ const direction = delta > 0 ? 'up' : 'down'
+
+ if (newScrollY === 0) {
+ scrollDirection.value = undefined
+ } else if (direction === 'up' && delta > scrollDirectionDeltaThreshold) {
+ scrollDirection.value = 'up'
+ } else if (direction === 'down' && delta < -scrollDirectionDeltaThreshold) {
+ scrollDirection.value = 'down'
+ }
+
+ scrollY.value = newScrollY
}
return scrollHandler
diff --git a/src/contexts/SendContext.tsx b/src/contexts/SendContext.tsx
index 1602d620..7c223ccb 100644
--- a/src/contexts/SendContext.tsx
+++ b/src/contexts/SendContext.tsx
@@ -42,7 +42,7 @@ type BuildTransactionCallbacks = {
onConsolidationSuccess: () => void
}
-interface SendContextProps {
+interface SendContextValue {
toAddress?: AddressHash
setToAddress: (toAddress: AddressHash) => void
fromAddress?: AddressHash
@@ -54,7 +54,7 @@ interface SendContextProps {
sendTransaction: (onSendSuccess: () => void) => Promise
}
-const initialValues: SendContextProps = {
+const initialValues: SendContextValue = {
toAddress: undefined,
setToAddress: () => null,
fromAddress: undefined,
@@ -72,9 +72,9 @@ export const SendContextProvider = ({ children }: { children: ReactNode }) => {
const requiresAuth = useAppSelector((s) => s.settings.requireAuth)
const dispatch = useAppDispatch()
- const [toAddress, setToAddress] = useState(initialValues.toAddress)
- const [fromAddress, setFromAddress] = useState(initialValues.fromAddress)
- const [assetAmounts, setAssetAmounts] = useState(initialValues.assetAmounts)
+ const [toAddress, setToAddress] = useState(initialValues.toAddress)
+ const [fromAddress, setFromAddress] = useState(initialValues.fromAddress)
+ const [assetAmounts, setAssetAmounts] = useState(initialValues.assetAmounts)
const [unsignedTxData, setUnsignedTxData] = useState({ unsignedTxs: [], fees: initialValues.fees })
const [consolidationRequired, setConsolidationRequired] = useState(false)
@@ -201,7 +201,10 @@ export const SendContextProvider = ({ children }: { children: ReactNode }) => {
/>
)}
{isAuthenticationModalVisible && (
- sendTransaction(onSendSuccessCallback)} />
+ sendTransaction(onSendSuccessCallback)}
+ onClose={() => setIsAuthenticationModalVisible(false)}
+ />
)}
)
diff --git a/src/hooks/layout/useBottomModalOptions.tsx b/src/hooks/layout/useBottomModalOptions.tsx
index df112dce..1cfc9420 100644
--- a/src/hooks/layout/useBottomModalOptions.tsx
+++ b/src/hooks/layout/useBottomModalOptions.tsx
@@ -41,7 +41,7 @@ const useBottomModalOptions = (options?: BottomModalOptions): StackNavigationOpt
borderTopLeftRadius: borderRadius,
backgroundColor: theme.bg.primary
},
- header: () =>
+ header: ({ options }) =>
}
}
diff --git a/src/navigation/NewAddressNavigation.tsx b/src/navigation/NewAddressNavigation.tsx
new file mode 100644
index 00000000..e84b91b7
--- /dev/null
+++ b/src/navigation/NewAddressNavigation.tsx
@@ -0,0 +1,56 @@
+/*
+Copyright 2018 - 2022 The Alephium Authors
+This file is part of the alephium project.
+
+The library is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+The library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the library. If not, see .
+*/
+
+import { ParamListBase } from '@react-navigation/native'
+import { createStackNavigator, StackScreenProps } from '@react-navigation/stack'
+
+import { NewAddressContextProvider } from '~/contexts/NewAddressContext'
+import useBottomModalOptions from '~/hooks/layout/useBottomModalOptions'
+import RootStackParamList from '~/navigation/rootStackRoutes'
+import GroupSelectScreen from '~/screens/Address/GroupSelectScreen'
+import NewAddressScreen from '~/screens/Address/NewAddressScreen'
+
+export interface NewAddressNavigationParamList extends ParamListBase {
+ NewAddressScreen: undefined
+ GroupSelectScreen: undefined
+}
+
+const NewAddressStack = createStackNavigator()
+
+const NewAddressNavigation = (props: StackScreenProps) => {
+ const bottomModalOptions = useBottomModalOptions()
+
+ return (
+
+
+
+
+
+
+ )
+}
+
+export default NewAddressNavigation
diff --git a/src/navigation/ReceiveNavigation.tsx b/src/navigation/ReceiveNavigation.tsx
new file mode 100644
index 00000000..f003690a
--- /dev/null
+++ b/src/navigation/ReceiveNavigation.tsx
@@ -0,0 +1,41 @@
+/*
+Copyright 2018 - 2022 The Alephium Authors
+This file is part of the alephium project.
+
+The library is free software: you can redistribute it and/or modify
+it under the terms of the GNU Lesser General Public License as published by
+the Free Software Foundation, either version 3 of the License, or
+(at your option) any later version.
+
+The library is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU Lesser General Public License for more details.
+
+You should have received a copy of the GNU Lesser General Public License
+along with the library. If not, see .
+*/
+
+import { ParamListBase } from '@react-navigation/native'
+import { createStackNavigator, StackScreenProps } from '@react-navigation/stack'
+
+import RootStackParamList from '~/navigation/rootStackRoutes'
+import AddressScreen from '~/screens/SendReceive/Receive/AddressScreen'
+import QRCodeScreen from '~/screens/SendReceive/Receive/QRCodeScreen'
+import { AddressHash } from '~/types/addresses'
+
+export interface ReceiveNavigationParamList extends ParamListBase {
+ AddressScreen: undefined
+ QRCodeScreen: { addressHash: AddressHash }
+}
+
+const ReceiveStack = createStackNavigator()
+
+const ReceiveNavigation = ({ navigation }: StackScreenProps) => (
+
+
+
+
+)
+
+export default ReceiveNavigation
diff --git a/src/navigation/RootStackNavigation.tsx b/src/navigation/RootStackNavigation.tsx
index 5f15604b..6a459771 100644
--- a/src/navigation/RootStackNavigation.tsx
+++ b/src/navigation/RootStackNavigation.tsx
@@ -25,10 +25,13 @@ import { ScrollContextProvider } from '~/contexts/ScrollContext'
import useBottomModalOptions from '~/hooks/layout/useBottomModalOptions'
import { useAppDispatch } from '~/hooks/redux'
import InWalletTabsNavigation from '~/navigation/InWalletNavigation'
+import NewAddressNavigation from '~/navigation/NewAddressNavigation'
+import ReceiveNavigation from '~/navigation/ReceiveNavigation'
import RootStackParamList from '~/navigation/rootStackRoutes'
import SendNavigation from '~/navigation/SendNavigation'
+import EditAddressScreen from '~/screens/Address/EditAddressScreen'
import AddressDiscoveryScreen from '~/screens/AddressDiscovery'
-import EditAddressScreen from '~/screens/EditAddressScreen'
+import CurrencySelectScreen from '~/screens/CurrencySelectScreen'
import LandingScreen from '~/screens/LandingScreen'
import LoginScreen from '~/screens/LoginScreen'
import AddBiometricsScreen from '~/screens/new-wallet/AddBiometricsScreen'
@@ -38,10 +41,8 @@ import NewWalletIntroScreen from '~/screens/new-wallet/NewWalletIntroScreen'
import NewWalletNameScreen from '~/screens/new-wallet/NewWalletNameScreen'
import NewWalletSuccessPage from '~/screens/new-wallet/NewWalletSuccessPage'
import PinCodeCreationScreen from '~/screens/new-wallet/PinCodeCreationScreen'
-import NewAddressScreen from '~/screens/NewAddressScreen'
-import ReceiveScreen from '~/screens/ReceiveScreen'
import SecurityScreen from '~/screens/SecurityScreen'
-import SendScreenHeader from '~/screens/Send/SendScreenHeader'
+import ScreenHeader from '~/screens/SendReceive/ScreenHeader'
import SettingsScreen from '~/screens/SettingsScreen'
import SplashScreen from '~/screens/SplashScreen'
import SwitchNetworkScreen from '~/screens/SwitchNetworkScreen'
@@ -83,72 +84,71 @@ const RootStackNavigation = () => {
screenOptions={{
headerStyle: { elevation: 0, shadowOpacity: 0 },
headerTitle: '',
- cardStyle: {
- backgroundColor: theme.bg.primary
- }
+ headerBackTitleVisible: false
}}
>
-
-
-
-
- {/* NEW WALLET */}
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- }}
- />
+ {/* Screens with header */}
+
+
+
+
+
+
+
+
+
+
+
+
+
+ {/* Screens without header */}
+
+
+
+
+
+
+
+
+
+ {/* Bottom modal screens */}
+
+
+
+
+
+
+ }}
+ />
+ }}
+ />
+
diff --git a/src/navigation/SendNavigation.tsx b/src/navigation/SendNavigation.tsx
index 519e5c89..bed653d6 100644
--- a/src/navigation/SendNavigation.tsx
+++ b/src/navigation/SendNavigation.tsx
@@ -21,35 +21,37 @@ import { createStackNavigator, StackScreenProps } from '@react-navigation/stack'
import { SendContextProvider } from '~/contexts/SendContext'
import RootStackParamList from '~/navigation/rootStackRoutes'
-import AssetsScreen from '~/screens/Send/AssetsScreen'
-import DestinationScreen from '~/screens/Send/DestinationScreen'
-import OriginScreen from '~/screens/Send/OriginScreen'
-import VerifyScreen from '~/screens/Send/VerifyScreen'
+import AssetsScreen from '~/screens/SendReceive/Send/AssetsScreen'
+import DestinationScreen from '~/screens/SendReceive/Send/DestinationScreen'
+import OriginScreen from '~/screens/SendReceive/Send/OriginScreen'
+import VerifyScreen from '~/screens/SendReceive/Send/VerifyScreen'
import { AddressHash } from '~/types/addresses'
export interface SendNavigationParamList extends ParamListBase {
- DestinationScreen?: { addressHash?: AddressHash }
- OriginScreen?: { addressHash?: AddressHash }
+ DestinationScreen?: { fromAddressHash?: AddressHash }
+ OriginScreen?: { toAddressHash?: AddressHash }
AssetsScreen: undefined
VerifyScreen: undefined
}
const SendStack = createStackNavigator()
-const SendNavigation = ({
- navigation,
- route: {
- params: { fromAddressHash, toAddressHash }
- }
-}: StackScreenProps) => (
+const SendNavigation = ({ navigation, route: { params } }: StackScreenProps) => (
-
+
+
-
diff --git a/src/navigation/rootStackRoutes.ts b/src/navigation/rootStackRoutes.ts
index 07fbc63f..502aa087 100644
--- a/src/navigation/rootStackRoutes.ts
+++ b/src/navigation/rootStackRoutes.ts
@@ -28,14 +28,14 @@ type RootStackParamList = {
NewWalletSuccessPage: undefined
ImportWalletSeedScreen: undefined
ImportWalletAddressDiscoveryScreen: undefined
- InWalletScreen: undefined
+ InWalletTabsNavigation: undefined
LoginScreen: {
walletIdToLogin?: string
workflow: 'wallet-switch' | 'wallet-unlock'
}
SplashScreen: undefined
SwitchWalletScreen: undefined
- NewAddressScreen: undefined
+ NewAddressNavigation: undefined
EditAddressScreen: {
addressHash: AddressHash
}
@@ -46,17 +46,16 @@ type RootStackParamList = {
// TODO: Make all params serializable to help with state persistance
tx: AddressConfirmedTransaction
}
- ReceiveScreen: {
- addressHash: AddressHash
- }
- SendNavigation: {
+ SendNavigation?: {
fromAddressHash?: AddressHash
toAddressHash?: AddressHash
}
+ ReceiveNavigation: undefined
SecurityScreen: undefined
AddressDiscoveryScreen?: {
isImporting?: boolean
}
+ CurrencySelectScreen: undefined
}
export default RootStackParamList
diff --git a/src/persistent-storage/wallets.ts b/src/persistent-storage/wallets.ts
index aa7dddd8..dfbf4bf6 100644
--- a/src/persistent-storage/wallets.ts
+++ b/src/persistent-storage/wallets.ts
@@ -198,7 +198,7 @@ export const deleteAllWallets = async () => {
const deleteWallet = async ({ id, name, authType }: WalletMetadata) => {
if (authType === 'biometrics') {
- deleteBiometricsEnabledMnemonic(id, name)
+ await deleteBiometricsEnabledMnemonic(id, name)
}
console.log(`🗑️ Deleting pin-encrypted mnemonic for wallet with ID ${id}`)
diff --git a/src/screens/AddressFormScreen.tsx b/src/screens/Address/AddressForm.tsx
similarity index 66%
rename from src/screens/AddressFormScreen.tsx
rename to src/screens/Address/AddressForm.tsx
index 89c11198..4e7803d8 100644
--- a/src/screens/AddressFormScreen.tsx
+++ b/src/screens/Address/AddressForm.tsx
@@ -16,10 +16,8 @@ You should have received a copy of the GNU Lesser General Public License
along with the library. If not, see .
*/
-import { TOTAL_NUMBER_OF_GROUPS } from '@alephium/web3'
import { useState } from 'react'
import { ScrollView } from 'react-native'
-import styled from 'styled-components/native'
import AppText from '~/components/AppText'
import Button from '~/components/buttons/Button'
@@ -27,10 +25,10 @@ import ExpandableRow from '~/components/ExpandableRow'
import HighlightRow from '~/components/HighlightRow'
import ColorPicker from '~/components/inputs/ColorPicker'
import Input from '~/components/inputs/Input'
-import Select, { SelectOption } from '~/components/inputs/Select'
import BoxSurface from '~/components/layout/BoxSurface'
-import { BottomModalScreenTitle, BottomScreenSection, ScreenSection } from '~/components/layout/Screen'
+import { BottomScreenSection, ScreenSection } from '~/components/layout/Screen'
import Toggle from '~/components/Toggle'
+import { useNewAddressContext } from '~/contexts/NewAddressContext'
import { AddressHash, AddressSettings } from '~/types/addresses'
export type AddressFormData = AddressSettings & {
@@ -40,38 +38,24 @@ export type AddressFormData = AddressSettings & {
interface AddressFormProps {
initialValues: AddressFormData
onSubmit: (data: AddressFormData) => void
+ onGroupPress?: () => void
buttonText?: string
disableIsMainToggle?: boolean
- includeGroup?: boolean
addressHash?: AddressHash
}
-const groupSelectOptions: SelectOption[] = Array.from(Array(TOTAL_NUMBER_OF_GROUPS)).map(
- (_, index) => ({
- value: index,
- label: `Group ${index}`
- })
-)
-
-const emptyOption = {
- value: undefined,
- label: ''
-} as SelectOption
-
-groupSelectOptions.unshift(emptyOption)
-
const AddressForm = ({
initialValues,
onSubmit,
+ onGroupPress,
buttonText = 'Generate',
- disableIsMainToggle = false,
- includeGroup = false,
- addressHash
+ disableIsMainToggle = false
}: AddressFormProps) => {
+ const { group } = useNewAddressContext()
+
const [label, setLabel] = useState(initialValues.label)
const [color, setColor] = useState(initialValues.color)
const [isMain, setIsMain] = useState(initialValues.isMain)
- const [group, setGroup] = useState(initialValues?.group)
const toggleIsMain = () => {
if (!disableIsMainToggle) {
@@ -79,18 +63,8 @@ const AddressForm = ({
}
}
- const renderGroupValue = (group?: number) => (group !== undefined ? `Group ${group}` : undefined)
-
return (
<>
-
- Address settings
- {addressHash && (
-
- {addressHash}
-
- )}
-
@@ -109,16 +83,14 @@ const AddressForm = ({
- {includeGroup && (
+ {onGroupPress && (
-
-
+
+
+
+ {group !== undefined ? `Group ${group}` : 'Default'}
+
+
)}
@@ -131,8 +103,3 @@ const AddressForm = ({
}
export default AddressForm
-
-const HashEllipsed = styled(AppText)`
- max-width: 50%;
- margin-top: 8px;
-`
diff --git a/src/screens/EditAddressScreen.tsx b/src/screens/Address/EditAddressScreen.tsx
similarity index 71%
rename from src/screens/EditAddressScreen.tsx
rename to src/screens/Address/EditAddressScreen.tsx
index aec44902..9d12d00a 100644
--- a/src/screens/EditAddressScreen.tsx
+++ b/src/screens/Address/EditAddressScreen.tsx
@@ -17,13 +17,17 @@ along with the library. If not, see .
*/
import { StackScreenProps } from '@react-navigation/stack'
-import { useState } from 'react'
+import React, { useEffect, useState } from 'react'
+import styled from 'styled-components/native'
+import AppText from '~/components/AppText'
+import BottomModalHeader from '~/components/headers/BottomModalHeader'
+import { BottomModalScreenTitle, ScreenSection } from '~/components/layout/Screen'
import SpinnerModal from '~/components/SpinnerModal'
import usePersistAddressSettings from '~/hooks/layout/usePersistAddressSettings'
import { useAppDispatch, useAppSelector } from '~/hooks/redux'
import RootStackParamList from '~/navigation/rootStackRoutes'
-import AddressFormScreen from '~/screens/AddressFormScreen'
+import AddressForm from '~/screens/Address/AddressForm'
import { addressSettingsSaved, selectAddressByHash } from '~/store/addressesSlice'
import { AddressSettings } from '~/types/addresses'
@@ -41,6 +45,21 @@ const EditAddressScreen = ({
const [loading, setLoading] = useState(false)
+ useEffect(() => {
+ navigation.setOptions({
+ header: () => (
+
+
+ Address settings
+
+ {addressHash}
+
+
+
+ )
+ })
+ }, [addressHash, navigation])
+
if (!address) return null
const handleSavePress = async (settings: AddressSettings) => {
@@ -57,7 +76,7 @@ const EditAddressScreen = ({
return (
<>
- .
+*/
+
+import { TOTAL_NUMBER_OF_GROUPS } from '@alephium/web3'
+import { StackScreenProps } from '@react-navigation/stack'
+import { map } from 'lodash'
+import React from 'react'
+
+import BoxSurface from '~/components/layout/BoxSurface'
+import { ScreenSection } from '~/components/layout/Screen'
+import ScrollScreen from '~/components/layout/ScrollScreen'
+import RadioButtonRow from '~/components/RadioButtonRow'
+import { useNewAddressContext } from '~/contexts/NewAddressContext'
+import { NewAddressNavigationParamList } from '~/navigation/NewAddressNavigation'
+
+type ScreenProps = StackScreenProps
+
+const groupSelectOptions = map(Array(TOTAL_NUMBER_OF_GROUPS + 1), (_, i) => ({
+ value: i === 0 ? undefined : i - 1,
+ label: i === 0 ? 'Default' : `Group ${i - 1}`
+}))
+
+const GroupSelectScreen = ({ navigation }: ScreenProps) => {
+ const { group, setGroup } = useNewAddressContext()
+
+ const onGroupSelect = (group?: number) => {
+ setGroup(group)
+ navigation.goBack()
+ }
+
+ return (
+
+
+
+ {groupSelectOptions.map((groupOption) => (
+ onGroupSelect(groupOption.value)}
+ isActive={group === groupOption.value}
+ />
+ ))}
+
+
+
+ )
+}
+
+export default GroupSelectScreen
diff --git a/src/screens/NewAddressScreen.tsx b/src/screens/Address/NewAddressScreen.tsx
similarity index 86%
rename from src/screens/NewAddressScreen.tsx
rename to src/screens/Address/NewAddressScreen.tsx
index 347796e6..43c3e878 100644
--- a/src/screens/NewAddressScreen.tsx
+++ b/src/screens/Address/NewAddressScreen.tsx
@@ -23,8 +23,8 @@ import { useRef, useState } from 'react'
import SpinnerModal from '~/components/SpinnerModal'
import usePersistAddressSettings from '~/hooks/layout/usePersistAddressSettings'
import { useAppDispatch, useAppSelector } from '~/hooks/redux'
-import RootStackParamList from '~/navigation/rootStackRoutes'
-import AddressFormScreen, { AddressFormData } from '~/screens/AddressFormScreen'
+import { NewAddressNavigationParamList } from '~/navigation/NewAddressNavigation'
+import AddressForm, { AddressFormData } from '~/screens/Address/AddressForm'
import {
newAddressGenerated,
selectAllAddresses,
@@ -34,7 +34,7 @@ import {
import { getRandomLabelColor } from '~/utils/colors'
import { mnemonicToSeed } from '~/utils/crypto'
-type ScreenProps = StackScreenProps
+type ScreenProps = StackScreenProps
const NewAddressScreen = ({ navigation }: ScreenProps) => {
const dispatch = useAppDispatch()
@@ -69,7 +69,11 @@ const NewAddressScreen = ({ navigation }: ScreenProps) => {
return (
<>
-
+ navigation.navigate('GroupSelectScreen')}
+ />
>
)
diff --git a/src/screens/AddressDiscovery.tsx b/src/screens/AddressDiscovery.tsx
index e6e92723..ea3355a3 100644
--- a/src/screens/AddressDiscovery.tsx
+++ b/src/screens/AddressDiscovery.tsx
@@ -78,7 +78,7 @@ const AddressDiscoveryScreen = ({ navigation, route: { params } }: ScreenProps)
await dispatch(syncAddressesData(newAddressHashes))
await dispatch(syncAddressesHistoricBalances(newAddressHashes))
- navigation.navigate(isImporting ? 'NewWalletSuccessPage' : 'InWalletScreen')
+ navigation.navigate(isImporting ? 'NewWalletSuccessPage' : 'InWalletTabsNavigation')
setImportLoading(false)
}
diff --git a/src/screens/AddressesScreen.tsx b/src/screens/AddressesScreen.tsx
index 8cdd19e7..480a8c44 100644
--- a/src/screens/AddressesScreen.tsx
+++ b/src/screens/AddressesScreen.tsx
@@ -28,7 +28,6 @@ import AddressesTokensList from '~/components/AddressesTokensList'
import Button from '~/components/buttons/Button'
import Carousel from '~/components/Carousel'
import ScrollScreen from '~/components/layout/ScrollScreen'
-import QRCodeModal from '~/components/QRCodeModal'
import { useAppDispatch, useAppSelector } from '~/hooks/redux'
import { AddressTabsParamList } from '~/navigation/AddressesTabNavigation'
import RootStackParamList from '~/navigation/rootStackRoutes'
@@ -49,7 +48,6 @@ const AddressesScreen = ({ navigation, style }: ScreenProps) => {
const selectedAddress = useAppSelector((s) => selectAddressByHash(s, selectedAddressHash))
const theme = useTheme()
- const [isQrCodeModalOpen, setIsQrCodeModalOpen] = useState(false)
const [heightCarouselItem, setHeightCarouselItem] = useState(200)
useEffect(() => {
@@ -90,7 +88,7 @@ const AddressesScreen = ({ navigation, style }: ScreenProps) => {
height={heightCarouselItem}
FooterComponent={