Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions app/components/UI/Notification/List/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -157,11 +157,11 @@ export function NotificationsListItem(props: NotificationsListItemProps) {
style={tw`gap-2`}
>
<Box style={tw`flex-row gap-4`}>
<NotificationMenuItem.Icon
<NotificationMenuItem.Icon {...menuItemState} />
<NotificationMenuItem.Content
isRead={props.notification.isRead}
{...menuItemState}
/>
<NotificationMenuItem.Content {...menuItemState} />
</Box>
</NotificationMenuItem.Root>
);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react';
import renderWithProvider from '../../../../util/test/renderWithProvider';

import NotificationContent from './Content';
import NotificationContent, { TEST_IDS } from './Content';

describe('NotificationContent', () => {
const title = 'Welcome to the new Test!';
Expand All @@ -15,6 +15,7 @@ describe('NotificationContent', () => {
it('renders title and description', () => {
const { getByText } = renderWithProvider(
<NotificationContent
isRead
title={title}
description={{
start: description.start,
Expand All @@ -28,4 +29,32 @@ describe('NotificationContent', () => {
expect(getByText(description.start)).toBeOnTheScreen();
expect(getByText(description.end)).toBeOnTheScreen();
});

it.each([
{ isRead: false, visible: true },
{ isRead: true, visible: false },
])(
'renders unread indicator when isRead is $isRead',
({ isRead, visible }) => {
const { queryByTestId } = renderWithProvider(
<NotificationContent
isRead={isRead}
title={title}
description={{
start: description.start,
end: description.end,
}}
createdAt={createdAt}
/>,
);

const unreadBadge = queryByTestId(TEST_IDS.UNREAD_BADGE);

if (visible) {
expect(unreadBadge).toBeOnTheScreen();
} else {
expect(unreadBadge).not.toBeOnTheScreen();
}
},
);
});
29 changes: 24 additions & 5 deletions app/components/UI/Notification/NotificationMenuItem/Content.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,10 @@
import React from 'react';
import { View } from 'react-native';
import {
BadgeStatus,
BadgeStatusStatus,
} from '@metamask/design-system-react-native';
import { useTailwind } from '@metamask/design-system-twrnc-preset';
import Text, {
TextColor,
TextVariant,
Expand All @@ -8,28 +13,42 @@ import { NotificationMenuItem } from '../../../../util/notifications/notificatio
import useStyles from '../List/useStyles';
import { formatMenuItemDate } from '../../../../util/notifications/methods';

export const TEST_IDS = {
UNREAD_BADGE: 'notification-menu-item-content:unread-badge',
};

type NotificationContentProps = Pick<
NotificationMenuItem,
'title' | 'description' | 'createdAt'
>;
> & { isRead: boolean };

function NotificationContent(props: NotificationContentProps) {
const { styles } = useStyles();
const tw = useTailwind();

return (
<View style={styles.containerFill}>
{/* Section 1 - Title + Timestamp */}
<View style={styles.rowInsider}>
<View style={[styles.rowInsider, tw`items-center`]}>
<Text
color={TextColor.Alternative}
variant={TextVariant.BodySM}
style={styles.containerFill}
>
{props.title}
</Text>
<Text color={TextColor.Muted} variant={TextVariant.BodySM}>
{formatMenuItemDate(new Date(props.createdAt))}
</Text>
<View style={tw`flex-row items-center gap-1`}>
{!props.isRead && (
<BadgeStatus
status={BadgeStatusStatus.New}
testID={TEST_IDS.UNREAD_BADGE}
style={tw`self-center`}
/>
)}
<Text color={TextColor.Muted} variant={TextVariant.BodySM}>
{formatMenuItemDate(new Date(props.createdAt))}
</Text>
</View>
</View>
{/* Section 2 - Left Desc + Right Desc */}
<View style={styles.rowInsider}>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,6 @@ describe('NotificationIcon', () => {
({ hasBadge, assertion }) => {
const { getByTestId, queryByTestId } = renderWithProvider(
<NotificationIcon
isRead={false}
image={{ url: walletNotification.imageUrl.name }}
badgeIcon={hasBadge ? walletNotification.badgeIcon : undefined}
/>,
Expand Down
31 changes: 6 additions & 25 deletions app/components/UI/Notification/NotificationMenuItem/Icon.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,6 @@
import { View } from 'react-native';
import { Image } from 'expo-image';
import {
BadgeIcon,
IconSize,
BadgeStatus,
BadgeStatusStatus,
} from '@metamask/design-system-react-native';
import { BadgeIcon, IconSize } from '@metamask/design-system-react-native';
import { useTailwind } from '@metamask/design-system-twrnc-preset';
import { NotificationMenuItem } from '../../../../util/notifications/notification-states/types/NotificationMenuItem';
import React, {
Expand All @@ -24,12 +19,9 @@
ICON: 'notification-menu-item-icon:icon',
};

type NotificationIconProps = Pick<
NotificationMenuItem,
'image' | 'badgeIcon'
> & { isRead: boolean };
type NotificationIconProps = Pick<NotificationMenuItem, 'image' | 'badgeIcon'>;

function MenuIcon(props: NotificationIconProps) {

Check warning on line 24 in app/components/UI/Notification/NotificationMenuItem/Icon.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Mark the props of the component as read-only.

See more on https://sonarcloud.io/project/issues?id=MetaMask_metamask-mobile&issues=AZ8-tt9rMuL2N5cTbnfQ&open=AZ8-tt9rMuL2N5cTbnfQ&pullRequest=32919
const tw = useTailwind();
const { styles } = useStyles();

Expand All @@ -55,8 +47,7 @@
);
}

function NotificationIcon(props: NotificationIconProps) {

Check warning on line 50 in app/components/UI/Notification/NotificationMenuItem/Icon.tsx

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Mark the props of the component as read-only.

See more on https://sonarcloud.io/project/issues?id=MetaMask_metamask-mobile&issues=AZ8-tt9rMuL2N5cTbnfR&open=AZ8-tt9rMuL2N5cTbnfR&pullRequest=32919
const tw = useTailwind();
const { styles } = useStyles();

const MaybeBadgeContainer: FC<PropsWithChildren> = useCallback(
Expand All @@ -79,21 +70,11 @@
[props.badgeIcon],
);

const statusStyle = useMemo(
() => (props.isRead ? tw`self-center opacity-0` : tw`self-center`),
[props.isRead, tw],
);

return (
<View>
<View style={tw`flex-row gap-1`}>
<BadgeStatus status={BadgeStatusStatus.New} style={statusStyle} />
<View style={styles.itemLogoSize} testID={TEST_IDS.CONTAINER}>
<MaybeBadgeContainer>
<MenuIcon {...props} />
</MaybeBadgeContainer>
</View>
</View>
<View style={styles.itemLogoSize} testID={TEST_IDS.CONTAINER}>
<MaybeBadgeContainer>
<MenuIcon {...props} />
</MaybeBadgeContainer>
</View>
);
}
Expand Down
Loading