Mark as Unread (#12254)

* Support the mark as unread flag

* Add mark as unread menu option

and make clering notifications also clear the unread flag

* Mark as read on viewing room

* Tests

* Remove random import

* Don't show mark as unread for historical rooms

* Fix tests & add test for menu option

* Test RoomNotificationState updates on unread flag change

* Test it doesn't update on other room account data

* New icon for mark as unread

* Add analytics events for mark as (un)read

* Bump to new analytics-events package

* Read from both stable & unstable prefixes

* Cast to boolean before checking

to avoid setting state unnecessarily

* Typo

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* Doc external interface (and the rest at the same time)

* Doc & rename unread market set function

* Doc const exports

* Remove listener on destroy

* Add playwright test

* Clearer language, hopefully

* Move comment

* Add reference to the MSC

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* Expand on function doc

* Remove empty beforeEach

* Rejig badge logic a little and add tests

* Fix basdges to not display dots in room sublists again

and hopefully rename the forceDot option to something that better
indicates what it does, and add tests.

* Remove duplicate license header (?)

* Missing word (several times...)

* Incorporate PR suggestion on badge type switch

* Better description in doc comment

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>

* Update other doc comments in the same way

* Remove duplicate quote

* Use quotes consistently

* Better test name

* c+p fail

---------

Co-authored-by: Richard van der Hoff <1389908+richvdh@users.noreply.github.com>
This commit is contained in:
David Baker 2024-03-19 13:28:20 +00:00 committed by GitHub
parent a8341c0e95
commit a5ed97b903
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
20 changed files with 458 additions and 33 deletions

View file

@ -102,7 +102,7 @@ export default class NotificationBadge extends React.PureComponent<XOR<IProps, I
if (notification.isIdle && !notification.knocked) return null;
if (hideIfDot && notification.level < NotificationLevel.Notification) {
// This would just be a dot and we've been told not to show dots, so don't show it
if (!notification.hasUnreadCount) return null;
return null;
}
const commonProps: React.ComponentProps<typeof StatelessNotificationBadge> = {

View file

@ -70,6 +70,16 @@ 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
? "badge_2char"
: "badge_3char";
const classes = classNames({
mx_NotificationBadge: true,
mx_NotificationBadge_visible: isEmptyBadge || knocked ? true : hasUnreadCount,
@ -77,10 +87,10 @@ export const StatelessNotificationBadge = forwardRef<HTMLDivElement, XOR<Props,
mx_NotificationBadge_level_highlight: level >= NotificationLevel.Highlight,
mx_NotificationBadge_knocked: knocked,
// At most one of mx_NotificationBadge_dot, mx_NotificationBadge_2char, mx_NotificationBadge_3char
mx_NotificationBadge_dot: (isEmptyBadge && !knocked) || forceDot,
mx_NotificationBadge_2char: !forceDot && symbol && symbol.length > 0 && symbol.length < 3,
mx_NotificationBadge_3char: !forceDot && symbol && symbol.length > 2,
// Exactly one of mx_NotificationBadge_dot, mx_NotificationBadge_2char, mx_NotificationBadge_3char
mx_NotificationBadge_dot: badgeType === "dot",
mx_NotificationBadge_2char: badgeType === "badge_2char",
mx_NotificationBadge_3char: badgeType === "badge_3char",
});
if (props.onClick) {

View file

@ -362,6 +362,12 @@ export class RoomTile extends React.PureComponent<ClassProps, State> {
onPostLeaveClick={(ev: ButtonEvent) =>
PosthogTrackers.trackInteraction("WebRoomListRoomTileContextMenuLeaveItem", ev)
}
onPostMarkAsReadClick={(ev: ButtonEvent) =>
PosthogTrackers.trackInteraction("WebRoomListRoomTileContextMenuMarkRead", ev)
}
onPostMarkAsUnreadClick={(ev: ButtonEvent) =>
PosthogTrackers.trackInteraction("WebRoomListRoomTileContextMenuMarkUnread", ev)
}
/>
)}
</React.Fragment>