@@ -17,8 +17,8 @@ limitations under the License.
17
17
18
18
import { ClientEvent , MatrixClient } from "matrix-js-sdk/src/client" ;
19
19
import { MatrixEvent } from "matrix-js-sdk/src/models/event" ;
20
+ import { defer } from "matrix-js-sdk/src/utils" ;
20
21
21
- import { MatrixClientPeg } from '../../MatrixClientPeg' ;
22
22
import MatrixClientBackedSettingsHandler from "./MatrixClientBackedSettingsHandler" ;
23
23
import { objectClone , objectKeyChanges } from "../../utils/objects" ;
24
24
import { SettingLevel } from "../SettingLevel" ;
@@ -30,6 +30,7 @@ const BREADCRUMBS_EVENT_TYPES = [BREADCRUMBS_LEGACY_EVENT_TYPE, BREADCRUMBS_EVEN
30
30
const RECENT_EMOJI_EVENT_TYPE = "io.element.recent_emoji" ;
31
31
const INTEG_PROVISIONING_EVENT_TYPE = "im.vector.setting.integration_provisioning" ;
32
32
const ANALYTICS_EVENT_TYPE = "im.vector.analytics" ;
33
+ const DEFAULT_SETTINGS_EVENT_TYPE = "im.vector.web.settings" ;
33
34
34
35
/**
35
36
* Gets and sets settings at the "account" level for the current user.
@@ -45,10 +46,7 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa
45
46
}
46
47
47
48
public initMatrixClient ( oldClient : MatrixClient , newClient : MatrixClient ) {
48
- if ( oldClient ) {
49
- oldClient . removeListener ( ClientEvent . AccountData , this . onAccountData ) ;
50
- }
51
-
49
+ oldClient ?. removeListener ( ClientEvent . AccountData , this . onAccountData ) ;
52
50
newClient . on ( ClientEvent . AccountData , this . onAccountData ) ;
53
51
}
54
52
@@ -62,9 +60,9 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa
62
60
}
63
61
64
62
this . watchers . notifyUpdate ( "urlPreviewsEnabled" , null , SettingLevel . ACCOUNT , val ) ;
65
- } else if ( event . getType ( ) === "im.vector.web.settings" || event . getType ( ) === ANALYTICS_EVENT_TYPE ) {
63
+ } else if ( event . getType ( ) === DEFAULT_SETTINGS_EVENT_TYPE || event . getType ( ) === ANALYTICS_EVENT_TYPE ) {
66
64
// Figure out what changed and fire those updates
67
- const prevContent = prevEvent ? prevEvent . getContent ( ) : { } ;
65
+ const prevContent = prevEvent ? .getContent ( ) ?? { } ;
68
66
const changedSettings = objectKeyChanges < Record < string , any > > ( prevContent , event . getContent ( ) ) ;
69
67
for ( const settingName of changedSettings ) {
70
68
const val = event . getContent ( ) [ settingName ] ;
@@ -136,72 +134,81 @@ export default class AccountSettingsHandler extends MatrixClientBackedSettingsHa
136
134
return preferredValue ;
137
135
}
138
136
139
- public async setValue ( settingName : string , roomId : string , newValue : any ) : Promise < void > {
140
- // Special case URL previews
141
- if ( settingName === "urlPreviewsEnabled" ) {
142
- const content = this . getSettings ( "org.matrix.preview_urls" ) || { } ;
143
- content [ 'disable' ] = ! newValue ;
144
- await MatrixClientPeg . get ( ) . setAccountData ( "org.matrix.preview_urls" , content ) ;
145
- return ;
137
+ // helper function to set account data then await it being echoed back
138
+ private async setAccountData (
139
+ eventType : string ,
140
+ field : string ,
141
+ value : any ,
142
+ legacyEventType ?: string ,
143
+ ) : Promise < void > {
144
+ let content = this . getSettings ( eventType ) ;
145
+ if ( legacyEventType && ! content ?. [ field ] ) {
146
+ content = this . getSettings ( legacyEventType ) ;
146
147
}
147
148
148
- // Special case for breadcrumbs
149
- if ( settingName === "breadcrumb_rooms" ) {
150
- // We read the value first just to make sure we preserve whatever random keys might be present.
151
- let content = this . getSettings ( BREADCRUMBS_EVENT_TYPE ) ;
152
- if ( ! content || ! content [ 'recent_rooms' ] ) {
153
- content = this . getSettings ( BREADCRUMBS_LEGACY_EVENT_TYPE ) ;
154
- }
155
- if ( ! content ) content = { } ; // If we still don't have content, make some
156
-
157
- content [ 'recent_rooms' ] = newValue ;
158
- await MatrixClientPeg . get ( ) . setAccountData ( BREADCRUMBS_EVENT_TYPE , content ) ;
159
- return ;
149
+ if ( ! content ) {
150
+ content = { } ;
160
151
}
161
152
162
- // Special case recent emoji
163
- if ( settingName === "recent_emoji" ) {
164
- const content = this . getSettings ( RECENT_EMOJI_EVENT_TYPE ) || { } ;
165
- content [ "recent_emoji" ] = newValue ;
166
- await MatrixClientPeg . get ( ) . setAccountData ( RECENT_EMOJI_EVENT_TYPE , content ) ;
167
- return ;
168
- }
153
+ content [ field ] = value ;
169
154
170
- // Special case integration manager provisioning
171
- if ( settingName === "integrationProvisioning" ) {
172
- const content = this . getSettings ( INTEG_PROVISIONING_EVENT_TYPE ) || { } ;
173
- content [ 'enabled' ] = newValue ;
174
- await MatrixClientPeg . get ( ) . setAccountData ( INTEG_PROVISIONING_EVENT_TYPE , content ) ;
175
- return ;
176
- }
155
+ await this . client . setAccountData ( eventType , content ) ;
177
156
178
- // Special case analytics
179
- if ( settingName === "pseudonymousAnalyticsOptIn" ) {
180
- const content = this . getSettings ( ANALYTICS_EVENT_TYPE ) || { } ;
181
- content [ settingName ] = newValue ;
182
- await MatrixClientPeg . get ( ) . setAccountData ( ANALYTICS_EVENT_TYPE , content ) ;
183
- return ;
184
- }
157
+ const deferred = defer < void > ( ) ;
158
+ const handler = ( event : MatrixEvent ) => {
159
+ if ( event . getType ( ) !== eventType || event . getContent ( ) [ field ] !== value ) return ;
160
+ this . client . off ( ClientEvent . AccountData , handler ) ;
161
+ deferred . resolve ( ) ;
162
+ } ;
163
+ this . client . on ( ClientEvent . AccountData , handler ) ;
185
164
186
- const content = this . getSettings ( ) || { } ;
187
- content [ settingName ] = newValue ;
188
- await MatrixClientPeg . get ( ) . setAccountData ( "im.vector.web.settings" , content ) ;
165
+ await deferred . promise ;
166
+ }
167
+
168
+ public setValue ( settingName : string , roomId : string , newValue : any ) : Promise < void > {
169
+ switch ( settingName ) {
170
+ // Special case URL previews
171
+ case "urlPreviewsEnabled" :
172
+ return this . setAccountData ( "org.matrix.preview_urls" , "disable" , ! newValue ) ;
173
+
174
+ // Special case for breadcrumbs
175
+ case "breadcrumb_rooms" :
176
+ return this . setAccountData (
177
+ BREADCRUMBS_EVENT_TYPE ,
178
+ "recent_rooms" ,
179
+ newValue ,
180
+ BREADCRUMBS_LEGACY_EVENT_TYPE ,
181
+ ) ;
182
+
183
+ // Special case recent emoji
184
+ case "recent_emoji" :
185
+ return this . setAccountData ( RECENT_EMOJI_EVENT_TYPE , "recent_emoji" , newValue ) ;
186
+
187
+ // Special case integration manager provisioning
188
+ case "integrationProvisioning" :
189
+ return this . setAccountData ( INTEG_PROVISIONING_EVENT_TYPE , "enabled" , newValue ) ;
190
+
191
+ // Special case analytics
192
+ case "pseudonymousAnalyticsOptIn" :
193
+ return this . setAccountData ( ANALYTICS_EVENT_TYPE , "pseudonymousAnalyticsOptIn" , newValue ) ;
194
+
195
+ default :
196
+ return this . setAccountData ( DEFAULT_SETTINGS_EVENT_TYPE , settingName , newValue ) ;
197
+ }
189
198
}
190
199
191
200
public canSetValue ( settingName : string , roomId : string ) : boolean {
192
201
return true ; // It's their account, so they should be able to
193
202
}
194
203
195
204
public isSupported ( ) : boolean {
196
- const cli = MatrixClientPeg . get ( ) ;
197
- return cli !== undefined && cli !== null && ! cli . isGuest ( ) ;
205
+ return this . client && ! this . client . isGuest ( ) ;
198
206
}
199
207
200
208
private getSettings ( eventType = "im.vector.web.settings" ) : any { // TODO: [TS] Types on return
201
- const cli = MatrixClientPeg . get ( ) ;
202
- if ( ! cli ) return null ;
209
+ if ( ! this . client ) return null ;
203
210
204
- const event = cli . getAccountData ( eventType ) ;
211
+ const event = this . client . getAccountData ( eventType ) ;
205
212
if ( ! event || ! event . getContent ( ) ) return null ;
206
213
return objectClone ( event . getContent ( ) ) ; // clone to prevent mutation
207
214
}
0 commit comments