[FIX] mail: add more menu for rtc buttons
This commit revert the changes from this PR https://github.com/odoo/odoo/pull/127377 Before this commit: Chat window shows all 7 rtc buttons due to this the alignment of the button is not set because there are way too many buttons. After this commit: This commit fixes the issue by showing only 5 buttons Mute,Deafen,Video,More, Close call and other 3 buttons will moved in expandable More menu. The testcases were changed accordingly. Task-3346085 closes odoo/odoo#129360 X-original-commit: 909fb073eada42ff22c4ef4b20b44dc5536b250e Signed-off-by: Alexandre Kühn (aku) <aku@odoo.com>
This commit is contained in:
committed by
Alexandre Kühn
parent
a48fa4fe40
commit
80af1c3d65
@@ -25,7 +25,7 @@
|
||||
<i t-else="" class="o-discuss-Call-sidebarToggler p-2 fs-5 cursor-pointer position-absolute oi oi-arrow-left" title="Show sidebar" t-on-click="() => this.state.sidebar = true"/>
|
||||
</t>
|
||||
<div t-if="state.overlay or !isControllerFloating" class="o-discuss-Call-overlay d-flex justify-content-center w-100 pb-1" t-att-class="{ 'o-isFloating position-absolute bottom-0 pb-3': isControllerFloating }">
|
||||
<div t-att-class="{ 'w-100': props.compact }" t-on-mousemove="onMousemoveOverlay">
|
||||
<div t-on-mousemove="onMousemoveOverlay">
|
||||
<CallActionList thread="props.thread" compact="props.compact" fullscreen="{ isActive: state.isFullscreen, enter: () => this.enterFullScreen(), exit: () => this.exitFullScreen() }"/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -5,8 +5,12 @@ import { useRtc } from "@mail/discuss/call/common/rtc_hook";
|
||||
import { Component } from "@odoo/owl";
|
||||
|
||||
import { isMobileOS } from "@web/core/browser/feature_detection";
|
||||
import { Dropdown } from "@web/core/dropdown/dropdown";
|
||||
import { DropdownItem } from "@web/core/dropdown/dropdown_item";
|
||||
import { _t } from "@web/core/l10n/translation";
|
||||
|
||||
export class CallActionList extends Component {
|
||||
static components = { Dropdown, DropdownItem };
|
||||
static props = ["thread", "fullscreen", "compact?"];
|
||||
static template = "discuss.CallActionList";
|
||||
|
||||
@@ -14,6 +18,44 @@ export class CallActionList extends Component {
|
||||
this.rtc = useRtc();
|
||||
}
|
||||
|
||||
get MORE() {
|
||||
return _t("More");
|
||||
}
|
||||
|
||||
get moreActions() {
|
||||
const acts = [];
|
||||
acts.push({
|
||||
id: "raiseHand",
|
||||
name: !this.rtc.state?.selfSession.raisingHand ? _t("Raise Hand") : _t("Lower Hand"),
|
||||
icon: "fa fa-fw fa-hand-paper-o",
|
||||
onSelect: (ev) => this.onClickRaiseHand(ev),
|
||||
});
|
||||
if (isMobileOS) {
|
||||
acts.push({
|
||||
id: "shareScreen",
|
||||
name: !this.rtc.state.sendScreen ? _t("Share Screen") : _t("Stop Sharing Screen"),
|
||||
icon: "fa fa-fw fa-desktop",
|
||||
onSelect: () => this.rtc.toggleVideo("screen"),
|
||||
});
|
||||
}
|
||||
if (!this.props.fullscreen.isActive) {
|
||||
acts.push({
|
||||
id: "fullScreen",
|
||||
name: _t("Enter Full Screen"),
|
||||
icon: "fa fa-fw fa-arrows-alt",
|
||||
onSelect: () => this.props.fullscreen.enter(),
|
||||
});
|
||||
} else {
|
||||
acts.push({
|
||||
id: "exitFullScreen",
|
||||
name: _t("Exit Full Screen"),
|
||||
icon: "fa fa-fw fa-compress",
|
||||
onSelect: () => this.props.fullscreen.exit(),
|
||||
});
|
||||
}
|
||||
return acts;
|
||||
}
|
||||
|
||||
get isOfActiveCall() {
|
||||
return Boolean(this.props.thread.id === this.rtc.state?.channel?.id);
|
||||
}
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
<t t-if="isOfActiveCall and rtc.state.selfSession">
|
||||
<t t-if="rtc.state?.selfSession.isMute" t-set="micText">Unmute</t>
|
||||
<t t-else="" t-set="micText">Mute</t>
|
||||
<button class="btn d-flex border-0 rounded-circle shadow-none opacity-100 opacity-75-hover"
|
||||
t-att-class="{ 'p-2': isSmall, 'p-3 m-1': !isSmall }"
|
||||
<button class="btn d-flex m-1 border-0 rounded-circle shadow-none opacity-100 opacity-75-hover"
|
||||
t-att-class="{ 'p-2': isSmall, 'p-3': !isSmall }"
|
||||
t-att-aria-label="micText"
|
||||
t-att-title="micText"
|
||||
t-on-click="onClickMicrophone">
|
||||
@@ -23,8 +23,8 @@
|
||||
</button>
|
||||
<t t-if="rtc.state?.selfSession.isDeaf" t-set="headphoneText">Undeafen</t>
|
||||
<t t-else="" t-set="headphoneText">Deafen</t>
|
||||
<button class="btn d-flex border-0 rounded-circle shadow-none opacity-100 opacity-75-hover"
|
||||
t-att-class="{ 'p-2': isSmall, 'p-3 m-1': !isSmall }"
|
||||
<button class="btn d-flex m-1 border-0 rounded-circle shadow-none opacity-100 opacity-75-hover"
|
||||
t-att-class="{ 'p-2': isSmall, 'p-3': !isSmall }"
|
||||
t-att-aria-label="headphoneText"
|
||||
t-att-title="headphoneText"
|
||||
t-on-click="onClickDeafen">
|
||||
@@ -37,23 +37,12 @@
|
||||
}"/>
|
||||
</div>
|
||||
</button>
|
||||
<t t-if="rtc.state?.selfSession.raisingHand" t-set="handText">Lower hand</t>
|
||||
<t t-else="" t-set="handText">Raise hand</t>
|
||||
<button class="btn d-flex border-0 rounded-circle shadow-none opacity-100 opacity-75-hover"
|
||||
t-att-class="{ 'p-2': isSmall, 'p-3 m-1': !isSmall, 'bg-500' : rtc.state?.selfSession.raisingHand }"
|
||||
t-att-aria-label="handText"
|
||||
t-att-title="handText"
|
||||
t-on-click="onClickRaiseHand">
|
||||
<div class="fa-stack">
|
||||
<i class="fa fa-stack-1x fa-hand-paper-o" t-att-class="{'fa-lg': !isSmall }"/>
|
||||
</div>
|
||||
</button>
|
||||
<t t-if="rtc.state.sendCamera" t-set="cameraText">Stop camera</t>
|
||||
<t t-else="" t-set="cameraText">Turn camera on</t>
|
||||
<button class="btn d-flex border-0 rounded-circle shadow-none opacity-100 opacity-75-hover"
|
||||
<button class="btn d-flex m-1 border-0 rounded-circle shadow-none opacity-100 opacity-75-hover"
|
||||
t-att-class="{
|
||||
'p-2': isSmall,
|
||||
'p-3 m-1': !isSmall,
|
||||
'p-3': !isSmall,
|
||||
}"
|
||||
t-att-aria-label="cameraText"
|
||||
t-att-title="cameraText"
|
||||
@@ -62,43 +51,22 @@
|
||||
<i class="fa fa-video-camera fa-stack-1x" t-att-class="{ 'fa-lg': !isSmall, 'text-success': rtc.state.sendCamera }"/>
|
||||
</div>
|
||||
</button>
|
||||
<t t-if="rtc.state.sendScreen" t-set="screenSharingText">Stop screen sharing</t>
|
||||
<t t-else="" t-set="screenSharingText">Share screen</t>
|
||||
<button t-if="!isMobileOS" class="btn d-flex border-0 rounded-circle shadow-none opacity-100 opacity-75-hover"
|
||||
t-att-class="{
|
||||
'p-2': isSmall,
|
||||
'p-3 m-1': !isSmall,
|
||||
}"
|
||||
t-att-aria-label="screenSharingText"
|
||||
t-att-title="screenSharingText"
|
||||
t-on-click="() => this.rtc.toggleVideo('screen')">
|
||||
<div class="fa-stack">
|
||||
<i class="fa fa-desktop fa-stack-1x" t-att-class="{ 'fa-lg': !isSmall, 'text-success': rtc.state.sendScreen }"/>
|
||||
</div>
|
||||
</button>
|
||||
<button t-if="!props.fullscreen.isActive" class="btn d-flex border-0 rounded-circle shadow-none opacity-100 opacity-75-hover"
|
||||
aria-label="Enter Full Screen"
|
||||
title="Enter Full Screen"
|
||||
t-att-class="{ 'p-2': isSmall, 'p-3 m-1': !isSmall }"
|
||||
t-on-click="props.fullscreen.enter"
|
||||
>
|
||||
<div class="fa-stack">
|
||||
<i class="fa fa-arrows-alt fa-stack-1x" t-att-class="{ 'fa-lg': !isSmall }"/>
|
||||
</div>
|
||||
</button>
|
||||
<button t-if="props.fullscreen.isActive" class="btn d-flex border-0 rounded-circle shadow-none opacity-100 opacity-75-hover"
|
||||
aria-label="Exit Full Screen"
|
||||
title="Exit Full Screen"
|
||||
t-att-class="{ 'p-2': isSmall, 'p-3 m-1': !isSmall }"
|
||||
t-on-click="props.fullscreen.exit"
|
||||
>
|
||||
<div class="fa-stack">
|
||||
<i class="fa fa-compress fa-stack-1x" t-att-class="{ 'fa-lg': !isSmall }"/>
|
||||
</div>
|
||||
</button>
|
||||
<Dropdown position="'top-end'" togglerClass="`btn d-flex m-1 border-0 rounded-circle shadow-none opacity-100 opacity-75-hover ${ isSmall ? 'p-2' : 'p-3' }`" menuClass="'d-flex flex-column py-0'" title="MORE">
|
||||
<t t-set-slot="toggler">
|
||||
<div class="fa-stack">
|
||||
<i class="fa fa-ellipsis-v fa-stack-1x" t-att-class="{ 'fa-lg': !isSmall }"/>
|
||||
</div>
|
||||
</t>
|
||||
<t t-set-slot="default">
|
||||
<DropdownItem t-foreach="moreActions" t-as="action" t-key="action.id" class="'btn rounded-0 d-flex align-items-center px-2 py-2 m-0 opacity-75 opacity-100-hover'" title="action.name" onSelected="action.onSelect">
|
||||
<i t-att-class="action.icon"/>
|
||||
<span class="mx-2" t-out="action.name"/>
|
||||
</DropdownItem>
|
||||
</t>
|
||||
</Dropdown>
|
||||
</t>
|
||||
<button t-if="props.thread.rtcInvitingSession and !isOfActiveCall" class="btn btn-danger d-flex border-0 rounded-circle shadow-none"
|
||||
t-att-class="{ 'p-2': isSmall, 'p-3 m-1': !isSmall }"
|
||||
<button t-if="props.thread.rtcInvitingSession and !isOfActiveCall" class="btn btn-danger d-flex m-1 border-0 rounded-circle shadow-none"
|
||||
t-att-class="{ 'p-2': isSmall, 'p-3': !isSmall }"
|
||||
aria-label="Reject"
|
||||
title="Reject"
|
||||
t-att-disabled="rtc.state.hasPendingRequest"
|
||||
@@ -109,9 +77,9 @@
|
||||
</button>
|
||||
<t t-if="props.thread === rtc.state.channel" t-set="callText">Disconnect</t>
|
||||
<t t-else="" t-set="callText">Join Call</t>
|
||||
<button class="btn d-flex border-0 rounded-circle shadow-none"
|
||||
<button class="btn d-flex m-1 border-0 rounded-circle shadow-none"
|
||||
t-att-aria-label="callText"
|
||||
t-att-class="{ 'btn-danger': isOfActiveCall, 'p-2': isSmall, 'p-3 m-1': !isSmall, 'btn-success': !isOfActiveCall }"
|
||||
t-att-class="{ 'btn-danger': isOfActiveCall, 'p-2': isSmall, 'p-3': !isSmall, 'btn-success': !isOfActiveCall }"
|
||||
t-att-disabled="rtc.state.hasPendingRequest"
|
||||
t-att-title="callText"
|
||||
t-on-click="onClickToggleAudioCall">
|
||||
|
||||
@@ -28,14 +28,16 @@ QUnit.test("basic rendering", async (assert) => {
|
||||
assert.containsOnce($, ".o-discuss-CallParticipantCard[aria-label='Mitchell Admin']");
|
||||
assert.containsOnce($, ".o-discuss-CallActionList");
|
||||
assert.containsOnce($, ".o-discuss-CallMenu-buttonContent");
|
||||
assert.containsN($, ".o-discuss-CallActionList button", 7);
|
||||
assert.containsN($, ".o-discuss-CallActionList button", 5);
|
||||
assert.containsOnce($, "button[aria-label='Unmute'], button[aria-label='Mute']"); // FIXME depends on current browser permission
|
||||
assert.containsOnce($, ".o-discuss-CallActionList button[aria-label='Deafen']");
|
||||
assert.containsOnce($, ".o-discuss-CallActionList button[aria-label='Raise hand']");
|
||||
assert.containsOnce($, ".o-discuss-CallActionList button[aria-label='Turn camera on']");
|
||||
assert.containsOnce($, ".o-discuss-CallActionList button[aria-label='Share screen']");
|
||||
assert.containsOnce($, ".o-discuss-CallActionList button[aria-label='Enter Full Screen']");
|
||||
assert.containsOnce($, "button[title='More']");
|
||||
assert.containsOnce($, ".o-discuss-CallActionList button[aria-label='Disconnect']");
|
||||
await click("button[title='More']");
|
||||
assert.containsOnce($, "[title='Raise Hand']");
|
||||
assert.containsOnce($, "[title='Share Screen']");
|
||||
assert.containsOnce($, "[title='Enter Full Screen']");
|
||||
});
|
||||
|
||||
QUnit.test("no call with odoobot", async (assert) => {
|
||||
@@ -177,9 +179,11 @@ QUnit.test("can share screen", async (assert) => {
|
||||
const { openDiscuss } = await start();
|
||||
await openDiscuss(channelId);
|
||||
await click(".o-mail-Discuss-header button[title='Start a Call']");
|
||||
await click(".o-discuss-CallActionList button[title='Share screen']");
|
||||
await click(".o-discuss-CallActionList [title='More']");
|
||||
await click("[title='Share Screen']");
|
||||
assert.containsOnce($, ".o-discuss-CallParticipantCard video");
|
||||
await click(".o-discuss-CallActionList button[title='Stop screen sharing']");
|
||||
await click(".o-discuss-CallActionList [title='More']");
|
||||
await click("[title='Stop Sharing Screen']");
|
||||
assert.containsNone($, ".o-discuss-CallParticipantCard video");
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user