Files
ThreadNet-Web/src/notifications/ContentRules.ts
T

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

137 lines
5.2 KiB
TypeScript
Raw Normal View History

2018-04-11 23:58:37 +01:00
/*
2024-09-09 14:57:16 +01:00
Copyright 2024 New Vector Ltd.
Copyright 2016-2021 The Matrix.org Foundation C.I.C.
2018-04-11 23:58:37 +01:00
SPDX-License-Identifier: AGPL-3.0-only OR GPL-3.0-only OR LicenseRef-Element-Commercial
2024-09-09 14:57:16 +01:00
Please see LICENSE files in the repository root for full details.
2018-04-11 23:58:37 +01:00
*/
2025-02-05 13:25:06 +00:00
import { type IAnnotatedPushRule, type IPushRules, PushRuleKind, type PushRuleSet } from "matrix-js-sdk/src/matrix";
2018-04-11 23:58:37 +01:00
2021-10-22 17:23:32 -05:00
import { PushRuleVectorState, VectorState } from "./PushRuleVectorState";
export interface IContentRules {
2021-07-11 20:53:12 -06:00
vectorState: VectorState;
2021-07-11 20:03:07 -06:00
rules: IAnnotatedPushRule[];
externalRules: IAnnotatedPushRule[];
}
export class ContentRules {
2018-04-11 23:58:37 +01:00
/**
* Extract the keyword rules from a list of rules, and parse them
* into a form which is useful for Vector's UI.
*
* Returns an object containing:
* rules: the primary list of keyword rules
* vectorState: a PushRuleVectorState indicating whether those rules are
* OFF/ON/LOUD
* externalRules: a list of other keyword rules, with states other than
* vectorState
*/
2021-07-11 20:03:07 -06:00
public static parseContentRules(rulesets: IPushRules): IContentRules {
2018-04-11 23:58:37 +01:00
// first categorise the keyword rules in terms of their actions
2021-07-11 20:03:07 -06:00
const contentRules = ContentRules.categoriseContentRules(rulesets);
2018-04-11 23:58:37 +01:00
// Decide which content rules to display in Vector UI.
// Vector displays a single global rule for a list of keywords
// whereas Matrix has a push rule per keyword.
// Vector can set the unique rule in ON, LOUD or OFF state.
// Matrix has enabled/disabled plus a combination of (highlight, sound) tweaks.
// The code below determines which set of user's content push rules can be
// displayed by the vector UI.
// Push rules that does not fit, ie defined by another Matrix client, ends
// in externalRules.
// There is priority in the determination of which set will be the displayed one.
// The set with rules that have LOUD tweaks is the first choice. Then, the ones
// with ON tweaks (no tweaks).
if (contentRules.loud.length) {
return {
2021-07-11 20:53:12 -06:00
vectorState: VectorState.Loud,
2018-04-11 23:58:37 +01:00
rules: contentRules.loud,
externalRules: [
...contentRules.loud_but_disabled,
...contentRules.on,
...contentRules.on_but_disabled,
...contentRules.other,
],
2018-04-11 23:58:37 +01:00
};
2018-10-11 22:04:53 -05:00
} else if (contentRules.loud_but_disabled.length) {
2018-04-11 23:58:37 +01:00
return {
2021-07-11 20:53:12 -06:00
vectorState: VectorState.Off,
2018-04-11 23:58:37 +01:00
rules: contentRules.loud_but_disabled,
externalRules: [...contentRules.on, ...contentRules.on_but_disabled, ...contentRules.other],
2018-04-11 23:58:37 +01:00
};
2018-10-11 22:04:53 -05:00
} else if (contentRules.on.length) {
2018-04-11 23:58:37 +01:00
return {
2021-07-11 20:53:12 -06:00
vectorState: VectorState.On,
2018-04-11 23:58:37 +01:00
rules: contentRules.on,
externalRules: [...contentRules.on_but_disabled, ...contentRules.other],
2018-04-11 23:58:37 +01:00
};
2018-10-11 22:04:53 -05:00
} else if (contentRules.on_but_disabled.length) {
2018-04-11 23:58:37 +01:00
return {
2021-07-11 20:53:12 -06:00
vectorState: VectorState.Off,
2018-04-11 23:58:37 +01:00
rules: contentRules.on_but_disabled,
externalRules: contentRules.other,
2018-10-11 22:04:53 -05:00
};
} else {
2018-04-11 23:58:37 +01:00
return {
2021-07-11 20:53:12 -06:00
vectorState: VectorState.On,
2018-04-11 23:58:37 +01:00
rules: [],
externalRules: contentRules.other,
2018-10-11 22:04:53 -05:00
};
2018-04-11 23:58:37 +01:00
}
}
2018-04-11 23:58:37 +01:00
private static categoriseContentRules(
rulesets: IPushRules,
): Record<"on" | "on_but_disabled" | "loud" | "loud_but_disabled" | "other", IAnnotatedPushRule[]> {
2021-07-11 20:03:07 -06:00
const contentRules: Record<
"on" | "on_but_disabled" | "loud" | "loud_but_disabled" | "other",
IAnnotatedPushRule[]
> = {
on: [],
on_but_disabled: [],
loud: [],
loud_but_disabled: [],
other: [],
};
2018-10-11 22:04:53 -05:00
for (const kind in rulesets.global) {
for (let i = 0; i < Object.keys(rulesets.global[kind as keyof PushRuleSet]!).length; ++i) {
const r = rulesets.global[kind as keyof PushRuleSet]![i] as IAnnotatedPushRule;
2018-04-11 23:58:37 +01:00
// check it's not a default rule
2021-07-11 20:03:07 -06:00
if (r.rule_id[0] === "." || kind !== PushRuleKind.ContentSpecific) {
2018-04-11 23:58:37 +01:00
continue;
}
// this is needed as we are flattening an object of arrays into a single array
r.kind = kind;
2018-04-11 23:58:37 +01:00
switch (PushRuleVectorState.contentRuleVectorStateKind(r)) {
2021-07-11 20:53:12 -06:00
case VectorState.On:
2018-04-11 23:58:37 +01:00
if (r.enabled) {
contentRules.on.push(r);
2018-10-11 22:04:53 -05:00
} else {
2018-04-11 23:58:37 +01:00
contentRules.on_but_disabled.push(r);
}
break;
2021-07-11 20:53:12 -06:00
case VectorState.Loud:
2018-04-11 23:58:37 +01:00
if (r.enabled) {
contentRules.loud.push(r);
2018-10-11 22:04:53 -05:00
} else {
2018-04-11 23:58:37 +01:00
contentRules.loud_but_disabled.push(r);
}
break;
default:
contentRules.other.push(r);
break;
}
}
}
return contentRules;
}
}