Skip to content

Commit ecc9fda

Browse files
authored
Merge pull request #1778 from matrix-org/travis/notifications-2
Add minimal types for "notification settings" UI
2 parents 69415ba + 7f7c3cb commit ecc9fda

File tree

4 files changed

+224
-40
lines changed

4 files changed

+224
-40
lines changed

src/@types/PushRules.ts

Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
/*
2+
Copyright 2021 The Matrix.org Foundation C.I.C.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
// allow camelcase as these are things that go onto the wire
18+
/* eslint-disable camelcase */
19+
20+
export enum PushRuleActionName {
21+
DontNotify = "dont_notify",
22+
Notify = "notify",
23+
Coalesce = "coalesce",
24+
}
25+
26+
export enum TweakName {
27+
Highlight = "highlight",
28+
Sound = "sound",
29+
}
30+
31+
export type Tweak<N extends TweakName, V> = {
32+
set_tweak: N;
33+
value: V;
34+
};
35+
36+
export type TweakHighlight = Tweak<TweakName.Highlight, boolean>;
37+
export type TweakSound = Tweak<TweakName.Sound, string>;
38+
39+
export type Tweaks = TweakHighlight | TweakSound;
40+
41+
export enum ConditionOperator {
42+
ExactEquals = "==",
43+
LessThan = "<",
44+
GreaterThan = ">",
45+
GreaterThanOrEqual = ">=",
46+
LessThanOrEqual = "<=",
47+
}
48+
49+
export type PushRuleAction = Tweaks | PushRuleActionName;
50+
51+
export type MemberCountCondition
52+
<N extends number, Op extends ConditionOperator = ConditionOperator.ExactEquals>
53+
= `${Op}${N}` | (Op extends ConditionOperator.ExactEquals ? `${N}` : never);
54+
55+
export type AnyMemberCountCondition = MemberCountCondition<number, ConditionOperator>;
56+
57+
export const DMMemberCountCondition: MemberCountCondition<2> = "2";
58+
59+
export function isDmMemberCountCondition(condition: AnyMemberCountCondition): boolean {
60+
return condition === "==2" || condition === "2";
61+
}
62+
63+
export enum ConditionKind {
64+
EventMatch = "event_match",
65+
ContainsDisplayName = "contains_display_name",
66+
RoomMemberCount = "room_member_count",
67+
SenderNotificationPermission = "sender_notification_permission",
68+
}
69+
70+
export interface IPushRuleCondition<N extends ConditionKind | string> {
71+
[k: string]: any; // for custom conditions, there can be other fields here
72+
kind: N;
73+
}
74+
75+
export interface IEventMatchCondition extends IPushRuleCondition<ConditionKind.EventMatch> {
76+
key: string;
77+
pattern: string;
78+
}
79+
80+
export interface IContainsDisplayNameCondition extends IPushRuleCondition<ConditionKind.ContainsDisplayName> {
81+
// no additional fields
82+
}
83+
84+
export interface IRoomMemberCountCondition extends IPushRuleCondition<ConditionKind.RoomMemberCount> {
85+
is: AnyMemberCountCondition;
86+
}
87+
88+
export interface ISenderNotificationPermissionCondition
89+
extends IPushRuleCondition<ConditionKind.SenderNotificationPermission> {
90+
key: string;
91+
}
92+
93+
export type PushRuleCondition = IPushRuleCondition<string>
94+
| IEventMatchCondition
95+
| IContainsDisplayNameCondition
96+
| IRoomMemberCountCondition
97+
| ISenderNotificationPermissionCondition;
98+
99+
export enum PushRuleKind {
100+
Override = "override",
101+
ContentSpecific = "content",
102+
RoomSpecific = "room",
103+
SenderSpecific = "sender",
104+
Underride = "underride",
105+
}
106+
107+
export enum RuleId {
108+
Master = ".m.rule.master",
109+
ContainsDisplayName = ".m.rule.contains_display_name",
110+
ContainsUserName = ".m.rule.contains_user_name",
111+
AtRoomNotification = ".m.rule.roomnotif",
112+
DM = ".m.rule.room_one_to_one",
113+
EncryptedDM = ".m.rule.encrypted_room_one_to_one",
114+
Message = ".m.rule.message",
115+
EncryptedMessage = ".m.rule.encrypted",
116+
InviteToSelf = ".m.rule.invite_for_me",
117+
MemberEvent = ".m.rule.member_event",
118+
IncomingCall = ".m.rule.call",
119+
SuppressNotices = ".m.rule.suppress_notices",
120+
Tombstone = ".m.rule.tombstone",
121+
}
122+
123+
export type PushRuleSet = {
124+
[k in PushRuleKind]?: IPushRule[];
125+
};
126+
127+
export interface IPushRule {
128+
actions: PushRuleAction[];
129+
conditions?: PushRuleCondition[];
130+
default: boolean;
131+
enabled: boolean;
132+
pattern?: string;
133+
rule_id: RuleId | string;
134+
}
135+
136+
export interface IAnnotatedPushRule extends IPushRule {
137+
kind: PushRuleKind;
138+
}
139+
140+
export interface IPushRules {
141+
global: PushRuleSet;
142+
device?: PushRuleSet;
143+
}
144+
145+
export interface IPusher {
146+
app_display_name: string;
147+
app_id: string;
148+
data: {
149+
format?: string; // TODO: Types
150+
url?: string; // TODO: Required if kind==http
151+
brand?: string; // TODO: For email notifications only?
152+
};
153+
device_display_name: string;
154+
kind: string; // TODO: Types
155+
lang: string;
156+
profile_tag?: string;
157+
pushkey: string;
158+
}
159+
160+
export interface IPusherRequest extends IPusher {
161+
append?: boolean;
162+
}
163+
164+
/* eslint-enable camelcase */

src/@types/requests.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import { Preset, Visibility } from "./partials";
1919
import { SearchKey } from "./search";
2020
import { IRoomEventFilter } from "../filter";
2121

22-
// allow camelcase as these are things go onto the wire
22+
// allow camelcase as these are things that go onto the wire
2323
/* eslint-disable camelcase */
2424

2525
export interface IJoinRoomOpts {

src/@types/threepids.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
Copyright 2021 The Matrix.org Foundation C.I.C.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
*/
16+
17+
export enum ThreepidMedium {
18+
Email = "email",
19+
Phone = "msisdn",
20+
}
21+
22+
// TODO: Are these types universal, or specific to just /account/3pid?
23+
export interface IThreepid {
24+
medium: ThreepidMedium;
25+
address: string;
26+
validated_at: number; // eslint-disable-line camelcase
27+
added_at: number; // eslint-disable-line camelcase
28+
}

src/client.ts

Lines changed: 31 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ import {
144144
} from "./@types/search";
145145
import { ISynapseAdminDeactivateResponse, ISynapseAdminWhoisResponse } from "./@types/synapse";
146146
import { ISpaceSummaryEvent, ISpaceSummaryRoom } from "./@types/spaces";
147+
import { IPusher, IPusherRequest, IPushRules, PushRuleAction, PushRuleKind, RuleId } from "./@types/PushRules";
148+
import { IThreepid } from "./@types/threepids";
147149

148150
export type Store = IStore;
149151
export type SessionStore = WebStorageSessionStore;
@@ -595,35 +597,13 @@ interface IUserDirectoryResponse {
595597
limited: boolean;
596598
}
597599

598-
interface IThreepid {
599-
medium: "email" | "msisdn";
600-
address: string;
601-
validated_at: number;
602-
added_at: number;
603-
}
604-
605600
interface IMyDevice {
606601
device_id: string;
607602
display_name?: string;
608603
last_seen_ip?: string;
609604
last_seen_ts?: number;
610605
}
611606

612-
interface IPusher {
613-
pushkey: string;
614-
kind: string;
615-
app_id: string;
616-
app_display_name: string;
617-
device_display_name: string;
618-
profile_tag?: string;
619-
lang: string;
620-
data: {
621-
url?: string;
622-
format?: string;
623-
brand?: string; // undocumented
624-
};
625-
}
626-
627607
interface IDownloadKeyResult {
628608
failures: { [serverName: string]: object };
629609
device_keys: {
@@ -3883,7 +3863,7 @@ export class MatrixClient extends EventEmitter {
38833863
* @return {Promise} Resolves: to an empty object
38843864
* @return {module:http-api.MatrixError} Rejects: with an error response.
38853865
*/
3886-
public async sendReadReceipt(event: MatrixEvent, opts: { hidden?: boolean }, callback?: Callback): Promise<{}> {
3866+
public async sendReadReceipt(event: MatrixEvent, opts?: { hidden?: boolean }, callback?: Callback): Promise<{}> {
38873867
if (typeof (opts) === 'function') {
38883868
callback = opts as any as Callback; // legacy
38893869
opts = {};
@@ -5220,20 +5200,20 @@ export class MatrixClient extends EventEmitter {
52205200
if (!mute) {
52215201
// Remove the rule only if it is a muting rule
52225202
if (hasDontNotifyRule) {
5223-
deferred = this.deletePushRule(scope, "room", roomPushRule.rule_id);
5203+
deferred = this.deletePushRule(scope, PushRuleKind.RoomSpecific, roomPushRule.rule_id);
52245204
}
52255205
} else {
52265206
if (!roomPushRule) {
5227-
deferred = this.addPushRule(scope, "room", roomId, {
5207+
deferred = this.addPushRule(scope, PushRuleKind.RoomSpecific, roomId, {
52285208
actions: ["dont_notify"],
52295209
});
52305210
} else if (!hasDontNotifyRule) {
52315211
// Remove the existing one before setting the mute push rule
52325212
// This is a workaround to SYN-590 (Push rule update fails)
52335213
deferred = utils.defer();
5234-
this.deletePushRule(scope, "room", roomPushRule.rule_id)
5214+
this.deletePushRule(scope, PushRuleKind.RoomSpecific, roomPushRule.rule_id)
52355215
.then(() => {
5236-
this.addPushRule(scope, "room", roomId, {
5216+
this.addPushRule(scope, PushRuleKind.RoomSpecific, roomId, {
52375217
actions: ["dont_notify"],
52385218
}).then(() => {
52395219
deferred.resolve();
@@ -6974,7 +6954,7 @@ export class MatrixClient extends EventEmitter {
69746954

69756955
/**
69766956
* @param {module:client.callback} callback Optional.
6977-
* @return {Promise} Resolves: TODO
6957+
* @return {Promise} Resolves to a list of the user's threepids.
69786958
* @return {module:http-api.MatrixError} Rejects: with an error response.
69796959
*/
69806960
public getThreePids(callback?: Callback): Promise<{ threepids: IThreepid[] }> {
@@ -7205,22 +7185,23 @@ export class MatrixClient extends EventEmitter {
72057185
/**
72067186
* Adds a new pusher or updates an existing pusher
72077187
*
7208-
* @param {Object} pusher Object representing a pusher
7188+
* @param {IPusherRequest} pusher Object representing a pusher
72097189
* @param {module:client.callback} callback Optional.
72107190
* @return {Promise} Resolves: Empty json object on success
72117191
* @return {module:http-api.MatrixError} Rejects: with an error response.
72127192
*/
7213-
public setPusher(pusher: IPusher, callback?: Callback): Promise<{}> {
7193+
public setPusher(pusher: IPusherRequest, callback?: Callback): Promise<{}> {
72147194
const path = "/pushers/set";
72157195
return this.http.authedRequest(callback, "POST", path, null, pusher);
72167196
}
72177197

72187198
/**
7199+
* Get the push rules for the account from the server.
72197200
* @param {module:client.callback} callback Optional.
7220-
* @return {Promise} Resolves: TODO
7201+
* @return {Promise} Resolves to the push rules.
72217202
* @return {module:http-api.MatrixError} Rejects: with an error response.
72227203
*/
7223-
public getPushRules(callback?: Callback): Promise<any> { // TODO: Types
7204+
public getPushRules(callback?: Callback): Promise<IPushRules> {
72247205
return this.http.authedRequest(callback, "GET", "/pushrules/").then(rules => {
72257206
return PushProcessor.rewriteDefaultRules(rules);
72267207
});
@@ -7235,7 +7216,13 @@ export class MatrixClient extends EventEmitter {
72357216
* @return {Promise} Resolves: an empty object {}
72367217
* @return {module:http-api.MatrixError} Rejects: with an error response.
72377218
*/
7238-
public addPushRule(scope: string, kind: string, ruleId: string, body: any, callback?: Callback): Promise<{}> {
7219+
public addPushRule(
7220+
scope: string,
7221+
kind: PushRuleKind,
7222+
ruleId: Exclude<string, RuleId>,
7223+
body: any,
7224+
callback?: Callback,
7225+
): Promise<any> { // TODO: Types
72397226
// NB. Scope not uri encoded because devices need the '/'
72407227
const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId", {
72417228
$kind: kind,
@@ -7252,7 +7239,12 @@ export class MatrixClient extends EventEmitter {
72527239
* @return {Promise} Resolves: an empty object {}
72537240
* @return {module:http-api.MatrixError} Rejects: with an error response.
72547241
*/
7255-
public deletePushRule(scope: string, kind: string, ruleId: string, callback?: Callback): Promise<{}> {
7242+
public deletePushRule(
7243+
scope: string,
7244+
kind: PushRuleKind,
7245+
ruleId: Exclude<string, RuleId>,
7246+
callback?: Callback,
7247+
): Promise<any> { // TODO: Types
72567248
// NB. Scope not uri encoded because devices need the '/'
72577249
const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId", {
72587250
$kind: kind,
@@ -7273,8 +7265,8 @@ export class MatrixClient extends EventEmitter {
72737265
*/
72747266
public setPushRuleEnabled(
72757267
scope: string,
7276-
kind: string,
7277-
ruleId: string,
7268+
kind: PushRuleKind,
7269+
ruleId: RuleId | string,
72787270
enabled: boolean,
72797271
callback?: Callback,
72807272
): Promise<{}> {
@@ -7299,9 +7291,9 @@ export class MatrixClient extends EventEmitter {
72997291
*/
73007292
public setPushRuleActions(
73017293
scope: string,
7302-
kind: string,
7303-
ruleId: string,
7304-
actions: string[],
7294+
kind: PushRuleKind,
7295+
ruleId: RuleId | string,
7296+
actions: PushRuleAction[],
73057297
callback?: Callback,
73067298
): Promise<{}> {
73077299
const path = utils.encodeUri("/pushrules/" + scope + "/$kind/$ruleId/actions", {

0 commit comments

Comments
 (0)