Reuse PushProcessor from MatrixClient (#29561)

* Reuse PushProcessor from MatrixClient

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Reuse PushProcessor getPushRuleGlobRegex

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* delint

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Iterate

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

* Update regex handling

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>

---------

Signed-off-by: Michael Telatynski <7t3chguy@gmail.com>
This commit is contained in:
Michael Telatynski
2025-03-21 11:34:06 +00:00
committed by GitHub
parent 3a39486468
commit 0d28df0f67
11 changed files with 35 additions and 33 deletions

View File

@@ -22,7 +22,6 @@ import {
type MatrixCall, type MatrixCall,
} from "matrix-js-sdk/src/webrtc/call"; } from "matrix-js-sdk/src/webrtc/call";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import { PushProcessor } from "matrix-js-sdk/src/pushprocessor";
import { CallEventHandlerEvent } from "matrix-js-sdk/src/webrtc/callEventHandler"; import { CallEventHandlerEvent } from "matrix-js-sdk/src/webrtc/callEventHandler";
import { MatrixClientPeg } from "./MatrixClientPeg"; import { MatrixClientPeg } from "./MatrixClientPeg";
@@ -596,7 +595,7 @@ export default class LegacyCallHandler extends TypedEventEmitter<LegacyCallHandl
switch (newState) { switch (newState) {
case CallState.Ringing: { case CallState.Ringing: {
const incomingCallPushRule = new PushProcessor(MatrixClientPeg.safeGet()).getPushRuleById( const incomingCallPushRule = MatrixClientPeg.safeGet().pushProcessor.getPushRuleById(
RuleId.IncomingCall, RuleId.IncomingCall,
); );
const pushRuleEnabled = incomingCallPushRule?.enabled; const pushRuleEnabled = incomingCallPushRule?.enabled;

View File

@@ -9,7 +9,7 @@ Please see LICENSE files in the repository root for full details.
import React, { createRef, type SyntheticEvent, type MouseEvent, StrictMode } from "react"; import React, { createRef, type SyntheticEvent, type MouseEvent, StrictMode } from "react";
import { MsgType, PushRuleKind } from "matrix-js-sdk/src/matrix"; import { MsgType, PushRuleKind } from "matrix-js-sdk/src/matrix";
import { TooltipProvider } from "@vector-im/compound-web"; import { TooltipProvider } from "@vector-im/compound-web";
import { globToRegexp } from "matrix-js-sdk/src/utils"; import { PushProcessor } from "matrix-js-sdk/src/pushprocessor";
import * as HtmlUtils from "../../../HtmlUtils"; import * as HtmlUtils from "../../../HtmlUtils";
import { formatDate } from "../../../DateUtils"; import { formatDate } from "../../../DateUtils";
@@ -110,7 +110,10 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
pushDetails.rule.kind === PushRuleKind.ContentSpecific && pushDetails.rule.kind === PushRuleKind.ContentSpecific &&
pushDetails.rule.pattern pushDetails.rule.pattern
) { ) {
this.pillifyNotificationKeywords([content], this.regExpForKeywordPattern(pushDetails.rule.pattern)); this.pillifyNotificationKeywords(
[content],
PushProcessor.getPushRuleGlobRegex(pushDetails.rule.pattern, true),
);
} }
} }
@@ -235,12 +238,12 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
continue; continue;
} }
const match = text.match(exp); const match = text.match(exp);
if (!match || match.length < 3) { if (!match || match.length < 2) {
node = node.nextSibling; node = node.nextSibling;
continue; continue;
} }
const keywordText = match[2]; const keywordText = match[1];
const idx = match.index! + match[1].length; const idx = match.index!;
const before = text.substring(0, idx); const before = text.substring(0, idx);
const after = text.substring(idx + keywordText.length); const after = text.substring(idx + keywordText.length);
@@ -265,12 +268,6 @@ export default class TextualBody extends React.Component<IBodyProps, IState> {
} }
} }
private regExpForKeywordPattern(pattern: string): RegExp {
// Reflects the push notification pattern-matching implementation at
// https://github.com/matrix-org/matrix-js-sdk/blob/dbd7d26968b94700827bac525c39afff2c198e61/src/pushprocessor.ts#L570
return new RegExp("(^|\\W)(" + globToRegexp(pattern) + ")(\\W|$)", "i");
}
private findLinks(nodes: ArrayLike<Element>): string[] { private findLinks(nodes: ArrayLike<Element>): string[] {
let links: string[] = []; let links: string[] = [];

View File

@@ -8,8 +8,6 @@ Please see LICENSE files in the repository root for full details.
*/ */
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
// XXX: This feels wrong.
import { PushProcessor } from "matrix-js-sdk/src/pushprocessor";
import { PushRuleActionName } from "matrix-js-sdk/src/matrix"; import { PushRuleActionName } from "matrix-js-sdk/src/matrix";
import SettingController from "./SettingController"; import SettingController from "./SettingController";
@@ -20,8 +18,7 @@ import { type SettingLevel } from "../SettingLevel";
// default action on this rule is dont_notify, but it could be something else // default action on this rule is dont_notify, but it could be something else
export function isPushNotifyDisabled(): boolean { export function isPushNotifyDisabled(): boolean {
// Return the value of the master push rule as a default // Return the value of the master push rule as a default
const processor = new PushProcessor(MatrixClientPeg.safeGet()); const masterRule = MatrixClientPeg.safeGet().pushProcessor.getPushRuleById(".m.rule.master");
const masterRule = processor.getPushRuleById(".m.rule.master");
if (!masterRule) { if (!masterRule) {
logger.warn("No master push rule! Notifications are disabled for this user."); logger.warn("No master push rule! Notifications are disabled for this user.");

View File

@@ -7,7 +7,6 @@ Please see LICENSE files in the repository root for full details.
*/ */
import React, { StrictMode } from "react"; import React, { StrictMode } from "react";
import { PushProcessor } from "matrix-js-sdk/src/pushprocessor";
import { type MatrixClient, type MatrixEvent, RuleId } from "matrix-js-sdk/src/matrix"; import { type MatrixClient, type MatrixEvent, RuleId } from "matrix-js-sdk/src/matrix";
import { TooltipProvider } from "@vector-im/compound-web"; import { TooltipProvider } from "@vector-im/compound-web";
@@ -119,11 +118,10 @@ export function pillifyLinks(
} }
if (roomNotifTextNodes.length > 0) { if (roomNotifTextNodes.length > 0) {
const pushProcessor = new PushProcessor(matrixClient); const atRoomRule = matrixClient.pushProcessor.getPushRuleById(
const atRoomRule = pushProcessor.getPushRuleById(
mxEvent.getContent()["m.mentions"] !== undefined ? RuleId.IsRoomMention : RuleId.AtRoomNotification, mxEvent.getContent()["m.mentions"] !== undefined ? RuleId.IsRoomMention : RuleId.AtRoomNotification,
); );
if (atRoomRule && pushProcessor.ruleMatchesEvent(atRoomRule, mxEvent)) { if (atRoomRule && matrixClient.pushProcessor.ruleMatchesEvent(atRoomRule, mxEvent)) {
// Now replace all those nodes with Pills // Now replace all those nodes with Pills
for (const roomNotifTextNode of roomNotifTextNodes) { for (const roomNotifTextNode of roomNotifTextNodes) {
// Set the next node to be processed to the one after the node // Set the next node to be processed to the one after the node

View File

@@ -12,15 +12,16 @@ import {
EventType, EventType,
type RuleId, type RuleId,
type IAnnotatedPushRule, type IAnnotatedPushRule,
type IPushRule,
type PushRuleKind,
} from "matrix-js-sdk/src/matrix"; } from "matrix-js-sdk/src/matrix";
import { PushProcessor } from "matrix-js-sdk/src/pushprocessor";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import { VectorPushRulesDefinitions, type VectorPushRuleDefinition } from "../../notifications"; import { VectorPushRulesDefinitions, type VectorPushRuleDefinition } from "../../notifications";
import { updateExistingPushRulesWithActions } from "./updatePushRuleActions"; import { updateExistingPushRulesWithActions } from "./updatePushRuleActions";
const pushRuleAndKindToAnnotated = ( const pushRuleAndKindToAnnotated = (
ruleAndKind: ReturnType<PushProcessor["getPushRuleAndKindById"]>, ruleAndKind: { rule: IPushRule; kind: PushRuleKind } | null,
): IAnnotatedPushRule | undefined => ): IAnnotatedPushRule | undefined =>
ruleAndKind ruleAndKind
? { ? {
@@ -34,23 +35,21 @@ const pushRuleAndKindToAnnotated = (
* And updates any that are out of sync * And updates any that are out of sync
* Ignores ruleIds that do not exist for the user * Ignores ruleIds that do not exist for the user
* @param matrixClient - cli * @param matrixClient - cli
* @param pushProcessor - processor used to retrieve current state of rules
* @param ruleId - primary rule * @param ruleId - primary rule
* @param definition - VectorPushRuleDefinition of the primary rule * @param definition - VectorPushRuleDefinition of the primary rule
*/ */
const monitorSyncedRule = async ( const monitorSyncedRule = async (
matrixClient: MatrixClient, matrixClient: MatrixClient,
pushProcessor: PushProcessor,
ruleId: RuleId | string, ruleId: RuleId | string,
definition: VectorPushRuleDefinition, definition: VectorPushRuleDefinition,
): Promise<void> => { ): Promise<void> => {
const primaryRule = pushRuleAndKindToAnnotated(pushProcessor.getPushRuleAndKindById(ruleId)); const primaryRule = pushRuleAndKindToAnnotated(matrixClient.pushProcessor.getPushRuleAndKindById(ruleId));
if (!primaryRule) { if (!primaryRule) {
return; return;
} }
const syncedRules: IAnnotatedPushRule[] | undefined = definition.syncedRuleIds const syncedRules: IAnnotatedPushRule[] | undefined = definition.syncedRuleIds
?.map((ruleId) => pushRuleAndKindToAnnotated(pushProcessor.getPushRuleAndKindById(ruleId))) ?.map((ruleId) => pushRuleAndKindToAnnotated(matrixClient.pushProcessor.getPushRuleAndKindById(ruleId)))
.filter((n?: IAnnotatedPushRule): n is IAnnotatedPushRule => Boolean(n)); .filter((n?: IAnnotatedPushRule): n is IAnnotatedPushRule => Boolean(n));
// no synced rules to manage // no synced rules to manage
@@ -94,11 +93,10 @@ export const monitorSyncedPushRules = async (
if (accountDataEvent?.getType() !== EventType.PushRules) { if (accountDataEvent?.getType() !== EventType.PushRules) {
return; return;
} }
const pushProcessor = new PushProcessor(matrixClient);
Object.entries(VectorPushRulesDefinitions).forEach(async ([ruleId, definition]) => { Object.entries(VectorPushRulesDefinitions).forEach(async ([ruleId, definition]) => {
try { try {
await monitorSyncedRule(matrixClient, pushProcessor, ruleId, definition); await monitorSyncedRule(matrixClient, ruleId, definition);
} catch (error) { } catch (error) {
logger.error(`Failed to fully synchronise push rules for ${ruleId}`, error); logger.error(`Failed to fully synchronise push rules for ${ruleId}`, error);
} }

View File

@@ -7,7 +7,6 @@ Please see LICENSE files in the repository root for full details.
*/ */
import { type MatrixClient, type IPushRule, type PushRuleAction, type PushRuleKind } from "matrix-js-sdk/src/matrix"; import { type MatrixClient, type IPushRule, type PushRuleAction, type PushRuleKind } from "matrix-js-sdk/src/matrix";
import { PushProcessor } from "matrix-js-sdk/src/pushprocessor";
/** /**
* Sets the actions for a given push rule id and kind * Sets the actions for a given push rule id and kind
@@ -51,10 +50,8 @@ export const updateExistingPushRulesWithActions = async (
ruleIds?: IPushRule["rule_id"][], ruleIds?: IPushRule["rule_id"][],
actions?: PushRuleAction[], actions?: PushRuleAction[],
): Promise<void> => { ): Promise<void> => {
const pushProcessor = new PushProcessor(matrixClient);
const rules: PushRuleAndKind[] | undefined = ruleIds const rules: PushRuleAndKind[] | undefined = ruleIds
?.map((ruleId) => pushProcessor.getPushRuleAndKindById(ruleId)) ?.map((ruleId) => matrixClient.pushProcessor.getPushRuleAndKindById(ruleId))
.filter((n: PushRuleAndKind | null): n is PushRuleAndKind => Boolean(n)); .filter((n: PushRuleAndKind | null): n is PushRuleAndKind => Boolean(n));
if (!rules?.length) { if (!rules?.length) {

View File

@@ -22,6 +22,7 @@ import { mocked } from "jest-mock";
import { CallEventHandlerEvent } from "matrix-js-sdk/src/webrtc/callEventHandler"; import { CallEventHandlerEvent } from "matrix-js-sdk/src/webrtc/callEventHandler";
import fetchMock from "fetch-mock-jest"; import fetchMock from "fetch-mock-jest";
import { waitFor } from "jest-matrix-react"; import { waitFor } from "jest-matrix-react";
import { PushProcessor } from "matrix-js-sdk/src/pushprocessor";
import LegacyCallHandler, { import LegacyCallHandler, {
AudioID, AudioID,
@@ -473,6 +474,9 @@ describe("LegacyCallHandler without third party protocols", () => {
throw new Error("Endpoint unsupported."); throw new Error("Endpoint unsupported.");
}; };
// @ts-expect-error
MatrixClientPeg.safeGet().pushProcessor = new PushProcessor(MatrixClientPeg.safeGet());
audioElement = document.createElement("audio"); audioElement = document.createElement("audio");
audioElement.id = "remoteAudio"; audioElement.id = "remoteAudio";
document.body.appendChild(audioElement); document.body.appendChild(audioElement);

View File

@@ -19,6 +19,7 @@ import {
import { MediaHandler } from "matrix-js-sdk/src/webrtc/mediaHandler"; import { MediaHandler } from "matrix-js-sdk/src/webrtc/mediaHandler";
import { logger } from "matrix-js-sdk/src/logger"; import { logger } from "matrix-js-sdk/src/logger";
import userEvent from "@testing-library/user-event"; import userEvent from "@testing-library/user-event";
import { PushProcessor } from "matrix-js-sdk/src/pushprocessor";
import LoggedInView from "../../../../src/components/structures/LoggedInView"; import LoggedInView from "../../../../src/components/structures/LoggedInView";
import { SDKContext } from "../../../../src/contexts/SDKContext"; import { SDKContext } from "../../../../src/contexts/SDKContext";
@@ -75,6 +76,8 @@ describe("<LoggedInView />", () => {
jest.clearAllMocks(); jest.clearAllMocks();
mockClient.getMediaHandler.mockReturnValue(mediaHandler); mockClient.getMediaHandler.mockReturnValue(mediaHandler);
mockClient.setPushRuleActions.mockReset().mockResolvedValue({}); mockClient.setPushRuleActions.mockReset().mockResolvedValue({});
// @ts-expect-error
mockClient.pushProcessor = new PushProcessor(mockClient);
}); });
describe("synced push rules", () => { describe("synced push rules", () => {

View File

@@ -10,6 +10,7 @@ import React from "react";
import { type MatrixClient, type MatrixEvent, PushRuleKind } from "matrix-js-sdk/src/matrix"; import { type MatrixClient, type MatrixEvent, PushRuleKind } from "matrix-js-sdk/src/matrix";
import { mocked, type MockedObject } from "jest-mock"; import { mocked, type MockedObject } from "jest-mock";
import { render, waitFor } from "jest-matrix-react"; import { render, waitFor } from "jest-matrix-react";
import { PushProcessor } from "matrix-js-sdk/src/pushprocessor";
import { getMockClientWithEventEmitter, mkEvent, mkMessage, mkStubRoom } from "../../../../test-utils"; import { getMockClientWithEventEmitter, mkEvent, mkMessage, mkStubRoom } from "../../../../test-utils";
import { MatrixClientPeg } from "../../../../../src/MatrixClientPeg"; import { MatrixClientPeg } from "../../../../../src/MatrixClientPeg";
@@ -85,6 +86,8 @@ describe("<TextualBody />", () => {
throw new Error("MockClient event not found"); throw new Error("MockClient event not found");
}, },
}); });
// @ts-expect-error
defaultMatrixClient.pushProcessor = new PushProcessor(defaultMatrixClient);
mocked(defaultRoom).findEventById.mockImplementation((eventId: string) => { mocked(defaultRoom).findEventById.mockImplementation((eventId: string) => {
if (eventId === defaultEvent.getId()) return defaultEvent; if (eventId === defaultEvent.getId()) return defaultEvent;

View File

@@ -36,6 +36,7 @@ import {
} from "jest-matrix-react"; } from "jest-matrix-react";
import { mocked } from "jest-mock"; import { mocked } from "jest-mock";
import userEvent from "@testing-library/user-event"; import userEvent from "@testing-library/user-event";
import { PushProcessor } from "matrix-js-sdk/src/pushprocessor";
import Notifications from "../../../../../src/components/views/settings/Notifications"; import Notifications from "../../../../../src/components/views/settings/Notifications";
import SettingsStore from "../../../../../src/settings/SettingsStore"; import SettingsStore from "../../../../../src/settings/SettingsStore";
@@ -301,6 +302,8 @@ describe("<Notifications />", () => {
mockClient.getPushRules.mockClear().mockResolvedValue(pushRules); mockClient.getPushRules.mockClear().mockResolvedValue(pushRules);
mockClient.addPushRule.mockClear(); mockClient.addPushRule.mockClear();
mockClient.deletePushRule.mockClear(); mockClient.deletePushRule.mockClear();
// @ts-expect-error
mockClient.pushProcessor = new PushProcessor(mockClient);
userEvent.setup(); userEvent.setup();

View File

@@ -10,6 +10,7 @@ import React from "react";
import { act, render } from "jest-matrix-react"; import { act, render } from "jest-matrix-react";
import { MatrixEvent, ConditionKind, EventType, PushRuleActionName, Room, TweakName } from "matrix-js-sdk/src/matrix"; import { MatrixEvent, ConditionKind, EventType, PushRuleActionName, Room, TweakName } from "matrix-js-sdk/src/matrix";
import { mocked } from "jest-mock"; import { mocked } from "jest-mock";
import { PushProcessor } from "matrix-js-sdk/src/pushprocessor";
import { pillifyLinks } from "../../../src/utils/pillify"; import { pillifyLinks } from "../../../src/utils/pillify";
import { stubClient } from "../../test-utils"; import { stubClient } from "../../test-utils";
@@ -78,6 +79,8 @@ describe("pillify", () => {
}, },
], ],
}; };
// @ts-expect-error
cli.pushProcessor = new PushProcessor(cli);
DMRoomMap.makeShared(cli); DMRoomMap.makeShared(cli);
}); });