matrix-js-sdk 21.2.0 → 22.0.0-rc.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +22 -0
- package/README.md +8 -2
- package/dist/browser-matrix.js +809 -600
- package/dist/browser-matrix.js.map +80 -80
- package/dist/browser-matrix.min.js +5 -5
- package/dist/browser-matrix.min.js.map +1 -1
- package/git-revision.txt +1 -1
- package/lib/@types/PushRules.d.ts +9 -9
- package/lib/@types/PushRules.d.ts.map +1 -1
- package/lib/@types/auth.d.ts +1 -1
- package/lib/@types/auth.d.ts.map +1 -1
- package/lib/@types/beacon.d.ts +3 -3
- package/lib/@types/beacon.d.ts.map +1 -1
- package/lib/@types/crypto.d.ts +1 -1
- package/lib/@types/crypto.d.ts.map +1 -1
- package/lib/@types/location.d.ts +11 -11
- package/lib/@types/location.d.ts.map +1 -1
- package/lib/@types/partials.d.ts +2 -2
- package/lib/@types/partials.d.ts.map +1 -1
- package/lib/@types/read_receipts.d.ts +29 -0
- package/lib/@types/read_receipts.d.ts.map +1 -1
- package/lib/@types/read_receipts.js +3 -1
- package/lib/@types/read_receipts.js.map +1 -1
- package/lib/@types/search.d.ts +1 -1
- package/lib/@types/search.d.ts.map +1 -1
- package/lib/@types/topic.d.ts +3 -3
- package/lib/@types/topic.d.ts.map +1 -1
- package/lib/@types/uia.d.ts +2 -2
- package/lib/@types/uia.d.ts.map +1 -1
- package/lib/ReEmitter.d.ts.map +1 -1
- package/lib/ReEmitter.js.map +1 -1
- package/lib/ToDeviceMessageQueue.d.ts.map +1 -1
- package/lib/ToDeviceMessageQueue.js.map +1 -1
- package/lib/client.d.ts +12 -12
- package/lib/client.d.ts.map +1 -1
- package/lib/client.js +7 -9
- package/lib/client.js.map +1 -1
- package/lib/content-helpers.d.ts +13 -37
- package/lib/content-helpers.d.ts.map +1 -1
- package/lib/content-helpers.js.map +1 -1
- package/lib/crypto/CrossSigning.d.ts +1 -1
- package/lib/crypto/CrossSigning.d.ts.map +1 -1
- package/lib/crypto/CrossSigning.js.map +1 -1
- package/lib/crypto/DeviceList.d.ts +2 -2
- package/lib/crypto/DeviceList.d.ts.map +1 -1
- package/lib/crypto/DeviceList.js.map +1 -1
- package/lib/crypto/EncryptionSetup.d.ts.map +1 -1
- package/lib/crypto/EncryptionSetup.js.map +1 -1
- package/lib/crypto/OlmDevice.d.ts.map +1 -1
- package/lib/crypto/OlmDevice.js +6 -5
- package/lib/crypto/OlmDevice.js.map +1 -1
- package/lib/crypto/OutgoingRoomKeyRequestManager.js.map +1 -1
- package/lib/crypto/RoomList.d.ts.map +1 -1
- package/lib/crypto/RoomList.js.map +1 -1
- package/lib/crypto/SecretStorage.d.ts +2 -2
- package/lib/crypto/SecretStorage.d.ts.map +1 -1
- package/lib/crypto/SecretStorage.js.map +1 -1
- package/lib/crypto/algorithms/base.d.ts +1 -1
- package/lib/crypto/algorithms/base.d.ts.map +1 -1
- package/lib/crypto/algorithms/base.js.map +1 -1
- package/lib/crypto/algorithms/megolm.js +8 -8
- package/lib/crypto/algorithms/megolm.js.map +1 -1
- package/lib/crypto/backup.d.ts +4 -4
- package/lib/crypto/backup.d.ts.map +1 -1
- package/lib/crypto/backup.js.map +1 -1
- package/lib/crypto/dehydration.d.ts.map +1 -1
- package/lib/crypto/dehydration.js.map +1 -1
- package/lib/crypto/deviceinfo.d.ts.map +1 -1
- package/lib/crypto/deviceinfo.js.map +1 -1
- package/lib/crypto/index.d.ts +2 -2
- package/lib/crypto/index.d.ts.map +1 -1
- package/lib/crypto/index.js +1 -1
- package/lib/crypto/index.js.map +1 -1
- package/lib/crypto/olmlib.d.ts.map +1 -1
- package/lib/crypto/olmlib.js.map +1 -1
- package/lib/crypto/store/base.d.ts +1 -1
- package/lib/crypto/store/base.d.ts.map +1 -1
- package/lib/crypto/store/indexeddb-crypto-store-backend.d.ts.map +1 -1
- package/lib/crypto/store/indexeddb-crypto-store-backend.js.map +1 -1
- package/lib/crypto/store/indexeddb-crypto-store.d.ts.map +1 -1
- package/lib/crypto/store/indexeddb-crypto-store.js.map +1 -1
- package/lib/crypto/store/localStorage-crypto-store.d.ts.map +1 -1
- package/lib/crypto/store/localStorage-crypto-store.js.map +1 -1
- package/lib/crypto/store/memory-crypto-store.d.ts.map +1 -1
- package/lib/crypto/store/memory-crypto-store.js.map +1 -1
- package/lib/crypto/verification/Base.d.ts +2 -2
- package/lib/crypto/verification/Base.d.ts.map +1 -1
- package/lib/crypto/verification/Base.js.map +1 -1
- package/lib/crypto/verification/QRCode.d.ts +1 -1
- package/lib/crypto/verification/QRCode.d.ts.map +1 -1
- package/lib/crypto/verification/QRCode.js +1 -1
- package/lib/crypto/verification/QRCode.js.map +1 -1
- package/lib/crypto/verification/SAS.d.ts +2 -2
- package/lib/crypto/verification/SAS.d.ts.map +1 -1
- package/lib/crypto/verification/SAS.js.map +1 -1
- package/lib/crypto/verification/request/InRoomChannel.js.map +1 -1
- package/lib/crypto/verification/request/ToDeviceChannel.d.ts +1 -1
- package/lib/crypto/verification/request/ToDeviceChannel.d.ts.map +1 -1
- package/lib/crypto/verification/request/ToDeviceChannel.js.map +1 -1
- package/lib/crypto/verification/request/VerificationRequest.d.ts +1 -1
- package/lib/crypto/verification/request/VerificationRequest.d.ts.map +1 -1
- package/lib/crypto/verification/request/VerificationRequest.js.map +1 -1
- package/lib/embedded.d.ts.map +1 -1
- package/lib/embedded.js +3 -1
- package/lib/embedded.js.map +1 -1
- package/lib/event-mapper.d.ts +1 -1
- package/lib/event-mapper.d.ts.map +1 -1
- package/lib/event-mapper.js.map +1 -1
- package/lib/filter-component.d.ts.map +1 -1
- package/lib/filter-component.js.map +1 -1
- package/lib/filter.d.ts.map +1 -1
- package/lib/filter.js.map +1 -1
- package/lib/http-api/errors.d.ts.map +1 -1
- package/lib/http-api/errors.js.map +1 -1
- package/lib/http-api/fetch.d.ts +2 -2
- package/lib/http-api/fetch.d.ts.map +1 -1
- package/lib/http-api/fetch.js.map +1 -1
- package/lib/http-api/index.js.map +1 -1
- package/lib/http-api/interface.d.ts +2 -2
- package/lib/http-api/interface.d.ts.map +1 -1
- package/lib/http-api/utils.js.map +1 -1
- package/lib/indexeddb-helpers.js +1 -1
- package/lib/indexeddb-helpers.js.map +1 -1
- package/lib/interactive-auth.d.ts.map +1 -1
- package/lib/interactive-auth.js.map +1 -1
- package/lib/logger.js.map +1 -1
- package/lib/matrix.d.ts +2 -1
- package/lib/matrix.d.ts.map +1 -1
- package/lib/matrix.js.map +1 -1
- package/lib/models/MSC3089Branch.js +1 -1
- package/lib/models/MSC3089Branch.js.map +1 -1
- package/lib/models/MSC3089TreeSpace.js +3 -3
- package/lib/models/MSC3089TreeSpace.js.map +1 -1
- package/lib/models/ToDeviceMessage.d.ts +1 -1
- package/lib/models/ToDeviceMessage.d.ts.map +1 -1
- package/lib/models/beacon.d.ts +2 -2
- package/lib/models/beacon.d.ts.map +1 -1
- package/lib/models/beacon.js.map +1 -1
- package/lib/models/event-context.d.ts.map +1 -1
- package/lib/models/event-context.js.map +1 -1
- package/lib/models/event-timeline-set.d.ts +2 -2
- package/lib/models/event-timeline-set.d.ts.map +1 -1
- package/lib/models/event-timeline-set.js +1 -1
- package/lib/models/event-timeline-set.js.map +1 -1
- package/lib/models/event-timeline.d.ts.map +1 -1
- package/lib/models/event-timeline.js.map +1 -1
- package/lib/models/event.d.ts +11 -4
- package/lib/models/event.d.ts.map +1 -1
- package/lib/models/event.js +10 -0
- package/lib/models/event.js.map +1 -1
- package/lib/models/invites-ignorer.d.ts.map +1 -1
- package/lib/models/invites-ignorer.js.map +1 -1
- package/lib/models/read-receipt.d.ts +1 -23
- package/lib/models/read-receipt.d.ts.map +1 -1
- package/lib/models/read-receipt.js +2 -6
- package/lib/models/read-receipt.js.map +1 -1
- package/lib/models/related-relations.d.ts.map +1 -1
- package/lib/models/related-relations.js.map +1 -1
- package/lib/models/relations-container.d.ts.map +1 -1
- package/lib/models/relations-container.js.map +1 -1
- package/lib/models/relations.d.ts +1 -1
- package/lib/models/relations.d.ts.map +1 -1
- package/lib/models/relations.js.map +1 -1
- package/lib/models/room-member.d.ts +1 -1
- package/lib/models/room-member.d.ts.map +1 -1
- package/lib/models/room-member.js.map +1 -1
- package/lib/models/room-state.d.ts +4 -4
- package/lib/models/room-state.d.ts.map +1 -1
- package/lib/models/room-state.js.map +1 -1
- package/lib/models/room-summary.d.ts.map +1 -1
- package/lib/models/room-summary.js.map +1 -1
- package/lib/models/room.d.ts +4 -4
- package/lib/models/room.d.ts.map +1 -1
- package/lib/models/room.js +2 -2
- package/lib/models/room.js.map +1 -1
- package/lib/models/search-result.d.ts.map +1 -1
- package/lib/models/search-result.js.map +1 -1
- package/lib/models/thread.d.ts +2 -2
- package/lib/models/thread.d.ts.map +1 -1
- package/lib/models/thread.js.map +1 -1
- package/lib/models/typed-event-emitter.d.ts +5 -5
- package/lib/models/typed-event-emitter.d.ts.map +1 -1
- package/lib/models/user.d.ts +1 -1
- package/lib/models/user.d.ts.map +1 -1
- package/lib/models/user.js.map +1 -1
- package/lib/pushprocessor.d.ts.map +1 -1
- package/lib/pushprocessor.js +3 -1
- package/lib/pushprocessor.js.map +1 -1
- package/lib/realtime-callbacks.js.map +1 -1
- package/lib/rendezvous/MSC3906Rendezvous.d.ts.map +1 -1
- package/lib/rendezvous/MSC3906Rendezvous.js.map +1 -1
- package/lib/rendezvous/RendezvousError.d.ts.map +1 -1
- package/lib/rendezvous/RendezvousError.js.map +1 -1
- package/lib/rendezvous/RendezvousFailureReason.d.ts +1 -1
- package/lib/rendezvous/RendezvousFailureReason.d.ts.map +1 -1
- package/lib/rendezvous/channels/MSC3903ECDHv1RendezvousChannel.d.ts +1 -1
- package/lib/rendezvous/channels/MSC3903ECDHv1RendezvousChannel.d.ts.map +1 -1
- package/lib/room-hierarchy.js.map +1 -1
- package/lib/scheduler.d.ts +1 -1
- package/lib/scheduler.d.ts.map +1 -1
- package/lib/scheduler.js +1 -1
- package/lib/scheduler.js.map +1 -1
- package/lib/service-types.js +1 -1
- package/lib/service-types.js.map +1 -1
- package/lib/sliding-sync-sdk.d.ts +1 -1
- package/lib/sliding-sync-sdk.d.ts.map +1 -1
- package/lib/sliding-sync-sdk.js +69 -1
- package/lib/sliding-sync-sdk.js.map +1 -1
- package/lib/sliding-sync.d.ts +5 -2
- package/lib/sliding-sync.d.ts.map +1 -1
- package/lib/sliding-sync.js +7 -1
- package/lib/sliding-sync.js.map +1 -1
- package/lib/store/indexeddb-backend.d.ts +1 -1
- package/lib/store/indexeddb-backend.d.ts.map +1 -1
- package/lib/store/indexeddb-local-backend.d.ts.map +1 -1
- package/lib/store/indexeddb-local-backend.js +2 -2
- package/lib/store/indexeddb-local-backend.js.map +1 -1
- package/lib/store/indexeddb-remote-backend.js.map +1 -1
- package/lib/store/indexeddb-store-worker.d.ts.map +1 -1
- package/lib/store/indexeddb-store-worker.js.map +1 -1
- package/lib/store/indexeddb.d.ts +2 -2
- package/lib/store/indexeddb.d.ts.map +1 -1
- package/lib/store/indexeddb.js.map +1 -1
- package/lib/store/local-storage-events-emitter.d.ts +1 -1
- package/lib/store/local-storage-events-emitter.d.ts.map +1 -1
- package/lib/store/memory.d.ts.map +1 -1
- package/lib/store/memory.js.map +1 -1
- package/lib/store/stub.d.ts.map +1 -1
- package/lib/store/stub.js.map +1 -1
- package/lib/sync-accumulator.d.ts.map +1 -1
- package/lib/sync-accumulator.js +32 -27
- package/lib/sync-accumulator.js.map +1 -1
- package/lib/sync.d.ts.map +1 -1
- package/lib/sync.js.map +1 -1
- package/lib/timeline-window.d.ts.map +1 -1
- package/lib/timeline-window.js.map +1 -1
- package/lib/utils.d.ts +6 -1
- package/lib/utils.d.ts.map +1 -1
- package/lib/utils.js +14 -0
- package/lib/utils.js.map +1 -1
- package/lib/webrtc/audioContext.d.ts.map +1 -1
- package/lib/webrtc/audioContext.js.map +1 -1
- package/lib/webrtc/call.d.ts +2 -1
- package/lib/webrtc/call.d.ts.map +1 -1
- package/lib/webrtc/call.js +13 -2
- package/lib/webrtc/call.js.map +1 -1
- package/lib/webrtc/callEventHandler.d.ts +1 -1
- package/lib/webrtc/callEventHandler.d.ts.map +1 -1
- package/lib/webrtc/callEventHandler.js +1 -1
- package/lib/webrtc/callEventHandler.js.map +1 -1
- package/lib/webrtc/callFeed.d.ts +3 -1
- package/lib/webrtc/callFeed.d.ts.map +1 -1
- package/lib/webrtc/callFeed.js +4 -1
- package/lib/webrtc/callFeed.js.map +1 -1
- package/lib/webrtc/groupCall.d.ts +74 -52
- package/lib/webrtc/groupCall.d.ts.map +1 -1
- package/lib/webrtc/groupCall.js +459 -387
- package/lib/webrtc/groupCall.js.map +1 -1
- package/lib/webrtc/groupCallEventHandler.d.ts +3 -1
- package/lib/webrtc/groupCallEventHandler.d.ts.map +1 -1
- package/lib/webrtc/groupCallEventHandler.js +1 -6
- package/lib/webrtc/groupCallEventHandler.js.map +1 -1
- package/lib/webrtc/mediaHandler.d.ts +1 -1
- package/lib/webrtc/mediaHandler.d.ts.map +1 -1
- package/lib/webrtc/mediaHandler.js.map +1 -1
- package/package.json +7 -7
- package/src/@types/read_receipts.ts +35 -0
- package/src/ReEmitter.ts +3 -3
- package/src/ToDeviceMessageQueue.ts +1 -1
- package/src/client.ts +35 -36
- package/src/content-helpers.ts +7 -6
- package/src/crypto/CrossSigning.ts +15 -8
- package/src/crypto/DeviceList.ts +4 -4
- package/src/crypto/EncryptionSetup.ts +5 -5
- package/src/crypto/OlmDevice.ts +12 -12
- package/src/crypto/OutgoingRoomKeyRequestManager.ts +2 -2
- package/src/crypto/RoomList.ts +1 -1
- package/src/crypto/SecretStorage.ts +2 -2
- package/src/crypto/algorithms/base.ts +4 -4
- package/src/crypto/algorithms/megolm.ts +25 -21
- package/src/crypto/backup.ts +5 -5
- package/src/crypto/dehydration.ts +2 -2
- package/src/crypto/deviceinfo.ts +1 -1
- package/src/crypto/index.ts +30 -30
- package/src/crypto/olmlib.ts +5 -5
- package/src/crypto/store/indexeddb-crypto-store-backend.ts +48 -48
- package/src/crypto/store/indexeddb-crypto-store.ts +9 -9
- package/src/crypto/store/localStorage-crypto-store.ts +3 -3
- package/src/crypto/store/memory-crypto-store.ts +1 -1
- package/src/crypto/verification/Base.ts +4 -4
- package/src/crypto/verification/QRCode.ts +5 -5
- package/src/crypto/verification/SAS.ts +10 -8
- package/src/crypto/verification/request/InRoomChannel.ts +1 -1
- package/src/crypto/verification/request/ToDeviceChannel.ts +1 -1
- package/src/crypto/verification/request/VerificationRequest.ts +4 -4
- package/src/embedded.ts +9 -7
- package/src/event-mapper.ts +1 -1
- package/src/filter-component.ts +1 -1
- package/src/filter.ts +6 -6
- package/src/http-api/errors.ts +4 -4
- package/src/http-api/fetch.ts +1 -1
- package/src/http-api/index.ts +3 -3
- package/src/http-api/utils.ts +2 -2
- package/src/indexeddb-helpers.ts +4 -4
- package/src/interactive-auth.ts +3 -3
- package/src/logger.ts +2 -2
- package/src/matrix.ts +3 -2
- package/src/models/MSC3089TreeSpace.ts +2 -2
- package/src/models/beacon.ts +2 -2
- package/src/models/event-context.ts +1 -1
- package/src/models/event-timeline-set.ts +3 -3
- package/src/models/event-timeline.ts +2 -2
- package/src/models/event.ts +16 -6
- package/src/models/invites-ignorer.ts +3 -3
- package/src/models/read-receipt.ts +9 -35
- package/src/models/related-relations.ts +2 -2
- package/src/models/relations-container.ts +2 -2
- package/src/models/relations.ts +6 -6
- package/src/models/room-member.ts +2 -2
- package/src/models/room-state.ts +4 -4
- package/src/models/room-summary.ts +1 -1
- package/src/models/room.ts +7 -10
- package/src/models/search-result.ts +1 -1
- package/src/models/thread.ts +6 -6
- package/src/models/user.ts +1 -1
- package/src/pushprocessor.ts +1 -1
- package/src/realtime-callbacks.ts +1 -1
- package/src/rendezvous/MSC3906Rendezvous.ts +2 -2
- package/src/rendezvous/RendezvousError.ts +1 -1
- package/src/room-hierarchy.ts +1 -1
- package/src/scheduler.ts +4 -4
- package/src/sliding-sync-sdk.ts +90 -9
- package/src/sliding-sync.ts +14 -10
- package/src/store/indexeddb-local-backend.ts +24 -24
- package/src/store/indexeddb-remote-backend.ts +1 -1
- package/src/store/indexeddb-store-worker.ts +1 -1
- package/src/store/indexeddb.ts +2 -2
- package/src/store/memory.ts +6 -6
- package/src/store/stub.ts +9 -9
- package/src/sync-accumulator.ts +47 -16
- package/src/sync.ts +8 -8
- package/src/timeline-window.ts +4 -4
- package/src/utils.ts +17 -4
- package/src/webrtc/audioContext.ts +1 -1
- package/src/webrtc/call.ts +16 -7
- package/src/webrtc/callEventHandler.ts +9 -7
- package/src/webrtc/callFeed.ts +9 -4
- package/src/webrtc/groupCall.ts +612 -537
- package/src/webrtc/groupCallEventHandler.ts +5 -11
- package/src/webrtc/mediaHandler.ts +5 -5
package/dist/browser-matrix.js
CHANGED
|
@@ -41853,7 +41853,7 @@ module.exports={
|
|
|
41853
41853
|
"⑧": "➇",
|
|
41854
41854
|
"🄉": "8,",
|
|
41855
41855
|
"⒏": "8.",
|
|
41856
|
-
"
|
|
41856
|
+
"㏧": "8日",
|
|
41857
41857
|
"㋇": "8月",
|
|
41858
41858
|
"㍠": "8点",
|
|
41859
41859
|
"੧": "9",
|
|
@@ -45893,7 +45893,7 @@ module.exports={
|
|
|
45893
45893
|
"𠠄": "𠠄",
|
|
45894
45894
|
"カ": "力",
|
|
45895
45895
|
"力": "力",
|
|
45896
|
-
"
|
|
45896
|
+
"⼒": "力",
|
|
45897
45897
|
"劣": "劣",
|
|
45898
45898
|
"㔕": "㔕",
|
|
45899
45899
|
"劳": "劳",
|
|
@@ -48826,13 +48826,14 @@ See the License for the specific language governing permissions and
|
|
|
48826
48826
|
limitations under the License.
|
|
48827
48827
|
*/
|
|
48828
48828
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
48829
|
-
exports.ReceiptType = void 0;
|
|
48829
|
+
exports.MAIN_ROOM_TIMELINE = exports.ReceiptType = void 0;
|
|
48830
48830
|
var ReceiptType;
|
|
48831
48831
|
(function (ReceiptType) {
|
|
48832
48832
|
ReceiptType["Read"] = "m.read";
|
|
48833
48833
|
ReceiptType["FullyRead"] = "m.fully_read";
|
|
48834
48834
|
ReceiptType["ReadPrivate"] = "m.read.private";
|
|
48835
48835
|
})(ReceiptType = exports.ReceiptType || (exports.ReceiptType = {}));
|
|
48836
|
+
exports.MAIN_ROOM_TIMELINE = "main";
|
|
48836
48837
|
|
|
48837
48838
|
},{}],295:[function(require,module,exports){
|
|
48838
48839
|
"use strict";
|
|
@@ -49919,7 +49920,6 @@ const thread_1 = require("./models/thread");
|
|
|
49919
49920
|
const beacon_1 = require("./@types/beacon");
|
|
49920
49921
|
const NamespacedValue_1 = require("./NamespacedValue");
|
|
49921
49922
|
const ToDeviceMessageQueue_1 = require("./ToDeviceMessageQueue");
|
|
49922
|
-
const read_receipt_1 = require("./models/read-receipt");
|
|
49923
49923
|
const invites_ignorer_1 = require("./models/invites-ignorer");
|
|
49924
49924
|
const sync_2 = require("./@types/sync");
|
|
49925
49925
|
const feature_1 = require("./feature");
|
|
@@ -51115,7 +51115,7 @@ class MatrixClient extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
51115
51115
|
if (!this.crypto) {
|
|
51116
51116
|
throw new Error("End-to-end encryption disabled");
|
|
51117
51117
|
}
|
|
51118
|
-
|
|
51118
|
+
this.crypto.prepareToEncrypt(room);
|
|
51119
51119
|
}
|
|
51120
51120
|
/**
|
|
51121
51121
|
* Checks whether cross signing:
|
|
@@ -51184,7 +51184,7 @@ class MatrixClient extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
51184
51184
|
if (!this.crypto) {
|
|
51185
51185
|
throw new Error("End-to-end encryption disabled");
|
|
51186
51186
|
}
|
|
51187
|
-
|
|
51187
|
+
this.crypto.setCryptoTrustCrossSignedDevices(val);
|
|
51188
51188
|
}
|
|
51189
51189
|
/**
|
|
51190
51190
|
* Counts the number of end to end session keys that are waiting to be backed up
|
|
@@ -52190,7 +52190,9 @@ class MatrixClient extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
52190
52190
|
}
|
|
52191
52191
|
let signPromise = Promise.resolve();
|
|
52192
52192
|
if (opts.inviteSignUrl) {
|
|
52193
|
-
|
|
52193
|
+
const url = new URL(opts.inviteSignUrl);
|
|
52194
|
+
url.searchParams.set("mxid", this.credentials.userId);
|
|
52195
|
+
signPromise = this.http.requestOtherUrl(http_api_1.Method.Post, url);
|
|
52194
52196
|
}
|
|
52195
52197
|
const queryString = {};
|
|
52196
52198
|
if (opts.viaServers) {
|
|
@@ -52792,7 +52794,7 @@ class MatrixClient extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
52792
52794
|
const isThread = !!event.threadRootId;
|
|
52793
52795
|
body = Object.assign(Object.assign({}, body), { thread_id: isThread
|
|
52794
52796
|
? event.threadRootId
|
|
52795
|
-
:
|
|
52797
|
+
: read_receipts_1.MAIN_ROOM_TIMELINE });
|
|
52796
52798
|
}
|
|
52797
52799
|
const promise = this.http.authedRequest(http_api_1.Method.Post, path, undefined, body || {});
|
|
52798
52800
|
const room = this.getRoom(event.getRoomId());
|
|
@@ -53086,8 +53088,8 @@ class MatrixClient extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
53086
53088
|
return this.leave(roomId).then(() => {
|
|
53087
53089
|
delete populationResults[roomId];
|
|
53088
53090
|
}).catch((err) => {
|
|
53091
|
+
// suppress error
|
|
53089
53092
|
populationResults[roomId] = err;
|
|
53090
|
-
return null; // suppress error
|
|
53091
53093
|
});
|
|
53092
53094
|
};
|
|
53093
53095
|
for (const room of eligibleToLeave) {
|
|
@@ -57114,7 +57116,7 @@ exports.fixNotificationCountOnDecryption = fixNotificationCountOnDecryption;
|
|
|
57114
57116
|
|
|
57115
57117
|
}).call(this)}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
|
|
57116
57118
|
|
|
57117
|
-
},{"./@types/PushRules":288,"./@types/beacon":289,"./@types/event":290,"./@types/partials":293,"./@types/read_receipts":294,"./@types/search":296,"./@types/sync":297,"./NamespacedValue":299,"./ReEmitter":300,"./ToDeviceMessageQueue":301,"./autodiscovery":302,"./content-helpers":305,"./content-repo":306,"./crypto":324,"./crypto/RoomList":312,"./crypto/api":319,"./crypto/backup":320,"./crypto/dehydration":322,"./crypto/key_passphrase":325,"./crypto/olmlib":326,"./crypto/recoverykey":327,"./event-mapper":343,"./feature":344,"./filter":346,"./http-api":349,"./logger":356,"./models/MSC3089TreeSpace":359,"./models/event":365,"./models/event-timeline":364,"./models/invites-ignorer":366,"./models/
|
|
57119
|
+
},{"./@types/PushRules":288,"./@types/beacon":289,"./@types/event":290,"./@types/partials":293,"./@types/read_receipts":294,"./@types/search":296,"./@types/sync":297,"./NamespacedValue":299,"./ReEmitter":300,"./ToDeviceMessageQueue":301,"./autodiscovery":302,"./content-helpers":305,"./content-repo":306,"./crypto":324,"./crypto/RoomList":312,"./crypto/api":319,"./crypto/backup":320,"./crypto/dehydration":322,"./crypto/key_passphrase":325,"./crypto/olmlib":326,"./crypto/recoverykey":327,"./event-mapper":343,"./feature":344,"./filter":346,"./http-api":349,"./logger":356,"./models/MSC3089TreeSpace":359,"./models/event":365,"./models/event-timeline":364,"./models/invites-ignorer":366,"./models/room":373,"./models/search-result":374,"./models/thread":375,"./models/typed-event-emitter":376,"./models/user":377,"./pushprocessor":378,"./randomstring":379,"./service-types":382,"./sliding-sync-sdk":383,"./store/stub":389,"./sync":391,"./utils":393,"./webrtc/call":395,"./webrtc/callEventHandler":396,"./webrtc/groupCall":399,"./webrtc/groupCallEventHandler":400,"./webrtc/mediaHandler":401,"matrix-events-sdk":168}],305:[function(require,module,exports){
|
|
57118
57120
|
"use strict";
|
|
57119
57121
|
/*
|
|
57120
57122
|
Copyright 2018 - 2022 The Matrix.org Foundation C.I.C.
|
|
@@ -60160,6 +60162,7 @@ class OlmDevice {
|
|
|
60160
60162
|
}
|
|
60161
60163
|
recordSessionProblem(deviceKey, type, fixed) {
|
|
60162
60164
|
return __awaiter(this, void 0, void 0, function* () {
|
|
60165
|
+
logger_1.logger.info(`Recording problem on olm session with ${deviceKey} of type ${type}. Recreating: ${fixed}`);
|
|
60163
60166
|
yield this.cryptoStore.storeEndToEndSessionProblem(deviceKey, type, fixed);
|
|
60164
60167
|
});
|
|
60165
60168
|
}
|
|
@@ -60339,15 +60342,14 @@ class OlmDevice {
|
|
|
60339
60342
|
senderKey);
|
|
60340
60343
|
}
|
|
60341
60344
|
if (existingSession) {
|
|
60342
|
-
logger_1.logger.log(
|
|
60343
|
-
+ senderKey + "/" + sessionId);
|
|
60345
|
+
logger_1.logger.log(`Update for megolm session ${senderKey}|${sessionId}`);
|
|
60344
60346
|
if (existingSession.first_known_index() <= session.first_known_index()) {
|
|
60345
60347
|
if (!existingSessionData.untrusted || extraSessionData.untrusted) {
|
|
60346
60348
|
// existing session has less-than-or-equal index
|
|
60347
60349
|
// (i.e. can decrypt at least as much), and the
|
|
60348
60350
|
// new session's trust does not win over the old
|
|
60349
60351
|
// session's trust, so keep it
|
|
60350
|
-
logger_1.logger.log(`Keeping existing megolm session ${sessionId}`);
|
|
60352
|
+
logger_1.logger.log(`Keeping existing megolm session ${senderKey}|${sessionId}`);
|
|
60351
60353
|
return;
|
|
60352
60354
|
}
|
|
60353
60355
|
if (existingSession.first_known_index() < session.first_known_index()) {
|
|
@@ -60359,12 +60361,12 @@ class OlmDevice {
|
|
|
60359
60361
|
if (existingSession.export_session(session.first_known_index())
|
|
60360
60362
|
=== session.export_session(session.first_known_index())) {
|
|
60361
60363
|
logger_1.logger.info("Upgrading trust of existing megolm session " +
|
|
60362
|
-
sessionId
|
|
60364
|
+
`${senderKey}|${sessionId} based on newly-received trusted session`);
|
|
60363
60365
|
existingSessionData.untrusted = false;
|
|
60364
60366
|
this.cryptoStore.storeEndToEndInboundGroupSession(senderKey, sessionId, existingSessionData, txn);
|
|
60365
60367
|
}
|
|
60366
60368
|
else {
|
|
60367
|
-
logger_1.logger.warn(
|
|
60369
|
+
logger_1.logger.warn(`Newly-received megolm session ${senderKey}|$sessionId}` +
|
|
60368
60370
|
" does not match existing session! Keeping existing session");
|
|
60369
60371
|
}
|
|
60370
60372
|
return;
|
|
@@ -60372,8 +60374,8 @@ class OlmDevice {
|
|
|
60372
60374
|
// If the sessions have the same index, go ahead and store the new trusted one.
|
|
60373
60375
|
}
|
|
60374
60376
|
}
|
|
60375
|
-
logger_1.logger.info(
|
|
60376
|
-
|
|
60377
|
+
logger_1.logger.info(`Storing megolm session ${senderKey}|${sessionId} with first index ` +
|
|
60378
|
+
session.first_known_index());
|
|
60377
60379
|
const sessionData = Object.assign({}, extraSessionData, {
|
|
60378
60380
|
room_id: roomId,
|
|
60379
60381
|
session: session.pickle(this.pickleKey),
|
|
@@ -62635,30 +62637,29 @@ class MegolmEncryption extends base_1.EncryptionAlgorithm {
|
|
|
62635
62637
|
return __awaiter(this, void 0, void 0, function* () {
|
|
62636
62638
|
const obSessionInfo = this.outboundSessions[sessionId];
|
|
62637
62639
|
if (!obSessionInfo) {
|
|
62638
|
-
logger_1.logger.debug(`megolm session ${sessionId} not found: not re-sharing keys`);
|
|
62640
|
+
logger_1.logger.debug(`megolm session ${senderKey}|${sessionId} not found: not re-sharing keys`);
|
|
62639
62641
|
return;
|
|
62640
62642
|
}
|
|
62641
62643
|
// The chain index of the key we previously sent this device
|
|
62642
62644
|
if (obSessionInfo.sharedWithDevices[userId] === undefined) {
|
|
62643
|
-
logger_1.logger.debug(`megolm session ${sessionId} never shared with user ${userId}`);
|
|
62645
|
+
logger_1.logger.debug(`megolm session ${senderKey}|${sessionId} never shared with user ${userId}`);
|
|
62644
62646
|
return;
|
|
62645
62647
|
}
|
|
62646
62648
|
const sessionSharedData = obSessionInfo.sharedWithDevices[userId][device.deviceId];
|
|
62647
62649
|
if (sessionSharedData === undefined) {
|
|
62648
|
-
logger_1.logger.debug(
|
|
62649
|
-
userId + ":" + device.deviceId);
|
|
62650
|
+
logger_1.logger.debug(`megolm session ${senderKey}|${sessionId} never shared with device ${userId}:${device.deviceId}`);
|
|
62650
62651
|
return;
|
|
62651
62652
|
}
|
|
62652
62653
|
if (sessionSharedData.deviceKey !== device.getIdentityKey()) {
|
|
62653
|
-
logger_1.logger.warn(`
|
|
62654
|
-
`key ${sessionSharedData.deviceKey}. Key is now ${device.getIdentityKey()}!`);
|
|
62654
|
+
logger_1.logger.warn(`Megolm session ${senderKey}|${sessionId} has been shared with device ${device.deviceId} but ` +
|
|
62655
|
+
`with identity key ${sessionSharedData.deviceKey}. Key is now ${device.getIdentityKey()}!`);
|
|
62655
62656
|
return;
|
|
62656
62657
|
}
|
|
62657
62658
|
// get the key from the inbound session: the outbound one will already
|
|
62658
62659
|
// have been ratcheted to the next chain index.
|
|
62659
62660
|
const key = yield this.olmDevice.getInboundGroupSessionKey(this.roomId, senderKey, sessionId, sessionSharedData.messageIndex);
|
|
62660
62661
|
if (!key) {
|
|
62661
|
-
logger_1.logger.warn(`No inbound session key found for megolm ${sessionId}: not re-sharing keys`);
|
|
62662
|
+
logger_1.logger.warn(`No inbound session key found for megolm session ${senderKey}|${sessionId}: not re-sharing keys`);
|
|
62662
62663
|
return;
|
|
62663
62664
|
}
|
|
62664
62665
|
yield olmlib.ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, {
|
|
@@ -62689,7 +62690,7 @@ class MegolmEncryption extends base_1.EncryptionAlgorithm {
|
|
|
62689
62690
|
[device.deviceId]: encryptedContent,
|
|
62690
62691
|
},
|
|
62691
62692
|
});
|
|
62692
|
-
logger_1.logger.debug(`Re-shared key for megolm session ${sessionId} with ${userId}:${device.deviceId}`);
|
|
62693
|
+
logger_1.logger.debug(`Re-shared key for megolm session ${senderKey}|${sessionId} with ${userId}:${device.deviceId}`);
|
|
62693
62694
|
});
|
|
62694
62695
|
}
|
|
62695
62696
|
/**
|
|
@@ -63130,6 +63131,8 @@ class MegolmDecryption extends base_1.DecryptionAlgorithm {
|
|
|
63130
63131
|
// event was sent. Use a fuzz factor of 2 minutes.
|
|
63131
63132
|
const problem = yield this.olmDevice.sessionMayHaveProblems(content.sender_key, event.getTs() - 120000);
|
|
63132
63133
|
if (problem) {
|
|
63134
|
+
logger_1.logger.info(`When handling UISI from ${event.getSender()} (sender key ${content.sender_key}): ` +
|
|
63135
|
+
`recent session problem with that sender: ${problem}`);
|
|
63133
63136
|
let problemDescription = PROBLEM_DESCRIPTIONS[problem.type] || PROBLEM_DESCRIPTIONS.unknown;
|
|
63134
63137
|
if (problem.fixed) {
|
|
63135
63138
|
problemDescription +=
|
|
@@ -63573,9 +63576,8 @@ class MegolmDecryption extends base_1.DecryptionAlgorithm {
|
|
|
63573
63576
|
sendSharedHistoryInboundSessions(devicesByUser) {
|
|
63574
63577
|
return __awaiter(this, void 0, void 0, function* () {
|
|
63575
63578
|
yield olmlib.ensureOlmSessionsForDevices(this.olmDevice, this.baseApis, devicesByUser);
|
|
63576
|
-
logger_1.logger.log("sendSharedHistoryInboundSessions to users", Object.keys(devicesByUser));
|
|
63577
63579
|
const sharedHistorySessions = yield this.olmDevice.getSharedHistoryInboundGroupSessions(this.roomId);
|
|
63578
|
-
logger_1.logger.log(
|
|
63580
|
+
logger_1.logger.log(`Sharing history in ${this.roomId} with users ${Object.keys(devicesByUser)}`, sharedHistorySessions.map(([senderKey, sessionId]) => `${senderKey}|${sessionId}`));
|
|
63579
63581
|
for (const [senderKey, sessionId] of sharedHistorySessions) {
|
|
63580
63582
|
const payload = yield this.buildKeyForwardingMessage(this.roomId, senderKey, sessionId);
|
|
63581
63583
|
// FIXME: use encryptAndSendToDevices() rather than duplicating it here.
|
|
@@ -65013,15 +65015,6 @@ var DeviceVerification;
|
|
|
65013
65015
|
* @param {string} deviceId id of the device
|
|
65014
65016
|
*/
|
|
65015
65017
|
class DeviceInfo {
|
|
65016
|
-
constructor(deviceId) {
|
|
65017
|
-
this.deviceId = deviceId;
|
|
65018
|
-
this.algorithms = [];
|
|
65019
|
-
this.keys = {};
|
|
65020
|
-
this.verified = DeviceVerification.Unverified;
|
|
65021
|
-
this.known = false;
|
|
65022
|
-
this.unsigned = {};
|
|
65023
|
-
this.signatures = {};
|
|
65024
|
-
}
|
|
65025
65018
|
/**
|
|
65026
65019
|
* rehydrate a DeviceInfo from the session store
|
|
65027
65020
|
*
|
|
@@ -65039,6 +65032,15 @@ class DeviceInfo {
|
|
|
65039
65032
|
}
|
|
65040
65033
|
return res;
|
|
65041
65034
|
}
|
|
65035
|
+
constructor(deviceId) {
|
|
65036
|
+
this.deviceId = deviceId;
|
|
65037
|
+
this.algorithms = [];
|
|
65038
|
+
this.keys = {};
|
|
65039
|
+
this.verified = DeviceVerification.Unverified;
|
|
65040
|
+
this.known = false;
|
|
65041
|
+
this.unsigned = {};
|
|
65042
|
+
this.signatures = {};
|
|
65043
|
+
}
|
|
65042
65044
|
/**
|
|
65043
65045
|
* Prepare a DeviceInfo for JSON serialisation in the session store
|
|
65044
65046
|
*
|
|
@@ -65255,6 +65257,12 @@ var CryptoEvent;
|
|
|
65255
65257
|
CryptoEvent["KeysChanged"] = "crossSigning.keysChanged";
|
|
65256
65258
|
})(CryptoEvent = exports.CryptoEvent || (exports.CryptoEvent = {}));
|
|
65257
65259
|
class Crypto extends typed_event_emitter_1.TypedEventEmitter {
|
|
65260
|
+
/**
|
|
65261
|
+
* @return {string} The version of Olm.
|
|
65262
|
+
*/
|
|
65263
|
+
static getOlmVersion() {
|
|
65264
|
+
return OlmDevice_1.OlmDevice.getOlmVersion();
|
|
65265
|
+
}
|
|
65258
65266
|
/**
|
|
65259
65267
|
* Cryptography bits
|
|
65260
65268
|
*
|
|
@@ -65505,12 +65513,6 @@ class Crypto extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
65505
65513
|
});
|
|
65506
65514
|
}
|
|
65507
65515
|
}
|
|
65508
|
-
/**
|
|
65509
|
-
* @return {string} The version of Olm.
|
|
65510
|
-
*/
|
|
65511
|
-
static getOlmVersion() {
|
|
65512
|
-
return OlmDevice_1.OlmDevice.getOlmVersion();
|
|
65513
|
-
}
|
|
65514
65516
|
/**
|
|
65515
65517
|
* Initialise the crypto module so that it is ready for use
|
|
65516
65518
|
*
|
|
@@ -67806,9 +67808,9 @@ class Crypto extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
67806
67808
|
logger_1.logger.error("key withheld event is missing fields");
|
|
67807
67809
|
return;
|
|
67808
67810
|
}
|
|
67809
|
-
logger_1.logger.info(`Got room key withheld event from ${event.getSender()}
|
|
67810
|
-
+ `for ${content.algorithm}
|
|
67811
|
-
+ `with
|
|
67811
|
+
logger_1.logger.info(`Got room key withheld event from ${event.getSender()} `
|
|
67812
|
+
+ `for ${content.algorithm} session ${content.sender_key}|${content.session_id} `
|
|
67813
|
+
+ `in room ${content.room_id} with code ${content.code} (${content.reason})`);
|
|
67812
67814
|
const alg = this.getRoomDecryptor(content.room_id, content.algorithm);
|
|
67813
67815
|
if (alg.onRoomKeyWithheldEvent) {
|
|
67814
67816
|
alg.onRoomKeyWithheldEvent(event);
|
|
@@ -70052,6 +70054,9 @@ const IndexedDBHelpers = __importStar(require("../../indexeddb-helpers"));
|
|
|
70052
70054
|
* @implements {module:crypto/store/base~CryptoStore}
|
|
70053
70055
|
*/
|
|
70054
70056
|
class IndexedDBCryptoStore {
|
|
70057
|
+
static exists(indexedDB, dbName) {
|
|
70058
|
+
return IndexedDBHelpers.exists(indexedDB, dbName);
|
|
70059
|
+
}
|
|
70055
70060
|
/**
|
|
70056
70061
|
* Create a new IndexedDBCryptoStore
|
|
70057
70062
|
*
|
|
@@ -70062,9 +70067,6 @@ class IndexedDBCryptoStore {
|
|
|
70062
70067
|
this.indexedDB = indexedDB;
|
|
70063
70068
|
this.dbName = dbName;
|
|
70064
70069
|
}
|
|
70065
|
-
static exists(indexedDB, dbName) {
|
|
70066
|
-
return IndexedDBHelpers.exists(indexedDB, dbName);
|
|
70067
|
-
}
|
|
70068
70070
|
/**
|
|
70069
70071
|
* Ensure the database exists and is up-to-date, or fall back to
|
|
70070
70072
|
* a local storage or in-memory store.
|
|
@@ -70645,10 +70647,6 @@ function keyEndToEndRoomsPrefix(roomId) {
|
|
|
70645
70647
|
* @implements {module:crypto/store/base~CryptoStore}
|
|
70646
70648
|
*/
|
|
70647
70649
|
class LocalStorageCryptoStore extends memory_crypto_store_1.MemoryCryptoStore {
|
|
70648
|
-
constructor(store) {
|
|
70649
|
-
super();
|
|
70650
|
-
this.store = store;
|
|
70651
|
-
}
|
|
70652
70650
|
static exists(store) {
|
|
70653
70651
|
var _a;
|
|
70654
70652
|
const length = store.length;
|
|
@@ -70659,6 +70657,10 @@ class LocalStorageCryptoStore extends memory_crypto_store_1.MemoryCryptoStore {
|
|
|
70659
70657
|
}
|
|
70660
70658
|
return false;
|
|
70661
70659
|
}
|
|
70660
|
+
constructor(store) {
|
|
70661
|
+
super();
|
|
70662
|
+
this.store = store;
|
|
70663
|
+
}
|
|
70662
70664
|
// Olm Sessions
|
|
70663
70665
|
countEndToEndSessions(txn, func) {
|
|
70664
70666
|
var _a;
|
|
@@ -74382,28 +74384,37 @@ class RoomWidgetClient extends client_1.MatrixClient {
|
|
|
74382
74384
|
});
|
|
74383
74385
|
}
|
|
74384
74386
|
watchTurnServers() {
|
|
74385
|
-
var e_1,
|
|
74387
|
+
var _a, e_1, _b, _c;
|
|
74386
74388
|
return __awaiter(this, void 0, void 0, function* () {
|
|
74387
74389
|
const servers = this.widgetApi.getTurnServers();
|
|
74388
|
-
const onClientStopped = () =>
|
|
74390
|
+
const onClientStopped = () => {
|
|
74391
|
+
servers.return(undefined);
|
|
74392
|
+
};
|
|
74389
74393
|
this.lifecycle.signal.addEventListener("abort", onClientStopped);
|
|
74390
74394
|
try {
|
|
74391
74395
|
try {
|
|
74392
|
-
for (var servers_1 = __asyncValues(servers), servers_1_1; servers_1_1 = yield servers_1.next(),
|
|
74393
|
-
|
|
74394
|
-
|
|
74395
|
-
|
|
74396
|
-
|
|
74397
|
-
|
|
74398
|
-
|
|
74399
|
-
|
|
74400
|
-
|
|
74396
|
+
for (var _d = true, servers_1 = __asyncValues(servers), servers_1_1; servers_1_1 = yield servers_1.next(), _a = servers_1_1.done, !_a;) {
|
|
74397
|
+
_c = servers_1_1.value;
|
|
74398
|
+
_d = false;
|
|
74399
|
+
try {
|
|
74400
|
+
const server = _c;
|
|
74401
|
+
this.turnServers = [{
|
|
74402
|
+
urls: server.uris,
|
|
74403
|
+
username: server.username,
|
|
74404
|
+
credential: server.password,
|
|
74405
|
+
}];
|
|
74406
|
+
this.emit(client_1.ClientEvent.TurnServers, this.turnServers);
|
|
74407
|
+
logger_1.logger.log(`Received TURN server: ${server.uris}`);
|
|
74408
|
+
}
|
|
74409
|
+
finally {
|
|
74410
|
+
_d = true;
|
|
74411
|
+
}
|
|
74401
74412
|
}
|
|
74402
74413
|
}
|
|
74403
74414
|
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
74404
74415
|
finally {
|
|
74405
74416
|
try {
|
|
74406
|
-
if (
|
|
74417
|
+
if (!_d && !_a && (_b = servers_1.return)) yield _b.call(servers_1);
|
|
74407
74418
|
}
|
|
74408
74419
|
finally { if (e_1) throw e_1.error; }
|
|
74409
74420
|
}
|
|
@@ -74842,11 +74853,6 @@ function setProp(obj, keyNesting, val) {
|
|
|
74842
74853
|
* @prop {?string} filterId The filter ID
|
|
74843
74854
|
*/
|
|
74844
74855
|
class Filter {
|
|
74845
|
-
constructor(userId, filterId) {
|
|
74846
|
-
this.userId = userId;
|
|
74847
|
-
this.filterId = filterId;
|
|
74848
|
-
this.definition = {};
|
|
74849
|
-
}
|
|
74850
74856
|
/**
|
|
74851
74857
|
* Create a filter from existing data.
|
|
74852
74858
|
* @static
|
|
@@ -74860,6 +74866,11 @@ class Filter {
|
|
|
74860
74866
|
filter.setDefinition(jsonObj);
|
|
74861
74867
|
return filter;
|
|
74862
74868
|
}
|
|
74869
|
+
constructor(userId, filterId) {
|
|
74870
|
+
this.userId = userId;
|
|
74871
|
+
this.filterId = filterId;
|
|
74872
|
+
this.definition = {};
|
|
74873
|
+
}
|
|
74863
74874
|
/**
|
|
74864
74875
|
* Get the ID of this filter on your homeserver (if known)
|
|
74865
74876
|
* @return {?string} The filter ID
|
|
@@ -75921,7 +75932,7 @@ function exists(indexedDB, dbName) {
|
|
|
75921
75932
|
}
|
|
75922
75933
|
resolve(exists);
|
|
75923
75934
|
};
|
|
75924
|
-
req.onerror =
|
|
75935
|
+
req.onerror = () => reject(req.error);
|
|
75925
75936
|
});
|
|
75926
75937
|
}
|
|
75927
75938
|
exports.exists = exists;
|
|
@@ -77093,7 +77104,7 @@ class MSC3089TreeSpace {
|
|
|
77093
77104
|
const currentPls = this.room.currentState.getStateEvents(event_1.EventType.RoomPowerLevels, "");
|
|
77094
77105
|
if (Array.isArray(currentPls))
|
|
77095
77106
|
throw new Error("Unexpected return type for power levels");
|
|
77096
|
-
const pls = currentPls.getContent() || {};
|
|
77107
|
+
const pls = (currentPls === null || currentPls === void 0 ? void 0 : currentPls.getContent()) || {};
|
|
77097
77108
|
const viewLevel = pls['users_default'] || 0;
|
|
77098
77109
|
const editLevel = pls['events_default'] || 50;
|
|
77099
77110
|
const adminLevel = ((_a = pls['events']) === null || _a === void 0 ? void 0 : _a[event_1.EventType.RoomPowerLevels]) || 100;
|
|
@@ -77127,7 +77138,7 @@ class MSC3089TreeSpace {
|
|
|
77127
77138
|
const currentPls = this.room.currentState.getStateEvents(event_1.EventType.RoomPowerLevels, "");
|
|
77128
77139
|
if (Array.isArray(currentPls))
|
|
77129
77140
|
throw new Error("Unexpected return type for power levels");
|
|
77130
|
-
const pls = currentPls.getContent() || {};
|
|
77141
|
+
const pls = (currentPls === null || currentPls === void 0 ? void 0 : currentPls.getContent()) || {};
|
|
77131
77142
|
const viewLevel = pls['users_default'] || 0;
|
|
77132
77143
|
const editLevel = pls['events_default'] || 50;
|
|
77133
77144
|
const adminLevel = ((_a = pls['events']) === null || _a === void 0 ? void 0 : _a[event_1.EventType.RoomPowerLevels]) || 100;
|
|
@@ -78276,7 +78287,7 @@ class EventTimelineSet extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
78276
78287
|
'`EventTimelineSet.addEventToTimeline(event, timeline, IAddEventToTimelineOptions)`');
|
|
78277
78288
|
}
|
|
78278
78289
|
if (timeline.getTimelineSet() !== this) {
|
|
78279
|
-
throw new Error(`EventTimelineSet.addEventToTimeline: Timeline=${timeline.toString()} does not belong " +
|
|
78290
|
+
throw new Error(`EventTimelineSet.addEventToTimeline: Timeline=${timeline.toString()} does not belong " +
|
|
78280
78291
|
"in timelineSet(threadId=${(_a = this.thread) === null || _a === void 0 ? void 0 : _a.id})`);
|
|
78281
78292
|
}
|
|
78282
78293
|
// Make sure events don't get mixed in timelines they shouldn't be in (e.g. a
|
|
@@ -78513,6 +78524,36 @@ var Direction;
|
|
|
78513
78524
|
Direction["Forward"] = "f";
|
|
78514
78525
|
})(Direction = exports.Direction || (exports.Direction = {}));
|
|
78515
78526
|
class EventTimeline {
|
|
78527
|
+
/**
|
|
78528
|
+
* Static helper method to set sender and target properties
|
|
78529
|
+
*
|
|
78530
|
+
* @param {MatrixEvent} event the event whose metadata is to be set
|
|
78531
|
+
* @param {RoomState} stateContext the room state to be queried
|
|
78532
|
+
* @param {boolean} toStartOfTimeline if true the event's forwardLooking flag is set false
|
|
78533
|
+
*/
|
|
78534
|
+
static setEventMetadata(event, stateContext, toStartOfTimeline) {
|
|
78535
|
+
var _a, _b, _c, _d;
|
|
78536
|
+
// When we try to generate a sentinel member before we have that member
|
|
78537
|
+
// in the members object, we still generate a sentinel but it doesn't
|
|
78538
|
+
// have a membership event, so test to see if events.member is set. We
|
|
78539
|
+
// check this to avoid overriding non-sentinel members by sentinel ones
|
|
78540
|
+
// when adding the event to a filtered timeline
|
|
78541
|
+
if (!((_b = (_a = event.sender) === null || _a === void 0 ? void 0 : _a.events) === null || _b === void 0 ? void 0 : _b.member)) {
|
|
78542
|
+
event.sender = stateContext.getSentinelMember(event.getSender());
|
|
78543
|
+
}
|
|
78544
|
+
if (!((_d = (_c = event.target) === null || _c === void 0 ? void 0 : _c.events) === null || _d === void 0 ? void 0 : _d.member) && event.getType() === event_1.EventType.RoomMember) {
|
|
78545
|
+
event.target = stateContext.getSentinelMember(event.getStateKey());
|
|
78546
|
+
}
|
|
78547
|
+
if (event.isState()) {
|
|
78548
|
+
// room state has no concept of 'old' or 'current', but we want the
|
|
78549
|
+
// room state to regress back to previous values if toStartOfTimeline
|
|
78550
|
+
// is set, which means inspecting prev_content if it exists. This
|
|
78551
|
+
// is done by toggling the forwardLooking flag.
|
|
78552
|
+
if (toStartOfTimeline) {
|
|
78553
|
+
event.forwardLooking = false;
|
|
78554
|
+
}
|
|
78555
|
+
}
|
|
78556
|
+
}
|
|
78516
78557
|
/**
|
|
78517
78558
|
* Construct a new EventTimeline
|
|
78518
78559
|
*
|
|
@@ -78557,36 +78598,6 @@ class EventTimeline {
|
|
|
78557
78598
|
this.paginationRequests = { 'b': null, 'f': null };
|
|
78558
78599
|
this.name = this.roomId + ":" + new Date().toISOString();
|
|
78559
78600
|
}
|
|
78560
|
-
/**
|
|
78561
|
-
* Static helper method to set sender and target properties
|
|
78562
|
-
*
|
|
78563
|
-
* @param {MatrixEvent} event the event whose metadata is to be set
|
|
78564
|
-
* @param {RoomState} stateContext the room state to be queried
|
|
78565
|
-
* @param {boolean} toStartOfTimeline if true the event's forwardLooking flag is set false
|
|
78566
|
-
*/
|
|
78567
|
-
static setEventMetadata(event, stateContext, toStartOfTimeline) {
|
|
78568
|
-
var _a, _b, _c, _d;
|
|
78569
|
-
// When we try to generate a sentinel member before we have that member
|
|
78570
|
-
// in the members object, we still generate a sentinel but it doesn't
|
|
78571
|
-
// have a membership event, so test to see if events.member is set. We
|
|
78572
|
-
// check this to avoid overriding non-sentinel members by sentinel ones
|
|
78573
|
-
// when adding the event to a filtered timeline
|
|
78574
|
-
if (!((_b = (_a = event.sender) === null || _a === void 0 ? void 0 : _a.events) === null || _b === void 0 ? void 0 : _b.member)) {
|
|
78575
|
-
event.sender = stateContext.getSentinelMember(event.getSender());
|
|
78576
|
-
}
|
|
78577
|
-
if (!((_d = (_c = event.target) === null || _c === void 0 ? void 0 : _c.events) === null || _d === void 0 ? void 0 : _d.member) && event.getType() === event_1.EventType.RoomMember) {
|
|
78578
|
-
event.target = stateContext.getSentinelMember(event.getStateKey());
|
|
78579
|
-
}
|
|
78580
|
-
if (event.isState()) {
|
|
78581
|
-
// room state has no concept of 'old' or 'current', but we want the
|
|
78582
|
-
// room state to regress back to previous values if toStartOfTimeline
|
|
78583
|
-
// is set, which means inspecting prev_content if it exists. This
|
|
78584
|
-
// is done by toggling the forwardLooking flag.
|
|
78585
|
-
if (toStartOfTimeline) {
|
|
78586
|
-
event.forwardLooking = false;
|
|
78587
|
-
}
|
|
78588
|
-
}
|
|
78589
|
-
}
|
|
78590
78601
|
/**
|
|
78591
78602
|
* Initialise the start and end state with the given events
|
|
78592
78603
|
*
|
|
@@ -80071,10 +80082,19 @@ class MatrixEvent extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
80071
80082
|
* Checks if this event is associated with another event. See `getAssociatedId`.
|
|
80072
80083
|
*
|
|
80073
80084
|
* @return {boolean}
|
|
80085
|
+
* @deprecated use hasAssociation instead.
|
|
80074
80086
|
*/
|
|
80075
80087
|
hasAssocation() {
|
|
80076
80088
|
return !!this.getAssociatedId();
|
|
80077
80089
|
}
|
|
80090
|
+
/**
|
|
80091
|
+
* Checks if this event is associated with another event. See `getAssociatedId`.
|
|
80092
|
+
*
|
|
80093
|
+
* @return {boolean}
|
|
80094
|
+
*/
|
|
80095
|
+
hasAssociation() {
|
|
80096
|
+
return !!this.getAssociatedId();
|
|
80097
|
+
}
|
|
80078
80098
|
/**
|
|
80079
80099
|
* Update the related id with a new one.
|
|
80080
80100
|
*
|
|
@@ -80640,13 +80660,12 @@ var __importStar = (this && this.__importStar) || function (mod) {
|
|
|
80640
80660
|
return result;
|
|
80641
80661
|
};
|
|
80642
80662
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
80643
|
-
exports.ReadReceipt = exports.synthesizeReceipt =
|
|
80663
|
+
exports.ReadReceipt = exports.synthesizeReceipt = void 0;
|
|
80644
80664
|
const read_receipts_1 = require("../@types/read_receipts");
|
|
80645
80665
|
const typed_event_emitter_1 = require("./typed-event-emitter");
|
|
80646
80666
|
const utils = __importStar(require("../utils"));
|
|
80647
80667
|
const event_1 = require("./event");
|
|
80648
80668
|
const event_2 = require("../@types/event");
|
|
80649
|
-
exports.MAIN_ROOM_TIMELINE = "main";
|
|
80650
80669
|
function synthesizeReceipt(userId, event, receiptType) {
|
|
80651
80670
|
var _a;
|
|
80652
80671
|
return new event_1.MatrixEvent({
|
|
@@ -80655,7 +80674,7 @@ function synthesizeReceipt(userId, event, receiptType) {
|
|
|
80655
80674
|
[receiptType]: {
|
|
80656
80675
|
[userId]: {
|
|
80657
80676
|
ts: event.getTs(),
|
|
80658
|
-
threadId: (_a = event.threadRootId) !== null && _a !== void 0 ? _a :
|
|
80677
|
+
threadId: (_a = event.threadRootId) !== null && _a !== void 0 ? _a : read_receipts_1.MAIN_ROOM_TIMELINE,
|
|
80659
80678
|
},
|
|
80660
80679
|
},
|
|
80661
80680
|
},
|
|
@@ -82938,7 +82957,7 @@ class Room extends read_receipt_1.ReadReceipt {
|
|
|
82938
82957
|
// If this is in the current state, replace it with the redacted version
|
|
82939
82958
|
if (redactedEvent.isState()) {
|
|
82940
82959
|
const currentStateEvent = this.currentState.getStateEvents(redactedEvent.getType(), redactedEvent.getStateKey());
|
|
82941
|
-
if (currentStateEvent.getId() === redactedEvent.getId()) {
|
|
82960
|
+
if ((currentStateEvent === null || currentStateEvent === void 0 ? void 0 : currentStateEvent.getId()) === redactedEvent.getId()) {
|
|
82942
82961
|
this.currentState.setStateEvents([redactedEvent]);
|
|
82943
82962
|
}
|
|
82944
82963
|
}
|
|
@@ -84884,7 +84903,7 @@ class Room extends read_receipt_1.ReadReceipt {
|
|
|
84884
84903
|
Object.keys(content[eventId][receiptType]).forEach((userId) => {
|
|
84885
84904
|
var _a;
|
|
84886
84905
|
const receipt = content[eventId][receiptType][userId];
|
|
84887
|
-
const receiptForMainTimeline = !receipt.thread_id || receipt.thread_id ===
|
|
84906
|
+
const receiptForMainTimeline = !receipt.thread_id || receipt.thread_id === read_receipts_1.MAIN_ROOM_TIMELINE;
|
|
84888
84907
|
const receiptDestination = receiptForMainTimeline
|
|
84889
84908
|
? this
|
|
84890
84909
|
: this.threads.get((_a = receipt.thread_id) !== null && _a !== void 0 ? _a : "");
|
|
@@ -85574,19 +85593,6 @@ exports.SearchResult = void 0;
|
|
|
85574
85593
|
*/
|
|
85575
85594
|
const event_context_1 = require("./event-context");
|
|
85576
85595
|
class SearchResult {
|
|
85577
|
-
/**
|
|
85578
|
-
* Construct a new SearchResult
|
|
85579
|
-
*
|
|
85580
|
-
* @param {number} rank where this SearchResult ranks in the results
|
|
85581
|
-
* @param {event-context.EventContext} context the matching event and its
|
|
85582
|
-
* context
|
|
85583
|
-
*
|
|
85584
|
-
* @constructor
|
|
85585
|
-
*/
|
|
85586
|
-
constructor(rank, context) {
|
|
85587
|
-
this.rank = rank;
|
|
85588
|
-
this.context = context;
|
|
85589
|
-
}
|
|
85590
85596
|
/**
|
|
85591
85597
|
* Create a SearchResponse from the response to /search
|
|
85592
85598
|
* @static
|
|
@@ -85609,6 +85615,19 @@ class SearchResult {
|
|
|
85609
85615
|
context.setPaginateToken(jsonContext.end, false);
|
|
85610
85616
|
return new SearchResult(jsonObj.rank, context);
|
|
85611
85617
|
}
|
|
85618
|
+
/**
|
|
85619
|
+
* Construct a new SearchResult
|
|
85620
|
+
*
|
|
85621
|
+
* @param {number} rank where this SearchResult ranks in the results
|
|
85622
|
+
* @param {event-context.EventContext} context the matching event and its
|
|
85623
|
+
* context
|
|
85624
|
+
*
|
|
85625
|
+
* @constructor
|
|
85626
|
+
*/
|
|
85627
|
+
constructor(rank, context) {
|
|
85628
|
+
this.rank = rank;
|
|
85629
|
+
this.context = context;
|
|
85630
|
+
}
|
|
85612
85631
|
}
|
|
85613
85632
|
exports.SearchResult = SearchResult;
|
|
85614
85633
|
|
|
@@ -87060,6 +87079,58 @@ const DEBUG = false; // set true to enable console logging.
|
|
|
87060
87079
|
*/
|
|
87061
87080
|
// eslint-disable-next-line camelcase
|
|
87062
87081
|
class MatrixScheduler {
|
|
87082
|
+
/**
|
|
87083
|
+
* Retries events up to 4 times using exponential backoff. This produces wait
|
|
87084
|
+
* times of 2, 4, 8, and 16 seconds (30s total) after which we give up. If the
|
|
87085
|
+
* failure was due to a rate limited request, the time specified in the error is
|
|
87086
|
+
* waited before being retried.
|
|
87087
|
+
* @param {MatrixEvent} event
|
|
87088
|
+
* @param {Number} attempts Number of attempts that have been made, including the one that just failed (ie. starting at 1)
|
|
87089
|
+
* @param {MatrixError} err
|
|
87090
|
+
* @return {Number}
|
|
87091
|
+
* @see module:scheduler~retryAlgorithm
|
|
87092
|
+
*/
|
|
87093
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
87094
|
+
static RETRY_BACKOFF_RATELIMIT(event, attempts, err) {
|
|
87095
|
+
if (err.httpStatus === 400 || err.httpStatus === 403 || err.httpStatus === 401) {
|
|
87096
|
+
// client error; no amount of retrying with save you now.
|
|
87097
|
+
return -1;
|
|
87098
|
+
}
|
|
87099
|
+
if (err instanceof http_api_1.ConnectionError) {
|
|
87100
|
+
return -1;
|
|
87101
|
+
}
|
|
87102
|
+
// if event that we are trying to send is too large in any way then retrying won't help
|
|
87103
|
+
if (err.name === "M_TOO_LARGE") {
|
|
87104
|
+
return -1;
|
|
87105
|
+
}
|
|
87106
|
+
if (err.name === "M_LIMIT_EXCEEDED") {
|
|
87107
|
+
const waitTime = err.data.retry_after_ms;
|
|
87108
|
+
if (waitTime > 0) {
|
|
87109
|
+
return waitTime;
|
|
87110
|
+
}
|
|
87111
|
+
}
|
|
87112
|
+
if (attempts > 4) {
|
|
87113
|
+
return -1; // give up
|
|
87114
|
+
}
|
|
87115
|
+
return (1000 * Math.pow(2, attempts));
|
|
87116
|
+
}
|
|
87117
|
+
/**
|
|
87118
|
+
* Queues <code>m.room.message</code> events and lets other events continue
|
|
87119
|
+
* concurrently.
|
|
87120
|
+
* @param {MatrixEvent} event
|
|
87121
|
+
* @return {string}
|
|
87122
|
+
* @see module:scheduler~queueAlgorithm
|
|
87123
|
+
*/
|
|
87124
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
87125
|
+
static QUEUE_MESSAGES(event) {
|
|
87126
|
+
// enqueue messages or events that associate with another event (redactions and relations)
|
|
87127
|
+
if (event.getType() === event_1.EventType.RoomMessage || event.hasAssociation()) {
|
|
87128
|
+
// put these events in the 'message' queue.
|
|
87129
|
+
return "message";
|
|
87130
|
+
}
|
|
87131
|
+
// allow all other events continue concurrently.
|
|
87132
|
+
return null;
|
|
87133
|
+
}
|
|
87063
87134
|
constructor(retryAlgorithm = MatrixScheduler.RETRY_BACKOFF_RATELIMIT, queueAlgorithm = MatrixScheduler.QUEUE_MESSAGES) {
|
|
87064
87135
|
this.retryAlgorithm = retryAlgorithm;
|
|
87065
87136
|
this.queueAlgorithm = queueAlgorithm;
|
|
@@ -87118,58 +87189,6 @@ class MatrixScheduler {
|
|
|
87118
87189
|
});
|
|
87119
87190
|
};
|
|
87120
87191
|
}
|
|
87121
|
-
/**
|
|
87122
|
-
* Retries events up to 4 times using exponential backoff. This produces wait
|
|
87123
|
-
* times of 2, 4, 8, and 16 seconds (30s total) after which we give up. If the
|
|
87124
|
-
* failure was due to a rate limited request, the time specified in the error is
|
|
87125
|
-
* waited before being retried.
|
|
87126
|
-
* @param {MatrixEvent} event
|
|
87127
|
-
* @param {Number} attempts Number of attempts that have been made, including the one that just failed (ie. starting at 1)
|
|
87128
|
-
* @param {MatrixError} err
|
|
87129
|
-
* @return {Number}
|
|
87130
|
-
* @see module:scheduler~retryAlgorithm
|
|
87131
|
-
*/
|
|
87132
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
87133
|
-
static RETRY_BACKOFF_RATELIMIT(event, attempts, err) {
|
|
87134
|
-
if (err.httpStatus === 400 || err.httpStatus === 403 || err.httpStatus === 401) {
|
|
87135
|
-
// client error; no amount of retrying with save you now.
|
|
87136
|
-
return -1;
|
|
87137
|
-
}
|
|
87138
|
-
if (err instanceof http_api_1.ConnectionError) {
|
|
87139
|
-
return -1;
|
|
87140
|
-
}
|
|
87141
|
-
// if event that we are trying to send is too large in any way then retrying won't help
|
|
87142
|
-
if (err.name === "M_TOO_LARGE") {
|
|
87143
|
-
return -1;
|
|
87144
|
-
}
|
|
87145
|
-
if (err.name === "M_LIMIT_EXCEEDED") {
|
|
87146
|
-
const waitTime = err.data.retry_after_ms;
|
|
87147
|
-
if (waitTime > 0) {
|
|
87148
|
-
return waitTime;
|
|
87149
|
-
}
|
|
87150
|
-
}
|
|
87151
|
-
if (attempts > 4) {
|
|
87152
|
-
return -1; // give up
|
|
87153
|
-
}
|
|
87154
|
-
return (1000 * Math.pow(2, attempts));
|
|
87155
|
-
}
|
|
87156
|
-
/**
|
|
87157
|
-
* Queues <code>m.room.message</code> events and lets other events continue
|
|
87158
|
-
* concurrently.
|
|
87159
|
-
* @param {MatrixEvent} event
|
|
87160
|
-
* @return {string}
|
|
87161
|
-
* @see module:scheduler~queueAlgorithm
|
|
87162
|
-
*/
|
|
87163
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
87164
|
-
static QUEUE_MESSAGES(event) {
|
|
87165
|
-
// enqueue messages or events that associate with another event (redactions and relations)
|
|
87166
|
-
if (event.getType() === event_1.EventType.RoomMessage || event.hasAssocation()) {
|
|
87167
|
-
// put these events in the 'message' queue.
|
|
87168
|
-
return "message";
|
|
87169
|
-
}
|
|
87170
|
-
// allow all other events continue concurrently.
|
|
87171
|
-
return null;
|
|
87172
|
-
}
|
|
87173
87192
|
/**
|
|
87174
87193
|
* Retrieve a queue based on an event. The event provided does not need to be in
|
|
87175
87194
|
* the queue.
|
|
@@ -87578,6 +87597,60 @@ class ExtensionAccountData {
|
|
|
87578
87597
|
});
|
|
87579
87598
|
}
|
|
87580
87599
|
}
|
|
87600
|
+
class ExtensionTyping {
|
|
87601
|
+
constructor(client) {
|
|
87602
|
+
this.client = client;
|
|
87603
|
+
}
|
|
87604
|
+
name() {
|
|
87605
|
+
return "typing";
|
|
87606
|
+
}
|
|
87607
|
+
when() {
|
|
87608
|
+
return sliding_sync_1.ExtensionState.PostProcess;
|
|
87609
|
+
}
|
|
87610
|
+
onRequest(isInitial) {
|
|
87611
|
+
if (!isInitial) {
|
|
87612
|
+
return undefined; // don't send a JSON object for subsequent requests, we don't need to.
|
|
87613
|
+
}
|
|
87614
|
+
return {
|
|
87615
|
+
enabled: true,
|
|
87616
|
+
};
|
|
87617
|
+
}
|
|
87618
|
+
onResponse(data) {
|
|
87619
|
+
if (!data || !data.rooms) {
|
|
87620
|
+
return;
|
|
87621
|
+
}
|
|
87622
|
+
for (const roomId in data.rooms) {
|
|
87623
|
+
processEphemeralEvents(this.client, roomId, [data.rooms[roomId]]);
|
|
87624
|
+
}
|
|
87625
|
+
}
|
|
87626
|
+
}
|
|
87627
|
+
class ExtensionReceipts {
|
|
87628
|
+
constructor(client) {
|
|
87629
|
+
this.client = client;
|
|
87630
|
+
}
|
|
87631
|
+
name() {
|
|
87632
|
+
return "receipts";
|
|
87633
|
+
}
|
|
87634
|
+
when() {
|
|
87635
|
+
return sliding_sync_1.ExtensionState.PostProcess;
|
|
87636
|
+
}
|
|
87637
|
+
onRequest(isInitial) {
|
|
87638
|
+
if (isInitial) {
|
|
87639
|
+
return {
|
|
87640
|
+
enabled: true,
|
|
87641
|
+
};
|
|
87642
|
+
}
|
|
87643
|
+
return undefined; // don't send a JSON object for subsequent requests, we don't need to.
|
|
87644
|
+
}
|
|
87645
|
+
onResponse(data) {
|
|
87646
|
+
if (!data || !data.rooms) {
|
|
87647
|
+
return;
|
|
87648
|
+
}
|
|
87649
|
+
for (const roomId in data.rooms) {
|
|
87650
|
+
processEphemeralEvents(this.client, roomId, [data.rooms[roomId]]);
|
|
87651
|
+
}
|
|
87652
|
+
}
|
|
87653
|
+
}
|
|
87581
87654
|
/**
|
|
87582
87655
|
* A copy of SyncApi such that it can be used as a drop-in replacement for sync v2. For the actual
|
|
87583
87656
|
* sliding sync API, see sliding-sync.ts or the class SlidingSync.
|
|
@@ -87613,6 +87686,8 @@ class SlidingSyncSdk {
|
|
|
87613
87686
|
const extensions = [
|
|
87614
87687
|
new ExtensionToDevice(this.client),
|
|
87615
87688
|
new ExtensionAccountData(this.client),
|
|
87689
|
+
new ExtensionTyping(this.client),
|
|
87690
|
+
new ExtensionReceipts(this.client),
|
|
87616
87691
|
];
|
|
87617
87692
|
if (this.opts.crypto) {
|
|
87618
87693
|
extensions.push(new ExtensionE2EE(this.opts.crypto));
|
|
@@ -88184,6 +88259,18 @@ function mapEvents(client, roomId, events, decrypt = true) {
|
|
|
88184
88259
|
return mapper(e);
|
|
88185
88260
|
});
|
|
88186
88261
|
}
|
|
88262
|
+
function processEphemeralEvents(client, roomId, ephEvents) {
|
|
88263
|
+
const ephemeralEvents = mapEvents(client, roomId, ephEvents);
|
|
88264
|
+
const room = client.getRoom(roomId);
|
|
88265
|
+
if (!room) {
|
|
88266
|
+
logger_1.logger.warn("got ephemeral events for room but room doesn't exist on client:", roomId);
|
|
88267
|
+
return;
|
|
88268
|
+
}
|
|
88269
|
+
room.addEphemeralEvents(ephemeralEvents);
|
|
88270
|
+
ephemeralEvents.forEach((e) => {
|
|
88271
|
+
client.emit(client_1.ClientEvent.Event, e);
|
|
88272
|
+
});
|
|
88273
|
+
}
|
|
88187
88274
|
|
|
88188
88275
|
},{"./@types/event":290,"./client":304,"./http-api":349,"./logger":356,"./models/event-timeline":364,"./models/room":373,"./models/room-member":370,"./models/room-state":371,"./pushprocessor":378,"./sliding-sync":384,"./sync":391,"./utils":393}],384:[function(require,module,exports){
|
|
88189
88276
|
"use strict";
|
|
@@ -88212,7 +88299,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
88212
88299
|
});
|
|
88213
88300
|
};
|
|
88214
88301
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
88215
|
-
exports.SlidingSync = exports.SlidingSyncEvent = exports.ExtensionState = exports.SlidingSyncState = void 0;
|
|
88302
|
+
exports.SlidingSync = exports.SlidingSyncEvent = exports.ExtensionState = exports.SlidingSyncState = exports.MSC3575_STATE_KEY_LAZY = exports.MSC3575_STATE_KEY_ME = exports.MSC3575_WILDCARD = void 0;
|
|
88216
88303
|
const logger_1 = require("./logger");
|
|
88217
88304
|
const typed_event_emitter_1 = require("./models/typed-event-emitter");
|
|
88218
88305
|
const utils_1 = require("./utils");
|
|
@@ -88221,6 +88308,9 @@ const utils_1 = require("./utils");
|
|
|
88221
88308
|
// to keep open the connection. This constant is *ADDED* to the timeout= value
|
|
88222
88309
|
// to determine the max time we're willing to wait.
|
|
88223
88310
|
const BUFFER_PERIOD_MS = 10 * 1000;
|
|
88311
|
+
exports.MSC3575_WILDCARD = "*";
|
|
88312
|
+
exports.MSC3575_STATE_KEY_ME = "$ME";
|
|
88313
|
+
exports.MSC3575_STATE_KEY_LAZY = "$LAZY";
|
|
88224
88314
|
var SlidingSyncState;
|
|
88225
88315
|
(function (SlidingSyncState) {
|
|
88226
88316
|
/**
|
|
@@ -89045,6 +89135,10 @@ function reqAsCursorPromise(req) {
|
|
|
89045
89135
|
return reqAsEventPromise(req).then((event) => req.result);
|
|
89046
89136
|
}
|
|
89047
89137
|
class LocalIndexedDBStoreBackend {
|
|
89138
|
+
static exists(indexedDB, dbName) {
|
|
89139
|
+
dbName = "matrix-js-sdk:" + (dbName || "default");
|
|
89140
|
+
return IndexedDBHelpers.exists(indexedDB, dbName);
|
|
89141
|
+
}
|
|
89048
89142
|
/**
|
|
89049
89143
|
* Does the actual reading from and writing to the indexeddb
|
|
89050
89144
|
*
|
|
@@ -89065,10 +89159,6 @@ class LocalIndexedDBStoreBackend {
|
|
|
89065
89159
|
this.dbName = "matrix-js-sdk:" + dbName;
|
|
89066
89160
|
this.syncAccumulator = new sync_accumulator_1.SyncAccumulator();
|
|
89067
89161
|
}
|
|
89068
|
-
static exists(indexedDB, dbName) {
|
|
89069
|
-
dbName = "matrix-js-sdk:" + (dbName || "default");
|
|
89070
|
-
return IndexedDBHelpers.exists(indexedDB, dbName);
|
|
89071
|
-
}
|
|
89072
89162
|
/**
|
|
89073
89163
|
* Attempt to connect to the database. This can fail if the user does not
|
|
89074
89164
|
* grant permission.
|
|
@@ -89099,7 +89189,7 @@ class LocalIndexedDBStoreBackend {
|
|
|
89099
89189
|
logger_1.logger.log(`can't yet open LocalIndexedDBStoreBackend because it is open elsewhere`);
|
|
89100
89190
|
};
|
|
89101
89191
|
logger_1.logger.log(`LocalIndexedDBStoreBackend.connect: awaiting connection...`);
|
|
89102
|
-
return reqAsEventPromise(req).then(() => {
|
|
89192
|
+
return reqAsEventPromise(req).then(() => __awaiter(this, void 0, void 0, function* () {
|
|
89103
89193
|
logger_1.logger.log(`LocalIndexedDBStoreBackend.connect: connected`);
|
|
89104
89194
|
this.db = req.result;
|
|
89105
89195
|
// add a poorly-named listener for when deleteDatabase is called
|
|
@@ -89108,8 +89198,8 @@ class LocalIndexedDBStoreBackend {
|
|
|
89108
89198
|
var _a;
|
|
89109
89199
|
(_a = this.db) === null || _a === void 0 ? void 0 : _a.close();
|
|
89110
89200
|
};
|
|
89111
|
-
|
|
89112
|
-
});
|
|
89201
|
+
yield this.init();
|
|
89202
|
+
}));
|
|
89113
89203
|
}
|
|
89114
89204
|
/** @return {boolean} whether or not the database was newly created in this session. */
|
|
89115
89205
|
isNewlyCreated() {
|
|
@@ -89718,6 +89808,9 @@ const typed_event_emitter_1 = require("../models/typed-event-emitter");
|
|
|
89718
89808
|
// response is persisted each time.
|
|
89719
89809
|
const WRITE_DELAY_MS = 1000 * 60 * 5; // once every 5 minutes
|
|
89720
89810
|
class IndexedDBStore extends memory_1.MemoryStore {
|
|
89811
|
+
static exists(indexedDB, dbName) {
|
|
89812
|
+
return indexeddb_local_backend_1.LocalIndexedDBStoreBackend.exists(indexedDB, dbName);
|
|
89813
|
+
}
|
|
89721
89814
|
/**
|
|
89722
89815
|
* Construct a new Indexed Database store, which extends MemoryStore.
|
|
89723
89816
|
*
|
|
@@ -89864,9 +89957,6 @@ class IndexedDBStore extends memory_1.MemoryStore {
|
|
|
89864
89957
|
this.backend = new indexeddb_local_backend_1.LocalIndexedDBStoreBackend(opts.indexedDB, opts.dbName);
|
|
89865
89958
|
}
|
|
89866
89959
|
}
|
|
89867
|
-
static exists(indexedDB, dbName) {
|
|
89868
|
-
return indexeddb_local_backend_1.LocalIndexedDBStoreBackend.exists(indexedDB, dbName);
|
|
89869
|
-
}
|
|
89870
89960
|
/**
|
|
89871
89961
|
* @return {Promise} Resolved when loaded from indexed db.
|
|
89872
89962
|
*/
|
|
@@ -90716,6 +90806,7 @@ exports.SyncAccumulator = exports.Category = void 0;
|
|
|
90716
90806
|
const logger_1 = require("./logger");
|
|
90717
90807
|
const utils_1 = require("./utils");
|
|
90718
90808
|
const event_1 = require("./@types/event");
|
|
90809
|
+
const read_receipts_1 = require("./@types/read_receipts");
|
|
90719
90810
|
const sync_1 = require("./@types/sync");
|
|
90720
90811
|
/* eslint-enable camelcase */
|
|
90721
90812
|
var Category;
|
|
@@ -90907,6 +90998,7 @@ class SyncAccumulator {
|
|
|
90907
90998
|
_unreadThreadNotifications: {},
|
|
90908
90999
|
_summary: {},
|
|
90909
91000
|
_readReceipts: {},
|
|
91001
|
+
_threadReadReceipts: {},
|
|
90910
91002
|
};
|
|
90911
91003
|
}
|
|
90912
91004
|
const currentData = this.joinRooms[roomId];
|
|
@@ -90957,16 +91049,23 @@ class SyncAccumulator {
|
|
|
90957
91049
|
// getJSON() is called.
|
|
90958
91050
|
Object.keys(e.content).forEach((eventId) => {
|
|
90959
91051
|
Object.entries(e.content[eventId]).forEach(([key, value]) => {
|
|
91052
|
+
var _a;
|
|
90960
91053
|
if (!(0, utils_1.isSupportedReceiptType)(key))
|
|
90961
91054
|
return;
|
|
90962
|
-
Object.keys(value)
|
|
90963
|
-
|
|
90964
|
-
|
|
91055
|
+
for (const userId of Object.keys(value)) {
|
|
91056
|
+
const data = e.content[eventId][key][userId];
|
|
91057
|
+
const receipt = {
|
|
90965
91058
|
data: e.content[eventId][key][userId],
|
|
90966
91059
|
type: key,
|
|
90967
91060
|
eventId: eventId,
|
|
90968
91061
|
};
|
|
90969
|
-
|
|
91062
|
+
if (!data.thread_id || data.thread_id === read_receipts_1.MAIN_ROOM_TIMELINE) {
|
|
91063
|
+
currentData._readReceipts[userId] = receipt;
|
|
91064
|
+
}
|
|
91065
|
+
else {
|
|
91066
|
+
currentData._threadReadReceipts = Object.assign(Object.assign({}, currentData._threadReadReceipts), { [data.thread_id]: Object.assign(Object.assign({}, ((_a = currentData._threadReadReceipts[data.thread_id]) !== null && _a !== void 0 ? _a : {})), { [userId]: receipt }) });
|
|
91067
|
+
}
|
|
91068
|
+
}
|
|
90970
91069
|
});
|
|
90971
91070
|
});
|
|
90972
91071
|
});
|
|
@@ -91084,8 +91183,7 @@ class SyncAccumulator {
|
|
|
91084
91183
|
// $event_id: { "m.read": { $user_id: $json } }
|
|
91085
91184
|
},
|
|
91086
91185
|
};
|
|
91087
|
-
Object.
|
|
91088
|
-
const receiptData = roomData._readReceipts[userId];
|
|
91186
|
+
for (const [userId, receiptData] of Object.entries(roomData._readReceipts)) {
|
|
91089
91187
|
if (!receiptEvent.content[receiptData.eventId]) {
|
|
91090
91188
|
receiptEvent.content[receiptData.eventId] = {};
|
|
91091
91189
|
}
|
|
@@ -91093,7 +91191,18 @@ class SyncAccumulator {
|
|
|
91093
91191
|
receiptEvent.content[receiptData.eventId][receiptData.type] = {};
|
|
91094
91192
|
}
|
|
91095
91193
|
receiptEvent.content[receiptData.eventId][receiptData.type][userId] = (receiptData.data);
|
|
91096
|
-
}
|
|
91194
|
+
}
|
|
91195
|
+
for (const threadReceipts of Object.values(roomData._threadReadReceipts)) {
|
|
91196
|
+
for (const [userId, receiptData] of Object.entries(threadReceipts)) {
|
|
91197
|
+
if (!receiptEvent.content[receiptData.eventId]) {
|
|
91198
|
+
receiptEvent.content[receiptData.eventId] = {};
|
|
91199
|
+
}
|
|
91200
|
+
if (!receiptEvent.content[receiptData.eventId][receiptData.type]) {
|
|
91201
|
+
receiptEvent.content[receiptData.eventId][receiptData.type] = {};
|
|
91202
|
+
}
|
|
91203
|
+
receiptEvent.content[receiptData.eventId][receiptData.type][userId] = (receiptData.data);
|
|
91204
|
+
}
|
|
91205
|
+
}
|
|
91097
91206
|
// add only if we have some receipt data
|
|
91098
91207
|
if (Object.keys(receiptEvent.content).length > 0) {
|
|
91099
91208
|
roomJson.ephemeral.events.push(receiptEvent);
|
|
@@ -91193,7 +91302,7 @@ function setState(eventMap, event) {
|
|
|
91193
91302
|
eventMap[event.type][event.state_key] = event;
|
|
91194
91303
|
}
|
|
91195
91304
|
|
|
91196
|
-
},{"./@types/event":290,"./@types/sync":297,"./logger":356,"./utils":393}],391:[function(require,module,exports){
|
|
91305
|
+
},{"./@types/event":290,"./@types/read_receipts":294,"./@types/sync":297,"./logger":356,"./utils":393}],391:[function(require,module,exports){
|
|
91197
91306
|
(function (global){(function (){
|
|
91198
91307
|
"use strict";
|
|
91199
91308
|
/*
|
|
@@ -93321,7 +93430,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
|
93321
93430
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
93322
93431
|
};
|
|
93323
93432
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
93324
|
-
exports.isSupportedReceiptType = exports.sortEventsByLatestContentTimestamp = exports.recursivelyAssign = exports.compare = exports.lexicographicCompare = exports.prevString = exports.nextString = exports.averageBetweenStrings = exports.stringToBase = exports.baseToString = exports.alphabetPad = exports.DEFAULT_ALPHABET = exports.simpleRetryOperation = exports.chunkPromises = exports.promiseTry = exports.promiseMapSeries = exports.defer = exports.isNullOrUndefined = exports.sleep = exports.ensureNoTrailingSlash = exports.globToRegexp = exports.escapeRegExp = exports.normalize = exports.removeDirectionOverrideChars = exports.removeHiddenChars = exports.isNumber = exports.deepSortedObjectEntries = exports.deepCompare = exports.deepCopy = exports.checkObjectHasKeys = exports.isFunction = exports.removeElement = exports.encodeUri = exports.decodeParams = exports.replaceParam = exports.encodeParams = exports.internaliseString = void 0;
|
|
93433
|
+
exports.mapsEqual = exports.isSupportedReceiptType = exports.sortEventsByLatestContentTimestamp = exports.recursivelyAssign = exports.compare = exports.lexicographicCompare = exports.prevString = exports.nextString = exports.averageBetweenStrings = exports.stringToBase = exports.baseToString = exports.alphabetPad = exports.DEFAULT_ALPHABET = exports.simpleRetryOperation = exports.chunkPromises = exports.promiseTry = exports.promiseMapSeries = exports.defer = exports.isNullOrUndefined = exports.sleep = exports.ensureNoTrailingSlash = exports.globToRegexp = exports.escapeRegExp = exports.normalize = exports.removeDirectionOverrideChars = exports.removeHiddenChars = exports.isNumber = exports.deepSortedObjectEntries = exports.deepCompare = exports.deepCopy = exports.checkObjectHasKeys = exports.isFunction = exports.removeElement = exports.encodeUri = exports.decodeParams = exports.replaceParam = exports.encodeParams = exports.internaliseString = void 0;
|
|
93325
93434
|
/**
|
|
93326
93435
|
* This is an internal module.
|
|
93327
93436
|
* @module utils
|
|
@@ -93949,6 +94058,21 @@ function isSupportedReceiptType(receiptType) {
|
|
|
93949
94058
|
return [read_receipts_1.ReceiptType.Read, read_receipts_1.ReceiptType.ReadPrivate].includes(receiptType);
|
|
93950
94059
|
}
|
|
93951
94060
|
exports.isSupportedReceiptType = isSupportedReceiptType;
|
|
94061
|
+
/**
|
|
94062
|
+
* Determines whether two maps are equal.
|
|
94063
|
+
* @param eq The equivalence relation to compare values by. Defaults to strict equality.
|
|
94064
|
+
*/
|
|
94065
|
+
function mapsEqual(x, y, eq = (v1, v2) => v1 === v2) {
|
|
94066
|
+
if (x.size !== y.size)
|
|
94067
|
+
return false;
|
|
94068
|
+
for (const [k, v1] of x) {
|
|
94069
|
+
const v2 = y.get(k);
|
|
94070
|
+
if (v2 === undefined || !eq(v1, v2))
|
|
94071
|
+
return false;
|
|
94072
|
+
}
|
|
94073
|
+
return true;
|
|
94074
|
+
}
|
|
94075
|
+
exports.mapsEqual = mapsEqual;
|
|
93952
94076
|
|
|
93953
94077
|
},{"./@types/location":292,"./@types/read_receipts":294,"p-retry":226,"unhomoglyph":282}],394:[function(require,module,exports){
|
|
93954
94078
|
"use strict";
|
|
@@ -94496,6 +94620,9 @@ class MatrixCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
94496
94620
|
getOpponentMember() {
|
|
94497
94621
|
return this.opponentMember;
|
|
94498
94622
|
}
|
|
94623
|
+
getOpponentDeviceId() {
|
|
94624
|
+
return this.opponentDeviceId;
|
|
94625
|
+
}
|
|
94499
94626
|
getOpponentSessionId() {
|
|
94500
94627
|
return this.opponentSessionId;
|
|
94501
94628
|
}
|
|
@@ -94660,6 +94787,7 @@ class MatrixCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
94660
94787
|
client: this.client,
|
|
94661
94788
|
roomId: this.roomId,
|
|
94662
94789
|
userId,
|
|
94790
|
+
deviceId: this.getOpponentDeviceId(),
|
|
94663
94791
|
stream,
|
|
94664
94792
|
purpose,
|
|
94665
94793
|
audioMuted,
|
|
@@ -94696,6 +94824,7 @@ class MatrixCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
94696
94824
|
audioMuted: false,
|
|
94697
94825
|
videoMuted: false,
|
|
94698
94826
|
userId,
|
|
94827
|
+
deviceId: this.getOpponentDeviceId(),
|
|
94699
94828
|
stream,
|
|
94700
94829
|
purpose,
|
|
94701
94830
|
}));
|
|
@@ -94719,6 +94848,7 @@ class MatrixCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
94719
94848
|
audioMuted: false,
|
|
94720
94849
|
videoMuted: false,
|
|
94721
94850
|
userId,
|
|
94851
|
+
deviceId: this.getOpponentDeviceId(),
|
|
94722
94852
|
stream,
|
|
94723
94853
|
purpose,
|
|
94724
94854
|
}), addToPeerConnection);
|
|
@@ -94952,6 +95082,7 @@ class MatrixCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
94952
95082
|
* Answer a call.
|
|
94953
95083
|
*/
|
|
94954
95084
|
answer(audio, video) {
|
|
95085
|
+
var _a;
|
|
94955
95086
|
return __awaiter(this, void 0, void 0, function* () {
|
|
94956
95087
|
if (this.inviteOrAnswerSent)
|
|
94957
95088
|
return;
|
|
@@ -94971,6 +95102,7 @@ class MatrixCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
94971
95102
|
client: this.client,
|
|
94972
95103
|
roomId: this.roomId,
|
|
94973
95104
|
userId: this.client.getUserId(),
|
|
95105
|
+
deviceId: (_a = this.client.getDeviceId()) !== null && _a !== void 0 ? _a : undefined,
|
|
94974
95106
|
stream,
|
|
94975
95107
|
purpose: callEventTypes_1.SDPStreamMetadataPurpose.Usermedia,
|
|
94976
95108
|
audioMuted: false,
|
|
@@ -95041,7 +95173,7 @@ class MatrixCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
95041
95173
|
logger_1.logger.debug(`Ending call ${this.callId} with reason ${reason}`);
|
|
95042
95174
|
this.terminate(CallParty.Local, reason, !suppressEvent);
|
|
95043
95175
|
// We don't want to send hangup here if we didn't even get to sending an invite
|
|
95044
|
-
if (
|
|
95176
|
+
if ([CallState.Fledgling, CallState.WaitLocalMedia].includes(this.state))
|
|
95045
95177
|
return;
|
|
95046
95178
|
const content = {};
|
|
95047
95179
|
// Don't send UserHangup reason to older clients
|
|
@@ -96203,6 +96335,7 @@ class MatrixCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
96203
96335
|
* @throws if have passed audio=false.
|
|
96204
96336
|
*/
|
|
96205
96337
|
placeCall(audio, video) {
|
|
96338
|
+
var _a;
|
|
96206
96339
|
return __awaiter(this, void 0, void 0, function* () {
|
|
96207
96340
|
if (!audio) {
|
|
96208
96341
|
throw new Error("You CANNOT start a call without audio");
|
|
@@ -96218,6 +96351,7 @@ class MatrixCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
96218
96351
|
client: this.client,
|
|
96219
96352
|
roomId: this.roomId,
|
|
96220
96353
|
userId: this.client.getUserId(),
|
|
96354
|
+
deviceId: (_a = this.client.getDeviceId()) !== null && _a !== void 0 ? _a : undefined,
|
|
96221
96355
|
stream,
|
|
96222
96356
|
purpose: callEventTypes_1.SDPStreamMetadataPurpose.Usermedia,
|
|
96223
96357
|
audioMuted: false,
|
|
@@ -96576,7 +96710,6 @@ class CallEventHandler {
|
|
|
96576
96710
|
const groupCallId = content.conf_id;
|
|
96577
96711
|
const type = event.getType();
|
|
96578
96712
|
const senderId = event.getSender();
|
|
96579
|
-
const weSentTheEvent = senderId === this.client.credentials.userId;
|
|
96580
96713
|
let call = content.call_id ? this.calls.get(content.call_id) : undefined;
|
|
96581
96714
|
let opponentDeviceId;
|
|
96582
96715
|
let groupCall;
|
|
@@ -96597,6 +96730,8 @@ class CallEventHandler {
|
|
|
96597
96730
|
return;
|
|
96598
96731
|
}
|
|
96599
96732
|
}
|
|
96733
|
+
const weSentTheEvent = senderId === this.client.credentials.userId
|
|
96734
|
+
&& (opponentDeviceId === undefined || opponentDeviceId === this.client.getDeviceId());
|
|
96600
96735
|
if (!callRoomId)
|
|
96601
96736
|
return;
|
|
96602
96737
|
if (type === event_1.EventType.CallInvite) {
|
|
@@ -96861,6 +96996,7 @@ class CallFeed extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
96861
96996
|
this.client = opts.client;
|
|
96862
96997
|
this.roomId = opts.roomId;
|
|
96863
96998
|
this.userId = opts.userId;
|
|
96999
|
+
this.deviceId = opts.deviceId;
|
|
96864
97000
|
this.purpose = opts.purpose;
|
|
96865
97001
|
this.audioMuted = opts.audioMuted;
|
|
96866
97002
|
this.videoMuted = opts.videoMuted;
|
|
@@ -96918,7 +97054,8 @@ class CallFeed extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
96918
97054
|
* @returns {boolean} is local?
|
|
96919
97055
|
*/
|
|
96920
97056
|
isLocal() {
|
|
96921
|
-
return this.userId === this.client.getUserId()
|
|
97057
|
+
return this.userId === this.client.getUserId()
|
|
97058
|
+
&& (this.deviceId === undefined || this.deviceId === this.client.getDeviceId());
|
|
96922
97059
|
}
|
|
96923
97060
|
/**
|
|
96924
97061
|
* Returns true if audio is muted or if there are no audio
|
|
@@ -97001,6 +97138,7 @@ class CallFeed extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97001
97138
|
client: this.client,
|
|
97002
97139
|
roomId: this.roomId,
|
|
97003
97140
|
userId: this.userId,
|
|
97141
|
+
deviceId: this.deviceId,
|
|
97004
97142
|
stream,
|
|
97005
97143
|
purpose: this.purpose,
|
|
97006
97144
|
audioMuted: this.audioMuted,
|
|
@@ -97051,12 +97189,14 @@ exports.GroupCall = exports.GroupCallState = exports.OtherUserSpeakingError = ex
|
|
|
97051
97189
|
const typed_event_emitter_1 = require("../models/typed-event-emitter");
|
|
97052
97190
|
const callFeed_1 = require("./callFeed");
|
|
97053
97191
|
const call_1 = require("./call");
|
|
97192
|
+
const room_state_1 = require("../models/room-state");
|
|
97054
97193
|
const logger_1 = require("../logger");
|
|
97055
97194
|
const ReEmitter_1 = require("../ReEmitter");
|
|
97056
97195
|
const callEventTypes_1 = require("./callEventTypes");
|
|
97057
97196
|
const event_1 = require("../@types/event");
|
|
97058
97197
|
const callEventHandler_1 = require("./callEventHandler");
|
|
97059
97198
|
const groupCallEventHandler_1 = require("./groupCallEventHandler");
|
|
97199
|
+
const utils_1 = require("../utils");
|
|
97060
97200
|
var GroupCallIntent;
|
|
97061
97201
|
(function (GroupCallIntent) {
|
|
97062
97202
|
GroupCallIntent["Ring"] = "m.ring";
|
|
@@ -97121,24 +97261,17 @@ var GroupCallState;
|
|
|
97121
97261
|
GroupCallState["LocalCallFeedUninitialized"] = "local_call_feed_uninitialized";
|
|
97122
97262
|
GroupCallState["InitializingLocalCallFeed"] = "initializing_local_call_feed";
|
|
97123
97263
|
GroupCallState["LocalCallFeedInitialized"] = "local_call_feed_initialized";
|
|
97124
|
-
GroupCallState["Entering"] = "entering";
|
|
97125
97264
|
GroupCallState["Entered"] = "entered";
|
|
97126
97265
|
GroupCallState["Ended"] = "ended";
|
|
97127
97266
|
})(GroupCallState = exports.GroupCallState || (exports.GroupCallState = {}));
|
|
97128
|
-
const
|
|
97129
|
-
const callMemberStateIsExpired = (event) => {
|
|
97130
|
-
var _a;
|
|
97131
|
-
const now = Date.now();
|
|
97132
|
-
const content = (_a = event === null || event === void 0 ? void 0 : event.getContent()) !== null && _a !== void 0 ? _a : {};
|
|
97133
|
-
const expiresAt = typeof content["m.expires_ts"] === "number" ? content["m.expires_ts"] : -Infinity;
|
|
97134
|
-
return expiresAt <= now;
|
|
97135
|
-
};
|
|
97267
|
+
const DEVICE_TIMEOUT = 1000 * 60 * 60; // 1 hour
|
|
97136
97268
|
function getCallUserId(call) {
|
|
97137
97269
|
var _a;
|
|
97138
97270
|
return ((_a = call.getOpponentMember()) === null || _a === void 0 ? void 0 : _a.userId) || call.invitee || null;
|
|
97139
97271
|
}
|
|
97140
97272
|
class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
97141
97273
|
constructor(client, room, type, isPtt, intent, groupCallId, dataChannelsEnabled, dataChannelOptions) {
|
|
97274
|
+
var _a, _b;
|
|
97142
97275
|
super();
|
|
97143
97276
|
this.client = client;
|
|
97144
97277
|
this.room = room;
|
|
@@ -97152,19 +97285,20 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97152
97285
|
this.retryCallInterval = 5000;
|
|
97153
97286
|
this.participantTimeout = 1000 * 15;
|
|
97154
97287
|
this.pttMaxTransmitTime = 1000 * 20;
|
|
97155
|
-
this.
|
|
97156
|
-
this.calls = [];
|
|
97157
|
-
this.participants = [];
|
|
97288
|
+
this.calls = new Map();
|
|
97158
97289
|
this.userMediaFeeds = [];
|
|
97159
97290
|
this.screenshareFeeds = [];
|
|
97160
|
-
this.callHandlers = new Map();
|
|
97291
|
+
this.callHandlers = new Map(); // User ID -> device ID -> handlers
|
|
97161
97292
|
this.retryCallCounts = new Map();
|
|
97162
97293
|
this.transmitTimer = null;
|
|
97163
|
-
this.
|
|
97294
|
+
this.participantsExpirationTimer = null;
|
|
97164
97295
|
this.resendMemberStateTimer = null;
|
|
97165
97296
|
this.initWithAudioMuted = false;
|
|
97166
97297
|
this.initWithVideoMuted = false;
|
|
97167
|
-
|
|
97298
|
+
this._state = GroupCallState.LocalCallFeedUninitialized;
|
|
97299
|
+
this._participants = new Map();
|
|
97300
|
+
this._creationTs = null;
|
|
97301
|
+
/*
|
|
97168
97302
|
* Call Setup
|
|
97169
97303
|
*
|
|
97170
97304
|
* There are two different paths for calls to be created:
|
|
@@ -97187,148 +97321,55 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97187
97321
|
newCall.reject();
|
|
97188
97322
|
return;
|
|
97189
97323
|
}
|
|
97190
|
-
const
|
|
97191
|
-
|
|
97192
|
-
|
|
97324
|
+
const opponent = newCall.getOpponentMember();
|
|
97325
|
+
if (opponent === undefined) {
|
|
97326
|
+
logger_1.logger.warn("Incoming call with no member. Ignoring.");
|
|
97193
97327
|
return;
|
|
97194
97328
|
}
|
|
97195
|
-
|
|
97196
|
-
|
|
97197
|
-
|
|
97198
|
-
|
|
97199
|
-
|
|
97200
|
-
|
|
97201
|
-
|
|
97202
|
-
|
|
97203
|
-
this.addCall(newCall);
|
|
97204
|
-
}
|
|
97329
|
+
const deviceMap = (_a = this.calls.get(opponent)) !== null && _a !== void 0 ? _a : new Map();
|
|
97330
|
+
const prevCall = deviceMap.get(newCall.getOpponentDeviceId());
|
|
97331
|
+
if ((prevCall === null || prevCall === void 0 ? void 0 : prevCall.callId) === newCall.callId)
|
|
97332
|
+
return;
|
|
97333
|
+
logger_1.logger.log(`GroupCall: incoming call from ${opponent.userId} with ID ${newCall.callId}`);
|
|
97334
|
+
if (prevCall)
|
|
97335
|
+
this.disposeCall(prevCall, call_1.CallErrorCode.Replaced);
|
|
97336
|
+
this.initCall(newCall);
|
|
97205
97337
|
newCall.answerWithCallFeeds(this.getLocalFeeds().map((feed) => feed.clone()));
|
|
97338
|
+
deviceMap.set(newCall.getOpponentDeviceId(), newCall);
|
|
97339
|
+
this.calls.set(opponent, deviceMap);
|
|
97340
|
+
this.emit(GroupCallEvent.CallsChanged, this.calls);
|
|
97206
97341
|
};
|
|
97207
|
-
this.onMemberStateChanged = (event) => __awaiter(this, void 0, void 0, function* () {
|
|
97208
|
-
// If we haven't entered the call yet, we don't care
|
|
97209
|
-
if (this.state !== GroupCallState.Entered) {
|
|
97210
|
-
return;
|
|
97211
|
-
}
|
|
97212
|
-
// The member events may be received for another room, which we will ignore.
|
|
97213
|
-
if (event.getRoomId() !== this.room.roomId)
|
|
97214
|
-
return;
|
|
97215
|
-
const member = this.room.getMember(event.getStateKey());
|
|
97216
|
-
if (!member) {
|
|
97217
|
-
logger_1.logger.warn(`Couldn't find room member for ${event.getStateKey()}: ignoring member state event!`);
|
|
97218
|
-
return;
|
|
97219
|
-
}
|
|
97220
|
-
// Don't process your own member.
|
|
97221
|
-
const localUserId = this.client.getUserId();
|
|
97222
|
-
if (member.userId === localUserId)
|
|
97223
|
-
return;
|
|
97224
|
-
logger_1.logger.debug(`Processing member state event for ${member.userId}`);
|
|
97225
|
-
const ignore = () => {
|
|
97226
|
-
this.removeParticipant(member);
|
|
97227
|
-
clearTimeout(this.memberStateExpirationTimers.get(member.userId));
|
|
97228
|
-
this.memberStateExpirationTimers.delete(member.userId);
|
|
97229
|
-
};
|
|
97230
|
-
const content = event.getContent();
|
|
97231
|
-
const callsState = !callMemberStateIsExpired(event) && Array.isArray(content["m.calls"])
|
|
97232
|
-
? content["m.calls"].filter((call) => call)
|
|
97233
|
-
: []; // Ignore expired device data
|
|
97234
|
-
if (callsState.length === 0) {
|
|
97235
|
-
logger_1.logger.info(`Ignoring member state from ${member.userId} member not in any calls.`);
|
|
97236
|
-
ignore();
|
|
97237
|
-
return;
|
|
97238
|
-
}
|
|
97239
|
-
// Currently we only support a single call per room. So grab the first call.
|
|
97240
|
-
const callState = callsState[0];
|
|
97241
|
-
const callId = callState["m.call_id"];
|
|
97242
|
-
if (!callId) {
|
|
97243
|
-
logger_1.logger.warn(`Room member ${member.userId} does not have a valid m.call_id set. Ignoring.`);
|
|
97244
|
-
ignore();
|
|
97245
|
-
return;
|
|
97246
|
-
}
|
|
97247
|
-
if (callId !== this.groupCallId) {
|
|
97248
|
-
logger_1.logger.warn(`Call id ${callId} does not match group call id ${this.groupCallId}, ignoring.`);
|
|
97249
|
-
ignore();
|
|
97250
|
-
return;
|
|
97251
|
-
}
|
|
97252
|
-
this.addParticipant(member);
|
|
97253
|
-
clearTimeout(this.memberStateExpirationTimers.get(member.userId));
|
|
97254
|
-
this.memberStateExpirationTimers.set(member.userId, setTimeout(() => {
|
|
97255
|
-
logger_1.logger.warn(`Call member state for ${member.userId} has expired`);
|
|
97256
|
-
this.removeParticipant(member);
|
|
97257
|
-
}, content["m.expires_ts"] - Date.now()));
|
|
97258
|
-
// Only initiate a call with a user who has a userId that is lexicographically
|
|
97259
|
-
// less than your own. Otherwise, that user will call you.
|
|
97260
|
-
if (member.userId < localUserId) {
|
|
97261
|
-
logger_1.logger.debug(`Waiting for ${member.userId} to send call invite.`);
|
|
97262
|
-
return;
|
|
97263
|
-
}
|
|
97264
|
-
const opponentDevice = this.getDeviceForMember(member.userId);
|
|
97265
|
-
if (!opponentDevice) {
|
|
97266
|
-
logger_1.logger.warn(`No opponent device found for ${member.userId}, ignoring.`);
|
|
97267
|
-
this.emit(GroupCallEvent.Error, new GroupCallUnknownDeviceError(member.userId));
|
|
97268
|
-
return;
|
|
97269
|
-
}
|
|
97270
|
-
const existingCall = this.getCallByUserId(member.userId);
|
|
97271
|
-
if (existingCall &&
|
|
97272
|
-
existingCall.getOpponentSessionId() === opponentDevice.session_id) {
|
|
97273
|
-
return;
|
|
97274
|
-
}
|
|
97275
|
-
const newCall = (0, call_1.createNewMatrixCall)(this.client, this.room.roomId, {
|
|
97276
|
-
invitee: member.userId,
|
|
97277
|
-
opponentDeviceId: opponentDevice.device_id,
|
|
97278
|
-
opponentSessionId: opponentDevice.session_id,
|
|
97279
|
-
groupCallId: this.groupCallId,
|
|
97280
|
-
});
|
|
97281
|
-
if (!newCall) {
|
|
97282
|
-
logger_1.logger.error("Failed to create call!");
|
|
97283
|
-
return;
|
|
97284
|
-
}
|
|
97285
|
-
if (existingCall) {
|
|
97286
|
-
logger_1.logger.debug(`Replacing call ${existingCall.callId} to ${member.userId} with ${newCall.callId}`);
|
|
97287
|
-
this.replaceCall(existingCall, newCall, call_1.CallErrorCode.NewSession);
|
|
97288
|
-
}
|
|
97289
|
-
else {
|
|
97290
|
-
logger_1.logger.debug(`Adding call ${newCall.callId} to ${member.userId}`);
|
|
97291
|
-
this.addCall(newCall);
|
|
97292
|
-
}
|
|
97293
|
-
newCall.isPtt = this.isPtt;
|
|
97294
|
-
const requestScreenshareFeed = opponentDevice.feeds.some((feed) => feed.purpose === callEventTypes_1.SDPStreamMetadataPurpose.Screenshare);
|
|
97295
|
-
logger_1.logger.debug(`Placing call to ${member.userId}/${opponentDevice.device_id} session ID ${opponentDevice.session_id}.`);
|
|
97296
|
-
try {
|
|
97297
|
-
yield newCall.placeCallWithCallFeeds(this.getLocalFeeds().map(feed => feed.clone()), requestScreenshareFeed);
|
|
97298
|
-
}
|
|
97299
|
-
catch (e) {
|
|
97300
|
-
logger_1.logger.warn(`Failed to place call to ${member.userId}!`, e);
|
|
97301
|
-
if (e instanceof call_1.CallError && e.code === GroupCallErrorCode.UnknownDevice) {
|
|
97302
|
-
this.emit(GroupCallEvent.Error, e);
|
|
97303
|
-
}
|
|
97304
|
-
else {
|
|
97305
|
-
this.emit(GroupCallEvent.Error, new GroupCallError(GroupCallErrorCode.PlaceCallFailed, `Failed to place call to ${member.userId}.`));
|
|
97306
|
-
}
|
|
97307
|
-
this.removeCall(newCall, call_1.CallErrorCode.SignallingFailed);
|
|
97308
|
-
return;
|
|
97309
|
-
}
|
|
97310
|
-
if (this.dataChannelsEnabled) {
|
|
97311
|
-
newCall.createDataChannel("datachannel", this.dataChannelOptions);
|
|
97312
|
-
}
|
|
97313
|
-
});
|
|
97314
97342
|
this.onRetryCallLoop = () => {
|
|
97315
|
-
|
|
97316
|
-
|
|
97317
|
-
|
|
97318
|
-
const
|
|
97319
|
-
|
|
97320
|
-
|
|
97321
|
-
|
|
97343
|
+
var _a;
|
|
97344
|
+
let needsRetry = false;
|
|
97345
|
+
for (const [member, participantMap] of this.participants) {
|
|
97346
|
+
const callMap = this.calls.get(member);
|
|
97347
|
+
let retriesMap = this.retryCallCounts.get(member);
|
|
97348
|
+
for (const [deviceId, participant] of participantMap) {
|
|
97349
|
+
const call = callMap === null || callMap === void 0 ? void 0 : callMap.get(deviceId);
|
|
97350
|
+
const retries = (_a = retriesMap === null || retriesMap === void 0 ? void 0 : retriesMap.get(deviceId)) !== null && _a !== void 0 ? _a : 0;
|
|
97351
|
+
if ((call === null || call === void 0 ? void 0 : call.getOpponentSessionId()) !== participant.sessionId
|
|
97352
|
+
&& this.wantsOutgoingCall(member.userId, deviceId)
|
|
97353
|
+
&& retries < 3) {
|
|
97354
|
+
if (retriesMap === undefined) {
|
|
97355
|
+
retriesMap = new Map();
|
|
97356
|
+
this.retryCallCounts.set(member, retriesMap);
|
|
97357
|
+
}
|
|
97358
|
+
retriesMap.set(deviceId, retries + 1);
|
|
97359
|
+
needsRetry = true;
|
|
97360
|
+
}
|
|
97322
97361
|
}
|
|
97323
97362
|
}
|
|
97324
|
-
|
|
97363
|
+
if (needsRetry)
|
|
97364
|
+
this.placeOutgoingCalls();
|
|
97325
97365
|
};
|
|
97326
97366
|
this.onCallFeedsChanged = (call) => {
|
|
97327
97367
|
const opponentMemberId = getCallUserId(call);
|
|
97368
|
+
const opponentDeviceId = call.getOpponentDeviceId();
|
|
97328
97369
|
if (!opponentMemberId) {
|
|
97329
97370
|
throw new Error("Cannot change call feeds without user id");
|
|
97330
97371
|
}
|
|
97331
|
-
const currentUserMediaFeed = this.
|
|
97372
|
+
const currentUserMediaFeed = this.getUserMediaFeed(opponentMemberId, opponentDeviceId);
|
|
97332
97373
|
const remoteUsermediaFeed = call.remoteUsermediaFeed;
|
|
97333
97374
|
const remoteFeedChanged = remoteUsermediaFeed !== currentUserMediaFeed;
|
|
97334
97375
|
if (remoteFeedChanged) {
|
|
@@ -97342,7 +97383,7 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97342
97383
|
this.removeUserMediaFeed(currentUserMediaFeed);
|
|
97343
97384
|
}
|
|
97344
97385
|
}
|
|
97345
|
-
const currentScreenshareFeed = this.
|
|
97386
|
+
const currentScreenshareFeed = this.getScreenshareFeed(opponentMemberId, opponentDeviceId);
|
|
97346
97387
|
const remoteScreensharingFeed = call.remoteScreensharingFeed;
|
|
97347
97388
|
const remoteScreenshareFeedChanged = remoteScreensharingFeed !== currentScreenshareFeed;
|
|
97348
97389
|
if (remoteScreenshareFeedChanged) {
|
|
@@ -97369,48 +97410,91 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97369
97410
|
call.setLocalVideoMuted(videoMuted);
|
|
97370
97411
|
}
|
|
97371
97412
|
if (state === call_1.CallState.Connected) {
|
|
97372
|
-
|
|
97413
|
+
const opponent = call.getOpponentMember();
|
|
97414
|
+
const retriesMap = this.retryCallCounts.get(opponent);
|
|
97415
|
+
retriesMap === null || retriesMap === void 0 ? void 0 : retriesMap.delete(call.getOpponentDeviceId());
|
|
97416
|
+
if ((retriesMap === null || retriesMap === void 0 ? void 0 : retriesMap.size) === 0)
|
|
97417
|
+
this.retryCallCounts.delete(opponent);
|
|
97373
97418
|
}
|
|
97374
97419
|
};
|
|
97375
97420
|
this.onCallHangup = (call) => {
|
|
97376
|
-
|
|
97421
|
+
var _a;
|
|
97422
|
+
if (call.hangupReason === call_1.CallErrorCode.Replaced)
|
|
97377
97423
|
return;
|
|
97424
|
+
const opponent = (_a = call.getOpponentMember()) !== null && _a !== void 0 ? _a : this.room.getMember(call.invitee);
|
|
97425
|
+
const deviceMap = this.calls.get(opponent);
|
|
97426
|
+
// Sanity check that this call is in fact in the map
|
|
97427
|
+
if ((deviceMap === null || deviceMap === void 0 ? void 0 : deviceMap.get(call.getOpponentDeviceId())) === call) {
|
|
97428
|
+
this.disposeCall(call, call.hangupReason);
|
|
97429
|
+
deviceMap.delete(call.getOpponentDeviceId());
|
|
97430
|
+
if (deviceMap.size === 0)
|
|
97431
|
+
this.calls.delete(opponent);
|
|
97432
|
+
this.emit(GroupCallEvent.CallsChanged, this.calls);
|
|
97378
97433
|
}
|
|
97379
|
-
|
|
97434
|
+
};
|
|
97435
|
+
this.onCallReplaced = (prevCall, newCall) => {
|
|
97436
|
+
const opponent = prevCall.getOpponentMember();
|
|
97437
|
+
let deviceMap = this.calls.get(opponent);
|
|
97438
|
+
if (deviceMap === undefined) {
|
|
97439
|
+
deviceMap = new Map();
|
|
97440
|
+
this.calls.set(opponent, deviceMap);
|
|
97441
|
+
}
|
|
97442
|
+
this.disposeCall(prevCall, call_1.CallErrorCode.Replaced);
|
|
97443
|
+
this.initCall(newCall);
|
|
97444
|
+
deviceMap.set(prevCall.getOpponentDeviceId(), newCall);
|
|
97445
|
+
this.emit(GroupCallEvent.CallsChanged, this.calls);
|
|
97380
97446
|
};
|
|
97381
97447
|
this.onActiveSpeakerLoop = () => {
|
|
97382
97448
|
let topAvg = undefined;
|
|
97383
97449
|
let nextActiveSpeaker = undefined;
|
|
97384
97450
|
for (const callFeed of this.userMediaFeeds) {
|
|
97385
|
-
if (callFeed.
|
|
97451
|
+
if (callFeed.isLocal() && this.userMediaFeeds.length > 1)
|
|
97386
97452
|
continue;
|
|
97387
|
-
|
|
97388
|
-
let total = 0;
|
|
97389
|
-
for (let i = 0; i < callFeed.speakingVolumeSamples.length; i++) {
|
|
97390
|
-
const volume = callFeed.speakingVolumeSamples[i];
|
|
97391
|
-
total += Math.max(volume, callFeed_1.SPEAKING_THRESHOLD);
|
|
97392
|
-
}
|
|
97453
|
+
const total = callFeed.speakingVolumeSamples.reduce((acc, volume) => acc + Math.max(volume, callFeed_1.SPEAKING_THRESHOLD));
|
|
97393
97454
|
const avg = total / callFeed.speakingVolumeSamples.length;
|
|
97394
97455
|
if (!topAvg || avg > topAvg) {
|
|
97395
97456
|
topAvg = avg;
|
|
97396
|
-
nextActiveSpeaker = callFeed
|
|
97457
|
+
nextActiveSpeaker = callFeed;
|
|
97397
97458
|
}
|
|
97398
97459
|
}
|
|
97399
97460
|
if (nextActiveSpeaker && this.activeSpeaker !== nextActiveSpeaker && topAvg && topAvg > callFeed_1.SPEAKING_THRESHOLD) {
|
|
97400
97461
|
this.activeSpeaker = nextActiveSpeaker;
|
|
97401
97462
|
this.emit(GroupCallEvent.ActiveSpeakerChanged, this.activeSpeaker);
|
|
97402
97463
|
}
|
|
97403
|
-
|
|
97464
|
+
};
|
|
97465
|
+
this.onRoomState = () => this.updateParticipants();
|
|
97466
|
+
this.onParticipantsChanged = () => {
|
|
97467
|
+
if (this.state === GroupCallState.Entered)
|
|
97468
|
+
this.placeOutgoingCalls();
|
|
97469
|
+
};
|
|
97470
|
+
this.onStateChanged = (newState, oldState) => {
|
|
97471
|
+
if (newState === GroupCallState.Entered
|
|
97472
|
+
|| oldState === GroupCallState.Entered
|
|
97473
|
+
|| newState === GroupCallState.Ended) {
|
|
97474
|
+
// We either entered, left, or ended the call
|
|
97475
|
+
this.updateParticipants();
|
|
97476
|
+
this.updateMemberState().catch(e => logger_1.logger.error("Failed to update member state devices", e));
|
|
97477
|
+
}
|
|
97478
|
+
};
|
|
97479
|
+
this.onLocalFeedsChanged = () => {
|
|
97480
|
+
if (this.state === GroupCallState.Entered) {
|
|
97481
|
+
this.updateMemberState().catch(e => logger_1.logger.error("Failed to update member state feeds", e));
|
|
97482
|
+
}
|
|
97404
97483
|
};
|
|
97405
97484
|
this.reEmitter = new ReEmitter_1.ReEmitter(this);
|
|
97406
|
-
this.groupCallId = groupCallId
|
|
97407
|
-
|
|
97408
|
-
|
|
97409
|
-
|
|
97485
|
+
this.groupCallId = groupCallId !== null && groupCallId !== void 0 ? groupCallId : (0, call_1.genCallID)();
|
|
97486
|
+
this.creationTs = (_b = (_a = room.currentState.getStateEvents(event_1.EventType.GroupCallPrefix, this.groupCallId)) === null || _a === void 0 ? void 0 : _a.getTs()) !== null && _b !== void 0 ? _b : null;
|
|
97487
|
+
this.updateParticipants();
|
|
97488
|
+
room.on(room_state_1.RoomStateEvent.Update, this.onRoomState);
|
|
97489
|
+
this.on(GroupCallEvent.ParticipantsChanged, this.onParticipantsChanged);
|
|
97490
|
+
this.on(GroupCallEvent.GroupCallStateChanged, this.onStateChanged);
|
|
97491
|
+
this.on(GroupCallEvent.LocalScreenshareStateChanged, this.onLocalFeedsChanged);
|
|
97410
97492
|
}
|
|
97411
97493
|
create() {
|
|
97412
97494
|
return __awaiter(this, void 0, void 0, function* () {
|
|
97495
|
+
this.creationTs = Date.now();
|
|
97413
97496
|
this.client.groupCallEventHandler.groupCalls.set(this.room.roomId, this);
|
|
97497
|
+
this.client.emit(groupCallEventHandler_1.GroupCallEventHandlerEvent.Outgoing, this);
|
|
97414
97498
|
yield this.client.sendStateEvent(this.room.roomId, event_1.EventType.GroupCallPrefix, {
|
|
97415
97499
|
"m.intent": this.intent,
|
|
97416
97500
|
"m.type": this.type,
|
|
@@ -97422,10 +97506,55 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97422
97506
|
return this;
|
|
97423
97507
|
});
|
|
97424
97508
|
}
|
|
97425
|
-
|
|
97426
|
-
|
|
97427
|
-
|
|
97428
|
-
|
|
97509
|
+
/**
|
|
97510
|
+
* The group call's state.
|
|
97511
|
+
*/
|
|
97512
|
+
get state() {
|
|
97513
|
+
return this._state;
|
|
97514
|
+
}
|
|
97515
|
+
set state(value) {
|
|
97516
|
+
const prevValue = this._state;
|
|
97517
|
+
if (value !== prevValue) {
|
|
97518
|
+
this._state = value;
|
|
97519
|
+
this.emit(GroupCallEvent.GroupCallStateChanged, value, prevValue);
|
|
97520
|
+
}
|
|
97521
|
+
}
|
|
97522
|
+
/**
|
|
97523
|
+
* The current participants in the call, as a map from members to device IDs
|
|
97524
|
+
* to participant info.
|
|
97525
|
+
*/
|
|
97526
|
+
get participants() {
|
|
97527
|
+
return this._participants;
|
|
97528
|
+
}
|
|
97529
|
+
set participants(value) {
|
|
97530
|
+
const prevValue = this._participants;
|
|
97531
|
+
const participantStateEqual = (x, y) => x.sessionId === y.sessionId && x.screensharing === y.screensharing;
|
|
97532
|
+
const deviceMapsEqual = (x, y) => (0, utils_1.mapsEqual)(x, y, participantStateEqual);
|
|
97533
|
+
// Only update if the map actually changed
|
|
97534
|
+
if (!(0, utils_1.mapsEqual)(value, prevValue, deviceMapsEqual)) {
|
|
97535
|
+
this._participants = value;
|
|
97536
|
+
this.emit(GroupCallEvent.ParticipantsChanged, value);
|
|
97537
|
+
}
|
|
97538
|
+
}
|
|
97539
|
+
/**
|
|
97540
|
+
* The timestamp at which the call was created, or null if it has not yet
|
|
97541
|
+
* been created.
|
|
97542
|
+
*/
|
|
97543
|
+
get creationTs() {
|
|
97544
|
+
return this._creationTs;
|
|
97545
|
+
}
|
|
97546
|
+
set creationTs(value) {
|
|
97547
|
+
this._creationTs = value;
|
|
97548
|
+
}
|
|
97549
|
+
/**
|
|
97550
|
+
* Executes the given callback on all calls in this group call.
|
|
97551
|
+
* @param f The callback.
|
|
97552
|
+
*/
|
|
97553
|
+
forEachCall(f) {
|
|
97554
|
+
for (const deviceMap of this.calls.values()) {
|
|
97555
|
+
for (const call of deviceMap.values())
|
|
97556
|
+
f(call);
|
|
97557
|
+
}
|
|
97429
97558
|
}
|
|
97430
97559
|
getLocalFeeds() {
|
|
97431
97560
|
const feeds = [];
|
|
@@ -97436,8 +97565,8 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97436
97565
|
return feeds;
|
|
97437
97566
|
}
|
|
97438
97567
|
hasLocalParticipant() {
|
|
97439
|
-
|
|
97440
|
-
return this.participants.
|
|
97568
|
+
var _a, _b;
|
|
97569
|
+
return (_b = (_a = this.participants.get(this.room.getMember(this.client.getUserId()))) === null || _a === void 0 ? void 0 : _a.has(this.client.getDeviceId())) !== null && _b !== void 0 ? _b : false;
|
|
97441
97570
|
}
|
|
97442
97571
|
initLocalCallFeed() {
|
|
97443
97572
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -97445,7 +97574,7 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97445
97574
|
if (this.state !== GroupCallState.LocalCallFeedUninitialized) {
|
|
97446
97575
|
throw new Error(`Cannot initialize local call feed in the "${this.state}" state.`);
|
|
97447
97576
|
}
|
|
97448
|
-
this.
|
|
97577
|
+
this.state = GroupCallState.InitializingLocalCallFeed;
|
|
97449
97578
|
let stream;
|
|
97450
97579
|
let disposed = false;
|
|
97451
97580
|
const onState = (state) => {
|
|
@@ -97458,7 +97587,7 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97458
97587
|
stream = yield this.client.getMediaHandler().getUserMediaStream(true, this.type === GroupCallType.Video);
|
|
97459
97588
|
}
|
|
97460
97589
|
catch (error) {
|
|
97461
|
-
this.
|
|
97590
|
+
this.state = GroupCallState.LocalCallFeedUninitialized;
|
|
97462
97591
|
throw error;
|
|
97463
97592
|
}
|
|
97464
97593
|
finally {
|
|
@@ -97467,11 +97596,11 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97467
97596
|
// The call could've been disposed while we were waiting
|
|
97468
97597
|
if (disposed)
|
|
97469
97598
|
throw new Error("Group call disposed");
|
|
97470
|
-
const userId = this.client.getUserId();
|
|
97471
97599
|
const callFeed = new callFeed_1.CallFeed({
|
|
97472
97600
|
client: this.client,
|
|
97473
97601
|
roomId: this.room.roomId,
|
|
97474
|
-
userId,
|
|
97602
|
+
userId: this.client.getUserId(),
|
|
97603
|
+
deviceId: this.client.getDeviceId(),
|
|
97475
97604
|
stream,
|
|
97476
97605
|
purpose: callEventTypes_1.SDPStreamMetadataPurpose.Usermedia,
|
|
97477
97606
|
audioMuted: this.initWithAudioMuted || stream.getAudioTracks().length === 0 || this.isPtt,
|
|
@@ -97481,7 +97610,7 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97481
97610
|
(0, call_1.setTracksEnabled)(stream.getVideoTracks(), !callFeed.isVideoMuted());
|
|
97482
97611
|
this.localCallFeed = callFeed;
|
|
97483
97612
|
this.addUserMediaFeed(callFeed);
|
|
97484
|
-
this.
|
|
97613
|
+
this.state = GroupCallState.LocalCallFeedInitialized;
|
|
97485
97614
|
return callFeed;
|
|
97486
97615
|
});
|
|
97487
97616
|
}
|
|
@@ -97501,30 +97630,22 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97501
97630
|
}
|
|
97502
97631
|
enter() {
|
|
97503
97632
|
return __awaiter(this, void 0, void 0, function* () {
|
|
97504
|
-
if (!(this.state === GroupCallState.LocalCallFeedUninitialized ||
|
|
97505
|
-
this.state === GroupCallState.LocalCallFeedInitialized)) {
|
|
97506
|
-
throw new Error(`Cannot enter call in the "${this.state}" state`);
|
|
97507
|
-
}
|
|
97508
97633
|
if (this.state === GroupCallState.LocalCallFeedUninitialized) {
|
|
97509
97634
|
yield this.initLocalCallFeed();
|
|
97510
97635
|
}
|
|
97511
|
-
|
|
97512
|
-
|
|
97513
|
-
|
|
97514
|
-
this.setState(GroupCallState.Entered);
|
|
97636
|
+
else if (this.state !== GroupCallState.LocalCallFeedInitialized) {
|
|
97637
|
+
throw new Error(`Cannot enter call in the "${this.state}" state`);
|
|
97638
|
+
}
|
|
97515
97639
|
logger_1.logger.log(`Entered group call ${this.groupCallId}`);
|
|
97640
|
+
this.state = GroupCallState.Entered;
|
|
97516
97641
|
this.client.on(callEventHandler_1.CallEventHandlerEvent.Incoming, this.onIncomingCall);
|
|
97517
|
-
const
|
|
97518
|
-
for (const call of calls) {
|
|
97642
|
+
for (const call of this.client.callEventHandler.calls.values()) {
|
|
97519
97643
|
this.onIncomingCall(call);
|
|
97520
97644
|
}
|
|
97521
|
-
|
|
97522
|
-
|
|
97523
|
-
for (const stateEvent of this.getMemberStateEvents()) {
|
|
97524
|
-
this.onMemberStateChanged(stateEvent);
|
|
97525
|
-
}
|
|
97526
|
-
this.retryCallLoopTimeout = setTimeout(this.onRetryCallLoop, this.retryCallInterval);
|
|
97645
|
+
this.retryCallLoopInterval = setInterval(this.onRetryCallLoop, this.retryCallInterval);
|
|
97646
|
+
this.activeSpeaker = undefined;
|
|
97527
97647
|
this.onActiveSpeakerLoop();
|
|
97648
|
+
this.activeSpeakerLoopInterval = setInterval(this.onActiveSpeakerLoop, this.activeSpeakerInterval);
|
|
97528
97649
|
});
|
|
97529
97650
|
}
|
|
97530
97651
|
dispose() {
|
|
@@ -97539,54 +97660,43 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97539
97660
|
this.localDesktopCapturerSourceId = undefined;
|
|
97540
97661
|
}
|
|
97541
97662
|
this.client.getMediaHandler().stopAllStreams();
|
|
97663
|
+
if (this.transmitTimer !== null) {
|
|
97664
|
+
clearTimeout(this.transmitTimer);
|
|
97665
|
+
this.transmitTimer = null;
|
|
97666
|
+
}
|
|
97667
|
+
if (this.retryCallLoopInterval !== undefined) {
|
|
97668
|
+
clearInterval(this.retryCallLoopInterval);
|
|
97669
|
+
this.retryCallLoopInterval = undefined;
|
|
97670
|
+
}
|
|
97542
97671
|
if (this.state !== GroupCallState.Entered) {
|
|
97543
97672
|
return;
|
|
97544
97673
|
}
|
|
97545
|
-
this.
|
|
97546
|
-
this.
|
|
97547
|
-
while (this.calls.length > 0) {
|
|
97548
|
-
this.removeCall(this.calls[this.calls.length - 1], call_1.CallErrorCode.UserHangup);
|
|
97549
|
-
}
|
|
97674
|
+
this.forEachCall(call => this.disposeCall(call, call_1.CallErrorCode.UserHangup));
|
|
97675
|
+
this.calls.clear();
|
|
97550
97676
|
this.activeSpeaker = undefined;
|
|
97551
|
-
|
|
97677
|
+
clearInterval(this.activeSpeakerLoopInterval);
|
|
97552
97678
|
this.retryCallCounts.clear();
|
|
97553
|
-
|
|
97554
|
-
for (const [userId] of this.memberStateExpirationTimers) {
|
|
97555
|
-
clearTimeout(this.memberStateExpirationTimers.get(userId));
|
|
97556
|
-
this.memberStateExpirationTimers.delete(userId);
|
|
97557
|
-
}
|
|
97558
|
-
if (this.transmitTimer !== null) {
|
|
97559
|
-
clearTimeout(this.transmitTimer);
|
|
97560
|
-
this.transmitTimer = null;
|
|
97561
|
-
}
|
|
97679
|
+
clearInterval(this.retryCallLoopInterval);
|
|
97562
97680
|
this.client.removeListener(callEventHandler_1.CallEventHandlerEvent.Incoming, this.onIncomingCall);
|
|
97563
97681
|
}
|
|
97564
97682
|
leave() {
|
|
97565
|
-
if (this.transmitTimer !== null) {
|
|
97566
|
-
clearTimeout(this.transmitTimer);
|
|
97567
|
-
this.transmitTimer = null;
|
|
97568
|
-
}
|
|
97569
97683
|
this.dispose();
|
|
97570
|
-
this.
|
|
97684
|
+
this.state = GroupCallState.LocalCallFeedUninitialized;
|
|
97571
97685
|
}
|
|
97572
97686
|
terminate(emitStateEvent = true) {
|
|
97573
97687
|
return __awaiter(this, void 0, void 0, function* () {
|
|
97574
97688
|
this.dispose();
|
|
97575
|
-
|
|
97576
|
-
clearTimeout(this.transmitTimer);
|
|
97577
|
-
this.transmitTimer = null;
|
|
97578
|
-
}
|
|
97579
|
-
this.participants = [];
|
|
97689
|
+
this.room.off(room_state_1.RoomStateEvent.Update, this.onRoomState);
|
|
97580
97690
|
this.client.groupCallEventHandler.groupCalls.delete(this.room.roomId);
|
|
97691
|
+
this.client.emit(groupCallEventHandler_1.GroupCallEventHandlerEvent.Ended, this);
|
|
97692
|
+
this.state = GroupCallState.Ended;
|
|
97581
97693
|
if (emitStateEvent) {
|
|
97582
97694
|
const existingStateEvent = this.room.currentState.getStateEvents(event_1.EventType.GroupCallPrefix, this.groupCallId);
|
|
97583
|
-
yield this.client.sendStateEvent(this.room.roomId, event_1.EventType.GroupCallPrefix, Object.assign(Object.assign({}, existingStateEvent.getContent()), {
|
|
97695
|
+
yield this.client.sendStateEvent(this.room.roomId, event_1.EventType.GroupCallPrefix, Object.assign(Object.assign({}, existingStateEvent.getContent()), { "m.terminated": GroupCallTerminationReason.CallEnded }), this.groupCallId);
|
|
97584
97696
|
}
|
|
97585
|
-
this.client.emit(groupCallEventHandler_1.GroupCallEventHandlerEvent.Ended, this);
|
|
97586
|
-
this.setState(GroupCallState.Ended);
|
|
97587
97697
|
});
|
|
97588
97698
|
}
|
|
97589
|
-
|
|
97699
|
+
/*
|
|
97590
97700
|
* Local Usermedia
|
|
97591
97701
|
*/
|
|
97592
97702
|
isLocalVideoMuted() {
|
|
@@ -97607,7 +97717,6 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97607
97717
|
* @returns {Promise<boolean>} Whether muting/unmuting was successful
|
|
97608
97718
|
*/
|
|
97609
97719
|
setMicrophoneMuted(muted) {
|
|
97610
|
-
var _a;
|
|
97611
97720
|
return __awaiter(this, void 0, void 0, function* () {
|
|
97612
97721
|
// hasAudioDevice can block indefinitely if the window has lost focus,
|
|
97613
97722
|
// and it doesn't make much sense to keep a device from being muted, so
|
|
@@ -97630,17 +97739,14 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97630
97739
|
this.transmitTimer = null;
|
|
97631
97740
|
}
|
|
97632
97741
|
}
|
|
97633
|
-
|
|
97634
|
-
|
|
97635
|
-
|
|
97636
|
-
|
|
97637
|
-
|
|
97638
|
-
|
|
97639
|
-
|
|
97640
|
-
|
|
97641
|
-
logger_1.logger.info("Failed to send one or more metadata updates", e);
|
|
97642
|
-
}
|
|
97643
|
-
}
|
|
97742
|
+
this.forEachCall(call => { var _a; return (_a = call.localUsermediaFeed) === null || _a === void 0 ? void 0 : _a.setAudioVideoMuted(muted, null); });
|
|
97743
|
+
const sendUpdates = () => __awaiter(this, void 0, void 0, function* () {
|
|
97744
|
+
const updates = [];
|
|
97745
|
+
this.forEachCall(call => updates.push(call.sendMetadataUpdate()));
|
|
97746
|
+
yield Promise.all(updates).catch(e => logger_1.logger.info("Failed to send some metadata updates", e));
|
|
97747
|
+
});
|
|
97748
|
+
if (sendUpdatesBefore)
|
|
97749
|
+
yield sendUpdates();
|
|
97644
97750
|
if (this.localCallFeed) {
|
|
97645
97751
|
logger_1.logger.log(`groupCall ${this.groupCallId} setMicrophoneMuted stream ${this.localCallFeed.stream.id} muted ${muted}`);
|
|
97646
97752
|
this.localCallFeed.setAudioVideoMuted(muted, null);
|
|
@@ -97654,18 +97760,10 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97654
97760
|
logger_1.logger.log(`groupCall ${this.groupCallId} setMicrophoneMuted no stream muted ${muted}`);
|
|
97655
97761
|
this.initWithAudioMuted = muted;
|
|
97656
97762
|
}
|
|
97657
|
-
|
|
97658
|
-
(0, call_1.setTracksEnabled)(call.localUsermediaFeed.stream.getAudioTracks(), !muted);
|
|
97659
|
-
}
|
|
97763
|
+
this.forEachCall(call => (0, call_1.setTracksEnabled)(call.localUsermediaFeed.stream.getAudioTracks(), !muted));
|
|
97660
97764
|
this.emit(GroupCallEvent.LocalMuteStateChanged, muted, this.isLocalVideoMuted());
|
|
97661
|
-
if (!sendUpdatesBefore)
|
|
97662
|
-
|
|
97663
|
-
yield Promise.all(this.calls.map(c => c.sendMetadataUpdate()));
|
|
97664
|
-
}
|
|
97665
|
-
catch (e) {
|
|
97666
|
-
logger_1.logger.info("Failed to send one or more metadata updates", e);
|
|
97667
|
-
}
|
|
97668
|
-
}
|
|
97765
|
+
if (!sendUpdatesBefore)
|
|
97766
|
+
yield sendUpdates();
|
|
97669
97767
|
return true;
|
|
97670
97768
|
});
|
|
97671
97769
|
}
|
|
@@ -97691,9 +97789,9 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97691
97789
|
logger_1.logger.log(`groupCall ${this.groupCallId} setLocalVideoMuted no stream muted ${muted}`);
|
|
97692
97790
|
this.initWithVideoMuted = muted;
|
|
97693
97791
|
}
|
|
97694
|
-
|
|
97695
|
-
|
|
97696
|
-
|
|
97792
|
+
const updates = [];
|
|
97793
|
+
this.forEachCall(call => updates.push(call.setLocalVideoMuted(muted)));
|
|
97794
|
+
yield Promise.all(updates);
|
|
97697
97795
|
this.emit(GroupCallEvent.LocalMuteStateChanged, this.isMicrophoneMuted(), muted);
|
|
97698
97796
|
return true;
|
|
97699
97797
|
});
|
|
@@ -97720,6 +97818,7 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97720
97818
|
client: this.client,
|
|
97721
97819
|
roomId: this.room.roomId,
|
|
97722
97820
|
userId: this.client.getUserId(),
|
|
97821
|
+
deviceId: this.client.getDeviceId(),
|
|
97723
97822
|
stream,
|
|
97724
97823
|
purpose: callEventTypes_1.SDPStreamMetadataPurpose.Screenshare,
|
|
97725
97824
|
audioMuted: false,
|
|
@@ -97728,8 +97827,7 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97728
97827
|
this.addScreenshareFeed(this.localScreenshareFeed);
|
|
97729
97828
|
this.emit(GroupCallEvent.LocalScreenshareStateChanged, true, this.localScreenshareFeed, this.localDesktopCapturerSourceId);
|
|
97730
97829
|
// TODO: handle errors
|
|
97731
|
-
|
|
97732
|
-
yield this.sendMemberStateEvent();
|
|
97830
|
+
this.forEachCall(call => call.pushLocalFeed(this.localScreenshareFeed.clone()));
|
|
97733
97831
|
return true;
|
|
97734
97832
|
}
|
|
97735
97833
|
catch (error) {
|
|
@@ -97741,15 +97839,14 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97741
97839
|
}
|
|
97742
97840
|
}
|
|
97743
97841
|
else {
|
|
97744
|
-
|
|
97842
|
+
this.forEachCall(call => {
|
|
97745
97843
|
if (call.localScreensharingFeed)
|
|
97746
97844
|
call.removeLocalFeed(call.localScreensharingFeed);
|
|
97747
|
-
})
|
|
97845
|
+
});
|
|
97748
97846
|
this.client.getMediaHandler().stopScreensharingStream(this.localScreenshareFeed.stream);
|
|
97749
97847
|
this.removeScreenshareFeed(this.localScreenshareFeed);
|
|
97750
97848
|
this.localScreenshareFeed = undefined;
|
|
97751
97849
|
this.localDesktopCapturerSourceId = undefined;
|
|
97752
|
-
yield this.sendMemberStateEvent();
|
|
97753
97850
|
this.emit(GroupCallEvent.LocalScreenshareStateChanged, false, undefined, undefined);
|
|
97754
97851
|
return false;
|
|
97755
97852
|
}
|
|
@@ -97758,128 +97855,86 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97758
97855
|
isScreensharing() {
|
|
97759
97856
|
return !!this.localScreenshareFeed;
|
|
97760
97857
|
}
|
|
97761
|
-
|
|
97762
|
-
|
|
97763
|
-
|
|
97764
|
-
|
|
97765
|
-
|
|
97766
|
-
|
|
97767
|
-
|
|
97768
|
-
|
|
97769
|
-
|
|
97770
|
-
|
|
97771
|
-
|
|
97772
|
-
|
|
97773
|
-
|
|
97774
|
-
|
|
97775
|
-
|
|
97776
|
-
{
|
|
97777
|
-
"device_id": this.client.getDeviceId(),
|
|
97778
|
-
"session_id": this.client.getSessionId(),
|
|
97779
|
-
"feeds": this.getLocalFeeds().map((feed) => ({
|
|
97780
|
-
purpose: feed.purpose,
|
|
97781
|
-
})),
|
|
97782
|
-
// TODO: Add data channels
|
|
97783
|
-
},
|
|
97784
|
-
],
|
|
97785
|
-
// TODO "m.foci"
|
|
97786
|
-
});
|
|
97787
|
-
const res = yield send();
|
|
97788
|
-
// Clear the old interval first, so that it isn't forgot
|
|
97789
|
-
if (this.resendMemberStateTimer !== null)
|
|
97790
|
-
clearInterval(this.resendMemberStateTimer);
|
|
97791
|
-
// Resend the state event every so often so it doesn't become stale
|
|
97792
|
-
this.resendMemberStateTimer = setInterval(() => __awaiter(this, void 0, void 0, function* () {
|
|
97793
|
-
logger_1.logger.log("Resending call member state");
|
|
97794
|
-
yield send();
|
|
97795
|
-
}), CALL_MEMBER_STATE_TIMEOUT * 3 / 4);
|
|
97796
|
-
return res;
|
|
97797
|
-
});
|
|
97798
|
-
}
|
|
97799
|
-
removeMemberStateEvent() {
|
|
97800
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
97801
|
-
if (this.resendMemberStateTimer !== null)
|
|
97802
|
-
clearInterval(this.resendMemberStateTimer);
|
|
97803
|
-
this.resendMemberStateTimer = null;
|
|
97804
|
-
return yield this.updateMemberCallState(undefined, true);
|
|
97805
|
-
});
|
|
97858
|
+
/**
|
|
97859
|
+
* Determines whether a given participant expects us to call them (versus
|
|
97860
|
+
* them calling us).
|
|
97861
|
+
* @param userId The participant's user ID.
|
|
97862
|
+
* @param deviceId The participant's device ID.
|
|
97863
|
+
* @returns Whether we need to place an outgoing call to the participant.
|
|
97864
|
+
*/
|
|
97865
|
+
wantsOutgoingCall(userId, deviceId) {
|
|
97866
|
+
const localUserId = this.client.getUserId();
|
|
97867
|
+
const localDeviceId = this.client.getDeviceId();
|
|
97868
|
+
return (
|
|
97869
|
+
// If a user's ID is less than our own, they'll call us
|
|
97870
|
+
userId >= localUserId
|
|
97871
|
+
// If this is another one of our devices, compare device IDs to tell whether it'll call us
|
|
97872
|
+
&& (userId !== localUserId || deviceId > localDeviceId));
|
|
97806
97873
|
}
|
|
97807
|
-
|
|
97874
|
+
/**
|
|
97875
|
+
* Places calls to all participants that we're responsible for calling.
|
|
97876
|
+
*/
|
|
97877
|
+
placeOutgoingCalls() {
|
|
97808
97878
|
var _a;
|
|
97809
|
-
|
|
97810
|
-
|
|
97811
|
-
const
|
|
97812
|
-
|
|
97813
|
-
|
|
97814
|
-
|
|
97815
|
-
|
|
97816
|
-
|
|
97817
|
-
|
|
97818
|
-
|
|
97819
|
-
|
|
97820
|
-
|
|
97821
|
-
|
|
97822
|
-
|
|
97823
|
-
|
|
97879
|
+
let callsChanged = false;
|
|
97880
|
+
for (const [member, participantMap] of this.participants) {
|
|
97881
|
+
const callMap = (_a = this.calls.get(member)) !== null && _a !== void 0 ? _a : new Map();
|
|
97882
|
+
for (const [deviceId, participant] of participantMap) {
|
|
97883
|
+
const prevCall = callMap.get(deviceId);
|
|
97884
|
+
if ((prevCall === null || prevCall === void 0 ? void 0 : prevCall.getOpponentSessionId()) !== participant.sessionId
|
|
97885
|
+
&& this.wantsOutgoingCall(member.userId, deviceId)) {
|
|
97886
|
+
callsChanged = true;
|
|
97887
|
+
if (prevCall !== undefined) {
|
|
97888
|
+
logger_1.logger.debug(`Replacing call ${prevCall.callId} to ${member.userId} ${deviceId}`);
|
|
97889
|
+
this.disposeCall(prevCall, call_1.CallErrorCode.NewSession);
|
|
97890
|
+
}
|
|
97891
|
+
const newCall = (0, call_1.createNewMatrixCall)(this.client, this.room.roomId, {
|
|
97892
|
+
invitee: member.userId,
|
|
97893
|
+
opponentDeviceId: deviceId,
|
|
97894
|
+
opponentSessionId: participant.sessionId,
|
|
97895
|
+
groupCallId: this.groupCallId,
|
|
97896
|
+
});
|
|
97897
|
+
if (newCall === null) {
|
|
97898
|
+
logger_1.logger.error(`Failed to create call with ${member.userId} ${deviceId}`);
|
|
97899
|
+
callMap.delete(deviceId);
|
|
97900
|
+
}
|
|
97901
|
+
else {
|
|
97902
|
+
this.initCall(newCall);
|
|
97903
|
+
callMap.set(deviceId, newCall);
|
|
97904
|
+
logger_1.logger.debug(`Placing call to ${member.userId} ${deviceId} (session ${participant.sessionId})`);
|
|
97905
|
+
newCall.placeCallWithCallFeeds(this.getLocalFeeds().map(feed => feed.clone()), participant.screensharing).then(() => {
|
|
97906
|
+
if (this.dataChannelsEnabled) {
|
|
97907
|
+
newCall.createDataChannel("datachannel", this.dataChannelOptions);
|
|
97908
|
+
}
|
|
97909
|
+
}).catch(e => {
|
|
97910
|
+
logger_1.logger.warn(`Failed to place call to ${member.userId}`, e);
|
|
97911
|
+
if (e instanceof call_1.CallError && e.code === GroupCallErrorCode.UnknownDevice) {
|
|
97912
|
+
this.emit(GroupCallEvent.Error, e);
|
|
97913
|
+
}
|
|
97914
|
+
else {
|
|
97915
|
+
this.emit(GroupCallEvent.Error, new GroupCallError(GroupCallErrorCode.PlaceCallFailed, `Failed to place call to ${member.userId}`));
|
|
97916
|
+
}
|
|
97917
|
+
this.disposeCall(newCall, call_1.CallErrorCode.SignallingFailed);
|
|
97918
|
+
if (callMap.get(deviceId) === newCall)
|
|
97919
|
+
callMap.delete(deviceId);
|
|
97920
|
+
});
|
|
97921
|
+
}
|
|
97824
97922
|
}
|
|
97825
97923
|
}
|
|
97826
|
-
|
|
97827
|
-
calls.
|
|
97924
|
+
if (callMap.size > 0) {
|
|
97925
|
+
this.calls.set(member, callMap);
|
|
97926
|
+
}
|
|
97927
|
+
else {
|
|
97928
|
+
this.calls.delete(member);
|
|
97828
97929
|
}
|
|
97829
|
-
const content = {
|
|
97830
|
-
"m.calls": calls,
|
|
97831
|
-
"m.expires_ts": Date.now() + CALL_MEMBER_STATE_TIMEOUT,
|
|
97832
|
-
};
|
|
97833
|
-
return this.client.sendStateEvent(this.room.roomId, event_1.EventType.GroupCallMemberPrefix, content, localUserId, { keepAlive });
|
|
97834
|
-
});
|
|
97835
|
-
}
|
|
97836
|
-
getDeviceForMember(userId) {
|
|
97837
|
-
var _a;
|
|
97838
|
-
const memberStateEvent = this.getMemberStateEvents(userId);
|
|
97839
|
-
if (!memberStateEvent) {
|
|
97840
|
-
return undefined;
|
|
97841
|
-
}
|
|
97842
|
-
const memberState = memberStateEvent.getContent();
|
|
97843
|
-
const memberGroupCallState = (_a = memberState["m.calls"]) === null || _a === void 0 ? void 0 : _a.find((call) => call && call["m.call_id"] === this.groupCallId);
|
|
97844
|
-
if (!memberGroupCallState) {
|
|
97845
|
-
return undefined;
|
|
97846
|
-
}
|
|
97847
|
-
const memberDevices = memberGroupCallState["m.devices"];
|
|
97848
|
-
if (!memberDevices || memberDevices.length === 0) {
|
|
97849
|
-
return undefined;
|
|
97850
|
-
}
|
|
97851
|
-
// NOTE: For now we only support one device so we use the device id in the first source.
|
|
97852
|
-
return memberDevices[0];
|
|
97853
|
-
}
|
|
97854
|
-
/**
|
|
97855
|
-
* Call Event Handlers
|
|
97856
|
-
*/
|
|
97857
|
-
getCallByUserId(userId) {
|
|
97858
|
-
return this.calls.find((call) => getCallUserId(call) === userId);
|
|
97859
|
-
}
|
|
97860
|
-
addCall(call) {
|
|
97861
|
-
this.calls.push(call);
|
|
97862
|
-
this.initCall(call);
|
|
97863
|
-
this.emit(GroupCallEvent.CallsChanged, this.calls);
|
|
97864
|
-
}
|
|
97865
|
-
replaceCall(existingCall, replacementCall, hangupReason = call_1.CallErrorCode.Replaced) {
|
|
97866
|
-
const existingCallIndex = this.calls.indexOf(existingCall);
|
|
97867
|
-
if (existingCallIndex === -1) {
|
|
97868
|
-
throw new Error("Couldn't find call to replace");
|
|
97869
97930
|
}
|
|
97870
|
-
|
|
97871
|
-
|
|
97872
|
-
this.initCall(replacementCall);
|
|
97873
|
-
this.emit(GroupCallEvent.CallsChanged, this.calls);
|
|
97931
|
+
if (callsChanged)
|
|
97932
|
+
this.emit(GroupCallEvent.CallsChanged, this.calls);
|
|
97874
97933
|
}
|
|
97875
|
-
|
|
97876
|
-
|
|
97877
|
-
|
|
97878
|
-
|
|
97879
|
-
throw new Error("Couldn't find call to remove");
|
|
97880
|
-
}
|
|
97881
|
-
this.calls.splice(callIndex, 1);
|
|
97882
|
-
this.emit(GroupCallEvent.CallsChanged, this.calls);
|
|
97934
|
+
getMemberStateEvents(userId) {
|
|
97935
|
+
return userId === undefined
|
|
97936
|
+
? this.room.currentState.getStateEvents(event_1.EventType.GroupCallMemberPrefix)
|
|
97937
|
+
: this.room.currentState.getStateEvents(event_1.EventType.GroupCallMemberPrefix, userId);
|
|
97883
97938
|
}
|
|
97884
97939
|
initCall(call) {
|
|
97885
97940
|
const opponentMemberId = getCallUserId(call);
|
|
@@ -97889,8 +97944,13 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97889
97944
|
const onCallFeedsChanged = () => this.onCallFeedsChanged(call);
|
|
97890
97945
|
const onCallStateChanged = (state, oldState) => this.onCallStateChanged(call, state, oldState);
|
|
97891
97946
|
const onCallHangup = this.onCallHangup;
|
|
97892
|
-
const onCallReplaced = (newCall) => this.
|
|
97893
|
-
this.callHandlers.
|
|
97947
|
+
const onCallReplaced = (newCall) => this.onCallReplaced(call, newCall);
|
|
97948
|
+
let deviceMap = this.callHandlers.get(opponentMemberId);
|
|
97949
|
+
if (deviceMap === undefined) {
|
|
97950
|
+
deviceMap = new Map();
|
|
97951
|
+
this.callHandlers.set(opponentMemberId, deviceMap);
|
|
97952
|
+
}
|
|
97953
|
+
deviceMap.set(call.getOpponentDeviceId(), {
|
|
97894
97954
|
onCallFeedsChanged,
|
|
97895
97955
|
onCallStateChanged,
|
|
97896
97956
|
onCallHangup,
|
|
@@ -97900,40 +97960,45 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97900
97960
|
call.on(call_1.CallEvent.State, onCallStateChanged);
|
|
97901
97961
|
call.on(call_1.CallEvent.Hangup, onCallHangup);
|
|
97902
97962
|
call.on(call_1.CallEvent.Replaced, onCallReplaced);
|
|
97963
|
+
call.isPtt = this.isPtt;
|
|
97903
97964
|
this.reEmitter.reEmit(call, Object.values(call_1.CallEvent));
|
|
97904
97965
|
onCallFeedsChanged();
|
|
97905
97966
|
}
|
|
97906
97967
|
disposeCall(call, hangupReason) {
|
|
97907
97968
|
const opponentMemberId = getCallUserId(call);
|
|
97969
|
+
const opponentDeviceId = call.getOpponentDeviceId();
|
|
97908
97970
|
if (!opponentMemberId) {
|
|
97909
97971
|
throw new Error("Cannot dispose call without user id");
|
|
97910
97972
|
}
|
|
97911
|
-
const
|
|
97973
|
+
const deviceMap = this.callHandlers.get(opponentMemberId);
|
|
97974
|
+
const { onCallFeedsChanged, onCallStateChanged, onCallHangup, onCallReplaced, } = deviceMap.get(opponentDeviceId);
|
|
97912
97975
|
call.removeListener(call_1.CallEvent.FeedsChanged, onCallFeedsChanged);
|
|
97913
97976
|
call.removeListener(call_1.CallEvent.State, onCallStateChanged);
|
|
97914
97977
|
call.removeListener(call_1.CallEvent.Hangup, onCallHangup);
|
|
97915
97978
|
call.removeListener(call_1.CallEvent.Replaced, onCallReplaced);
|
|
97916
|
-
|
|
97979
|
+
deviceMap.delete(opponentMemberId);
|
|
97980
|
+
if (deviceMap.size === 0)
|
|
97981
|
+
this.callHandlers.delete(opponentMemberId);
|
|
97917
97982
|
if (call.hangupReason === call_1.CallErrorCode.Replaced) {
|
|
97918
97983
|
return;
|
|
97919
97984
|
}
|
|
97920
97985
|
if (call.state !== call_1.CallState.Ended) {
|
|
97921
97986
|
call.hangup(hangupReason, false);
|
|
97922
97987
|
}
|
|
97923
|
-
const usermediaFeed = this.
|
|
97988
|
+
const usermediaFeed = this.getUserMediaFeed(opponentMemberId, opponentDeviceId);
|
|
97924
97989
|
if (usermediaFeed) {
|
|
97925
97990
|
this.removeUserMediaFeed(usermediaFeed);
|
|
97926
97991
|
}
|
|
97927
|
-
const screenshareFeed = this.
|
|
97992
|
+
const screenshareFeed = this.getScreenshareFeed(opponentMemberId, opponentDeviceId);
|
|
97928
97993
|
if (screenshareFeed) {
|
|
97929
97994
|
this.removeScreenshareFeed(screenshareFeed);
|
|
97930
97995
|
}
|
|
97931
97996
|
}
|
|
97932
|
-
|
|
97997
|
+
/*
|
|
97933
97998
|
* UserMedia CallFeed Event Handlers
|
|
97934
97999
|
*/
|
|
97935
|
-
|
|
97936
|
-
return this.userMediaFeeds.find(
|
|
98000
|
+
getUserMediaFeed(userId, deviceId) {
|
|
98001
|
+
return this.userMediaFeeds.find(f => f.userId === userId && f.deviceId === deviceId);
|
|
97937
98002
|
}
|
|
97938
98003
|
addUserMediaFeed(callFeed) {
|
|
97939
98004
|
this.userMediaFeeds.push(callFeed);
|
|
@@ -97941,7 +98006,7 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97941
98006
|
this.emit(GroupCallEvent.UserMediaFeedsChanged, this.userMediaFeeds);
|
|
97942
98007
|
}
|
|
97943
98008
|
replaceUserMediaFeed(existingFeed, replacementFeed) {
|
|
97944
|
-
const feedIndex = this.userMediaFeeds.findIndex(
|
|
98009
|
+
const feedIndex = this.userMediaFeeds.findIndex(f => f.userId === existingFeed.userId && f.deviceId === existingFeed.deviceId);
|
|
97945
98010
|
if (feedIndex === -1) {
|
|
97946
98011
|
throw new Error("Couldn't find user media feed to replace");
|
|
97947
98012
|
}
|
|
@@ -97951,31 +98016,30 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97951
98016
|
this.emit(GroupCallEvent.UserMediaFeedsChanged, this.userMediaFeeds);
|
|
97952
98017
|
}
|
|
97953
98018
|
removeUserMediaFeed(callFeed) {
|
|
97954
|
-
const feedIndex = this.userMediaFeeds.findIndex(
|
|
98019
|
+
const feedIndex = this.userMediaFeeds.findIndex(f => f.userId === callFeed.userId && f.deviceId === callFeed.deviceId);
|
|
97955
98020
|
if (feedIndex === -1) {
|
|
97956
98021
|
throw new Error("Couldn't find user media feed to remove");
|
|
97957
98022
|
}
|
|
97958
98023
|
this.userMediaFeeds.splice(feedIndex, 1);
|
|
97959
98024
|
callFeed.dispose();
|
|
97960
98025
|
this.emit(GroupCallEvent.UserMediaFeedsChanged, this.userMediaFeeds);
|
|
97961
|
-
if (this.activeSpeaker === callFeed
|
|
97962
|
-
this.
|
|
97963
|
-
this.activeSpeaker = this.userMediaFeeds[0].userId;
|
|
98026
|
+
if (this.activeSpeaker === callFeed) {
|
|
98027
|
+
this.activeSpeaker = this.userMediaFeeds[0];
|
|
97964
98028
|
this.emit(GroupCallEvent.ActiveSpeakerChanged, this.activeSpeaker);
|
|
97965
98029
|
}
|
|
97966
98030
|
}
|
|
97967
|
-
|
|
98031
|
+
/*
|
|
97968
98032
|
* Screenshare Call Feed Event Handlers
|
|
97969
98033
|
*/
|
|
97970
|
-
|
|
97971
|
-
return this.screenshareFeeds.find(
|
|
98034
|
+
getScreenshareFeed(userId, deviceId) {
|
|
98035
|
+
return this.screenshareFeeds.find(f => f.userId === userId && f.deviceId === deviceId);
|
|
97972
98036
|
}
|
|
97973
98037
|
addScreenshareFeed(callFeed) {
|
|
97974
98038
|
this.screenshareFeeds.push(callFeed);
|
|
97975
98039
|
this.emit(GroupCallEvent.ScreenshareFeedsChanged, this.screenshareFeeds);
|
|
97976
98040
|
}
|
|
97977
98041
|
replaceScreenshareFeed(existingFeed, replacementFeed) {
|
|
97978
|
-
const feedIndex = this.screenshareFeeds.findIndex(
|
|
98042
|
+
const feedIndex = this.screenshareFeeds.findIndex(f => f.userId === existingFeed.userId && f.deviceId === existingFeed.deviceId);
|
|
97979
98043
|
if (feedIndex === -1) {
|
|
97980
98044
|
throw new Error("Couldn't find screenshare feed to replace");
|
|
97981
98045
|
}
|
|
@@ -97984,7 +98048,7 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97984
98048
|
this.emit(GroupCallEvent.ScreenshareFeedsChanged, this.screenshareFeeds);
|
|
97985
98049
|
}
|
|
97986
98050
|
removeScreenshareFeed(callFeed) {
|
|
97987
|
-
const feedIndex = this.screenshareFeeds.findIndex(
|
|
98051
|
+
const feedIndex = this.screenshareFeeds.findIndex(f => f.userId === callFeed.userId && f.deviceId === callFeed.deviceId);
|
|
97988
98052
|
if (feedIndex === -1) {
|
|
97989
98053
|
throw new Error("Couldn't find screenshare feed to remove");
|
|
97990
98054
|
}
|
|
@@ -97993,29 +98057,180 @@ class GroupCall extends typed_event_emitter_1.TypedEventEmitter {
|
|
|
97993
98057
|
this.emit(GroupCallEvent.ScreenshareFeedsChanged, this.screenshareFeeds);
|
|
97994
98058
|
}
|
|
97995
98059
|
/**
|
|
97996
|
-
*
|
|
98060
|
+
* Recalculates and updates the participant map to match the room state.
|
|
97997
98061
|
*/
|
|
97998
|
-
|
|
97999
|
-
if (this.
|
|
98000
|
-
|
|
98062
|
+
updateParticipants() {
|
|
98063
|
+
if (this.participantsExpirationTimer !== null) {
|
|
98064
|
+
clearTimeout(this.participantsExpirationTimer);
|
|
98065
|
+
this.participantsExpirationTimer = null;
|
|
98001
98066
|
}
|
|
98002
|
-
this.
|
|
98003
|
-
|
|
98004
|
-
this.client.emit(groupCallEventHandler_1.GroupCallEventHandlerEvent.Participants, this.participants, this);
|
|
98005
|
-
}
|
|
98006
|
-
removeParticipant(member) {
|
|
98007
|
-
const index = this.participants.findIndex((m) => m.userId === member.userId);
|
|
98008
|
-
if (index === -1) {
|
|
98067
|
+
if (this.state === GroupCallState.Ended) {
|
|
98068
|
+
this.participants = new Map();
|
|
98009
98069
|
return;
|
|
98010
98070
|
}
|
|
98011
|
-
|
|
98012
|
-
|
|
98013
|
-
this.
|
|
98071
|
+
const participants = new Map();
|
|
98072
|
+
const now = Date.now();
|
|
98073
|
+
const entered = this.state === GroupCallState.Entered;
|
|
98074
|
+
let nextExpiration = Infinity;
|
|
98075
|
+
for (const e of this.getMemberStateEvents()) {
|
|
98076
|
+
const member = this.room.getMember(e.getStateKey());
|
|
98077
|
+
const content = e.getContent();
|
|
98078
|
+
const calls = Array.isArray(content["m.calls"]) ? content["m.calls"] : [];
|
|
98079
|
+
const call = calls.find(call => call["m.call_id"] === this.groupCallId);
|
|
98080
|
+
const devices = Array.isArray(call === null || call === void 0 ? void 0 : call["m.devices"]) ? call["m.devices"] : [];
|
|
98081
|
+
// Filter out invalid and expired devices
|
|
98082
|
+
let validDevices = devices.filter(d => (typeof d.device_id === "string"
|
|
98083
|
+
&& typeof d.session_id === "string"
|
|
98084
|
+
&& typeof d.expires_ts === "number"
|
|
98085
|
+
&& d.expires_ts > now
|
|
98086
|
+
&& Array.isArray(d.feeds)));
|
|
98087
|
+
// Apply local echo for the unentered case
|
|
98088
|
+
if (!entered && (member === null || member === void 0 ? void 0 : member.userId) === this.client.getUserId()) {
|
|
98089
|
+
validDevices = validDevices.filter(d => d.device_id !== this.client.getDeviceId());
|
|
98090
|
+
}
|
|
98091
|
+
// Must have a connected device and be joined to the room
|
|
98092
|
+
if (validDevices.length > 0 && (member === null || member === void 0 ? void 0 : member.membership) === "join") {
|
|
98093
|
+
const deviceMap = new Map();
|
|
98094
|
+
participants.set(member, deviceMap);
|
|
98095
|
+
for (const d of validDevices) {
|
|
98096
|
+
deviceMap.set(d.device_id, {
|
|
98097
|
+
sessionId: d.session_id,
|
|
98098
|
+
screensharing: d.feeds.some(f => f.purpose === callEventTypes_1.SDPStreamMetadataPurpose.Screenshare),
|
|
98099
|
+
});
|
|
98100
|
+
if (d.expires_ts < nextExpiration)
|
|
98101
|
+
nextExpiration = d.expires_ts;
|
|
98102
|
+
}
|
|
98103
|
+
}
|
|
98104
|
+
}
|
|
98105
|
+
// Apply local echo for the entered case
|
|
98106
|
+
if (entered) {
|
|
98107
|
+
const localMember = this.room.getMember(this.client.getUserId());
|
|
98108
|
+
let deviceMap = participants.get(localMember);
|
|
98109
|
+
if (deviceMap === undefined) {
|
|
98110
|
+
deviceMap = new Map();
|
|
98111
|
+
participants.set(localMember, deviceMap);
|
|
98112
|
+
}
|
|
98113
|
+
if (!deviceMap.has(this.client.getDeviceId())) {
|
|
98114
|
+
deviceMap.set(this.client.getDeviceId(), {
|
|
98115
|
+
sessionId: this.client.getSessionId(),
|
|
98116
|
+
screensharing: this.getLocalFeeds().some(f => f.purpose === callEventTypes_1.SDPStreamMetadataPurpose.Screenshare),
|
|
98117
|
+
});
|
|
98118
|
+
}
|
|
98119
|
+
}
|
|
98120
|
+
this.participants = participants;
|
|
98121
|
+
if (nextExpiration < Infinity) {
|
|
98122
|
+
this.participantsExpirationTimer = setTimeout(() => this.updateParticipants(), nextExpiration - now);
|
|
98123
|
+
}
|
|
98124
|
+
}
|
|
98125
|
+
/**
|
|
98126
|
+
* Updates the local user's member state with the devices returned by the given function.
|
|
98127
|
+
* @param fn A function from the current devices to the new devices. If it
|
|
98128
|
+
* returns null, the update will be skipped.
|
|
98129
|
+
* @param keepAlive Whether the request should outlive the window.
|
|
98130
|
+
*/
|
|
98131
|
+
updateDevices(fn, keepAlive = false) {
|
|
98132
|
+
var _a;
|
|
98133
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
98134
|
+
const now = Date.now();
|
|
98135
|
+
const localUserId = this.client.getUserId();
|
|
98136
|
+
const event = this.getMemberStateEvents(localUserId);
|
|
98137
|
+
const content = (_a = event === null || event === void 0 ? void 0 : event.getContent()) !== null && _a !== void 0 ? _a : {};
|
|
98138
|
+
const calls = Array.isArray(content["m.calls"]) ? content["m.calls"] : [];
|
|
98139
|
+
let call = null;
|
|
98140
|
+
const otherCalls = [];
|
|
98141
|
+
for (const c of calls) {
|
|
98142
|
+
if (c["m.call_id"] === this.groupCallId) {
|
|
98143
|
+
call = c;
|
|
98144
|
+
}
|
|
98145
|
+
else {
|
|
98146
|
+
otherCalls.push(c);
|
|
98147
|
+
}
|
|
98148
|
+
}
|
|
98149
|
+
if (call === null)
|
|
98150
|
+
call = {};
|
|
98151
|
+
const devices = Array.isArray(call["m.devices"]) ? call["m.devices"] : [];
|
|
98152
|
+
// Filter out invalid and expired devices
|
|
98153
|
+
const validDevices = devices.filter(d => (typeof d.device_id === "string"
|
|
98154
|
+
&& typeof d.session_id === "string"
|
|
98155
|
+
&& typeof d.expires_ts === "number"
|
|
98156
|
+
&& d.expires_ts > now
|
|
98157
|
+
&& Array.isArray(d.feeds)));
|
|
98158
|
+
const newDevices = fn(validDevices);
|
|
98159
|
+
if (newDevices === null)
|
|
98160
|
+
return;
|
|
98161
|
+
const newCalls = [...otherCalls];
|
|
98162
|
+
if (newDevices.length > 0) {
|
|
98163
|
+
newCalls.push(Object.assign(Object.assign({}, call), { "m.call_id": this.groupCallId, "m.devices": newDevices }));
|
|
98164
|
+
}
|
|
98165
|
+
const newContent = { "m.calls": newCalls };
|
|
98166
|
+
yield this.client.sendStateEvent(this.room.roomId, event_1.EventType.GroupCallMemberPrefix, newContent, localUserId, { keepAlive });
|
|
98167
|
+
});
|
|
98168
|
+
}
|
|
98169
|
+
addDeviceToMemberState() {
|
|
98170
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
98171
|
+
yield this.updateDevices(devices => [
|
|
98172
|
+
...devices.filter(d => d.device_id !== this.client.getDeviceId()),
|
|
98173
|
+
{
|
|
98174
|
+
"device_id": this.client.getDeviceId(),
|
|
98175
|
+
"session_id": this.client.getSessionId(),
|
|
98176
|
+
"expires_ts": Date.now() + DEVICE_TIMEOUT,
|
|
98177
|
+
"feeds": this.getLocalFeeds().map(feed => ({ purpose: feed.purpose })),
|
|
98178
|
+
// TODO: Add data channels
|
|
98179
|
+
},
|
|
98180
|
+
]);
|
|
98181
|
+
});
|
|
98182
|
+
}
|
|
98183
|
+
updateMemberState() {
|
|
98184
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
98185
|
+
// Clear the old update interval before proceeding
|
|
98186
|
+
if (this.resendMemberStateTimer !== null) {
|
|
98187
|
+
clearInterval(this.resendMemberStateTimer);
|
|
98188
|
+
this.resendMemberStateTimer = null;
|
|
98189
|
+
}
|
|
98190
|
+
if (this.state === GroupCallState.Entered) {
|
|
98191
|
+
// Add the local device
|
|
98192
|
+
yield this.addDeviceToMemberState();
|
|
98193
|
+
// Resend the state event every so often so it doesn't become stale
|
|
98194
|
+
this.resendMemberStateTimer = setInterval(() => __awaiter(this, void 0, void 0, function* () {
|
|
98195
|
+
logger_1.logger.log("Resending call member state");
|
|
98196
|
+
try {
|
|
98197
|
+
yield this.addDeviceToMemberState();
|
|
98198
|
+
}
|
|
98199
|
+
catch (e) {
|
|
98200
|
+
logger_1.logger.error("Failed to resend call member state", e);
|
|
98201
|
+
}
|
|
98202
|
+
}), DEVICE_TIMEOUT * 3 / 4);
|
|
98203
|
+
}
|
|
98204
|
+
else {
|
|
98205
|
+
// Remove the local device
|
|
98206
|
+
yield this.updateDevices(devices => devices.filter(d => d.device_id !== this.client.getDeviceId()), true);
|
|
98207
|
+
}
|
|
98208
|
+
});
|
|
98209
|
+
}
|
|
98210
|
+
/**
|
|
98211
|
+
* Cleans up our member state by filtering out logged out devices, inactive
|
|
98212
|
+
* devices, and our own device (if we know we haven't entered).
|
|
98213
|
+
*/
|
|
98214
|
+
cleanMemberState() {
|
|
98215
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
98216
|
+
const { devices: myDevices } = yield this.client.getDevices();
|
|
98217
|
+
const deviceMap = new Map(myDevices.map(d => [d.device_id, d]));
|
|
98218
|
+
// updateDevices takes care of filtering out inactive devices for us
|
|
98219
|
+
yield this.updateDevices(devices => {
|
|
98220
|
+
const newDevices = devices.filter(d => {
|
|
98221
|
+
const device = deviceMap.get(d.device_id);
|
|
98222
|
+
return (device === null || device === void 0 ? void 0 : device.last_seen_ts) !== undefined
|
|
98223
|
+
&& !(d.device_id === this.client.getDeviceId() && this.state !== GroupCallState.Entered);
|
|
98224
|
+
});
|
|
98225
|
+
// Skip the update if the devices are unchanged
|
|
98226
|
+
return newDevices.length === devices.length ? null : newDevices;
|
|
98227
|
+
});
|
|
98228
|
+
});
|
|
98014
98229
|
}
|
|
98015
98230
|
}
|
|
98016
98231
|
exports.GroupCall = GroupCall;
|
|
98017
98232
|
|
|
98018
|
-
},{"../@types/event":290,"../ReEmitter":300,"../logger":356,"../models/typed-event-emitter":376,"./call":395,"./callEventHandler":396,"./callEventTypes":397,"./callFeed":398,"./groupCallEventHandler":400}],400:[function(require,module,exports){
|
|
98233
|
+
},{"../@types/event":290,"../ReEmitter":300,"../logger":356,"../models/room-state":371,"../models/typed-event-emitter":376,"../utils":393,"./call":395,"./callEventHandler":396,"./callEventTypes":397,"./callFeed":398,"./groupCallEventHandler":400}],400:[function(require,module,exports){
|
|
98019
98234
|
"use strict";
|
|
98020
98235
|
/*
|
|
98021
98236
|
Copyright 2021 Šimon Brandner <simon.bra.ag@gmail.com>
|
|
@@ -98052,6 +98267,7 @@ const sync_1 = require("../sync");
|
|
|
98052
98267
|
var GroupCallEventHandlerEvent;
|
|
98053
98268
|
(function (GroupCallEventHandlerEvent) {
|
|
98054
98269
|
GroupCallEventHandlerEvent["Incoming"] = "GroupCall.incoming";
|
|
98270
|
+
GroupCallEventHandlerEvent["Outgoing"] = "GroupCall.outgoing";
|
|
98055
98271
|
GroupCallEventHandlerEvent["Ended"] = "GroupCall.ended";
|
|
98056
98272
|
GroupCallEventHandlerEvent["Participants"] = "GroupCall.participants";
|
|
98057
98273
|
})(GroupCallEventHandlerEvent = exports.GroupCallEventHandlerEvent || (exports.GroupCallEventHandlerEvent = {}));
|
|
@@ -98090,13 +98306,6 @@ class GroupCallEventHandler {
|
|
|
98090
98306
|
logger_1.logger.warn(`Multiple group calls detected for room: ${state.roomId}. Multiple group calls are currently unsupported.`);
|
|
98091
98307
|
}
|
|
98092
98308
|
}
|
|
98093
|
-
else if (eventType === event_1.EventType.GroupCallMemberPrefix) {
|
|
98094
|
-
const groupCall = this.groupCalls.get(state.roomId);
|
|
98095
|
-
if (!groupCall) {
|
|
98096
|
-
return;
|
|
98097
|
-
}
|
|
98098
|
-
groupCall.onMemberStateChanged(event);
|
|
98099
|
-
}
|
|
98100
98309
|
};
|
|
98101
98310
|
}
|
|
98102
98311
|
start() {
|