Devtools for stuck notifications (#10042)
This commit is contained in:
parent
469228f45e
commit
6dd578e5a7
9 changed files with 378 additions and 6 deletions
|
@ -33,6 +33,7 @@ import { SettingLevel } from "../../../settings/SettingLevel";
|
|||
import ServerInfo from "./devtools/ServerInfo";
|
||||
import { Features } from "../../../settings/Settings";
|
||||
import CopyableText from "../elements/CopyableText";
|
||||
import RoomNotifications from "./devtools/RoomNotifications";
|
||||
|
||||
enum Category {
|
||||
Room,
|
||||
|
@ -44,13 +45,14 @@ const categoryLabels: Record<Category, string> = {
|
|||
[Category.Other]: _td("Other"),
|
||||
};
|
||||
|
||||
export type Tool = React.FC<IDevtoolsProps>;
|
||||
export type Tool = React.FC<IDevtoolsProps> | ((props: IDevtoolsProps) => JSX.Element);
|
||||
const Tools: Record<Category, [label: string, tool: Tool][]> = {
|
||||
[Category.Room]: [
|
||||
[_td("Send custom timeline event"), TimelineEventEditor],
|
||||
[_td("Explore room state"), RoomStateExplorer],
|
||||
[_td("Explore room account data"), RoomAccountDataExplorer],
|
||||
[_td("View servers in room"), ServersInRoom],
|
||||
[_td("Notifications debug"), RoomNotifications],
|
||||
[_td("Verification explorer"), VerificationExplorer],
|
||||
[_td("Active Widgets"), WidgetExplorer],
|
||||
],
|
||||
|
|
180
src/components/views/dialogs/devtools/RoomNotifications.tsx
Normal file
180
src/components/views/dialogs/devtools/RoomNotifications.tsx
Normal file
|
@ -0,0 +1,180 @@
|
|||
/*
|
||||
Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
*/
|
||||
|
||||
import { NotificationCountType, Room } from "matrix-js-sdk/src/models/room";
|
||||
import { Thread } from "matrix-js-sdk/src/models/thread";
|
||||
import React, { useContext } from "react";
|
||||
|
||||
import MatrixClientContext from "../../../../contexts/MatrixClientContext";
|
||||
import { useNotificationState } from "../../../../hooks/useRoomNotificationState";
|
||||
import { _t } from "../../../../languageHandler";
|
||||
import { determineUnreadState } from "../../../../RoomNotifs";
|
||||
import { humanReadableNotificationColor } from "../../../../stores/notifications/NotificationColor";
|
||||
import { doesRoomOrThreadHaveUnreadMessages } from "../../../../Unread";
|
||||
import BaseTool, { DevtoolsContext, IDevtoolsProps } from "./BaseTool";
|
||||
|
||||
export default function RoomNotifications({ onBack }: IDevtoolsProps): JSX.Element {
|
||||
const { room } = useContext(DevtoolsContext);
|
||||
const cli = useContext(MatrixClientContext);
|
||||
|
||||
const { color, count } = determineUnreadState(room);
|
||||
const [notificationState] = useNotificationState(room);
|
||||
|
||||
return (
|
||||
<BaseTool onBack={onBack}>
|
||||
<section>
|
||||
<h2>{_t("Room status")}</h2>
|
||||
<ul>
|
||||
<li>
|
||||
{_t("Room unread status: ")}
|
||||
<strong>{humanReadableNotificationColor(color)}</strong>
|
||||
{count > 0 && (
|
||||
<>
|
||||
{_t(", count:")} <strong>{count}</strong>
|
||||
</>
|
||||
)}
|
||||
</li>
|
||||
<li>
|
||||
{_t("Notification state is")} <strong>{notificationState}</strong>
|
||||
</li>
|
||||
<li>
|
||||
{_t("Room is ")}
|
||||
<strong>
|
||||
{cli.isRoomEncrypted(room.roomId!) ? _t("encrypted ✅") : _t("not encrypted 🚨")}
|
||||
</strong>
|
||||
</li>
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>{_t("Main timeline")}</h2>
|
||||
|
||||
<ul>
|
||||
<li>
|
||||
{_t("Total: ")} {room.getRoomUnreadNotificationCount(NotificationCountType.Total)}
|
||||
</li>
|
||||
<li>
|
||||
{_t("Highlight: ")} {room.getRoomUnreadNotificationCount(NotificationCountType.Highlight)}
|
||||
</li>
|
||||
<li>
|
||||
{_t("Dot: ")} {doesRoomOrThreadHaveUnreadMessages(room) + ""}
|
||||
</li>
|
||||
{roomHasUnread(room) && (
|
||||
<>
|
||||
<li>
|
||||
{_t("User read up to: ")}
|
||||
<strong>
|
||||
{room.getReadReceiptForUserId(cli.getSafeUserId())?.eventId ??
|
||||
_t("No receipt found")}
|
||||
</strong>
|
||||
</li>
|
||||
<li>
|
||||
{_t("Last event:")}
|
||||
<ul>
|
||||
<li>
|
||||
{_t("ID: ")} <strong>{room.timeline[room.timeline.length - 1].getId()}</strong>
|
||||
</li>
|
||||
<li>
|
||||
{_t("Type: ")}{" "}
|
||||
<strong>{room.timeline[room.timeline.length - 1].getType()}</strong>
|
||||
</li>
|
||||
<li>
|
||||
{_t("Sender: ")}{" "}
|
||||
<strong>{room.timeline[room.timeline.length - 1].getSender()}</strong>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</>
|
||||
)}
|
||||
</ul>
|
||||
</section>
|
||||
|
||||
<section>
|
||||
<h2>{_t("Threads timeline")}</h2>
|
||||
<ul>
|
||||
{room
|
||||
.getThreads()
|
||||
.filter((thread) => threadHasUnread(thread))
|
||||
.map((thread) => (
|
||||
<li key={thread.id}>
|
||||
{_t("Thread Id: ")} {thread.id}
|
||||
<ul>
|
||||
<li>
|
||||
{_t("Total: ")}
|
||||
<strong>
|
||||
{room.getThreadUnreadNotificationCount(
|
||||
thread.id,
|
||||
NotificationCountType.Total,
|
||||
)}
|
||||
</strong>
|
||||
</li>
|
||||
<li>
|
||||
{_t("Highlight: ")}
|
||||
<strong>
|
||||
{room.getThreadUnreadNotificationCount(
|
||||
thread.id,
|
||||
NotificationCountType.Highlight,
|
||||
)}
|
||||
</strong>
|
||||
</li>
|
||||
<li>
|
||||
{_t("Dot: ")} <strong>{doesRoomOrThreadHaveUnreadMessages(thread) + ""}</strong>
|
||||
</li>
|
||||
<li>
|
||||
{_t("User read up to: ")}
|
||||
<strong>
|
||||
{thread.getReadReceiptForUserId(cli.getSafeUserId())?.eventId ??
|
||||
_t("No receipt found")}
|
||||
</strong>
|
||||
</li>
|
||||
<li>
|
||||
{_t("Last event:")}
|
||||
<ul>
|
||||
<li>
|
||||
{_t("ID: ")} <strong>{thread.lastReply()?.getId()}</strong>
|
||||
</li>
|
||||
<li>
|
||||
{_t("Type: ")} <strong>{thread.lastReply()?.getType()}</strong>
|
||||
</li>
|
||||
<li>
|
||||
{_t("Sender: ")} <strong>{thread.lastReply()?.getSender()}</strong>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
</ul>
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
</section>
|
||||
</BaseTool>
|
||||
);
|
||||
}
|
||||
|
||||
function threadHasUnread(thread: Thread): boolean {
|
||||
const total = thread.room.getThreadUnreadNotificationCount(thread.id, NotificationCountType.Total);
|
||||
const highlight = thread.room.getThreadUnreadNotificationCount(thread.id, NotificationCountType.Highlight);
|
||||
const dot = doesRoomOrThreadHaveUnreadMessages(thread);
|
||||
|
||||
return total > 0 || highlight > 0 || dot;
|
||||
}
|
||||
|
||||
function roomHasUnread(room: Room): boolean {
|
||||
const total = room.getRoomUnreadNotificationCount(NotificationCountType.Total);
|
||||
const highlight = room.getRoomUnreadNotificationCount(NotificationCountType.Highlight);
|
||||
const dot = doesRoomOrThreadHaveUnreadMessages(room);
|
||||
|
||||
return total > 0 || highlight > 0 || dot;
|
||||
}
|
|
@ -25,7 +25,7 @@ import { CryptoEvent } from "matrix-js-sdk/src/crypto";
|
|||
import { useTypedEventEmitter, useTypedEventEmitterState } from "../../../../hooks/useEventEmitter";
|
||||
import { _t, _td } from "../../../../languageHandler";
|
||||
import MatrixClientContext from "../../../../contexts/MatrixClientContext";
|
||||
import BaseTool, { DevtoolsContext } from "./BaseTool";
|
||||
import BaseTool, { DevtoolsContext, IDevtoolsProps } from "./BaseTool";
|
||||
import { Tool } from "../DevtoolsDialog";
|
||||
|
||||
const PHASE_MAP: Record<Phase, string> = {
|
||||
|
@ -81,7 +81,7 @@ const VerificationRequestExplorer: React.FC<{
|
|||
);
|
||||
};
|
||||
|
||||
const VerificationExplorer: Tool = ({ onBack }) => {
|
||||
const VerificationExplorer: Tool = ({ onBack }: IDevtoolsProps) => {
|
||||
const cli = useContext(MatrixClientContext);
|
||||
const context = useContext(DevtoolsContext);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue