Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Change 'type' prop on badges to 'forceDot' #12327

Merged
merged 8 commits into from
Mar 14, 2024
Merged
Show file tree
Hide file tree
Changes from 2 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
2 changes: 1 addition & 1 deletion src/components/views/rooms/EventTile.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -1311,7 +1311,7 @@ export class UnwrappedEventTile extends React.Component<EventTileProps, IState>
<UnreadNotificationBadge
room={room || undefined}
threadId={this.props.mxEvent.getId()}
type="dot"
forceDot={true}
/>
</div>
{isRenderingNotification && room ? (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,10 @@ interface Props {
count: number;
level: NotificationLevel;
knocked?: boolean;
type?: "badge" | "dot";
/**
* If true, the badge will always be displayed as a dot. Count will be ignored.
richvdh marked this conversation as resolved.
Show resolved Hide resolved
*/
forceDot?: boolean;
}

interface ClickableProps extends Props {
Expand All @@ -40,7 +43,7 @@ interface ClickableProps extends Props {
}

export const StatelessNotificationBadge = forwardRef<HTMLDivElement, XOR<Props, ClickableProps>>(
({ symbol, count, level, knocked, type = "badge", ...props }, ref) => {
({ symbol, count, level, knocked, forceDot = false, ...props }, ref) => {
const hideBold = useSettingValue("feature_hidebold");

// Don't show a badge if we don't need to
Expand All @@ -56,15 +59,27 @@ export const StatelessNotificationBadge = forwardRef<HTMLDivElement, XOR<Props,
symbol = formatCount(count);
}

// We show a dot if either:
// * The props force us to, or
// * It's just an activity-level notification or (in theory) lower and the room isn't knocked
const badgeType =
forceDot || (level <= NotificationLevel.Activity && !knocked)
? "dot"
: !symbol || symbol.length < 3
richvdh marked this conversation as resolved.
Show resolved Hide resolved
? "badge_2char"
: "badge_3char";

const classes = classNames({
mx_NotificationBadge: true,
mx_NotificationBadge_visible: isEmptyBadge || knocked ? true : hasUnreadCount,
mx_NotificationBadge_level_notification: level == NotificationLevel.Notification,
mx_NotificationBadge_level_highlight: level >= NotificationLevel.Highlight,
mx_NotificationBadge_dot: (isEmptyBadge && !knocked) || type === "dot",
mx_NotificationBadge_knocked: knocked,
mx_NotificationBadge_2char: type === "badge" && symbol && symbol.length > 0 && symbol.length < 3,
mx_NotificationBadge_3char: type === "badge" && symbol && symbol.length > 2,

// Exactly one of mx_NotificationBadge_dot, mx_NotificationBadge_2char, mx_NotificationBadge_3char
dbkr marked this conversation as resolved.
Show resolved Hide resolved
mx_NotificationBadge_dot: badgeType === "dot",
mx_NotificationBadge_2char: badgeType === "badge_2char",
mx_NotificationBadge_3char: badgeType === "badge_3char",
});

if (props.onClick) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,14 @@ import { StatelessNotificationBadge } from "./StatelessNotificationBadge";
interface Props {
room?: Room;
threadId?: string;
type?: "badge" | "dot";
/**
* If true, the badge will always be displayed as a dot. Count will be ignored.
*/
richvdh marked this conversation as resolved.
Show resolved Hide resolved
forceDot?: boolean;
}

export function UnreadNotificationBadge({ room, threadId, type }: Props): JSX.Element {
export function UnreadNotificationBadge({ room, threadId, forceDot }: Props): JSX.Element {
const { symbol, count, level } = useUnreadNotifications(room, threadId);

return <StatelessNotificationBadge symbol={symbol} count={count} level={level} type={type} />;
return <StatelessNotificationBadge symbol={symbol} count={count} level={level} forceDot={forceDot} />;
}
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@ function ThreadsActivityRow({ room, onClick, notificationLevel }: ThreadsActivit
label={room.name}
Icon={<DecoratedRoomAvatar room={room} size="32px" />}
>
<StatelessNotificationBadge level={notificationLevel} count={0} symbol={null} type="dot" />
<StatelessNotificationBadge level={notificationLevel} count={0} symbol={null} forceDot={true} />
</MenuItem>
);
}
Original file line number Diff line number Diff line change
Expand Up @@ -35,4 +35,30 @@ describe("StatelessNotificationBadge", () => {
expect(container.querySelector(".mx_NotificationBadge_dot")).not.toBeInTheDocument();
expect(container.querySelector(".mx_NotificationBadge_knocked")).toBeInTheDocument();
});

it("has dot style for activity", () => {
const { container } = render(
<StatelessNotificationBadge symbol={null} count={3} level={NotificationLevel.Activity} />,
);
expect(container.querySelector(".mx_NotificationBadge_dot")).toBeInTheDocument();
});

it("has badge style for notification", () => {
const { container } = render(
<StatelessNotificationBadge symbol={null} count={3} level={NotificationLevel.Notification} />,
);
expect(container.querySelector(".mx_NotificationBadge_dot")).not.toBeInTheDocument();
});

it("has dot style for notification when forced", () => {
const { container } = render(
<StatelessNotificationBadge
symbol={null}
count={3}
level={NotificationLevel.Notification}
forceDot={true}
/>,
);
expect(container.querySelector(".mx_NotificationBadge_dot")).toBeInTheDocument();
});
});
Loading