diff --git a/addons/mail/models/res_users_settings.py b/addons/mail/models/res_users_settings.py index 756f3c56db2..21a70604dcb 100644 --- a/addons/mail/models/res_users_settings.py +++ b/addons/mail/models/res_users_settings.py @@ -33,8 +33,9 @@ class ResUsersSettings(models.Model): self.ensure_one() res = self._read_format(fnames=[name for name, field in self._fields.items() if name == 'id' or not field.automatic])[0] res.pop('volume_settings_ids') + volume_settings = self.volume_settings_ids._discuss_users_settings_volume_format() res.update({ - 'volume_settings': self.volume_settings_ids._read_format(['id', 'user_setting_id', 'partner_id', 'volume']), + 'volume_settings': [('insert', volume_settings)] if volume_settings else [], }) return res @@ -47,21 +48,27 @@ class ResUsersSettings(models.Model): self.write(changed_settings) self.env['bus.bus']._sendone(self.user_id.partner_id, 'res.users.settings/changed', changed_settings) - def set_volume_setting(self, partner_id, volume): + def set_volume_setting(self, partner_id, volume, guest_id=None): + """ + Saves the volume of a guest or a partner. + Either partner_id or guest_id must be specified. + :param float volume: the selected volume between 0 and 1 + :param int partner_id: + :param int guest_id: + """ self.ensure_one() - volume_setting = self.env['res.users.settings.volumes'].search([('user_setting_id', '=', self.id), ('partner_id', '=', partner_id)]) + volume_setting = self.env['res.users.settings.volumes'].search([ + ('user_setting_id', '=', self.id), ('partner_id', '=', partner_id), ('guest_id', '=', guest_id) + ]) if volume_setting: volume_setting.volume = volume else: - volume_setting = self.env['res.users.settings.volumes'].create([{ + volume_setting = self.env['res.users.settings.volumes'].create({ 'user_setting_id': self.id, - 'partner_id': partner_id, 'volume': volume, - }]) + 'partner_id': partner_id, + 'guest_id': guest_id, + }) self.env['bus.bus']._sendone(self.user_id.partner_id, 'res.users.settings/volumes_update', { - 'volumeSettings': [('insert', { - 'id': volume_setting.id, - 'partner': [('insert-and-replace', {'id': partner_id})], - 'volume': volume_setting.volume, - })], + 'volumeSettings': [('insert', volume_setting._discuss_users_settings_volume_format())], }) diff --git a/addons/mail/models/res_users_settings_volumes.py b/addons/mail/models/res_users_settings_volumes.py index f65df2c84f1..29fb13094a8 100644 --- a/addons/mail/models/res_users_settings_volumes.py +++ b/addons/mail/models/res_users_settings_volumes.py @@ -21,3 +21,17 @@ class ResUsersSettingsVolumes(models.Model): _sql_constraints = [ ("partner_or_guest_exists", "CHECK((partner_id IS NOT NULL AND guest_id IS NULL) OR (partner_id IS NULL AND guest_id IS NOT NULL))", "A volume setting must have a partner or a guest."), ] + + def _discuss_users_settings_volume_format(self): + return [{ + 'id': volume_setting.id, + 'volume': volume_setting.volume, + 'guest': [('insert-and-replace', { + 'id': volume_setting.guest_id.id, + 'name': volume_setting.guest_id.name, + })] if volume_setting.guest_id else [('clear',)], + 'partner_id': [('insert-and-replace', { + 'id': volume_setting.partner_id.id, + 'name': volume_setting.partner_id.name, + })] if volume_setting.partner_id else [('clear',)] + } for volume_setting in self] diff --git a/addons/mail/static/src/models/guest/guest.js b/addons/mail/static/src/models/guest/guest.js index dff34933cf2..64e65d44078 100644 --- a/addons/mail/static/src/models/guest/guest.js +++ b/addons/mail/static/src/models/guest/guest.js @@ -1,6 +1,6 @@ /** @odoo-module **/ -import { attr, one2many } from '@mail/model/model_field'; +import { attr, one2many, one2one } from '@mail/model/model_field'; import { registerNewModel } from '@mail/model/model_core'; function factory(dependencies) { @@ -53,6 +53,12 @@ function factory(dependencies) { readonly: true, }), name: attr(), + rtcSessions: one2many('mail.rtc_session', { + inverse: 'guest', + }), + volumeSetting: one2one('mail.volume_setting', { + inverse: 'guest', + }), }; Guest.identifyingFields = ['id']; Guest.modelName = 'mail.guest'; diff --git a/addons/mail/static/src/models/messaging_initializer/messaging_initializer.js b/addons/mail/static/src/models/messaging_initializer/messaging_initializer.js index 73135f634f9..767c69ae55e 100644 --- a/addons/mail/static/src/models/messaging_initializer/messaging_initializer.js +++ b/addons/mail/static/src/models/messaging_initializer/messaging_initializer.js @@ -253,7 +253,7 @@ function factory(dependencies) { usePushToTalk: use_push_to_talk, pushToTalkKey: push_to_talk_key, voiceActiveDuration: voice_active_duration, - volumeSettings: insert(volume_settings.map(volumeSetting => this.messaging.models['mail.volume_setting'].convertData(volumeSetting))), + volumeSettings: volume_settings, }), }); this.messaging.discuss.update({ diff --git a/addons/mail/static/src/models/messaging_notification_handler/messaging_notification_handler.js b/addons/mail/static/src/models/messaging_notification_handler/messaging_notification_handler.js index 76d72052313..70ea9f630c1 100644 --- a/addons/mail/static/src/models/messaging_notification_handler/messaging_notification_handler.js +++ b/addons/mail/static/src/models/messaging_notification_handler/messaging_notification_handler.js @@ -423,7 +423,6 @@ function factory(dependencies) { usePushToTalk: settings.use_push_to_talk, pushToTalkKey: settings.push_to_talk_key, voiceActiveDuration: settings.voice_active_duration, - volumeSettings: settings.volume_settings && insert(settings.volume_settings.map(volumeSetting => this.messaging.models['mail.volume_setting'].convertData(volumeSetting))), }); } diff --git a/addons/mail/static/src/models/rtc_session/rtc_session.js b/addons/mail/static/src/models/rtc_session/rtc_session.js index 1495d7d6b45..04533d13472 100644 --- a/addons/mail/static/src/models/rtc_session/rtc_session.js +++ b/addons/mail/static/src/models/rtc_session/rtc_session.js @@ -73,7 +73,13 @@ function factory(dependencies) { console.error(error); } audioElement.load(); - audioElement.volume = this.partner && this.partner.volumeSetting ? this.partner.volumeSetting.volume : this.volume; + if (this.partner && this.partner.volumeSetting) { + audioElement.volume = this.partner.volumeSetting.volume; + } else if (this.guest && this.guest.volumeSetting) { + audioElement.volume = this.guest.volumeSetting.volume; + } else { + audioElement.volume = this.volume; + } audioElement.muted = this.messaging.rtc.currentRtcSession.isDeaf; // Using both autoplay and play() as safari may prevent play() outside of user interactions // while some browsers may not support or block autoplay. @@ -115,16 +121,23 @@ function factory(dependencies) { if (this.audioElement) { this.audioElement.volume = volume; } - if (!this.partner || this.isOwnSession) { + if (this.isOwnSession) { return; } - if (this.partner.volumeSetting) { + if (this.partner && this.partner.volumeSetting) { this.partner.volumeSetting.update({ volume }); } + if (this.guest && this.guest.volumeSetting) { + this.guest.volumeSetting.update({ volume }); + } if (this.messaging.isCurrentUserGuest) { return; } - this.messaging.userSetting.saveVolumeSetting(this.partner.id, volume); + this.messaging.userSetting.saveVolumeSetting({ + partnerId: this.partner && this.partner.id, + guestId: this.guest && this.guest.id, + volume, + }); } /** @@ -249,6 +262,8 @@ function factory(dependencies) { _computeVolume() { if (this.partner && this.partner.volumeSetting) { return this.partner.volumeSetting.volume; + } else if (this.guest && this.guest.volumeSetting) { + return this.guest.volumeSetting.volume; } if (this.audioElement) { return this.audioElement.volume; @@ -334,7 +349,6 @@ function factory(dependencies) { connectionState: attr({ default: 'Waiting for the peer to send a RTC offer', }), - guest: many2one('mail.guest'), /** * If this field is set, this session is 'focused' which means that it will * be displayed as the main session. @@ -342,6 +356,9 @@ function factory(dependencies) { focusingMessaging: one2one('mail.messaging', { inverse: 'focusedRtcSession', }), + guest: many2one('mail.guest', { + inverse: 'rtcSessions', + }), /** * Id of the record on the server. */ diff --git a/addons/mail/static/src/models/user_setting/user_setting.js b/addons/mail/static/src/models/user_setting/user_setting.js index c9010191f2a..a254b48c4ac 100644 --- a/addons/mail/static/src/models/user_setting/user_setting.js +++ b/addons/mail/static/src/models/user_setting/user_setting.js @@ -144,10 +144,12 @@ function factory(dependencies) { } /** - * @param {mail.partner} partner - * @param {number} volume + * @param {Object} param0 + * @param {number} [param0.guestId] + * @param {number} [param0.partnerId] + * @param {number} param0.volume */ - async saveVolumeSetting(partnerId, volume) { + async saveVolumeSetting({ guestId, partnerId, volume }) { this._debounce(async () => { await this.async(() => this.env.services.rpc( { @@ -158,6 +160,9 @@ function factory(dependencies) { partnerId, volume, ], + kwargs: { + guest_id: guestId, + }, }, { shadow: true }, )); diff --git a/addons/mail/static/src/models/volume_setting/volume_setting.js b/addons/mail/static/src/models/volume_setting/volume_setting.js index 082e6710f68..2875005ccaf 100644 --- a/addons/mail/static/src/models/volume_setting/volume_setting.js +++ b/addons/mail/static/src/models/volume_setting/volume_setting.js @@ -9,37 +9,6 @@ function factory(dependencies) { class VolumeSetting extends dependencies['mail.model'] { - - //---------------------------------------------------------------------- - // Public - //---------------------------------------------------------------------- - - /** - * @static - * @param {Object} data - * @returns {Object} - */ - static convertData(data) { - const data2 = {}; - if ('volume' in data) { - data2.volume = data.volume; - } - if ('id' in data) { - data2.id = data.id; - } - - // relations - if ('partner_id' in data) { - const partnerNameGet = data['partner_id']; - const partnerData = { - display_name: partnerNameGet[1], - id: partnerNameGet[0], - }; - data2.partner = insert(partnerData); - } - return data2; - } - //---------------------------------------------------------------------- // Private //---------------------------------------------------------------------- @@ -48,7 +17,15 @@ function factory(dependencies) { * @private */ _onChangeVolume() { - for (const rtcSession of this.partner.rtcSessions) { + let rtcSessions; + if (this.partner) { + rtcSessions = this.partner.rtcSessions; + } else if (this.guest) { + rtcSessions = this.guest.rtcSessions; + } else { + return; + } + for (const rtcSession of rtcSessions) { if (rtcSession.audioElement) { rtcSession.audioElement.volume = this.volume; } @@ -57,13 +34,15 @@ function factory(dependencies) { } VolumeSetting.fields = { + guest: one2one('mail.guest', { + inverse: 'volumeSetting', + }), id: attr({ readonly: true, required: true, }), partner: one2one('mail.partner', { inverse: 'volumeSetting', - required: true, }), userSetting: many2one('mail.user_setting', { inverse: 'volumeSettings',