@@ -21,7 +21,7 @@ limitations under the License.
21
21
22
22
import { EventEmitter } from "events" ;
23
23
24
- import { ISyncStateData , SyncApi } from "./sync" ;
24
+ import { ISyncStateData , SyncApi , SyncState } from "./sync" ;
25
25
import { EventStatus , IContent , IDecryptOptions , IEvent , MatrixEvent } from "./models/event" ;
26
26
import { StubStore } from "./store/stub" ;
27
27
import { createNewMatrixCall , MatrixCall } from "./webrtc/call" ;
@@ -96,7 +96,6 @@ import {
96
96
IRecoveryKey ,
97
97
ISecretStorageKeyInfo ,
98
98
} from "./crypto/api" ;
99
- import { SyncState } from "./sync" ;
100
99
import { EventTimelineSet } from "./models/event-timeline-set" ;
101
100
import { VerificationRequest } from "./crypto/verification/request/VerificationRequest" ;
102
101
import { VerificationBase as Verification } from "./crypto/verification/Base" ;
@@ -816,6 +815,7 @@ export class MatrixClient extends EventEmitter {
816
815
protected exportedOlmDeviceToImport : IOlmDevice ;
817
816
protected txnCtr = 0 ;
818
817
protected mediaHandler = new MediaHandler ( ) ;
818
+ protected pendingEventEncryption = new Map < string , Promise < void > > ( ) ;
819
819
820
820
constructor ( opts : IMatrixClientCreateOpts ) {
821
821
super ( ) ;
@@ -870,7 +870,7 @@ export class MatrixClient extends EventEmitter {
870
870
871
871
this . scheduler = opts . scheduler ;
872
872
if ( this . scheduler ) {
873
- this . scheduler . setProcessFunction ( async ( eventToSend ) => {
873
+ this . scheduler . setProcessFunction ( async ( eventToSend : MatrixEvent ) => {
874
874
const room = this . getRoom ( eventToSend . getRoomId ( ) ) ;
875
875
if ( eventToSend . status !== EventStatus . SENDING ) {
876
876
this . updatePendingEventStatus ( room , eventToSend , EventStatus . SENDING ) ;
@@ -3399,15 +3399,18 @@ export class MatrixClient extends EventEmitter {
3399
3399
* Cancel a queued or unsent event.
3400
3400
*
3401
3401
* @param {MatrixEvent } event Event to cancel
3402
- * @throws Error if the event is not in QUEUED or NOT_SENT state
3402
+ * @throws Error if the event is not in QUEUED, NOT_SENT or ENCRYPTING state
3403
3403
*/
3404
3404
public cancelPendingEvent ( event : MatrixEvent ) {
3405
- if ( [ EventStatus . QUEUED , EventStatus . NOT_SENT ] . indexOf ( event . status ) < 0 ) {
3405
+ if ( ! [ EventStatus . QUEUED , EventStatus . NOT_SENT , EventStatus . ENCRYPTING ] . includes ( event . status ) ) {
3406
3406
throw new Error ( "cannot cancel an event with status " + event . status ) ;
3407
3407
}
3408
3408
3409
- // first tell the scheduler to forget about it, if it's queued
3410
- if ( this . scheduler ) {
3409
+ // if the event is currently being encrypted then
3410
+ if ( event . status === EventStatus . ENCRYPTING ) {
3411
+ this . pendingEventEncryption . delete ( event . getId ( ) ) ;
3412
+ } else if ( this . scheduler && event . status === EventStatus . QUEUED ) {
3413
+ // tell the scheduler to forget about it, if it's queued
3411
3414
this . scheduler . removeEventFromQueue ( event ) ;
3412
3415
}
3413
3416
@@ -3669,16 +3672,26 @@ export class MatrixClient extends EventEmitter {
3669
3672
* @private
3670
3673
*/
3671
3674
private encryptAndSendEvent ( room : Room , event : MatrixEvent , callback ?: Callback ) : Promise < ISendEventResponse > {
3675
+ let cancelled = false ;
3672
3676
// Add an extra Promise.resolve() to turn synchronous exceptions into promise rejections,
3673
3677
// so that we can handle synchronous and asynchronous exceptions with the
3674
3678
// same code path.
3675
3679
return Promise . resolve ( ) . then ( ( ) => {
3676
3680
const encryptionPromise = this . encryptEventIfNeeded ( event , room ) ;
3677
- if ( ! encryptionPromise ) return null ;
3681
+ if ( ! encryptionPromise ) return null ; // doesn't need encryption
3678
3682
3683
+ this . pendingEventEncryption . set ( event . getId ( ) , encryptionPromise ) ;
3679
3684
this . updatePendingEventStatus ( room , event , EventStatus . ENCRYPTING ) ;
3680
- return encryptionPromise . then ( ( ) => this . updatePendingEventStatus ( room , event , EventStatus . SENDING ) ) ;
3685
+ return encryptionPromise . then ( ( ) => {
3686
+ if ( ! this . pendingEventEncryption . has ( event . getId ( ) ) ) {
3687
+ // cancelled via MatrixClient::cancelPendingEvent
3688
+ cancelled = true ;
3689
+ return ;
3690
+ }
3691
+ this . updatePendingEventStatus ( room , event , EventStatus . SENDING ) ;
3692
+ } ) ;
3681
3693
} ) . then ( ( ) => {
3694
+ if ( cancelled ) return { } as ISendEventResponse ;
3682
3695
let promise : Promise < ISendEventResponse > ;
3683
3696
if ( this . scheduler ) {
3684
3697
// if this returns a promise then the scheduler has control now and will
0 commit comments