From db800b9b36dcdfa048c5ae1895b99cd016fd6c6e Mon Sep 17 00:00:00 2001
From: Ming Rui Zhang <mingrui.zhang@savoirfairelinux.com>
Date: Wed, 2 Jun 2021 14:54:24 -0400
Subject: [PATCH] callActionBar: change share action to share menu action

Add share screen area, share file into the popup menu

Change-Id: Iea06f3e79b672cb824f56017a55086f4e5d17ae5
---
 src/constant/JamiStrings.qml                  |   1 +
 src/mainview/components/CallActionBar.qml     |  54 +++++++-
 .../components/CallButtonDelegate.qml         | 128 +++++++++---------
 src/mainview/components/CallOverlay.qml       |   9 ++
 .../components/CallViewContextMenu.qml        |   8 --
 5 files changed, 119 insertions(+), 81 deletions(-)

diff --git a/src/constant/JamiStrings.qml b/src/constant/JamiStrings.qml
index 1f8c7d3a6..31a3ff71d 100644
--- a/src/constant/JamiStrings.qml
+++ b/src/constant/JamiStrings.qml
@@ -224,6 +224,7 @@ Item {
     property string stopSharing: qsTr("Stop sharing screen or file")
     property string shareScreenArea: qsTr("Share screen area")
     property string shareFile: qsTr("Share file")
+    property string selectShareMethod: qsTr("Select sharing method")
     property string viewPlugin: qsTr("View plugin")
     property string noVideoDevice: qsTr("No video device")
     property string notAvailable: qsTr("N/A")
diff --git a/src/mainview/components/CallActionBar.qml b/src/mainview/components/CallActionBar.qml
index ef4d55747..c64d77f7f 100644
--- a/src/mainview/components/CallActionBar.qml
+++ b/src/mainview/components/CallActionBar.qml
@@ -29,6 +29,11 @@ import "../../commoncomponents"
 Control {
     id: root
 
+    enum ActionPopupMode {
+        MediaDevice = 0,
+        ListElement
+    }
+
     property alias overflowOpen: overflowButton.popup.visible
     property bool subMenuOpen: false
 
@@ -42,7 +47,8 @@ Control {
     signal showInputPanelClicked
     signal shareScreenClicked
     signal stopSharingClicked
-    signal shareScreenAreaClicked // TODO: bind this
+    signal shareScreenAreaClicked
+    signal shareFileClicked
     signal pluginsClicked
 
     Component {
@@ -106,6 +112,36 @@ Control {
                 AvAdapter.startAudioMeter(false)
             }
         },
+        Action {
+            id: shareMenuAction
+            text: JamiStrings.selectShareMethod
+            property int popupMode: CallActionBar.ActionPopupMode.ListElement
+            property var listModel: ListModel {
+                id: shareModel
+
+                Component.onCompleted: {
+                    shareModel.append({"Name": JamiStrings.shareScreen,
+                                       "IconSource": "qrc:/images/icons/share_screen_black_24dp.svg"})
+                    shareModel.append({"Name": JamiStrings.shareScreenArea,
+                                       "IconSource" :"qrc:/images/icons/share_screen_black_24dp.svg"})
+                    shareModel.append({"Name": JamiStrings.shareFile,
+                                       "IconSource" :"qrc:/images/icons/insert_photo-24px.svg"})
+                }
+            }
+            function accept(index) {
+                switch(shareModel.get(index).Name) {
+                  case JamiStrings.shareScreen:
+                      shareScreenClicked()
+                      break
+                  case JamiStrings.shareScreenArea:
+                      shareScreenAreaClicked()
+                      break
+                  case JamiStrings.shareFile:
+                      shareFileClicked()
+                      break
+                }
+            }
+        },
         Action {
             id: videoInputMenuAction
             text: JamiStrings.selectVideoDevice
@@ -177,8 +213,8 @@ Control {
         Action {
             id: audioOutputAction
             // temp hack for missing back-end, just open device selection
-            property bool bypassMuteAction: true
-            checkable: !bypassMuteAction
+            property bool openPopupWhenClicked: true
+            checkable: !openPopupWhenClicked
             icon.source: "qrc:/images/icons/spk_black_24dp.svg"
             icon.color: "white"
             text: JamiStrings.selectAudioOutputDevice
@@ -222,9 +258,12 @@ Control {
         },
         Action {
             id: shareAction
-            onTriggered: AvAdapter.currentRenderingDeviceType === Video.DeviceType.DISPLAY ?
-                             root.stopSharingClicked() :
-                             root.shareScreenClicked()
+            property bool openPopupWhenClicked: AvAdapter.currentRenderingDeviceType
+                                                !== Video.DeviceType.DISPLAY
+            onTriggered: {
+                if (AvAdapter.currentRenderingDeviceType === Video.DeviceType.DISPLAY)
+                    root.stopSharingClicked()
+            }
             icon.source: AvAdapter.currentRenderingDeviceType === Video.DeviceType.DISPLAY ?
                              "qrc:/images/icons/share_stop_black_24dp.svg" :
                              "qrc:/images/icons/share_screen_black_24dp.svg"
@@ -232,8 +271,9 @@ Control {
                             "red" : "white"
             text: AvAdapter.currentRenderingDeviceType === Video.DeviceType.DISPLAY ?
                       JamiStrings.stopSharing :
-                      JamiStrings.shareScreen
+                      JamiStrings.selectShareMethod
             property real size: 34
+            property var menuAction: shareMenuAction
         },
         Action {
             id: recordAction
diff --git a/src/mainview/components/CallButtonDelegate.qml b/src/mainview/components/CallButtonDelegate.qml
index 115f94449..cefa29f92 100644
--- a/src/mainview/components/CallButtonDelegate.qml
+++ b/src/mainview/components/CallButtonDelegate.qml
@@ -47,8 +47,8 @@ ItemDelegate {
 
     // TODO: remove this when output volume control is implemented
     MouseArea {
-        visible: ItemAction.bypassMuteAction !== undefined &&
-                 ItemAction.bypassMuteAction && !menu.popup.visible
+        visible: ItemAction.openPopupWhenClicked !== undefined
+                 && ItemAction.openPopupWhenClicked && !menu.popup.visible
         anchors.fill: wrapper
         onClicked: menu.popup.open()
     }
@@ -59,11 +59,8 @@ ItemDelegate {
         color: {
             if (supplimentaryBackground.visible)
                 return "#c4272727"
-            return wrapper.down ?
-                        "#c4777777" :
-                        wrapper.hovered && !menu.hovered ?
-                            "#c4444444" :
-                            "#c4272727"
+            return wrapper.down ? "#c4777777" : wrapper.hovered
+                                  && !menu.hovered ? "#c4444444" : "#c4272727"
         }
         type: {
             if (isVertical) {
@@ -75,13 +72,15 @@ ItemDelegate {
                 if (isFirst)
                     return HalfPill.Left
                 else if (isLast && hasLast)
-                     return HalfPill.Right
+                    return HalfPill.Right
             }
             return HalfPill.None
         }
 
         Behavior on color {
-            ColorAnimation { duration: JamiTheme.shortFadeDuration }
+            ColorAnimation {
+                duration: JamiTheme.shortFadeDuration
+            }
         }
     }
 
@@ -90,17 +89,18 @@ ItemDelegate {
         id: supplimentaryBackground
 
         visible: ItemAction.hasBg !== undefined
-        color: wrapper.down ?
-                   Qt.lighter(JamiTheme.refuseRed, 1.5) :
-                   wrapper.hovered && !menu.hovered ?
-                       JamiTheme.refuseRed :
-                       JamiTheme.refuseRedTransparent
+        color: wrapper.down ? Qt.lighter(JamiTheme.refuseRed, 1.5) :
+                              wrapper.hovered && !menu.hovered ?
+                                  JamiTheme.refuseRed :
+                                  JamiTheme.refuseRedTransparent
         anchors.fill: parent
         radius: isLast ? 5 : width / 2
         type: isLast ? HalfPill.Right : HalfPill.None
 
         Behavior on color {
-            ColorAnimation { duration: JamiTheme.shortFadeDuration }
+            ColorAnimation {
+                duration: JamiTheme.shortFadeDuration
+            }
         }
     }
 
@@ -108,8 +108,7 @@ ItemDelegate {
         id: icon
 
         // TODO: remove this when the icons are size corrected
-        property real size: ItemAction.size !== undefined ?
-                                ItemAction.size : 30
+        property real size: ItemAction.size !== undefined ? ItemAction.size : 30
         containerWidth: size
         containerHeight: size
 
@@ -120,12 +119,20 @@ ItemDelegate {
 
         SequentialAnimation on opacity {
             loops: Animation.Infinite
-            running: ItemAction !== undefined &&
-                     ItemAction.blinksWhenChecked !== undefined &&
-                     ItemAction.blinksWhenChecked && checked
+            running: ItemAction !== undefined
+                     && ItemAction.blinksWhenChecked !== undefined
+                     && ItemAction.blinksWhenChecked && checked
             onStopped: icon.opacity = 1
-            NumberAnimation { from: 1; to: 0; duration: JamiTheme.recordBlinkDuration }
-            NumberAnimation { from: 0; to: 1; duration: JamiTheme.recordBlinkDuration }
+            NumberAnimation {
+                from: 1
+                to: 0
+                duration: JamiTheme.recordBlinkDuration
+            }
+            NumberAnimation {
+                from: 0
+                to: 1
+                duration: JamiTheme.recordBlinkDuration
+            }
         }
     }
 
@@ -144,9 +151,8 @@ ItemDelegate {
             id: toolTip
             parent: parent
             visible: text.length > 0 && (wrapper.hovered || menu.hovered)
-            text: menu.hovered ?
-                      menuAction.text :
-                      (ItemAction !== undefined ? ItemAction.text : null)
+            text: menu.hovered ? menuAction.text : (ItemAction
+                                                    !== undefined ? ItemAction.text : null)
             verticalPadding: 1
             font.pointSize: 9
         }
@@ -163,40 +169,29 @@ ItemDelegate {
 
         y: isVertical ? 0 : -4
         x: isVertical ? -4 : 0
-        anchors.horizontalCenter: isVertical ?
-                                      undefined :
-                                      parent.horizontalCenter
-        anchors.verticalCenter: isVertical ?
-                                    parent.verticalCenter :
-                                    undefined
+        anchors.horizontalCenter: isVertical ? undefined : parent.horizontalCenter
+        anchors.verticalCenter: isVertical ? parent.verticalCenter : undefined
 
         width: 18
         height: width
 
         Connections {
-            target: menuAction !== undefined ?
-                        menuAction :
-                        null
+            target: menuAction !== undefined ? menuAction : null
             function onTriggered() {
-                itemListView.currentIndex =
-                        menuAction.listModel.getCurrentIndex()
+                if (menuAction.popupMode !== CallActionBar.ActionPopupMode.ListElement)
+                    itemListView.currentIndex = menuAction.listModel.getCurrentIndex()
             }
         }
 
         contentItem: ResponsiveImage {
-            source: isVertical ?
-                        "qrc:/images/icons/chevron_left_black_24dp.svg" :
-                        "qrc:/images/icons/expand_less-24px.svg"
+            source: isVertical ? "qrc:/images/icons/chevron_left_black_24dp.svg" :
+                                 "qrc:/images/icons/expand_less-24px.svg"
             smooth: true
             color: "white"
         }
 
         background: Rectangle {
-            color: menu.down ?
-                       "#aaaaaa" :
-                       menu.hovered ?
-                           "#777777" :
-                           "#444444"
+            color: menu.down ? "#aaaaaa" : menu.hovered ? "#777777" : "#444444"
             radius: 4
         }
 
@@ -209,19 +204,16 @@ ItemDelegate {
             height: itemListView.menuItemHeight
             background: Rectangle {
                 anchors.fill: parent
-                color: menuItem.down ?
-                           "#c4aaaaaa" :
-                           menuItem.hovered ?
-                               "#c4777777" :
-                               "transparent"
+                color: menuItem.down ? "#c4aaaaaa" : menuItem.hovered ? "#c4777777" : "transparent"
             }
             contentItem: RowLayout {
                 anchors.fill: parent
                 anchors.margins: 6
                 ResponsiveImage {
-                    source: menuItem.ListView.isCurrentItem ?
-                                "qrc:/images/icons/check_box-24px.svg" :
-                                "qrc:/images/icons/check_box_outline_blank-24px.svg"
+                    source: menuAction.popupMode === CallActionBar.ActionPopupMode.ListElement ?
+                                IconSource : (menuItem.ListView.isCurrentItem ?
+                                                  "qrc:/images/icons/check_box-24px.svg" :
+                                                  "qrc:/images/icons/check_box_outline_blank-24px.svg")
                     smooth: true
                     color: "white"
                 }
@@ -229,7 +221,8 @@ ItemDelegate {
                     Layout.fillWidth: true
                     horizontalAlignment: Text.AlignLeft
                     verticalAlignment: Text.AlignVCenter
-                    text: DeviceName
+                    text: menuAction.popupMode
+                          === CallActionBar.ActionPopupMode.ListElement ? Name : DeviceName
                     elide: Text.ElideRight
                     font.pointSize: 9
                     color: "white"
@@ -240,12 +233,8 @@ ItemDelegate {
         popup: Popup {
             id: itemPopup
 
-            y: isVertical ?
-                   -(implicitHeight - wrapper.height) / 2 - 18 :
-                   -implicitHeight - 12
-            x: isVertical ?
-                   -implicitWidth - 12 :
-                   -(implicitWidth - wrapper.width) / 2 - 18
+            y: isVertical ? -(implicitHeight - wrapper.height) / 2 - 18 : -implicitHeight - 12
+            x: isVertical ? -implicitWidth - 12 : -(implicitWidth - wrapper.width) / 2 - 18
 
             implicitWidth: contentItem.implicitWidth
             implicitHeight: contentItem.implicitHeight
@@ -263,8 +252,7 @@ ItemDelegate {
                 pixelAligned: true
                 orientation: ListView.Vertical
                 implicitWidth: menuItemWidth
-                implicitHeight: Math.min(contentHeight,
-                                         menuItemHeight * 6) + 24
+                implicitHeight: Math.min(contentHeight, menuItemHeight * 6) + 24
 
                 ScrollIndicator.vertical: ScrollIndicator {}
 
@@ -272,16 +260,24 @@ ItemDelegate {
 
                 model: menu.delegateModel
 
-                TextMetrics { id: itemTextMetrics }
+                TextMetrics {
+                    id: itemTextMetrics
+
+                    font.pointSize: 9
+                }
 
                 // recalc list width based on max item width
                 onCountChanged: {
-                    // Hack: use AudioDeviceModel.DeviceName role for video as well
                     var maxWidth = 0
                     for (var i = 0; i < count; ++i) {
-                        var idx = menuAction.listModel.index(i, 0)
-                        itemTextMetrics.text = menuAction.listModel.data(
-                                    idx, AudioDeviceModel.DeviceName)
+                        if (menuAction.popupMode === CallActionBar.ActionPopupMode.ListElement) {
+                            itemTextMetrics.text = menuAction.listModel.get(i).Name
+                        } else {
+                            // Hack: use AudioDeviceModel.DeviceName role for video as well
+                            var idx = menuAction.listModel.index(i, 0)
+                            itemTextMetrics.text = menuAction.listModel.data(
+                                        idx, AudioDeviceModel.DeviceName)
+                        }
                         if (itemTextMetrics.boundingRect.width > maxWidth)
                             maxWidth = itemTextMetrics.boundingRect.width
                     }
diff --git a/src/mainview/components/CallOverlay.qml b/src/mainview/components/CallOverlay.qml
index 8bc4866d7..12243e3de 100644
--- a/src/mainview/components/CallOverlay.qml
+++ b/src/mainview/components/CallOverlay.qml
@@ -135,6 +135,14 @@ Item {
         y: root.height / 2 - sipInputPanel.height / 2
     }
 
+    JamiFileDialog {
+        id: jamiFileDialog
+
+        mode: JamiFileDialog.Mode.OpenFile
+
+        onAccepted: AvAdapter.shareFile(jamiFileDialog.file)
+    }
+
     ResponsiveImage {
         id: onHoldImage
 
@@ -194,6 +202,7 @@ Item {
             function onShareScreenClicked() { openShareScreen() }
             function onStopSharingClicked() { AvAdapter.stopSharing() }
             function onShareScreenAreaClicked() { openShareScreenArea() }
+            function onShareFileClicked() { jamiFileDialog.open() }
             function onPluginsClicked() { openPluginsMenu() }
         }
     }
diff --git a/src/mainview/components/CallViewContextMenu.qml b/src/mainview/components/CallViewContextMenu.qml
index 9de9ec41a..1d2d15417 100644
--- a/src/mainview/components/CallViewContextMenu.qml
+++ b/src/mainview/components/CallViewContextMenu.qml
@@ -168,13 +168,5 @@ ContextMenuAutoLoader {
         }
     ]
 
-    JamiFileDialog {
-        id: jamiFileDialog
-
-        mode: JamiFileDialog.Mode.OpenFile
-
-        onAccepted: AvAdapter.shareFile(jamiFileDialog.file)
-    }
-
     Component.onCompleted: menuItemsToLoad = menuItems
 }
-- 
GitLab