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:
parent
a8341c0e95
commit
a5ed97b903
20 changed files with 458 additions and 33 deletions
|
@ -21,6 +21,7 @@ import {
|
|||
Room,
|
||||
LocalNotificationSettings,
|
||||
ReceiptType,
|
||||
IMarkedUnreadEvent,
|
||||
} from "matrix-js-sdk/src/matrix";
|
||||
import { IndicatorIcon } from "@vector-im/compound-web";
|
||||
|
||||
|
@ -28,6 +29,19 @@ import SettingsStore from "../settings/SettingsStore";
|
|||
import { NotificationLevel } from "../stores/notifications/NotificationLevel";
|
||||
import { doesRoomHaveUnreadMessages } from "../Unread";
|
||||
|
||||
// MSC2867 is not yet spec at time of writing. We read from both stable
|
||||
// and unstable prefixes and accept the risk that the format may change,
|
||||
// since the stable prefix is not actually defined yet.
|
||||
|
||||
/**
|
||||
* Unstable identifier for the marked_unread event, per MSC2867
|
||||
*/
|
||||
export const MARKED_UNREAD_TYPE_UNSTABLE = "com.famedly.marked_unread";
|
||||
/**
|
||||
* Stable identifier for the marked_unread event
|
||||
*/
|
||||
export const MARKED_UNREAD_TYPE_STABLE = "m.marked_unread";
|
||||
|
||||
export const deviceNotificationSettingsKeys = [
|
||||
"notificationsEnabled",
|
||||
"notificationBodyEnabled",
|
||||
|
@ -74,6 +88,8 @@ export function localNotificationsAreSilenced(cli: MatrixClient): boolean {
|
|||
export async function clearRoomNotification(room: Room, client: MatrixClient): Promise<{} | undefined> {
|
||||
const lastEvent = room.getLastLiveEvent();
|
||||
|
||||
await setMarkedUnreadState(room, client, false);
|
||||
|
||||
try {
|
||||
if (lastEvent) {
|
||||
const receiptType = SettingsStore.getValue("sendReadReceipts", room.roomId)
|
||||
|
@ -117,6 +133,39 @@ export function clearAllNotifications(client: MatrixClient): Promise<Array<{} |
|
|||
return Promise.all(receiptPromises);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gives the marked_unread state of the given room
|
||||
* @param room The room to check
|
||||
* @returns - The marked_unread state of the room, or undefined if no explicit state is set.
|
||||
*/
|
||||
export function getMarkedUnreadState(room: Room): boolean | undefined {
|
||||
const currentStateStable = room.getAccountData(MARKED_UNREAD_TYPE_STABLE)?.getContent<IMarkedUnreadEvent>()?.unread;
|
||||
const currentStateUnstable = room
|
||||
.getAccountData(MARKED_UNREAD_TYPE_UNSTABLE)
|
||||
?.getContent<IMarkedUnreadEvent>()?.unread;
|
||||
return currentStateStable ?? currentStateUnstable;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the marked_unread state of the given room. This sets some room account data that indicates to
|
||||
* clients that the user considers this room to be 'unread', but without any actual notifications.
|
||||
*
|
||||
* @param room The room to set
|
||||
* @param client MatrixClient object to use
|
||||
* @param unread The new marked_unread state of the room
|
||||
*/
|
||||
export async function setMarkedUnreadState(room: Room, client: MatrixClient, unread: boolean): Promise<void> {
|
||||
// if there's no event, treat this as false as we don't need to send the flag to clear it if the event isn't there
|
||||
const currentState = getMarkedUnreadState(room);
|
||||
|
||||
if (Boolean(currentState) !== unread) {
|
||||
// Assuming MSC2867 passes FCP with no changes, we should update to start writing
|
||||
// the flag to the stable prefix (or both) and then ultimately use only the
|
||||
// stable prefix.
|
||||
await client.setRoomAccountData(room.roomId, MARKED_UNREAD_TYPE_UNSTABLE, { unread });
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper to transform a notification color to the what the Compound Icon Button
|
||||
* expects
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue