diff --git a/apps/expo/app/_layout.tsx b/apps/expo/app/_layout.tsx index 313046fc..d9e85239 100644 --- a/apps/expo/app/_layout.tsx +++ b/apps/expo/app/_layout.tsx @@ -185,6 +185,11 @@ export default function HomeLayout() { headerShadowVisible: false, headerTintColor: config.tokens.color['primary-500'].val, headerTitle: 'Inbox', + headerTitleAlign: 'center', + headerTitleStyle: { + fontWeight: isAndroid() ? '700' : '500', // Match font weight on android to native back button style + fontSize: 18, + }, }} name="notifications/inbox" /> diff --git a/packages/app/components/CredentialCard.tsx b/packages/app/components/CredentialCard.tsx index 668fc989..5791c478 100644 --- a/packages/app/components/CredentialCard.tsx +++ b/packages/app/components/CredentialCard.tsx @@ -6,7 +6,6 @@ import { Image, Paragraph, Heading, - Spacer, FileBadge, darken, getTextColorBasedOnBg, @@ -61,6 +60,7 @@ export default function CredentialCard({ pressStyle={{ backgroundColor: onPress && darken(bgColor ?? '$grey-900', 0.05), }} + h="$16" borderWidth={0.5} borderColor="$borderTranslucent" onPress={onPress} @@ -69,7 +69,7 @@ export default function CredentialCard({ {icon} - + {name} - Issuer - + {issuerName} diff --git a/packages/app/components/CredentialRowCard.tsx b/packages/app/components/CredentialRowCard.tsx index a76ddc68..837878a7 100644 --- a/packages/app/components/CredentialRowCard.tsx +++ b/packages/app/components/CredentialRowCard.tsx @@ -6,6 +6,7 @@ interface CredentialRowCardProps { onPress?(): void bgColor?: string hideBorder?: boolean + showFullText?: boolean } export default function CredentialRowCard({ @@ -14,6 +15,7 @@ export default function CredentialRowCard({ bgColor, onPress, hideBorder = false, + showFullText = false, }: CredentialRowCardProps) { return ( @@ -24,13 +26,13 @@ export default function CredentialRowCard({ pressStyle={{ backgroundColor: onPress && '$grey-100' }} overflow="hidden" > - - - + + + {name} {issuer && ( - + {issuer} )} diff --git a/packages/app/components/DualResponseButtons.tsx b/packages/app/components/DualResponseButtons.tsx new file mode 100644 index 00000000..fc389c5d --- /dev/null +++ b/packages/app/components/DualResponseButtons.tsx @@ -0,0 +1,24 @@ +import { YStack, Button, Spinner } from '@internal/ui' + +interface DualResponseButtonProps { + isAccepting?: boolean + onAccept: () => void + onDecline: () => void +} + +export default function DualResponseButtons({ + onAccept, + onDecline, + isAccepting, +}: DualResponseButtonProps) { + return ( + + + {isAccepting ? : 'Accept'} + + + Decline + + + ) +} diff --git a/packages/app/components/InboxNotificationRowCard.tsx b/packages/app/components/InboxNotificationRowCard.tsx index dd067bbf..ba4f557a 100644 --- a/packages/app/components/InboxNotificationRowCard.tsx +++ b/packages/app/components/InboxNotificationRowCard.tsx @@ -21,7 +21,7 @@ export default function InboxNotificationRowCard({ overflow="hidden" > - + {description} diff --git a/packages/app/features/notifications/components/CredentialNotificationScreen.tsx b/packages/app/features/notifications/components/CredentialNotificationScreen.tsx index 539bb94a..37aaafd1 100644 --- a/packages/app/features/notifications/components/CredentialNotificationScreen.tsx +++ b/packages/app/features/notifications/components/CredentialNotificationScreen.tsx @@ -1,10 +1,12 @@ import type { CredentialDisplay } from '@internal/agent' -import { YStack, Heading, Button, Spacer, ScrollView, Spinner } from '@internal/ui' +import { YStack, Heading, ScrollView } from '@internal/ui' import React from 'react' +import { useSafeAreaInsets } from 'react-native-safe-area-context' import CredentialAttributes from 'app/components/CredentialAttributes' import CredentialCard from 'app/components/CredentialCard' +import DualResponseButtons from 'app/components/DualResponseButtons' interface CredentialNotificationScreenProps { display: CredentialDisplay @@ -22,8 +24,9 @@ export function CredentialNotificationScreen({ onAccept, onDecline, }: CredentialNotificationScreenProps) { + const { bottom } = useSafeAreaInsets() return ( - + @@ -41,16 +44,8 @@ export function CredentialNotificationScreen({ /> - - - {isAccepting ? : 'Accept'} - - - Decline - - + - ) } diff --git a/packages/app/features/notifications/components/PresentationNotificationScreen.tsx b/packages/app/features/notifications/components/PresentationNotificationScreen.tsx index f9d82af5..2faf7c1f 100644 --- a/packages/app/features/notifications/components/PresentationNotificationScreen.tsx +++ b/packages/app/features/notifications/components/PresentationNotificationScreen.tsx @@ -1,10 +1,12 @@ import type { FormattedSubmission } from '@internal/agent' -import { YStack, Heading, Button, ScrollView, Spinner, Paragraph } from '@internal/ui' +import { YStack, Heading, Button, ScrollView, Paragraph } from '@internal/ui' import { sanitizeString } from '@internal/utils' import React from 'react' +import { useSafeAreaInsets } from 'react-native-safe-area-context' import CredentialRowCard from 'app/components/CredentialRowCard' +import DualResponseButtons from 'app/components/DualResponseButtons' interface PresentationNotificationScreenProps { submission: FormattedSubmission @@ -21,14 +23,14 @@ export function PresentationNotificationScreen({ submission, verifierName, }: PresentationNotificationScreenProps) { + const { bottom } = useSafeAreaInsets() return ( @@ -56,8 +58,9 @@ export function PresentationNotificationScreen({ {s.description && ( @@ -66,13 +69,13 @@ export function PresentationNotificationScreen({ )} {s.isSatisfied && s.requestedAttributes ? ( - + The following information will be presented: {s.requestedAttributes.map((a) => ( - + • {sanitizeString(a)} ))} @@ -89,12 +92,11 @@ export function PresentationNotificationScreen({ {submission.areAllSatisfied ? ( - - - {isAccepting ? : 'Accept'} - - Decline - + ) : ( diff --git a/packages/app/features/wallet/WalletScreen.tsx b/packages/app/features/wallet/WalletScreen.tsx index 6ce0292c..d6360cd1 100644 --- a/packages/app/features/wallet/WalletScreen.tsx +++ b/packages/app/features/wallet/WalletScreen.tsx @@ -17,6 +17,7 @@ import { YStack, ZStack, } from '@internal/ui' +import { useSafeAreaInsets } from 'react-native-safe-area-context' import { useRouter } from 'solito/router' import CredentialCard from 'app/components/CredentialCard' @@ -32,7 +33,7 @@ export function WalletScreen() { const firstThreeRecords = credentials.slice(0, 3) const { handleScroll, isScrolledByOffset, scrollEventThrottle } = useScrollViewPosition(HEADER_TITLE_TEXT_HEIGHT) - + const { bottom } = useSafeAreaInsets() const navigateToCredentialDetail = (id: string) => push(`/credentials/${id}`) const navigateToScanner = useNetworkCallback(() => push('/scan')) @@ -51,7 +52,7 @@ export function WalletScreen() { zIndex="$5" position="absolute" right="$6" - bottom="$6" + bottom={bottom ?? '$6'} bg="$grey-900" br="$12" p="$4" diff --git a/packages/app/provider/index.tsx b/packages/app/provider/index.tsx index 85532b21..35c1c3e9 100644 --- a/packages/app/provider/index.tsx +++ b/packages/app/provider/index.tsx @@ -20,7 +20,7 @@ export function Provider({ children, ...rest }: Omit { + return ( + + {children} + + + ) +} diff --git a/packages/ui/src/base/index.ts b/packages/ui/src/base/index.ts index 4062e6ac..6e40db4b 100644 --- a/packages/ui/src/base/index.ts +++ b/packages/ui/src/base/index.ts @@ -3,3 +3,4 @@ export * from './Headings' export * from './Paragraph' export * from './Stacks' export * from './Page' +export * from './ScrollView' diff --git a/packages/ui/src/constants.ts b/packages/ui/src/constants.ts index 3993ba5e..6629bb6b 100644 --- a/packages/ui/src/constants.ts +++ b/packages/ui/src/constants.ts @@ -1,5 +1,4 @@ -export const HEADER_STATUS_BAR_HEIGHT = 56 -export const BASE_CREDENTIAL_CARD_HEIGHT = 196 +export const BASE_CREDENTIAL_CARD_HEIGHT = 212 export const CREDENTIAL_TOP_INFO_OFFSET = 56 export const CREDENTIAL_TOP_INFO_HEIGHT = 64 export const HEADER_TITLE_TEXT_HEIGHT = 38 diff --git a/packages/ui/src/content/Icon.tsx b/packages/ui/src/content/Icon.tsx index 89aa8b17..4eabfbf1 100644 --- a/packages/ui/src/content/Icon.tsx +++ b/packages/ui/src/content/Icon.tsx @@ -7,4 +7,5 @@ export { CornerDownRight, AlertOctagon, Inbox, + X, } from '@tamagui/lucide-icons' diff --git a/packages/ui/src/index.tsx b/packages/ui/src/index.tsx index 83772cd4..6be970c6 100644 --- a/packages/ui/src/index.tsx +++ b/packages/ui/src/index.tsx @@ -1,6 +1,6 @@ export { tokens, config, absoluteFill, Colors } from './config/tamagui.config' export * from './constants' -export { TamaguiProviderProps, TamaguiProvider, ScrollView, Spacer, AnimatePresence } from 'tamagui' +export { TamaguiProviderProps, TamaguiProvider, Spacer, AnimatePresence } from 'tamagui' export { ToastProvider, useToastController, ToastViewport, useToastState } from '@tamagui/toast' export * from './panels' export * from './base' diff --git a/packages/ui/src/panels/ToastContainer.tsx b/packages/ui/src/panels/ToastContainer.tsx index 67dd6482..a34dad1a 100644 --- a/packages/ui/src/panels/ToastContainer.tsx +++ b/packages/ui/src/panels/ToastContainer.tsx @@ -1,4 +1,7 @@ -import { Paragraph, YStack } from '../base' +import { useToastController } from '@tamagui/toast' + +import { Paragraph, XStack } from '../base' +import { X } from '../content' interface ToastContainerProps { title: string @@ -6,8 +9,9 @@ interface ToastContainerProps { } export const ToastContainer = ({ title, safeAreaMargin = false }: ToastContainerProps) => { + const toast = useToastController() return ( - - {title} - + {title} + toast.hide()} color="$grey-600" /> + ) } diff --git a/packages/utils/src/format.ts b/packages/utils/src/format.ts index 1d9a3125..f7ac220e 100644 --- a/packages/utils/src/format.ts +++ b/packages/utils/src/format.ts @@ -14,7 +14,7 @@ export function sanitizeString(str: string) { const result = str.replace(/([a-z0-9])([A-Z])/g, '$1 $2') let words = result.split(' ') words = words.map((word, index) => { - if (index === 0) { + if (index === 0 || word.toUpperCase() === word) { return word.charAt(0).toUpperCase() + word.slice(1) } else { return word.charAt(0).toLowerCase() + word.slice(1)