mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-07-21 16:05:26 +02:00
chatview: refactor msg options popup positioning
+ load the popup dynamically + calculate the position using the delegate's attached ListView geometry Gitlab: #979 Change-Id: I9d3a8a31b4aba2f195c4d6453e9dca88e99685ae
This commit is contained in:
parent
42a46fe165
commit
4612d5318b
8 changed files with 112 additions and 127 deletions
|
@ -26,6 +26,8 @@ import net.jami.Models 1.1
|
|||
ListView {
|
||||
id: root
|
||||
|
||||
property alias verticalScrollBar: verticalScrollBar
|
||||
|
||||
layer.mipmap: false
|
||||
clip: true
|
||||
maximumFlickVelocity: 1024
|
||||
|
@ -36,11 +38,6 @@ ListView {
|
|||
attachedFlickableMoving: root.moving
|
||||
}
|
||||
|
||||
property bool isScrolling: verticalScrollBar.active
|
||||
onIsScrollingChanged: {
|
||||
JamiQmlUtils.isChatviewScrolling = isScrolling
|
||||
}
|
||||
|
||||
Keys.onUpPressed: verticalScrollBar.decrease()
|
||||
Keys.onDownPressed: verticalScrollBar.increase()
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import QtQuick
|
||||
import QtQuick.Controls
|
||||
import Qt5Compat.GraphicalEffects
|
||||
|
@ -32,22 +33,79 @@ Popup {
|
|||
padding: 0
|
||||
background.visible: false
|
||||
|
||||
property string msgId
|
||||
property string msg
|
||||
property var emojiReplied
|
||||
property bool out
|
||||
property int type
|
||||
required property string msgId
|
||||
required property string msgBody
|
||||
required property var emojiReplied
|
||||
required property bool isOutgoing
|
||||
required property int type
|
||||
required property string transferName
|
||||
required property Item msgBubble
|
||||
required property ListView listView
|
||||
|
||||
property string transferId: msgId
|
||||
property string location: Body
|
||||
property string transferName
|
||||
property string location: msgBody
|
||||
property bool closeWithoutAnimation: false
|
||||
property var emojiPicker
|
||||
|
||||
function xPositionProvider(width) {
|
||||
// Use the width at function scope to retrigger property evaluation.
|
||||
const listViewWidth = listView.width
|
||||
if (isOutgoing) {
|
||||
const leftMargin = msgBubble.mapToItem(listView, 0, 0).x
|
||||
return width > leftMargin ? -leftMargin : -width
|
||||
} else {
|
||||
const rightMargin = listViewWidth - (msgBubble.x + msgBubble.width)
|
||||
return width > rightMargin ? msgBubble.width - width : msgBubble.width
|
||||
}
|
||||
}
|
||||
function yPositionProvider(height) {
|
||||
const topOffset = msgBubble.mapToItem(listView, 0, 0).y
|
||||
if (topOffset < 0) return -topOffset
|
||||
const bottomOffset = topOffset + height - listView.height
|
||||
if (bottomOffset > 0) return -bottomOffset
|
||||
return 0
|
||||
}
|
||||
x: xPositionProvider(width)
|
||||
y: yPositionProvider(height)
|
||||
|
||||
signal addMoreEmoji
|
||||
|
||||
onOpened: {
|
||||
root.closeWithoutAnimation = false
|
||||
onAddMoreEmoji: {
|
||||
JamiQmlUtils.updateMessageBarButtonsPoints()
|
||||
openEmojiPicker()
|
||||
}
|
||||
|
||||
function openEmojiPicker() {
|
||||
var component = WITH_WEBENGINE ?
|
||||
Qt.createComponent("qrc:/webengine/emojipicker/EmojiPicker.qml") :
|
||||
Qt.createComponent("qrc:/nowebengine/EmojiPicker.qml")
|
||||
emojiPicker = component.createObject(root.parent, { listView: listView })
|
||||
emojiPicker.emojiIsPicked.connect(function(content) {
|
||||
if (emojiReplied.includes(content)) {
|
||||
MessagesAdapter.removeEmojiReaction(CurrentConversation.id, content, msgId)
|
||||
} else {
|
||||
MessagesAdapter.addEmojiReaction(CurrentConversation.id, content, msgId)
|
||||
}
|
||||
})
|
||||
if (emojiPicker !== null) {
|
||||
root.opacity = 0
|
||||
emojiPicker.closed.connect(() => close())
|
||||
emojiPicker.x = xPositionProvider(JamiTheme.emojiPickerWidth)
|
||||
emojiPicker.y = yPositionProvider(JamiTheme.emojiPickerHeight)
|
||||
emojiPicker.open()
|
||||
} else {
|
||||
console.log("Error creating emojiPicker from message options popup");
|
||||
}
|
||||
}
|
||||
|
||||
// Close the picker when listView vertical properties change.
|
||||
property real listViewHeight: listView.height
|
||||
onListViewHeightChanged: close()
|
||||
property bool isScrolling: listView.verticalScrollBar.active
|
||||
onIsScrollingChanged: close()
|
||||
|
||||
onOpened: root.closeWithoutAnimation = false
|
||||
onClosed: if (emojiPicker) emojiPicker.closeEmojiPicker()
|
||||
|
||||
function getModel() {
|
||||
var model = ["👍", "👎", "😂"]
|
||||
var cur = []
|
||||
|
@ -132,7 +190,7 @@ Popup {
|
|||
onClicked: {
|
||||
root.closeWithoutAnimation = true
|
||||
root.addMoreEmoji()
|
||||
close()
|
||||
//close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -152,7 +210,7 @@ Popup {
|
|||
Layout.fillWidth: true
|
||||
Layout.margins: 5
|
||||
onClicked: {
|
||||
UtilsAdapter.setClipboardText(msg)
|
||||
UtilsAdapter.setClipboardText(msgBody)
|
||||
close()
|
||||
}
|
||||
}
|
||||
|
@ -184,7 +242,7 @@ Popup {
|
|||
MessageOptionButton {
|
||||
id: buttonEdit
|
||||
|
||||
visible: root.out && type === Interaction.Type.TEXT
|
||||
visible: root.isOutgoing && type === Interaction.Type.TEXT
|
||||
textButton: JamiStrings.editMessage
|
||||
iconSource: JamiResources.edit_svg
|
||||
Layout.fillWidth: true
|
||||
|
@ -198,7 +256,7 @@ Popup {
|
|||
}
|
||||
|
||||
MessageOptionButton {
|
||||
visible: root.out && type === Interaction.Type.TEXT
|
||||
visible: root.isOutgoing && type === Interaction.Type.TEXT
|
||||
textButton: JamiStrings.deleteMessage
|
||||
iconSource: JamiResources.delete_svg
|
||||
Layout.fillWidth: true
|
|
@ -55,9 +55,15 @@ Control {
|
|||
readonly property real hPadding: JamiTheme.sbsMessageBasePreferredPadding
|
||||
property bool textHovered: false
|
||||
property alias replyAnimation: selectAnimation
|
||||
width: ListView.view ? ListView.view.width : 0
|
||||
width: listView.width
|
||||
height: mainColumnLayout.implicitHeight
|
||||
|
||||
// If the ListView attached properties are not available,
|
||||
// then the root delegate is likely a Loader.
|
||||
readonly property ListView listView: ListView.view ?
|
||||
ListView.view :
|
||||
parent.ListView.view
|
||||
|
||||
rightPadding: hPadding
|
||||
leftPadding: hPadding
|
||||
|
||||
|
@ -184,9 +190,18 @@ Control {
|
|||
height: optionButtonItem.height
|
||||
|
||||
onClicked: {
|
||||
messageOptionPopup.open()
|
||||
messageOptionPopup.x = messageOptionPopup.setXposition(messageOptionPopup.width)
|
||||
messageOptionPopup.y = messageOptionPopup.setYposition(messageOptionPopup.height)
|
||||
var component = Qt.createComponent("qrc:/commoncomponents/MessageOptionsPopup.qml")
|
||||
var obj = component.createObject(bubble, {
|
||||
"emojiReplied": Qt.binding(() => emojiReaction.emojiTexts),
|
||||
"isOutgoing": isOutgoing,
|
||||
"msgId": Id,
|
||||
"msgBody": Body,
|
||||
"type": Type,
|
||||
"transferName": TransferName,
|
||||
"msgBubble": bubble,
|
||||
"listView": listView
|
||||
})
|
||||
obj.open()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -214,103 +229,6 @@ Control {
|
|||
}
|
||||
}
|
||||
|
||||
ChatviewMessageOptions {
|
||||
id: messageOptionPopup
|
||||
|
||||
emojiReplied: emojiReaction.emojiTexts
|
||||
out: isOutgoing
|
||||
msgId: Id
|
||||
msg: Body
|
||||
type: Type
|
||||
transferName: TransferName
|
||||
visible: false
|
||||
|
||||
property bool isScrolling: JamiQmlUtils.isChatviewScrolling
|
||||
property real rootWidth: root.width
|
||||
property var emojiPicker
|
||||
|
||||
onIsScrollingChanged: {
|
||||
messageOptionPopup.close()
|
||||
if (messageOptionPopup.emojiPicker)
|
||||
messageOptionPopup.emojiPicker.closeEmojiPicker()
|
||||
}
|
||||
|
||||
onAddMoreEmoji: {
|
||||
JamiQmlUtils.updateMessageBarButtonsPoints()
|
||||
openEmojiPicker()
|
||||
}
|
||||
|
||||
onRootWidthChanged: {
|
||||
if (emojiPicker)
|
||||
emojiPicker.x = setXposition(JamiTheme.emojiPickerWidth)
|
||||
messageOptionPopup.x = setXposition(width)
|
||||
messageOptionPopup.y = setYposition(height)
|
||||
}
|
||||
|
||||
Connections {
|
||||
target: messageOptionPopup.emojiPicker ? messageOptionPopup.emojiPicker : null
|
||||
function onEmojiIsPicked(content) {
|
||||
if (messageOptionPopup.emojiReplied.includes(content))
|
||||
MessagesAdapter.removeEmojiReaction(CurrentConversation.id,content,messageOptionPopup.msgId)
|
||||
else
|
||||
MessagesAdapter.addEmojiReaction(CurrentConversation.id,content,messageOptionPopup.msgId)
|
||||
}
|
||||
}
|
||||
|
||||
function openEmojiPicker() {
|
||||
var component = WITH_WEBENGINE
|
||||
? Qt.createComponent("qrc:/webengine/emojipicker/EmojiPicker.qml")
|
||||
: Qt.createComponent("qrc:/nowebengine/EmojiPicker.qml")
|
||||
messageOptionPopup.emojiPicker = component.createObject(msgRowlayout,
|
||||
{
|
||||
x: setXposition(JamiTheme.emojiPickerWidth),
|
||||
y: setYposition(JamiTheme.emojiPickerHeight)
|
||||
});
|
||||
if (messageOptionPopup.emojiPicker !== null) {
|
||||
messageOptionPopup.emojiPicker.open()
|
||||
} else {
|
||||
console.log("Error creating emojiPicker in SBSMessageBase");
|
||||
}
|
||||
}
|
||||
|
||||
function setXposition(width) {
|
||||
|
||||
var distBorders = root.width - bubble.width - width
|
||||
if (isOutgoing) {
|
||||
if (distBorders > 0)
|
||||
x = bubble.x - width
|
||||
else
|
||||
x = bubble.x
|
||||
} else {
|
||||
if (distBorders > 0)
|
||||
x = bubble.x + bubble.width
|
||||
else
|
||||
x = bubble.x + bubble.width - width
|
||||
}
|
||||
return x
|
||||
}
|
||||
|
||||
function setYposition(height) {
|
||||
var bottomOffset = 0
|
||||
if (JamiQmlUtils.messageBarButtonsRowObj) {
|
||||
bottomOffset = JamiQmlUtils.messageBarButtonsRowObj.height
|
||||
}
|
||||
var mappedCoord = bubble.mapToItem(appWindow.contentItem, 0, 0)
|
||||
var distBottomScreen = appWindow.height - mappedCoord.y - height - bottomOffset
|
||||
if (distBottomScreen < 0) {
|
||||
return distBottomScreen
|
||||
}
|
||||
var topOffset = 0
|
||||
if (JamiQmlUtils.messagingHeaderRectRowLayout) {
|
||||
topOffset = JamiQmlUtils.messagingHeaderRectRowLayout.height
|
||||
}
|
||||
var distTopScreen = mappedCoord.y - topOffset
|
||||
if (distTopScreen < 0)
|
||||
return -distTopScreen
|
||||
return 0
|
||||
}
|
||||
}
|
||||
|
||||
MessageBubble {
|
||||
id: bubble
|
||||
|
||||
|
@ -321,7 +239,8 @@ Control {
|
|||
function getBaseColor() {
|
||||
var baseColor = isOutgoing ? JamiTheme.messageOutBgColor
|
||||
: CurrentConversation.isCoreDialog ?
|
||||
JamiTheme.messageInBgColor : Qt.lighter(CurrentConversation.color, 1.5)
|
||||
JamiTheme.messageInBgColor :
|
||||
Qt.lighter(CurrentConversation.color, 1.5)
|
||||
if (Id === MessagesAdapter.replyToId || Id === MessagesAdapter.editId) {
|
||||
// If we are replying to or editing the message
|
||||
return Qt.darker(baseColor, 1.5)
|
||||
|
|
|
@ -38,10 +38,6 @@ Item {
|
|||
Object.assign(JamiQmlUtils.accountCreationInputParaObject, inputPara)
|
||||
return accountCreationInputParaObject
|
||||
}
|
||||
//to know if the chatview is being scrolled
|
||||
property bool isChatviewScrolling
|
||||
//chatviewHeader
|
||||
property var messagingHeaderRectRowLayout
|
||||
|
||||
// MessageBar buttons in mainview points
|
||||
property var mainViewRectObj
|
||||
|
|
|
@ -150,7 +150,11 @@ Rectangle {
|
|||
? Qt.createComponent("qrc:/webengine/emojipicker/EmojiPicker.qml")
|
||||
: Qt.createComponent("qrc:/nowebengine/EmojiPicker.qml")
|
||||
messageBar.emojiPicker =
|
||||
component.createObject(messageBar, {x: setXposition(), y: setYposition()});
|
||||
component.createObject(messageBar, {
|
||||
x: setXposition(),
|
||||
y: setYposition(),
|
||||
listView: null
|
||||
});
|
||||
if (messageBar.emojiPicker === null) {
|
||||
console.log("Error creating emojiPicker in chatViewFooter");
|
||||
}
|
||||
|
|
|
@ -260,7 +260,6 @@ Rectangle {
|
|||
}
|
||||
|
||||
}
|
||||
Component.onCompleted: JamiQmlUtils.messagingHeaderRectRowLayout = messagingHeaderRectRowLayout
|
||||
}
|
||||
|
||||
CustomBorder {
|
||||
|
|
|
@ -21,6 +21,8 @@ import QtQuick
|
|||
Rectangle {
|
||||
id: root
|
||||
|
||||
required property ListView listView
|
||||
|
||||
signal emojiIsPicked(string content)
|
||||
function openEmojiPicker() {}
|
||||
function closeEmojiPicker() {}
|
||||
|
|
|
@ -23,6 +23,7 @@ import Qt5Compat.GraphicalEffects
|
|||
import QtWebEngine
|
||||
import QtWebChannel
|
||||
|
||||
import net.jami.Models 1.1
|
||||
import net.jami.Constants 1.1
|
||||
import net.jami.Adapters 1.1
|
||||
|
||||
|
@ -31,8 +32,17 @@ import "../"
|
|||
Popup {
|
||||
id: root
|
||||
|
||||
required property ListView listView
|
||||
|
||||
signal emojiIsPicked(string content)
|
||||
|
||||
// Close the picker when attached to a listView that receives height/scroll
|
||||
// property changes.
|
||||
property real listViewHeight: listView ? listView.height : 0
|
||||
onListViewHeightChanged: close()
|
||||
property bool isScrolling: listView ? listView.verticalScrollBar.active : false
|
||||
onIsScrollingChanged: close()
|
||||
|
||||
function openEmojiPicker() {
|
||||
root.open()
|
||||
emojiPickerWebView.runJavaScript(
|
||||
|
|
Loading…
Add table
Reference in a new issue