mirror of
https://github.com/minibits-cash/minibits_wallet.git
synced 2026-10-05 11:18:24 +00:00
Fix animated header, fix pending filter, fix QRShareModal
This commit is contained in:
+1
-1
@@ -196,7 +196,7 @@ function App() {
|
|||||||
? require('../android/app/src/main/res/mipmap-xxhdpi/ic_launcher_golden.png')
|
? require('../android/app/src/main/res/mipmap-xxhdpi/ic_launcher_golden.png')
|
||||||
: require('../android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png')} />
|
: require('../android/app/src/main/res/mipmap-xxhdpi/ic_launcher.png')} />
|
||||||
</View>
|
</View>
|
||||||
<Text text={displayName} style={[$title]} />
|
<Text text={displayName} style={[$title, {paddingBottom: isAppLocked ? spacing.tiny : spacing.extraLarge}]} />
|
||||||
<View style={{
|
<View style={{
|
||||||
paddingHorizontal: spacing.large,
|
paddingHorizontal: spacing.large,
|
||||||
paddingBottom: spacing.extraLarge,
|
paddingBottom: spacing.extraLarge,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
import React from 'react'
|
import React from 'react'
|
||||||
import { TextStyle, ViewStyle } from 'react-native'
|
import { TextStyle, View, ViewStyle } from 'react-native'
|
||||||
import Animated, {
|
import Animated, {
|
||||||
SharedValue,
|
SharedValue,
|
||||||
useAnimatedStyle,
|
useAnimatedStyle,
|
||||||
@@ -24,91 +24,57 @@ export interface AnimatedHeaderProps {
|
|||||||
*/
|
*/
|
||||||
scrollY: SharedValue<number>
|
scrollY: SharedValue<number>
|
||||||
/**
|
/**
|
||||||
* The scroll distance over which the animation occurs.
|
* Header height. Title fades out over the first half of this distance.
|
||||||
* Defaults to spacing.screenHeight * 0.07
|
|
||||||
*/
|
|
||||||
scrollDistance?: number
|
|
||||||
/**
|
|
||||||
* Maximum header height when not scrolled.
|
|
||||||
* Defaults to spacing.screenHeight * 0.15
|
* Defaults to spacing.screenHeight * 0.15
|
||||||
*/
|
*/
|
||||||
maxHeight?: number
|
maxHeight?: number
|
||||||
/**
|
|
||||||
* Minimum header height when fully scrolled.
|
|
||||||
* Defaults to spacing.screenHeight * 0.08
|
|
||||||
*/
|
|
||||||
minHeight?: number
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* AnimatedHeader component that provides a collapsible header with animated title.
|
* AnimatedHeader component with a large title that fades as the user scrolls.
|
||||||
* Use with Animated.ScrollView and useAnimatedScrollHandler to track scroll position.
|
* Place this as the first child inside an Animated.ScrollView so that it scrolls
|
||||||
|
* away naturally — no height animation means no layout jitter.
|
||||||
*/
|
*/
|
||||||
export function AnimatedHeader(props: AnimatedHeaderProps) {
|
export function AnimatedHeader(props: AnimatedHeaderProps) {
|
||||||
const {
|
const {
|
||||||
title,
|
title,
|
||||||
titleTx,
|
titleTx,
|
||||||
scrollY,
|
scrollY,
|
||||||
scrollDistance = spacing.screenHeight * 0.07,
|
|
||||||
maxHeight = spacing.screenHeight * 0.15,
|
maxHeight = spacing.screenHeight * 0.15,
|
||||||
minHeight = spacing.screenHeight * 0.08,
|
|
||||||
} = props
|
} = props
|
||||||
|
|
||||||
const headerBg = useThemeColor('header')
|
const headerBg = useThemeColor('header')
|
||||||
const headerTitleColor = useThemeColor('headerTitle')
|
const headerTitleColor = useThemeColor('headerTitle')
|
||||||
|
|
||||||
const animatedHeaderStyle = useAnimatedStyle(() => {
|
|
||||||
const height = interpolate(
|
|
||||||
scrollY.value,
|
|
||||||
[0, scrollDistance],
|
|
||||||
[maxHeight, minHeight],
|
|
||||||
Extrapolation.CLAMP
|
|
||||||
)
|
|
||||||
return { height }
|
|
||||||
})
|
|
||||||
|
|
||||||
const animatedTitleStyle = useAnimatedStyle(() => {
|
const animatedTitleStyle = useAnimatedStyle(() => {
|
||||||
const scale = interpolate(
|
|
||||||
scrollY.value,
|
|
||||||
[0, scrollDistance],
|
|
||||||
[1, 0.75],
|
|
||||||
Extrapolation.CLAMP
|
|
||||||
)
|
|
||||||
const translateY = interpolate(
|
|
||||||
scrollY.value,
|
|
||||||
[0, scrollDistance],
|
|
||||||
[0, -spacing.extraLarge * 1.5],
|
|
||||||
Extrapolation.CLAMP
|
|
||||||
)
|
|
||||||
const opacity = interpolate(
|
const opacity = interpolate(
|
||||||
scrollY.value,
|
scrollY.value,
|
||||||
[0, scrollDistance * 0.8],
|
[0, maxHeight * 0.5],
|
||||||
[1, 0],
|
[1, 0],
|
||||||
Extrapolation.CLAMP
|
Extrapolation.CLAMP
|
||||||
)
|
)
|
||||||
return {
|
return { opacity }
|
||||||
transform: [{ scale }, { translateY }],
|
|
||||||
opacity,
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const titleContent = titleTx ? translate(titleTx) : title
|
const titleContent = titleTx ? translate(titleTx) : title
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Animated.View style={[animatedHeaderStyle, $headerContainer, { backgroundColor: headerBg }]}>
|
<View style={[$headerContainer, { height: maxHeight, backgroundColor: headerBg }]}>
|
||||||
<Animated.Text style={[animatedTitleStyle, $headerTitle, { color: headerTitleColor }]}>
|
<Animated.Text style={[animatedTitleStyle, $headerTitle, { color: headerTitleColor }]}>
|
||||||
{titleContent}
|
{titleContent}
|
||||||
</Animated.Text>
|
</Animated.Text>
|
||||||
</Animated.View>
|
</View>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
const $headerContainer: ViewStyle = {
|
const $headerContainer: ViewStyle = {
|
||||||
alignItems: 'center',
|
alignItems: 'center',
|
||||||
|
justifyContent: 'center',
|
||||||
}
|
}
|
||||||
|
|
||||||
const $headerTitle: TextStyle = {
|
const $headerTitle: TextStyle = {
|
||||||
fontSize: verticalScale(32),
|
fontSize: verticalScale(32),
|
||||||
lineHeight: verticalScale(44),
|
lineHeight: verticalScale(44),
|
||||||
fontFamily: typography.primary?.medium,
|
fontFamily: typography.primary?.medium,
|
||||||
|
marginBottom: spacing.extraLarge * 2,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ export function Header(props: HeaderProps) {
|
|||||||
}
|
}
|
||||||
const opacity = interpolate(
|
const opacity = interpolate(
|
||||||
scrollY.value,
|
scrollY.value,
|
||||||
[0, scrollDistance],
|
[scrollDistance * 0.5, scrollDistance],
|
||||||
[0, 1],
|
[0, 1],
|
||||||
Extrapolation.CLAMP
|
Extrapolation.CLAMP
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ export const QRShareModal = (props: QRShareModalProps) => {
|
|||||||
isVisible={isVisible}
|
isVisible={isVisible}
|
||||||
ContentComponent={
|
ContentComponent={
|
||||||
<>
|
<>
|
||||||
{shareModalTx || shareModalTitle && (
|
{(shareModalTx || shareModalTitle) && (
|
||||||
<Text
|
<Text
|
||||||
tx={shareModalTx}
|
tx={shareModalTx}
|
||||||
text={shareModalTitle}
|
text={shareModalTitle}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ type Props = StaticScreenProps<undefined>
|
|||||||
export const PrivacyScreen = observer(function PrivacyScreen({ route }: Props) {
|
export const PrivacyScreen = observer(function PrivacyScreen({ route }: Props) {
|
||||||
const navigation = useNavigation()
|
const navigation = useNavigation()
|
||||||
const scrollY = useSharedValue(0)
|
const scrollY = useSharedValue(0)
|
||||||
const HEADER_SCROLL_DISTANCE = spacing.screenHeight * 0.07
|
const HEADER_SCROLL_DISTANCE = spacing.screenHeight * 0.15
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
navigation.setOptions({
|
navigation.setOptions({
|
||||||
@@ -205,16 +205,15 @@ export const PrivacyScreen = observer(function PrivacyScreen({ route }: Props) {
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Screen style={$screen} preset='fixed'>
|
<Screen style={$screen} preset='fixed'>
|
||||||
<AnimatedHeader
|
|
||||||
titleTx="privacyScreen_title"
|
|
||||||
scrollY={scrollY}
|
|
||||||
scrollDistance={HEADER_SCROLL_DISTANCE}
|
|
||||||
/>
|
|
||||||
<Animated.ScrollView
|
<Animated.ScrollView
|
||||||
style={$contentContainer}
|
style={$contentContainer}
|
||||||
onScroll={scrollHandler}
|
onScroll={scrollHandler}
|
||||||
scrollEventThrottle={16}
|
scrollEventThrottle={16}
|
||||||
>
|
>
|
||||||
|
<AnimatedHeader
|
||||||
|
titleTx="privacyScreen_title"
|
||||||
|
scrollY={scrollY}
|
||||||
|
/>
|
||||||
{/*<Card
|
{/*<Card
|
||||||
style={[$card, {marginTop: spacing.medium}]}
|
style={[$card, {marginTop: spacing.medium}]}
|
||||||
ContentComponent={
|
ContentComponent={
|
||||||
@@ -288,7 +287,7 @@ export const PrivacyScreen = observer(function PrivacyScreen({ route }: Props) {
|
|||||||
}
|
}
|
||||||
/>*/}
|
/>*/}
|
||||||
<Card
|
<Card
|
||||||
style={[$card, {marginTop: spacing.medium}]}
|
style={[$card, {marginTop: -spacing.extraLarge * 2}]}
|
||||||
ContentComponent={
|
ContentComponent={
|
||||||
<>
|
<>
|
||||||
<ListItem
|
<ListItem
|
||||||
@@ -425,13 +424,14 @@ const $screen: ViewStyle = {}
|
|||||||
|
|
||||||
const $contentContainer: TextStyle = {
|
const $contentContainer: TextStyle = {
|
||||||
flex: 1,
|
flex: 1,
|
||||||
marginTop: -spacing.extraLarge * 2,
|
// marginTop: -spacing.extraLarge * 2,
|
||||||
padding: spacing.extraSmall,
|
// padding: spacing.extraSmall,
|
||||||
// alignItems: 'center',
|
// alignItems: 'center',
|
||||||
}
|
}
|
||||||
|
|
||||||
const $card: ViewStyle = {
|
const $card: ViewStyle = {
|
||||||
marginBottom: 0,
|
marginBottom: 0,
|
||||||
|
marginHorizontal: spacing.small,
|
||||||
}
|
}
|
||||||
|
|
||||||
const $bottomModal: ViewStyle = {
|
const $bottomModal: ViewStyle = {
|
||||||
|
|||||||
@@ -39,7 +39,7 @@ type Props = StaticScreenProps<undefined>
|
|||||||
export const RecoveryOptionsScreen = observer(function RecoveryOptionsScreen(_: Props) {
|
export const RecoveryOptionsScreen = observer(function RecoveryOptionsScreen(_: Props) {
|
||||||
const navigation = useNavigation()
|
const navigation = useNavigation()
|
||||||
const scrollY = useSharedValue(0)
|
const scrollY = useSharedValue(0)
|
||||||
const HEADER_SCROLL_DISTANCE = spacing.screenHeight * 0.07
|
const HEADER_SCROLL_DISTANCE = spacing.screenHeight * 0.15
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
navigation.setOptions({
|
navigation.setOptions({
|
||||||
@@ -327,18 +327,18 @@ export const RecoveryOptionsScreen = observer(function RecoveryOptionsScreen(_:
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Screen preset="fixed" contentContainerStyle={$screen}>
|
<Screen preset="fixed" contentContainerStyle={$screen}>
|
||||||
<AnimatedHeader
|
|
||||||
titleTx="recoveryOptionsTitle"
|
|
||||||
scrollY={scrollY}
|
|
||||||
scrollDistance={HEADER_SCROLL_DISTANCE}
|
|
||||||
/>
|
|
||||||
<Animated.ScrollView
|
<Animated.ScrollView
|
||||||
style={$contentContainer}
|
style={$contentContainer}
|
||||||
|
//contentContainerStyle={{ paddingBottom: HEADER_SCROLL_DISTANCE }}
|
||||||
onScroll={scrollHandler}
|
onScroll={scrollHandler}
|
||||||
scrollEventThrottle={16}
|
scrollEventThrottle={16}
|
||||||
>
|
>
|
||||||
|
<AnimatedHeader
|
||||||
|
titleTx="recoveryOptionsTitle"
|
||||||
|
scrollY={scrollY}
|
||||||
|
/>
|
||||||
<Card
|
<Card
|
||||||
style={$card}
|
style={[$card, {marginTop: -spacing.extraLarge * 2}]}
|
||||||
HeadingComponent={
|
HeadingComponent={
|
||||||
<ListItem
|
<ListItem
|
||||||
tx="seedRecoveryOptions"
|
tx="seedRecoveryOptions"
|
||||||
@@ -601,8 +601,8 @@ const $screen: ViewStyle = {
|
|||||||
|
|
||||||
const $contentContainer: TextStyle = {
|
const $contentContainer: TextStyle = {
|
||||||
//flex: 1,
|
//flex: 1,
|
||||||
marginTop: -spacing.extraLarge * 2,
|
// marginTop: -spacing.extraLarge * 2,
|
||||||
padding: spacing.extraSmall,
|
// padding: spacing.extraSmall,
|
||||||
// alignItems: 'center',
|
// alignItems: 'center',
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -641,6 +641,7 @@ const $quoteInput: TextStyle = {
|
|||||||
|
|
||||||
const $card: ViewStyle = {
|
const $card: ViewStyle = {
|
||||||
marginBottom: spacing.small,
|
marginBottom: spacing.small,
|
||||||
|
marginHorizontal: spacing.small,
|
||||||
}
|
}
|
||||||
|
|
||||||
const $rightContainer: ViewStyle = {
|
const $rightContainer: ViewStyle = {
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ type Props = StaticScreenProps<undefined>
|
|||||||
export const SettingsScreen = observer(function SettingsScreen({ route }: Props) {
|
export const SettingsScreen = observer(function SettingsScreen({ route }: Props) {
|
||||||
const navigation = useNavigation()
|
const navigation = useNavigation()
|
||||||
const scrollY = useSharedValue(0)
|
const scrollY = useSharedValue(0)
|
||||||
const HEADER_SCROLL_DISTANCE = spacing.screenHeight * 0.07
|
const HEADER_SCROLL_DISTANCE = spacing.screenHeight * 0.15
|
||||||
|
|
||||||
useLayoutEffect(() => {
|
useLayoutEffect(() => {
|
||||||
navigation.setOptions({
|
navigation.setOptions({
|
||||||
@@ -315,18 +315,17 @@ export const SettingsScreen = observer(function SettingsScreen({ route }: Props)
|
|||||||
|
|
||||||
return (
|
return (
|
||||||
<Screen contentContainerStyle={$screen} preset='fixed'>
|
<Screen contentContainerStyle={$screen} preset='fixed'>
|
||||||
<AnimatedHeader
|
|
||||||
titleTx="settingsScreen_title"
|
|
||||||
scrollY={scrollY}
|
|
||||||
scrollDistance={HEADER_SCROLL_DISTANCE}
|
|
||||||
/>
|
|
||||||
<Animated.ScrollView
|
<Animated.ScrollView
|
||||||
style={$contentContainer}
|
style={$contentContainer}
|
||||||
onScroll={scrollHandler}
|
onScroll={scrollHandler}
|
||||||
scrollEventThrottle={16}
|
scrollEventThrottle={16}
|
||||||
>
|
>
|
||||||
|
<AnimatedHeader
|
||||||
|
titleTx="settingsScreen_title"
|
||||||
|
scrollY={scrollY}
|
||||||
|
/>
|
||||||
<Card
|
<Card
|
||||||
style={$card}
|
style={[$card, {marginTop: -spacing.extraLarge * 2}]}
|
||||||
ContentComponent={
|
ContentComponent={
|
||||||
<>
|
<>
|
||||||
<ListItem
|
<ListItem
|
||||||
@@ -595,12 +594,13 @@ const $screen: ViewStyle = {
|
|||||||
}
|
}
|
||||||
|
|
||||||
const $contentContainer: TextStyle = {
|
const $contentContainer: TextStyle = {
|
||||||
marginTop: -spacing.extraLarge * 2,
|
//marginTop: -spacing.extraLarge * 2,
|
||||||
padding: spacing.extraSmall,
|
//padding: spacing.extraSmall,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const $card: ViewStyle = {
|
const $card: ViewStyle = {
|
||||||
|
marginHorizontal: spacing.small,
|
||||||
//paddingVertical: 0,
|
//paddingVertical: 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -120,9 +120,9 @@ export const TranHistoryScreen = observer(function TranHistoryScreen({ route }:
|
|||||||
log.trace('[initFilter] toggleShowPendingOnly ')
|
log.trace('[initFilter] toggleShowPendingOnly ')
|
||||||
toggleShowPendingOnly()
|
toggleShowPendingOnly()
|
||||||
//@ts-ignore
|
//@ts-ignore
|
||||||
/* navigation.setParams({
|
navigation.setParams({
|
||||||
showPending: undefined,
|
showPending: undefined,
|
||||||
})*/
|
})
|
||||||
}
|
}
|
||||||
}, [])
|
}, [])
|
||||||
|
|
||||||
@@ -349,7 +349,7 @@ export const TranHistoryScreen = observer(function TranHistoryScreen({ route }:
|
|||||||
) : (
|
) : (
|
||||||
<Button
|
<Button
|
||||||
preset="secondary"
|
preset="secondary"
|
||||||
onPress={addTransactionsToList}
|
onPress={showPendingOnly ? addPendingTransactionsToList : addTransactionsToList}
|
||||||
tx="tranHistory_viewMore"
|
tx="tranHistory_viewMore"
|
||||||
style={{minHeight: 25, paddingVertical: spacing.tiny}}
|
style={{minHeight: 25, paddingVertical: spacing.tiny}}
|
||||||
textStyle={{fontSize: 14}}
|
textStyle={{fontSize: 14}}
|
||||||
|
|||||||
Reference in New Issue
Block a user