Skip to content

Commit

Permalink
fix button && danger banner && refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
voloshinskii committed May 1, 2024
1 parent cc5aa59 commit 78e1205
Show file tree
Hide file tree
Showing 29 changed files with 275 additions and 125 deletions.
48 changes: 45 additions & 3 deletions packages/mobile/src/core/HideableAmount/ShowBalance.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,41 @@ import { Steezy } from '$styles';
import { Pressable, View } from '$uikit';
import { Haptics, isAndroid } from '$utils';
import { DarkTheme } from '$styled';
import { Text } from '@tonkeeper/uikit';
import { Icon, Text } from '@tonkeeper/uikit';
import { DangerLevel } from '@tonkeeper/shared/hooks';
import { useNavigation } from '@tonkeeper/router';
import { SettingsStackRouteNames } from '$navigation';

const TouchableComponent = isAndroid ? Pressable : TouchableHighlight;

export const ShowBalance: React.FC<{ amount: string }> = ({ amount }) => {
const getColorByDangerLevel = (
dangerLevel: DangerLevel,
): undefined | 'accentOrange' | 'accentRed' => {
switch (dangerLevel) {
case DangerLevel.Normal:
return undefined;
case DangerLevel.Medium:
return 'accentOrange';
case DangerLevel.High:
return 'accentRed';
}
};

export const ShowBalance: React.FC<{ amount: string; dangerLevel: DangerLevel }> = ({
amount,
dangerLevel,
}) => {
const hideAmounts = usePrivacyStore((state) => state.actions.toggleHiddenAmounts);
const isHidden = usePrivacyStore((state) => state.hiddenAmounts);
const nav = useNavigation();

const handleToggleHideAmounts = useCallback(() => {
hideAmounts();
Haptics.impactHeavy();
}, [hideAmounts]);

const handleNavigateToBackup = () => nav.navigate(SettingsStackRouteNames.Backup);

return (
<View style={styles.container}>
{isHidden ? (
Expand All @@ -34,7 +56,22 @@ export const ShowBalance: React.FC<{ amount: string }> = ({ amount }) => {
</View>
) : (
<TouchableOpacity activeOpacity={0.6} onPress={handleToggleHideAmounts}>
<Text type="num3">{amount}</Text>
<Text color={getColorByDangerLevel(dangerLevel)} type="num3">
{amount}
</Text>
</TouchableOpacity>
)}
{dangerLevel !== DangerLevel.Normal && (
<TouchableOpacity
onPress={handleNavigateToBackup}
activeOpacity={0.6}
hitSlop={{ right: 20 }}
style={styles.dangerButton.static}
>
<Icon
name={'ic-information-circle-24'}
color={getColorByDangerLevel(dangerLevel)}
/>
</TouchableOpacity>
)}
</View>
Expand All @@ -46,6 +83,7 @@ const styles = Steezy.create(({ colors }) => ({
flexDirection: 'row',
height: 54,
alignItems: 'center',
gap: 8,
},
starsContainer: {
height: 40,
Expand All @@ -59,4 +97,8 @@ const styles = Steezy.create(({ colors }) => ({
stars: {
paddingTop: 8,
},
dangerButton: {
paddingTop: 21,
paddingBottom: 11,
},
}));
51 changes: 49 additions & 2 deletions packages/mobile/src/screens/BackupScreen/BackupScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,16 +4,51 @@ import { memo } from 'react';
import { format } from 'date-fns';
import { getLocale } from '$utils/date';
import { i18n, t } from '@tonkeeper/shared/i18n';
import { useWalletSetup } from '@tonkeeper/shared/hooks';
import {
DangerLevel,
useDangerLevel,
useWalletCurrency,
useWalletSetup,
} from '@tonkeeper/shared/hooks';
import { tk } from '$wallet';
import { formatter } from '@tonkeeper/shared/formatter';

export const BackupScreen = memo(() => {
const { lastBackupAt } = useWalletSetup();
const nav = useNavigation();

const currency = useWalletCurrency();
const dangerLevel = useDangerLevel(tk.wallet.totalTon);

return (
<Screen>
<Screen.Header title={t('backup_screen.title')} />
<Screen.ScrollView>
{dangerLevel !== DangerLevel.Normal && (
<>
<View
style={[
styles.dangerBanner,
DangerLevel.Medium && styles.dangerBannerYellow,
DangerLevel.High && styles.dangerBannerRed,
]}
>
<Text
type="body2"
color={
dangerLevel === DangerLevel.Medium
? 'textPrimaryAlternate'
: 'textPrimary'
}
>
{t('backup_screen.backup_warning', {
totalFiat: formatter.format(tk.wallet.totalFiat, { currency }),
})}
</Text>
</View>
<Spacer y={16} />
</>
)}
<View style={styles.info}>
<Text type="h3">{t('backup_screen.manual_title')}</Text>
<Spacer y={4} />
Expand All @@ -27,7 +62,7 @@ export const BackupScreen = memo(() => {
<Button
onPress={() => nav.navigate('/backup-warning')}
title={t('backup_screen.manual_button')}
color="secondary"
color={dangerLevel === DangerLevel.Normal ? 'secondary' : 'primary'}
/>
</View>
) : (
Expand Down Expand Up @@ -92,4 +127,16 @@ const styles = Steezy.create(({ colors }) => ({
position: 'absolute',
right: 16,
},
dangerBanner: {
paddingHorizontal: 16,
paddingVertical: 12,
marginHorizontal: 16,
borderRadius: 16,
},
dangerBannerYellow: {
backgroundColor: colors.accentOrange,
},
dangerBannerRed: {
backgroundColor: colors.accentRed,
},
}));
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
import React, { FC, useCallback, useMemo, useRef, useState } from 'react';
import Animated, {
FadeIn,
FadeOut,
useAnimatedScrollHandler,
useAnimatedStyle,
useSharedValue,
withTiming,
} from 'react-native-reanimated';
import { TapGestureHandler } from 'react-native-gesture-handler';
import { useSafeAreaInsets } from 'react-native-safe-area-context';
Expand Down Expand Up @@ -40,7 +39,7 @@ export const ImportWalletForm: FC<ImportWalletFormProps> = (props) => {
const [isConfigInputShown, setConfigInputShown] = useState(false);
const [config, setConfig] = useState('');
const [isRestoring, setRestoring] = useState(false);
const [hasTouchedInputs, setHasTouchedInputs] = useState(false);
const [hasTextInAnyOfInputs, setHasTextInAnyOfInputs] = useState(false);

const deferredScrollToInput = useRef<((offset: number) => void) | null>(null);
const { keyboardHeight } = useReanimatedKeyboardHeight({
Expand All @@ -64,8 +63,8 @@ export const ImportWalletForm: FC<ImportWalletFormProps> = (props) => {

const handleMultipleWords = useCallback(
(index: number, text: string) => {
if (!hasTouchedInputs) {
setHasTouchedInputs(true);
if (!hasTextInAnyOfInputs) {
setHasTextInAnyOfInputs(true);
}
const words = text
.replace(/\r\n|\r|\n/g, ' ')
Expand All @@ -86,18 +85,18 @@ export const ImportWalletForm: FC<ImportWalletFormProps> = (props) => {
inputsRegistry.getRef(cursor - 1)?.focus();
}
},
[hasTouchedInputs, inputsRegistry],
[hasTextInAnyOfInputs, inputsRegistry],
);

const handlePasteButton = useCallback(async () => {
if (!hasTouchedInputs) {
setHasTouchedInputs(true);
if (!hasTextInAnyOfInputs) {
setHasTextInAnyOfInputs(true);
}
const maybePhrase = await Clipboard.getString();
if (maybePhrase.replace(/\r\n|\r|\n/g, ' ').split(' ').length === 24) {
handleMultipleWords(0, maybePhrase);
}
}, [hasTouchedInputs, handleMultipleWords]);
}, [hasTextInAnyOfInputs, handleMultipleWords]);

const handleSpace = useCallback((index: number) => {
if (index === 24) {
Expand Down Expand Up @@ -207,8 +206,14 @@ export const ImportWalletForm: FC<ImportWalletFormProps> = (props) => {

const handleChangeText = useCallback(
(index: number) => (text: string) => {
if (!hasTouchedInputs) {
setHasTouchedInputs(true);
if (
!text &&
hasTextInAnyOfInputs &&
Object.values(inputsRegistry.refs).filter((val) => val.getValue()).length === 1
) {
setHasTextInAnyOfInputs(false);
} else if (!hasTextInAnyOfInputs) {
setHasTextInAnyOfInputs(true);
}
const overlap = 10;
const offsetTop = inputsRegistry.getPosition(index) + S.INPUT_HEIGHT - overlap;
Expand All @@ -226,7 +231,7 @@ export const ImportWalletForm: FC<ImportWalletFormProps> = (props) => {
},
});
},
[hasTouchedInputs],
[hasTextInAnyOfInputs],
);

const scrollHandler = useAnimatedScrollHandler({
Expand Down Expand Up @@ -296,16 +301,21 @@ export const ImportWalletForm: FC<ImportWalletFormProps> = (props) => {
</Animated.ScrollView>
<KeyboardAvoidingView>
<View style={[styles.pasteButtonContainer, { bottom: bottomInset + 16 }]}>
{!hasTouchedInputs && (
<Animated.View exiting={FadeOut.duration(200)}>
<ButtonNew
onPress={handlePasteButton}
color="tertiary"
size="medium"
title={t('paste')}
/>
</Animated.View>
)}
<View style={styles.buttonContainer}>
{!hasTextInAnyOfInputs && (
<Animated.View
exiting={FadeOut.duration(200)}
entering={FadeIn.duration(200)}
>
<ButtonNew
onPress={handlePasteButton}
color="tertiary"
size="medium"
title={t('paste')}
/>
</Animated.View>
)}
</View>
</View>
</KeyboardAvoidingView>
</>
Expand All @@ -317,6 +327,6 @@ const styles = Steezy.create({
position: 'absolute',
left: 0,
right: 0,
alignItems: 'center',
},
buttonContainer: { height: 48, width: '100%', alignItems: 'center' },
});
5 changes: 4 additions & 1 deletion packages/mobile/src/tabs/Wallet/WalletScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,10 @@ export const WalletScreen = memo(({ navigation }) => {
{shouldUpdate && <UpdatesCell />}
<View style={styles.amount} pointerEvents="box-none">
<View style={styles.balanceWithBattery}>
<ShowBalance amount={balance} />
<ShowBalance
dangerLevel={balance.dangerLevel}
amount={balance.inSelectedCurrency}
/>
{!isWatchOnly && <BatteryIcon />}
</View>
<View style={styles.addressContainer}>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,13 @@
import { DependencyPrototype } from './utils/prototype';
import { tk } from '$wallet';

import { TonInscriptionsState } from '$wallet/managers/TonInscriptions';
import { Wallet } from '$wallet/Wallet';

export class InscriptionsDependency extends DependencyPrototype<
TonInscriptionsState,
TonInscriptionsState['items']
> {
constructor() {
super(tk.wallet.tonInscriptions.state, (state) => state.items);
}

setWallet(wallet) {
this.dataProvider = wallet.tonInscriptions.state;
super.setWallet(wallet);
constructor(wallet: Wallet) {
super(wallet.tonInscriptions.state, (state) => state.items);
}
}
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
import { DependencyPrototype } from './utils/prototype';
import { tk } from '$wallet';

import { JettonsState } from '$wallet/managers/JettonsManager';
import { FiatRate } from '../utils/types';
import { Address } from '@tonkeeper/core';
import { formatter } from '$utils/formatter';
import BigNumber from 'bignumber.js';
import { Wallet } from '$wallet/Wallet';

export class JettonBalancesDependency extends DependencyPrototype<
JettonsState,
Pick<JettonsState, 'jettonBalances' | 'jettonRates'>
> {
constructor() {
super(tk.wallet.jettons.state, (state) => ({
constructor(wallet: Wallet) {
super(wallet.jettons.state, (state) => ({
jettonBalances: state.jettonBalances,
jettonRates: state.jettonRates,
}));
Expand Down Expand Up @@ -40,6 +40,7 @@ export class JettonBalancesDependency extends DependencyPrototype<
trend:
rate.diff_24h.startsWith('+') || rate.diff_24h === '0' ? 'positive' : 'negative',
total: {
in_ton: new BigNumber(jettonBalance).multipliedBy(rate.ton).toString(),
formatted: formatter.format(
new BigNumber(jettonBalance).multipliedBy(rate.fiat),
{ currency },
Expand All @@ -48,9 +49,4 @@ export class JettonBalancesDependency extends DependencyPrototype<
},
};
}

setWallet(wallet) {
this.dataProvider = wallet.jettons.state;
super.setWallet(wallet);
}
}
Original file line number Diff line number Diff line change
@@ -1,21 +1,16 @@
import { DependencyPrototype } from './utils/prototype';
import { tk } from '$wallet';

import { StakingState } from '$wallet/managers/StakingManager';
import { AccountStakingInfo, PoolInfo } from '@tonkeeper/core/src/TonAPI';
import { Wallet } from '$wallet/Wallet';

export class StakingDependency extends DependencyPrototype<
StakingState,
{ info: AccountStakingInfo; pool: PoolInfo }[]
> {
constructor() {
super(tk.wallet.staking.state, (s) =>
constructor(wallet: Wallet) {
super(wallet.staking.state, (s) =>
s.pools.map((pool) => ({ info: s.stakingInfo[pool.address], pool })),
);
}

setWallet(wallet) {
this.dataProvider = wallet.staking.state;
super.setWallet(wallet);
}
}
Loading

0 comments on commit 78e1205

Please sign in to comment.