-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmatrixNotificationRules.ts
More file actions
120 lines (106 loc) · 3.28 KB
/
Copy pathmatrixNotificationRules.ts
File metadata and controls
120 lines (106 loc) · 3.28 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
/**
* Maps Matrix push rules to a small set of per-room notification levels,
* mirroring Element's room notification states. Pure helpers only; the
* imperative push-rule writes live in `useNotificationSettings`.
*/
export type RoomNotificationLevel = 'default' | 'all' | 'mentions' | 'mute'
/** Aggregate level for a whole space; `mixed` when child rooms disagree. */
export type SpaceNotificationLevel = RoomNotificationLevel | 'mixed'
export const ROOM_NOTIFICATION_LEVELS: RoomNotificationLevel[] = [
'default',
'all',
'mentions',
'mute',
]
interface PushRuleLike {
rule_id?: string
enabled?: boolean
actions?: Array<unknown>
conditions?: Array<{ kind?: string; key?: string; pattern?: string }>
}
interface PushRulesLike {
global?: {
override?: PushRuleLike[]
room?: PushRuleLike[]
}
}
function actionsTriggerNotify(actions: Array<unknown> | undefined): boolean {
if (!actions || actions.length === 0) {
return false
}
return actions.some((action) => action === 'notify')
}
/** Empty actions or a lone `dont_notify` squelch notifications (Element). */
export function isMutePushRuleActions(
actions: Array<unknown> | undefined,
): boolean {
if (!actions || actions.length === 0) {
return true
}
return actions.length === 1 && actions[0] === 'dont_notify'
}
/** Room-specific rule whose id matches the room (push rule kind `room`). */
export function findRoomPushRule(
pushRules: PushRulesLike | null | undefined,
roomId: string,
): PushRuleLike | undefined {
const roomRules = pushRules?.global?.room ?? []
return roomRules.find((rule) => rule.rule_id === roomId)
}
/**
* Override rule that squelches a whole room (used for the "mute" state).
* Element keys this rule by the room id and matches on `room_id`.
*/
export function findOverrideMuteRule(
pushRules: PushRulesLike | null | undefined,
roomId: string,
): PushRuleLike | undefined {
const overrideRules = pushRules?.global?.override ?? []
return overrideRules.find((rule) => {
if (rule.rule_id === roomId) {
return isMutePushRuleActions(rule.actions)
}
const conditions = rule.conditions ?? []
if (conditions.length !== 1) {
return false
}
const [condition] = conditions
return (
condition?.kind === 'event_match' &&
condition?.key === 'room_id' &&
condition?.pattern === roomId &&
isMutePushRuleActions(rule.actions)
)
})
}
export function resolveRoomNotificationLevel(
pushRules: PushRulesLike | null | undefined,
roomId: string,
): RoomNotificationLevel {
if (!roomId) {
return 'default'
}
const overrideMuteRule = findOverrideMuteRule(pushRules, roomId)
if (overrideMuteRule && overrideMuteRule.enabled !== false) {
return 'mute'
}
const roomRule = findRoomPushRule(pushRules, roomId)
if (!roomRule || roomRule.enabled === false) {
return 'default'
}
if (actionsTriggerNotify(roomRule.actions)) {
return 'all'
}
return 'mentions'
}
/** Aggregate the per-room levels into one space-level value. */
export function resolveSpaceNotificationLevel(
levels: RoomNotificationLevel[],
): SpaceNotificationLevel {
if (levels.length === 0) {
return 'default'
}
const [first, ...rest] = levels
const allEqual = rest.every((level) => level === first)
return allEqual ? first! : 'mixed'
}