Skip to content

Commit

Permalink
feat(app): implement Snackbar with react-call
Browse files Browse the repository at this point in the history
  • Loading branch information
hbriese committed Aug 23, 2024
1 parent 6907e41 commit aa3ca89
Show file tree
Hide file tree
Showing 31 changed files with 160 additions and 198 deletions.
Binary file not shown.
1 change: 0 additions & 1 deletion app/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,6 @@
"react-native-screens": "3.31.1",
"react-native-svg": "15.2.0",
"react-native-tab-view": "^3.5.2",
"react-native-toast-message": "^2.2.0",
"react-native-typewriter": "^0.7.0",
"react-native-unistyles": "^2.9.1",
"react-native-web": "~0.19.12",
Expand Down
2 changes: 1 addition & 1 deletion app/src/app/(nav)/[account]/swap.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ import { getSwapOperations } from '~/util/swap/syncswap/swap';
import Decimal from 'decimal.js';
import { ampli } from '~/lib/ampli';
import { SwapToTokenItem } from '#/swap/SwapToTokenItem';
import { showError } from '#/provider/SnackbarProvider';
import { showError } from '#/Snackbar';
import { estimateSwap } from '~/util/swap/syncswap/estimate';
import { ScreenSkeleton } from '#/skeleton/ScreenSkeleton';
import { graphql } from 'relay-runtime';
Expand Down
2 changes: 1 addition & 1 deletion app/src/app/(sheet)/link.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { materialCommunityIcon } from '@theme/icons';
import { View } from 'react-native';
import { Text } from 'react-native-paper';
import { Button } from '#/Button';
import { showSuccess } from '#/provider/SnackbarProvider';
import { showSuccess } from '#/Snackbar';
import { z } from 'zod';
import { useLocalParams } from '~/hooks/useLocalParams';
import { createStyles, useStyles } from '@theme/styles';
Expand Down
2 changes: 1 addition & 1 deletion app/src/app/(sheet)/select/address.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import { ADDRESS_SELECTED } from '~/hooks/useSelectAddress';
import { zChain, zArray, zUAddress, zAddress } from '~/lib/zod';
import * as Clipboard from 'expo-clipboard';
import { isAddress } from 'viem';
import { showWarning } from '#/provider/SnackbarProvider';
import { showWarning } from '#/Snackbar';
import { BottomSheetScrollView } from '@gorhom/bottom-sheet';
import { graphql } from 'relay-runtime';
import { useLazyQuery } from '~/api';
Expand Down
4 changes: 2 additions & 2 deletions app/src/app/(sheet)/sessions/connect/[id].tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Actions } from '#/layout/Actions';
import { Sheet } from '#/sheet/Sheet';
import { AccountsList } from '#/walletconnect/AccountsList';
import { DappHeader } from '#/walletconnect/DappHeader';
import { hideSnackbar, showError, showSuccess } from '#/provider/SnackbarProvider';
import { hideSnackbar, showError, showSuccess } from '#/Snackbar';
import {
sessionChains,
supportedNamespaces,
Expand Down Expand Up @@ -91,7 +91,7 @@ export default function ConnectSessionSheet() {
}),
});

showSuccess(`Connected with ${dapp}`, { visibilityTime: 2000 });
showSuccess(`Connected with ${dapp}`, { duration: 2000 });
} catch (error) {
showError(`Failed to connect to ${dapp}: ${(error as Error).message}`, { event: { error } });
}
Expand Down
2 changes: 1 addition & 1 deletion app/src/app/(sheet)/wc.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import { Sheet } from '#/sheet/Sheet';
import { useLocalParams } from '~/hooks/useLocalParams';
import { useWalletConnectWithoutWatching } from '~/lib/wc';
import { zWalletConnectUri } from '~/lib/wc/uri';
import { showError } from '#/provider/SnackbarProvider';
import { showError } from '#/Snackbar';
import { useRouter } from 'expo-router';

export const WalletConnectUriScreenParams = z.object({ uri: zWalletConnectUri() });
Expand Down
4 changes: 2 additions & 2 deletions app/src/app/_layout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import { WalletConnectListeners } from '#/walletconnect/WalletConnectListeners';
import { AuthGate } from '#/provider/AuthGate';
import { ApiProvider } from '~/api/ApiProvider';
import { NotificationsProvider } from '#/provider/NotificationsProvider';
import { SnackbarProvider } from '#/provider/SnackbarProvider';
import { Snackbar } from '#/Snackbar';
import { UpdateProvider } from '#/provider/UpdateProvider';
import { ThemeProvider } from '~/util/theme/ThemeProvider';
import { SafeAreaProvider } from 'react-native-safe-area-context';
Expand Down Expand Up @@ -114,7 +114,7 @@ function RootLayout() {
</AuthGate>
</Suspense>
</Background>
<SnackbarProvider />
<Snackbar.Root />
<Confirm.Root />
</GestureHandlerRootView>
</IntlProvider>
Expand Down
2 changes: 1 addition & 1 deletion app/src/app/auth.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ import { useEffect } from 'react';
import AsyncStorage from '@react-native-async-storage/async-storage';
import * as Updates from 'expo-updates';
import { Confirm } from '#/Confirm';
import { showInfo } from '#/provider/SnackbarProvider';
import { showInfo } from '#/Snackbar';

const UNLOCKED = new Subject<true>();
const emitAuth = () => UNLOCKED.next(true);
Expand Down
2 changes: 1 addition & 1 deletion app/src/app/scan.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import { Actions } from '#/layout/Actions';
import { Address, UAddress, tryAsAddress } from 'lib';
import * as Linking from 'expo-linking';
import useAsyncEffect from 'use-async-effect';
import { showError } from '#/provider/SnackbarProvider';
import { showError } from '#/Snackbar';
import { parseAppLink } from '~/lib/appLink';
import { useFocusEffect, useRouter } from 'expo-router';
import { ScanOverlay } from '#/ScanOverlay';
Expand Down
2 changes: 1 addition & 1 deletion app/src/components/ScanOverlay.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { BackIcon, ContactsIcon, PasteIcon } from '~/util/theme/icons';
import { IconButton } from 'react-native-paper';
import { StyleSheet, View } from 'react-native';
import * as Clipboard from 'expo-clipboard';
import { showWarning } from '#/provider/SnackbarProvider';
import { showWarning } from '#/Snackbar';
import { useSelectAddress } from '~/hooks/useSelectAddress';
import { useRouter } from 'expo-router';
import { createStyles, useStyles } from '@theme/styles';
Expand Down
115 changes: 115 additions & 0 deletions app/src/components/Snackbar.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,115 @@
import { createStyles, useStyles } from '@theme/styles';
import { useEffect } from 'react';
import { createCallable } from 'react-call';
import { Snackbar as BaseSnackbar, Text } from 'react-native-paper';
import { Subject } from 'rxjs';
import { hapticFeedback } from '~/lib/haptic';
import { logEvent, LogEventParams } from '~/util/analytics';

const HIDE_SNACKBAR = new Subject<true>();

type SnackbarVariant = 'info' | 'success' | 'warning' | 'error';

export interface SnackbarProps {
variant?: SnackbarVariant;
message: string;
duration?: number;
action?: string;
event?: Partial<LogEventParams> | boolean;
}

export const Snackbar = createCallable<SnackbarProps, boolean>(
({ call, variant = 'info', message, duration = 6000, action, event }) => {
const { styles } = useStyles(getStylesheet({ variant }));

useEffect(() => {
const sub = HIDE_SNACKBAR.subscribe(() => call.end(false));
return () => sub.unsubscribe();
}, [call]);

useEffect(() => {
if (variant !== 'info') hapticFeedback(variant);
}, [variant]);

useEffect(() => {
if (event && variant !== 'success') {
logEvent({
level: variant,
message,
snackbar: true,
...(typeof event === 'object' && event),
});
}
}, [message, variant, event]);

return (
<BaseSnackbar
elevation={2}
visible
duration={duration}
onDismiss={() => call.end(false)}
style={[styles.snackbarBase, styles.snackbar]}
{...(action && {
action: {
label: action,
labelStyle: styles.actionLabel,
onPress: () => call.end(true),
},
})}
>
<Text variant="bodyMedium" style={styles.message}>
{message}
</Text>
</BaseSnackbar>
);
},
);

const getStylesheet = ({ variant }: { variant: SnackbarVariant }) =>
createStyles(({ colors }) => {
const s = {
info: {
snackbar: { backgroundColor: colors.inverseSurface },
message: { color: colors.inverseOnSurface },
actionLabel: { color: colors.inversePrimary },
},
success: {
snackbar: { backgroundColor: colors.successContainer },
message: { color: colors.onSuccessContainer },
},
warning: {
snackbar: { backgroundColor: colors.warningContainer },
message: { color: colors.onWarningContainer },
},
error: {
snackbar: { backgroundColor: colors.errorContainer },
message: { color: colors.onErrorContainer },
},
}[variant];

return {
actionLabel: {
color: colors.primary,
},
snackbarBase: {
maxWidth: 600,
},
...s,
};
});

type ShowOptions = Omit<SnackbarProps, 'variant' | 'message'>;

export const showInfo = (message: string, options?: ShowOptions) =>
Snackbar.call({ variant: 'info', message, ...options });

export const showSuccess = (message: string, options?: ShowOptions) =>
Snackbar.call({ variant: 'success', message, ...options });

export const showWarning = (message: string, options?: ShowOptions) =>
Snackbar.call({ variant: 'warning', message, ...options });

export const showError = (message: string, options?: ShowOptions) =>
Snackbar.call({ variant: 'error', message, ...options });

export const hideSnackbar = () => HIDE_SNACKBAR.next(true);
1 change: 0 additions & 1 deletion app/src/components/account/PolicySuggestions.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { Chip } from '#/Chip';
import { showError } from '#/provider/SnackbarProvider';
import { createStyles, useStyles } from '@theme/styles';
import { useRouter } from 'expo-router';
import { asChain } from 'lib';
Expand Down
2 changes: 1 addition & 1 deletion app/src/components/auth/PasswordSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { changeSecureStorePassword } from '~/lib/secure-storage';
import { createStyles, useStyles } from '@theme/styles';
import { Actions } from '#/layout/Actions';
import { Button } from '#/Button';
import { showInfo } from '#/provider/SnackbarProvider';
import { showInfo } from '#/Snackbar';

const PASSWORD_HASH = persistedAtom<string | null>('passwordHash', null);
export const usePasswordHash = () => useAtomValue(PASSWORD_HASH);
Expand Down
2 changes: 1 addition & 1 deletion app/src/components/cloud/google/useLinkGoogle.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { showError } from '#/provider/SnackbarProvider';
import { showError } from '#/Snackbar';
import { ampli } from '~/lib/ampli';
import { useGetGoogleApprover } from '#/cloud/google/useGetGoogleApprover';
import { graphql } from 'relay-runtime';
Expand Down
2 changes: 1 addition & 1 deletion app/src/components/cloud/useLinkApple.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { useGetAppleApprover } from './useGetAppleApprover';
import { showError } from '#/provider/SnackbarProvider';
import { showError } from '#/Snackbar';
import { ampli } from '~/lib/ampli';
import { graphql } from 'relay-runtime';
import { useFragment } from 'react-relay';
Expand Down
11 changes: 6 additions & 5 deletions app/src/components/link/ledger/LedgerItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { useCallback } from 'react';
import { ListItem } from '#/list/ListItem';
import { useGetLedgerApprover } from '~/app/(sheet)/ledger/approve';
import { APPROVER_BLE_IDS } from '~/hooks/ledger/useLedger';
import { showError } from '#/provider/SnackbarProvider';
import { showError } from '#/Snackbar';
import { useImmerAtom } from 'jotai-immer';
import { getLedgerDeviceModel } from '~/hooks/ledger/connectLedger';
import { elipseTruncate } from '~/util/format';
Expand Down Expand Up @@ -94,10 +94,11 @@ export function LedgerItem({ device: d, ...props }: LedgerItemProps) {
},
}),
);
if (!authHeaders)
return showError('Connection request cancelled', {
action: { label: 'Try again', onPress: connect },
});
if (!authHeaders) {
const retry = await showError('Connection request cancelled', { action: 'Try again' });
if (retry) connect();
return;
}

// 1. Link
const { approvers } = (await link({ token: user.linkingToken }, { headers: authHeaders })).link;
Expand Down
21 changes: 9 additions & 12 deletions app/src/components/policy/ApprovalSettings.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { ListItemHorizontalTrailing } from '#/list/ListItemHorizontalTrailing';
import { ListItemTrailingText } from '#/list/ListItemTrailingText';
import { ApproverItem } from '#/policy/ApproverItem';
import { ThresholdChip } from './ThresholdChip';
import { showInfo } from '#/provider/SnackbarProvider';
import { showInfo } from '#/Snackbar';
import { useSelectAddress } from '~/hooks/useSelectAddress';
import { useToggle } from '~/hooks/useToggle';
import { usePolicyDraft } from '~/lib/policy/policyAsDraft';
Expand Down Expand Up @@ -38,24 +38,21 @@ export function ApprovalSettings() {
}
};

const remove = (approver: Address) => {
const remove = async (approver: Address) => {
const originalThreshold = policy.threshold;

update((draft) => {
draft.approvers.delete(approver);
draft.threshold = Math.max(policy.threshold, policy.approvers.size);
});

showInfo('Approver removed', {
action: {
label: 'Undo',
onPress: () =>
update((draft) => {
draft.approvers.add(approver);
draft.threshold = originalThreshold;
}),
},
});
const undo = await showInfo('Approver removed', { action: 'Undo' });
if (undo) {
update((draft) => {
draft.approvers.add(approver);
draft.threshold = originalThreshold;
});
}
};

return (
Expand Down
4 changes: 2 additions & 2 deletions app/src/components/policy/PolicySideSheet.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ import { FormTextField } from '#/fields/FormTextField';
import { Actions } from '#/layout/Actions';
import { FormSubmitButton } from '#/fields/FormSubmitButton';
import { usePolicyDraft } from '~/lib/policy/policyAsDraft';
import { showError } from '#/provider/SnackbarProvider';
import { showError } from '#/Snackbar';
import { SideSheet } from '../SideSheet/SideSheet';
import { Button } from '../Button';
import { createStyles, useStyles } from '@theme/styles';
Expand Down Expand Up @@ -122,7 +122,7 @@ export function PolicySideSheet(props: PolicySideSheetProps) {
if (policy && draft.key !== undefined) {
const r = (await rename({ account: draft.account, key: draft.key, name }))
?.updatePolicyDetails;
if (r?.__typename !== 'Policy') return showError(r?.message);
if (r?.__typename !== 'Policy') return showError(r?.message || 'Unknown error');
}

updateDraft((draft) => {
Expand Down
Loading

0 comments on commit aa3ca89

Please sign in to comment.