[FIX] mail: cleanup onbeforeunload and rpc button locks

This commits adds a proper event listener removal for `onbeforeunload`
to facilitate testing and cleans up the join/leave rpc button locking.

closes odoo/odoo#76327

X-original-commit: 28d4c80b0dd2f30fb6aab46099a3c64d18f8d3b9
Signed-off-by: Sébastien Theys (seb) <seb@odoo.com>
This commit is contained in:
Thanh Dodeur
2021-09-10 12:34:10 +00:00
parent c393a9882e
commit bd41225e46
6 changed files with 55 additions and 24 deletions
@@ -80,6 +80,9 @@ export class ChatWindowHeader extends Component {
*/
async _onClickCamera(ev) {
ev.stopPropagation();
if (this.chatWindow.thread.hasPendingRtcRequest) {
return;
}
await this.chatWindow.thread.toggleCall({ startWithVideo: true });
}
@@ -89,6 +92,9 @@ export class ChatWindowHeader extends Component {
*/
async _onClickPhone(ev) {
ev.stopPropagation();
if (this.chatWindow.thread.hasPendingRtcRequest) {
return;
}
await this.chatWindow.thread.toggleCall();
}
@@ -27,6 +27,9 @@ export class RtcInvitationCard extends Component {
*/
async _onClickAccept(ev) {
this.thread.open();
if (this.thread.hasPendingRtcRequest) {
return;
}
await this.thread.toggleCall();
}
@@ -43,6 +46,9 @@ export class RtcInvitationCard extends Component {
* @param {MouseEvent} ev
*/
_onClickRefuse(ev) {
if (this.thread.hasPendingRtcRequest) {
return;
}
this.thread.leaveCall();
}
@@ -38,6 +38,9 @@ export class ThreadViewTopbar extends Component {
* @param {MouseEvent} ev
*/
async _onClickPhone(ev) {
if (this.threadViewTopBar.thread.hasPendingRtcRequest) {
return;
}
await this.threadViewTopBar.thread.toggleCall();
}
@@ -46,6 +49,9 @@ export class ThreadViewTopbar extends Component {
* @param {MouseEvent} ev
*/
async _onClickCamera(ev) {
if (this.threadViewTopBar.thread.hasPendingRtcRequest) {
return;
}
await this.threadViewTopBar.thread.toggleCall({
startWithVideo: true,
});
+14 -3
View File
@@ -74,9 +74,9 @@ function factory(dependencies) {
this._onKeyUp = this._onKeyUp.bind(this);
browser.addEventListener('keydown', this._onKeyDown);
browser.addEventListener('keyup', this._onKeyUp);
browser.addEventListener('beforeunload', async () => {
this.channel && await this.channel.leaveCall();
});
// Disconnects the RTC session if the page is closed or reloaded.
this._onBeforeUnload = this._onBeforeUnload.bind(this);
browser.addEventListener('beforeunload', this._onBeforeUnload);
/**
* Call all sessions for which no peerConnection is established at
* a regular interval to try to recover any connection that failed
@@ -94,6 +94,7 @@ function factory(dependencies) {
* @override
*/
async _willDelete() {
browser.removeEventListener('beforeunload', this._onBeforeUnload);
browser.removeEventListener('keydown', this._onKeyDown);
browser.removeEventListener('keyup', this._onKeyUp);
return super._willDelete(...arguments);
@@ -975,6 +976,16 @@ function factory(dependencies) {
// Handlers
//----------------------------------------------------------------------
/**
* @private
* @param {Event} ev
*/
async _onBeforeUnload(ev) {
if (this.channel) {
await this.channel.performRpcLeaveCall();
}
}
/**
* @private
* @param {String} state the new state of the connection
@@ -51,6 +51,9 @@ function factory(dependencies) {
* @param {MouseEvent} ev
*/
async onClickRejectCall(ev) {
if (this.callViewer.threadView.thread.hasPendingRtcRequest) {
return;
}
await this.callViewer.threadView.thread.leaveCall();
}
@@ -65,6 +68,9 @@ function factory(dependencies) {
* @param {MouseEvent} ev
*/
async onClickToggleAudioCall(ev) {
if (this.callViewer.threadView.thread.hasPendingRtcRequest) {
return;
}
await this.callViewer.threadView.thread.toggleCall();
}
@@ -72,6 +78,9 @@ function factory(dependencies) {
* @param {MouseEvent} ev
*/
async onClickToggleVideoCall(ev) {
if (this.callViewer.threadView.thread.hasPendingRtcRequest) {
return;
}
await this.callViewer.threadView.thread.toggleCall({
startWithVideo: true,
});
+14 -21
View File
@@ -574,6 +574,16 @@ function factory(dependencies) {
);
}
/**
* Performs the rpc to leave the rtc call of the channel.
*/
async performRpcLeaveCall() {
await this.async(() => this.env.services.rpc({
route: '/mail/rtc/channel/leave_call',
params: { channel_id: this.id },
}, { shadow: true }));
}
/**
* Performs RPC on the route `/mail/get_suggested_recipients`.
*
@@ -731,14 +741,17 @@ function factory(dependencies) {
* @param {Object} options
*/
async toggleCall(options) {
this.update({ hasPendingRtcRequest: true });
const isActiveCall = !!this.mailRtc;
if (this.messaging.mailRtc.channel) {
await this.messaging.mailRtc.channel.leaveCall();
}
if (isActiveCall) {
this.update({ hasPendingRtcRequest: false });
return;
}
await this._joinCall(options);
this.update({ hasPendingRtcRequest: false });
}
/**
@@ -757,10 +770,6 @@ function factory(dependencies) {
});
return;
}
if (this.hasPendingRtcRequest) {
return;
}
this.update({ hasPendingRtcRequest: true });
const { rtcSessions, iceServers, sessionId, invitedPartners, invitedGuests } = await this.async(() => this.env.services.rpc({
route: '/mail/rtc/channel/join_call',
params: {
@@ -768,7 +777,6 @@ function factory(dependencies) {
},
}, { shadow: true }));
this.update({
hasPendingRtcRequest: false,
mailRtc: link(this.messaging.mailRtc),
rtcInvitingSession: unlink(),
rtcSessions: insertAndReplace(rtcSessions.map(record => this.messaging.models['mail.rtc_session'].convertData(record))),
@@ -789,10 +797,7 @@ function factory(dependencies) {
* Notifies the server and does the cleanup of the current call.
*/
async leaveCall() {
if (this.hasPendingRtcRequest) {
return;
}
await this._leaveCall();
await this.performRpcLeaveCall();
this.endCall();
}
@@ -1821,18 +1826,6 @@ function factory(dependencies) {
}
}
/**
* @private
*/
async _leaveCall() {
this.update({ hasPendingRtcRequest: true });
await this.async(() => this.env.services.rpc({
route: '/mail/rtc/channel/leave_call',
params: { channel_id: this.id },
}, { shadow: true }));
this.update({ hasPendingRtcRequest: false });
}
/**
* Handles change of fold state coming from the server. Useful to
* synchronize corresponding chat window.