mirror of
https://git.jami.net/savoirfairelinux/jami-client-qt.git
synced 2025-09-02 13:13:39 +02:00
Feature: search messages
Change-Id: Ia458e2e6ee183cad9d0418af0dbbbcd990f14281 GitLab: #918
This commit is contained in:
parent
c2d81149be
commit
06ab19f213
16 changed files with 710 additions and 161 deletions
1
resources/icons/search.svg
Normal file
1
resources/icons/search.svg
Normal file
|
@ -0,0 +1 @@
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" height="48" width="48"><path d="M39.8 41.95 26.65 28.8q-1.5 1.3-3.5 2.025-2 .725-4.25.725-5.4 0-9.15-3.75T6 18.75q0-5.3 3.75-9.05 3.75-3.75 9.1-3.75 5.3 0 9.025 3.75 3.725 3.75 3.725 9.05 0 2.15-.7 4.15-.7 2-2.1 3.75L42 39.75Zm-20.95-13.4q4.05 0 6.9-2.875Q28.6 22.8 28.6 18.75t-2.85-6.925Q22.9 8.95 18.85 8.95q-4.1 0-6.975 2.875T9 18.75q0 4.05 2.875 6.925t6.975 2.875Z"/></svg>
|
After Width: | Height: | Size: 417 B |
|
@ -354,6 +354,12 @@ Item {
|
||||||
property string noNetworkConnectivity: qsTr("No network connectivity")
|
property string noNetworkConnectivity: qsTr("No network connectivity")
|
||||||
property string deletedMessage: qsTr("Deleted message")
|
property string deletedMessage: qsTr("Deleted message")
|
||||||
|
|
||||||
|
//MessagesResearch
|
||||||
|
property string jumpTo: qsTr("Jump to")
|
||||||
|
property string messages: qsTr("Messages")
|
||||||
|
property string files: qsTr("Files")
|
||||||
|
property string search: qsTr("Search")
|
||||||
|
|
||||||
// Chatview footer
|
// Chatview footer
|
||||||
property string jumpToLatest: qsTr("Jump to latest")
|
property string jumpToLatest: qsTr("Jump to latest")
|
||||||
property string typeIndicatorSingle: qsTr("{} is typing…")
|
property string typeIndicatorSingle: qsTr("{} is typing…")
|
||||||
|
|
|
@ -376,7 +376,7 @@ Item {
|
||||||
property real swarmDetailsPageDocumentsMargins: 5
|
property real swarmDetailsPageDocumentsMargins: 5
|
||||||
property real swarmDetailsPageDocumentsMediaRadius: 15
|
property real swarmDetailsPageDocumentsMediaRadius: 15
|
||||||
property real swarmDetailsPageDocumentsPaperClipSize: 24
|
property real swarmDetailsPageDocumentsPaperClipSize: 24
|
||||||
property real swarmDetailsPageDocumentsMediaSize: 175
|
property real swarmDetailsPageDocumentsMediaSize: 150
|
||||||
|
|
||||||
//Call information
|
//Call information
|
||||||
property real textFontPointSize: calcSize(10)
|
property real textFontPointSize: calcSize(10)
|
||||||
|
@ -401,6 +401,11 @@ Item {
|
||||||
// Modal Popup
|
// Modal Popup
|
||||||
property real modalPopupRadius: 20
|
property real modalPopupRadius: 20
|
||||||
|
|
||||||
|
//MessagesResearch
|
||||||
|
property color blueLinkColor: darkTheme ? "#3366BB" : "#0645AD"
|
||||||
|
property real jumpToFontSize: calcSize(13)
|
||||||
|
property real searchbarSize: 200
|
||||||
|
|
||||||
// MessageWebView
|
// MessageWebView
|
||||||
property real chatViewHairLineSize: 1
|
property real chatViewHairLineSize: 1
|
||||||
property real chatViewMaximumWidth: 900
|
property real chatViewMaximumWidth: 900
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2020-2023 Savoir-faire Linux Inc.
|
* Copyright (C) 2020-2022 Savoir-faire Linux Inc.
|
||||||
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
* Author: Mingrui Zhang <mingrui.zhang@savoirfairelinux.com>
|
||||||
* Author: Trevor Tabah <trevor.tabah@savoirfairelinux.com>
|
* Author: Trevor Tabah <trevor.tabah@savoirfairelinux.com>
|
||||||
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
|
* Author: Andreas Traczyk <andreas.traczyk@savoirfairelinux.com>
|
||||||
|
@ -102,30 +102,53 @@ Rectangle {
|
||||||
|
|
||||||
onBackClicked: root.dismiss()
|
onBackClicked: root.dismiss()
|
||||||
|
|
||||||
onShowDetailsClicked: {
|
signal panelsVisibilityChange()
|
||||||
addMemberPanel.visible = false
|
|
||||||
if (swarmDetailsPanel.visible) {
|
onPanelsVisibilityChange: {
|
||||||
|
if (!swarmDetailsPanel.visible && !messagesResearchPanel.visible) {
|
||||||
chatContents.visible = true
|
chatContents.visible = true
|
||||||
} else {
|
} else {
|
||||||
if (chatViewHeader.width - JamiTheme.detailsPageMinWidth < JamiTheme.chatViewHeaderMinimumWidth)
|
if (chatViewHeader.width - JamiTheme.detailsPageMinWidth < JamiTheme.chatViewHeaderMinimumWidth)
|
||||||
chatContents.visible = false
|
chatContents.visible = false
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onShowDetailsClicked: {
|
||||||
|
addMemberPanel.visible = false
|
||||||
|
messagesResearchPanel.visible = false
|
||||||
swarmDetailsPanel.visible = !swarmDetailsPanel.visible
|
swarmDetailsPanel.visible = !swarmDetailsPanel.visible
|
||||||
|
panelsVisibilityChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
onSearchBarOpened: {
|
||||||
|
addMemberPanel.visible = false
|
||||||
|
swarmDetailsPanel.visible = false
|
||||||
|
messagesResearchPanel.visible = true
|
||||||
|
panelsVisibilityChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
onSearchBarClosed: {
|
||||||
|
chatContents.visible = true
|
||||||
|
messagesResearchPanel.visible = false
|
||||||
|
panelsVisibilityChange()
|
||||||
}
|
}
|
||||||
|
|
||||||
onWidthChanged: {
|
onWidthChanged: {
|
||||||
const isExpanding = previousWidth < width
|
const isExpanding = previousWidth < width
|
||||||
if (!swarmDetailsPanel.visible && !addMemberPanel.visible)
|
|
||||||
|
if (!swarmDetailsPanel.visible && !addMemberPanel.visible && !messagesResearchPanel.visible)
|
||||||
return
|
return
|
||||||
if (chatViewHeader.width < JamiTheme.detailsPageMinWidth + JamiTheme.chatViewHeaderMinimumWidth
|
if (chatViewHeader.width < JamiTheme.detailsPageMinWidth + JamiTheme.chatViewHeaderMinimumWidth
|
||||||
&& !isExpanding && chatContents.visible) {
|
&& !isExpanding && chatContents.visible) {
|
||||||
lastContentsSplitSize = chatContents.width
|
lastContentsSplitSize = chatContents.width
|
||||||
lastDetailsSplitSize = Math.min(JamiTheme.detailsPageMinWidth, (swarmDetailsPanel.visible ?
|
lastDetailsSplitSize = Math.min(JamiTheme.detailsPageMinWidth, (swarmDetailsPanel.visible
|
||||||
swarmDetailsPanel.width :
|
? swarmDetailsPanel.width
|
||||||
addMemberPanel.width))
|
: addMemberPanel.visible
|
||||||
|
? addMemberPanel.width
|
||||||
|
: messagesResearchPanel.width))
|
||||||
chatContents.visible = false
|
chatContents.visible = false
|
||||||
} else if (chatViewHeader.width >= JamiTheme.chatViewHeaderMinimumWidth + lastDetailsSplitSize
|
} else if (chatViewHeader.width >= JamiTheme.chatViewHeaderMinimumWidth + lastDetailsSplitSize
|
||||||
&& isExpanding && !layoutManager.isFullScreen && !chatContents.visible) {
|
&& isExpanding && !layoutManager.isFullScreen && !chatContents.visible) {
|
||||||
chatContents.visible = true
|
chatContents.visible = true
|
||||||
}
|
}
|
||||||
previousWidth = width
|
previousWidth = width
|
||||||
|
@ -244,10 +267,7 @@ Rectangle {
|
||||||
id: chatContents
|
id: chatContents
|
||||||
SplitView.maximumWidth: viewCoordinator.splitView.width
|
SplitView.maximumWidth: viewCoordinator.splitView.width
|
||||||
SplitView.minimumWidth: JamiTheme.chatViewHeaderMinimumWidth
|
SplitView.minimumWidth: JamiTheme.chatViewHeaderMinimumWidth
|
||||||
|
SplitView.fillWidth: true
|
||||||
SplitView.preferredWidth: chatViewHeader.width -
|
|
||||||
(swarmDetailsPanel.visible ? swarmDetailsPanel.width :
|
|
||||||
( addMemberPanel.visible ? addMemberPanel.width : 0))
|
|
||||||
|
|
||||||
StackLayout {
|
StackLayout {
|
||||||
id: chatViewStack
|
id: chatViewStack
|
||||||
|
@ -315,6 +335,15 @@ Rectangle {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MessagesResearchPanel {
|
||||||
|
id: messagesResearchPanel
|
||||||
|
|
||||||
|
visible: false
|
||||||
|
SplitView.maximumWidth: viewCoordinator.splitView.width
|
||||||
|
SplitView.minimumWidth: JamiTheme.detailsPageMinWidth
|
||||||
|
SplitView.preferredWidth: JamiTheme.detailsPageMinWidth
|
||||||
|
}
|
||||||
|
|
||||||
SwarmDetailsPanel {
|
SwarmDetailsPanel {
|
||||||
id: swarmDetailsPanel
|
id: swarmDetailsPanel
|
||||||
visible: false
|
visible: false
|
||||||
|
|
|
@ -19,6 +19,7 @@
|
||||||
|
|
||||||
import QtQuick
|
import QtQuick
|
||||||
import QtQuick.Layouts
|
import QtQuick.Layouts
|
||||||
|
import QtQuick.Controls
|
||||||
|
|
||||||
import net.jami.Adapters 1.1
|
import net.jami.Adapters 1.1
|
||||||
import net.jami.Constants 1.1
|
import net.jami.Constants 1.1
|
||||||
|
@ -34,6 +35,8 @@ Rectangle {
|
||||||
signal addToConversationClicked
|
signal addToConversationClicked
|
||||||
signal pluginSelector
|
signal pluginSelector
|
||||||
signal showDetailsClicked
|
signal showDetailsClicked
|
||||||
|
signal searchBarOpened
|
||||||
|
signal searchBarClosed
|
||||||
|
|
||||||
Connections {
|
Connections {
|
||||||
target: CurrentConversation
|
target: CurrentConversation
|
||||||
|
@ -145,98 +148,117 @@ Rectangle {
|
||||||
RowLayout {
|
RowLayout {
|
||||||
id: buttonGroup
|
id: buttonGroup
|
||||||
|
|
||||||
|
property int buttonGroupMargin: 8
|
||||||
|
|
||||||
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
Layout.fillWidth: true
|
Layout.rightMargin: buttonGroupMargin
|
||||||
Layout.rightMargin: 8
|
|
||||||
spacing: 16
|
spacing: 16
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
PushButton {
|
Searchbar {
|
||||||
id: startAAudioCallButton
|
id: rowSearchBar
|
||||||
|
|
||||||
visible: interactionButtonsVisibility && (!addMemberVisibility || UtilsAdapter.getAppValue(Settings.EnableExperimentalSwarm))
|
spacing: buttonGroup.spacing
|
||||||
|
visible: CurrentConversation.isSwarm
|
||||||
source: JamiResources.place_audiocall_24dp_svg
|
|
||||||
toolTipText: JamiStrings.placeAudioCall
|
|
||||||
|
|
||||||
normalColor: JamiTheme.chatviewBgColor
|
|
||||||
imageColor: JamiTheme.chatviewButtonColor
|
|
||||||
|
|
||||||
onClicked: CallAdapter.placeAudioOnlyCall()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
PushButton {
|
RowLayout {
|
||||||
id: startAVideoCallButton
|
id: pushbuttons
|
||||||
|
|
||||||
visible: CurrentAccount.videoEnabled_Video && interactionButtonsVisibility && (!addMemberVisibility || UtilsAdapter.getAppValue(Settings.EnableExperimentalSwarm))
|
Layout.alignment: Qt.AlignRight | Qt.AlignVCenter
|
||||||
source: JamiResources.videocam_24dp_svg
|
Layout.rightMargin: 8
|
||||||
toolTipText: JamiStrings.placeVideoCall
|
spacing: 16
|
||||||
|
Layout.fillWidth: true
|
||||||
|
|
||||||
normalColor: JamiTheme.chatviewBgColor
|
PushButton {
|
||||||
imageColor: JamiTheme.chatviewButtonColor
|
id: startAAudioCallButton
|
||||||
|
|
||||||
onClicked: {
|
visible: interactionButtonsVisibility && (!addMemberVisibility || UtilsAdapter.getAppValue(Settings.EnableExperimentalSwarm))
|
||||||
CallAdapter.placeCall()
|
|
||||||
|
source: JamiResources.place_audiocall_24dp_svg
|
||||||
|
toolTipText: JamiStrings.placeAudioCall
|
||||||
|
|
||||||
|
normalColor: JamiTheme.chatviewBgColor
|
||||||
|
imageColor: JamiTheme.chatviewButtonColor
|
||||||
|
|
||||||
|
onClicked: CallAdapter.placeAudioOnlyCall()
|
||||||
|
}
|
||||||
|
|
||||||
|
PushButton {
|
||||||
|
id: startAVideoCallButton
|
||||||
|
|
||||||
|
visible: CurrentAccount.videoEnabled_Video && interactionButtonsVisibility && (!addMemberVisibility || UtilsAdapter.getAppValue(Settings.EnableExperimentalSwarm))
|
||||||
|
source: JamiResources.videocam_24dp_svg
|
||||||
|
toolTipText: JamiStrings.placeVideoCall
|
||||||
|
|
||||||
|
normalColor: JamiTheme.chatviewBgColor
|
||||||
|
imageColor: JamiTheme.chatviewButtonColor
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
CallAdapter.placeCall()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PushButton {
|
||||||
|
id: addParticipantsButton
|
||||||
|
|
||||||
|
source: JamiResources.add_people_24dp_svg
|
||||||
|
toolTipText: JamiStrings.addParticipants
|
||||||
|
|
||||||
|
normalColor: JamiTheme.chatviewBgColor
|
||||||
|
imageColor: JamiTheme.chatviewButtonColor
|
||||||
|
|
||||||
|
visible: CurrentConversation.uris.length < 8 && addMemberVisibility
|
||||||
|
|
||||||
|
onClicked: addToConversationClicked()
|
||||||
|
}
|
||||||
|
|
||||||
|
PushButton {
|
||||||
|
id: selectPluginButton
|
||||||
|
|
||||||
|
visible: PluginAdapter.isEnabled && PluginAdapter.chatHandlersListCount &&
|
||||||
|
interactionButtonsVisibility
|
||||||
|
|
||||||
|
source: JamiResources.plugins_24dp_svg
|
||||||
|
toolTipText: JamiStrings.showPlugins
|
||||||
|
|
||||||
|
normalColor: JamiTheme.chatviewBgColor
|
||||||
|
imageColor: JamiTheme.chatviewButtonColor
|
||||||
|
|
||||||
|
onClicked: pluginSelector()
|
||||||
|
}
|
||||||
|
|
||||||
|
PushButton {
|
||||||
|
id: sendContactRequestButton
|
||||||
|
|
||||||
|
visible: CurrentConversation.isTemporary || CurrentConversation.isBanned
|
||||||
|
|
||||||
|
source: JamiResources.add_people_24dp_svg
|
||||||
|
toolTipText: JamiStrings.addToConversations
|
||||||
|
|
||||||
|
normalColor: JamiTheme.chatviewBgColor
|
||||||
|
imageColor: JamiTheme.chatviewButtonColor
|
||||||
|
|
||||||
|
onClicked: CurrentConversation.isBanned ?
|
||||||
|
MessagesAdapter.unbanConversation(CurrentConversation.id)
|
||||||
|
: MessagesAdapter.sendConversationRequest()
|
||||||
|
}
|
||||||
|
|
||||||
|
PushButton {
|
||||||
|
id: detailsButton
|
||||||
|
|
||||||
|
visible: swarmDetailsVisibility
|
||||||
|
|
||||||
|
source: JamiResources.swarm_details_panel_svg
|
||||||
|
toolTipText: JamiStrings.details
|
||||||
|
|
||||||
|
normalColor: JamiTheme.chatviewBgColor
|
||||||
|
imageColor: JamiTheme.chatviewButtonColor
|
||||||
|
|
||||||
|
onClicked: showDetailsClicked()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PushButton {
|
|
||||||
id: addParticipantsButton
|
|
||||||
|
|
||||||
source: JamiResources.add_people_24dp_svg
|
|
||||||
toolTipText: JamiStrings.addParticipants
|
|
||||||
|
|
||||||
normalColor: JamiTheme.chatviewBgColor
|
|
||||||
imageColor: JamiTheme.chatviewButtonColor
|
|
||||||
|
|
||||||
visible: CurrentConversation.uris.length < 8 && addMemberVisibility
|
|
||||||
|
|
||||||
onClicked: addToConversationClicked()
|
|
||||||
}
|
|
||||||
|
|
||||||
PushButton {
|
|
||||||
id: selectPluginButton
|
|
||||||
|
|
||||||
visible: PluginAdapter.isEnabled && PluginAdapter.chatHandlersListCount &&
|
|
||||||
interactionButtonsVisibility
|
|
||||||
|
|
||||||
source: JamiResources.plugins_24dp_svg
|
|
||||||
toolTipText: JamiStrings.showPlugins
|
|
||||||
|
|
||||||
normalColor: JamiTheme.chatviewBgColor
|
|
||||||
imageColor: JamiTheme.chatviewButtonColor
|
|
||||||
|
|
||||||
onClicked: pluginSelector()
|
|
||||||
}
|
|
||||||
|
|
||||||
PushButton {
|
|
||||||
id: sendContactRequestButton
|
|
||||||
|
|
||||||
visible: CurrentConversation.isTemporary || CurrentConversation.isBanned
|
|
||||||
|
|
||||||
source: JamiResources.add_people_24dp_svg
|
|
||||||
toolTipText: JamiStrings.addToConversations
|
|
||||||
|
|
||||||
normalColor: JamiTheme.chatviewBgColor
|
|
||||||
imageColor: JamiTheme.chatviewButtonColor
|
|
||||||
|
|
||||||
onClicked: CurrentConversation.isBanned ?
|
|
||||||
MessagesAdapter.unbanConversation(CurrentConversation.id)
|
|
||||||
: MessagesAdapter.sendConversationRequest()
|
|
||||||
}
|
|
||||||
|
|
||||||
PushButton {
|
|
||||||
id: detailsButton
|
|
||||||
|
|
||||||
visible: swarmDetailsVisibility
|
|
||||||
|
|
||||||
source: JamiResources.swarm_details_panel_svg
|
|
||||||
toolTipText: JamiStrings.details
|
|
||||||
|
|
||||||
normalColor: JamiTheme.chatviewBgColor
|
|
||||||
imageColor: JamiTheme.chatviewButtonColor
|
|
||||||
|
|
||||||
onClicked: showDetailsClicked()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
Component.onCompleted: JamiQmlUtils.messagingHeaderRectRowLayout = messagingHeaderRectRowLayout
|
Component.onCompleted: JamiQmlUtils.messagingHeaderRectRowLayout = messagingHeaderRectRowLayout
|
||||||
}
|
}
|
||||||
|
|
|
@ -128,7 +128,9 @@ Rectangle {
|
||||||
Shortcut {
|
Shortcut {
|
||||||
sequence: "Ctrl+F"
|
sequence: "Ctrl+F"
|
||||||
context: Qt.ApplicationShortcut
|
context: Qt.ApplicationShortcut
|
||||||
onActivated: contactSearchBar.forceActiveFocus()
|
onActivated: {
|
||||||
|
contactSearchBar.forceActiveFocus()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Keys.onPressed: function (keyEvent) {
|
Keys.onPressed: function (keyEvent) {
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2022-2023 Savoir-faire Linux Inc.
|
* Copyright (C) 2022-2023 Savoir-faire Linux Inc.
|
||||||
|
* Author: Nicolas Vengeon <nicolas.vengeon@savoirfairelinux.com>
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
@ -35,39 +36,46 @@ Flickable {
|
||||||
contentWidth: width
|
contentWidth: width
|
||||||
|
|
||||||
property int spacingFlow: JamiTheme.swarmDetailsPageDocumentsMargins
|
property int spacingFlow: JamiTheme.swarmDetailsPageDocumentsMargins
|
||||||
|
property real flickableWidth: width
|
||||||
property int numberElementsPerRow: {
|
property int numberElementsPerRow: {
|
||||||
var sizeW = flow.width
|
var sizeW = flow.width
|
||||||
var breakSize = JamiTheme.swarmDetailsPageDocumentsMediaSize
|
var breakSize = JamiTheme.swarmDetailsPageDocumentsMediaSize
|
||||||
return Math.floor(sizeW / breakSize)
|
return Math.floor(sizeW / breakSize)
|
||||||
}
|
}
|
||||||
property int spacingLength: spacingFlow * (numberElementsPerRow - 1)
|
property int spacingLength: spacingFlow * (numberElementsPerRow - 1)
|
||||||
|
property color themeColor: CurrentConversation.color
|
||||||
|
property string textFilter: ""
|
||||||
|
|
||||||
onVisibleChanged: {
|
onVisibleChanged: {
|
||||||
if (visible) {
|
if (visible) {
|
||||||
MessagesAdapter.getConvMedias()
|
MessagesAdapter.startSearch(textFilter,true)
|
||||||
} else {
|
|
||||||
MessagesAdapter.mediaMessageListModel = null
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
onTextFilterChanged: {
|
||||||
|
MessagesAdapter.startSearch(textFilter,true)
|
||||||
|
}
|
||||||
|
|
||||||
Flow {
|
Flow {
|
||||||
id: flow
|
id: flow
|
||||||
|
|
||||||
width: parent.width
|
width: parent.width
|
||||||
spacing: spacingFlow
|
spacing: spacingFlow
|
||||||
anchors.horizontalCenter: parent.horizontalCenter
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
|
||||||
Repeater {
|
Repeater {
|
||||||
model: MessagesAdapter.mediaMessageListModel
|
model: root.visible ? MessagesAdapter.mediaMessageListModel : 0
|
||||||
|
|
||||||
delegate: Loader {
|
delegate: Loader {
|
||||||
id: loaderRoot
|
id: loaderRoot
|
||||||
|
|
||||||
sourceComponent: {
|
sourceComponent: {
|
||||||
if(Status === Interaction.Status.TRANSFER_FINISHED || Status === Interaction.Status.SUCCESS ){
|
if (MessagesAdapter.isDocument(Type)) {
|
||||||
if (Object.keys(MessagesAdapter.getMediaInfo(Body)).length !== 0 && WITH_WEBENGINE)
|
if(Status === Interaction.Status.TRANSFER_FINISHED || Status === Interaction.Status.SUCCESS ){
|
||||||
return localMediaMsgComp
|
if (Object.keys(MessagesAdapter.getMediaInfo(Body)).length !== 0 && WITH_WEBENGINE)
|
||||||
|
return localMediaMsgComp
|
||||||
|
|
||||||
return fileMsgComp
|
return fileMsgComp
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -34,7 +34,7 @@ Component {
|
||||||
id: dataTransferRect
|
id: dataTransferRect
|
||||||
|
|
||||||
clip: true
|
clip: true
|
||||||
width: (documents.width - spacingLength ) / numberElementsPerRow
|
width: (contentWidth - spacingLength ) / numberElementsPerRow
|
||||||
height: width
|
height: width
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ Component {
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: JamiTheme.swarmDetailsPageDocumentsMargins
|
anchors.margins: JamiTheme.swarmDetailsPageDocumentsMargins
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
border.color: CurrentConversation.color
|
border.color: themeColor
|
||||||
border.width: 2
|
border.width: 2
|
||||||
radius: JamiTheme.swarmDetailsPageDocumentsMediaRadius
|
radius: JamiTheme.swarmDetailsPageDocumentsMediaRadius
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
|
|
|
@ -33,7 +33,7 @@ Component {
|
||||||
Rectangle {
|
Rectangle {
|
||||||
id: localMediaRect
|
id: localMediaRect
|
||||||
|
|
||||||
width: (documents.width - spacingLength) / numberElementsPerRow
|
width: (flickableWidth - spacingLength) / numberElementsPerRow
|
||||||
height: width
|
height: width
|
||||||
color: "transparent"
|
color: "transparent"
|
||||||
|
|
||||||
|
@ -62,7 +62,7 @@ Component {
|
||||||
|
|
||||||
anchors.fill: parent
|
anchors.fill: parent
|
||||||
anchors.margins: JamiTheme.swarmDetailsPageDocumentsMargins
|
anchors.margins: JamiTheme.swarmDetailsPageDocumentsMargins
|
||||||
color: CurrentConversation.color
|
color: themeColor
|
||||||
layer.enabled: true
|
layer.enabled: true
|
||||||
layer.effect: OpacityMask {
|
layer.effect: OpacityMask {
|
||||||
maskSource: Item {
|
maskSource: Item {
|
||||||
|
|
109
src/app/mainview/components/MessagesResearchPanel.qml
Normal file
109
src/app/mainview/components/MessagesResearchPanel.qml
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Savoir-faire Linux Inc.
|
||||||
|
* Author: Nicolas Vengeon <nicolas.vengeon@savoirfairelinux.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* 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 QtQuick.Layouts
|
||||||
|
import Qt.labs.platform
|
||||||
|
import Qt5Compat.GraphicalEffects
|
||||||
|
|
||||||
|
import net.jami.Models 1.1
|
||||||
|
import net.jami.Adapters 1.1
|
||||||
|
import net.jami.Constants 1.1
|
||||||
|
|
||||||
|
import "../../commoncomponents"
|
||||||
|
import "../../settingsview/components"
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
color: JamiTheme.chatviewBgColor
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
TabBar {
|
||||||
|
id: researchTabBar
|
||||||
|
|
||||||
|
currentIndex: 0
|
||||||
|
Layout.preferredHeight: contentHeight + 10
|
||||||
|
Layout.preferredWidth: root.width
|
||||||
|
background.visible: false
|
||||||
|
signal filterTabChange()
|
||||||
|
onCurrentIndexChanged: {
|
||||||
|
filterTabChange()
|
||||||
|
}
|
||||||
|
|
||||||
|
onVisibleChanged: {
|
||||||
|
researchTabBar.currentIndex = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
FilterTabButton {
|
||||||
|
id: messagesResearchTabButton
|
||||||
|
|
||||||
|
backgroundColor: "transparent"
|
||||||
|
hoverColor: "transparent"
|
||||||
|
borderWidth: 4
|
||||||
|
bottomMargin: JamiTheme.settingsMarginSize
|
||||||
|
fontSize: JamiTheme.menuFontSize
|
||||||
|
underlineContentOnly: true
|
||||||
|
|
||||||
|
down: researchTabBar.currentIndex === 0
|
||||||
|
labelText: JamiStrings.messages
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
|
||||||
|
FilterTabButton {
|
||||||
|
|
||||||
|
id: fileResearchTabButton
|
||||||
|
backgroundColor: "transparent"
|
||||||
|
hoverColor: "transparent"
|
||||||
|
borderWidth: 4
|
||||||
|
bottomMargin: JamiTheme.settingsMarginSize
|
||||||
|
fontSize: JamiTheme.menuFontSize
|
||||||
|
underlineContentOnly: true
|
||||||
|
|
||||||
|
down: researchTabBar.currentIndex === 1
|
||||||
|
labelText: JamiStrings.files
|
||||||
|
Layout.fillWidth: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: view
|
||||||
|
|
||||||
|
color: JamiTheme.chatviewBgColor
|
||||||
|
Layout.fillWidth: true
|
||||||
|
Layout.fillHeight: true
|
||||||
|
|
||||||
|
MessagesResearchView {
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: researchTabBar.currentIndex === 0
|
||||||
|
clip: true
|
||||||
|
}
|
||||||
|
|
||||||
|
DocumentsScrollview {
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: researchTabBar.currentIndex === 1
|
||||||
|
clip: true
|
||||||
|
themeColor: JamiTheme.chatviewTextColor
|
||||||
|
textFilter: MessagesAdapter.searchbarPrompt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
163
src/app/mainview/components/MessagesResearchView.qml
Normal file
163
src/app/mainview/components/MessagesResearchView.qml
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Savoir-faire Linux Inc.
|
||||||
|
* Author: Nicolas Vengeon <nicolas.vengeon@savoirfairelinux.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* 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 QtQuick.Layouts
|
||||||
|
import Qt.labs.platform
|
||||||
|
import Qt5Compat.GraphicalEffects
|
||||||
|
import SortFilterProxyModel
|
||||||
|
|
||||||
|
import net.jami.Models 1.1
|
||||||
|
import net.jami.Adapters 1.1
|
||||||
|
import net.jami.Constants 1.1
|
||||||
|
|
||||||
|
import "../../commoncomponents"
|
||||||
|
import "../../settingsview/components"
|
||||||
|
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
spacing: 10
|
||||||
|
model: SortFilterProxyModel {
|
||||||
|
id: proxyModel
|
||||||
|
|
||||||
|
property var messageListModel: MessagesAdapter.mediaMessageListModel
|
||||||
|
readonly property int textType: Interaction.Type.TEXT
|
||||||
|
|
||||||
|
onMessageListModelChanged: sourceModel = root.visible ? messageListModel : null
|
||||||
|
|
||||||
|
filters: ExpressionFilter {
|
||||||
|
expression: Type === proxyModel.textType
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
property var prompt: MessagesAdapter.searchbarPrompt
|
||||||
|
|
||||||
|
onPromptChanged: {
|
||||||
|
MessagesAdapter.startSearch(prompt)
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: researchTabBar
|
||||||
|
function onFilterTabChange() {
|
||||||
|
MessagesAdapter.startSearch(prompt)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
delegate: Item {
|
||||||
|
width: root.width
|
||||||
|
height: msgLayout.height
|
||||||
|
|
||||||
|
HoverHandler {
|
||||||
|
id: msgHover
|
||||||
|
|
||||||
|
target: parent
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
id: msgLayout
|
||||||
|
|
||||||
|
width: root.width
|
||||||
|
|
||||||
|
TimestampInfo {
|
||||||
|
id: timestampItem
|
||||||
|
|
||||||
|
showDay: true
|
||||||
|
showTime: true
|
||||||
|
formattedTime: MessagesAdapter.getFormattedTime(Timestamp)
|
||||||
|
formattedDay: MessagesAdapter.getFormattedDay(Timestamp)
|
||||||
|
}
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: contentRow
|
||||||
|
|
||||||
|
property bool isMe: Author === CurrentAccount.uri
|
||||||
|
|
||||||
|
Avatar {
|
||||||
|
id: avatar
|
||||||
|
|
||||||
|
width: 30
|
||||||
|
height: 30
|
||||||
|
imageId: contentRow.isMe ? CurrentAccount.id : Author
|
||||||
|
showPresenceIndicator: false
|
||||||
|
mode: contentRow.isMe ? Avatar.Mode.Account : Avatar.Mode.Contact
|
||||||
|
Layout.leftMargin: 10
|
||||||
|
}
|
||||||
|
|
||||||
|
ColumnLayout {
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: contentRow.isMe
|
||||||
|
? CurrentAccount.bestName
|
||||||
|
: UtilsAdapter.getBestNameForUri(CurrentAccount.id, Author) + " :"
|
||||||
|
Layout.preferredWidth: myText.width
|
||||||
|
Layout.rightMargin: 10
|
||||||
|
Layout.leftMargin: 10
|
||||||
|
font.pixelSize: 0
|
||||||
|
color: JamiTheme.chatviewUsernameColor
|
||||||
|
font.bold: true
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: myText
|
||||||
|
|
||||||
|
text: Body
|
||||||
|
color: JamiTheme.textColor
|
||||||
|
Layout.preferredWidth: msgLayout.width - avatar.width - 30 - 10
|
||||||
|
elide: Text.ElideRight
|
||||||
|
Layout.rightMargin: 10
|
||||||
|
Layout.leftMargin: 10
|
||||||
|
font.pixelSize: IsEmojiOnly? JamiTheme.chatviewEmojiSize : JamiTheme.chatviewFontSize
|
||||||
|
Layout.alignment:Qt.AlignHCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
id: buttonJumpTo
|
||||||
|
|
||||||
|
visible: msgHover.hovered || hovered
|
||||||
|
anchors.top: msgLayout.top
|
||||||
|
anchors.right: msgLayout.right
|
||||||
|
anchors.rightMargin: 20
|
||||||
|
anchors.topMargin: timestampItem.height - 20
|
||||||
|
width: buttonJumpText.width + 10
|
||||||
|
height: buttonJumpText.height + 10
|
||||||
|
background.visible: false
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
CurrentConversation.scrollToMsg(Id)
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: buttonJumpText
|
||||||
|
|
||||||
|
text: JamiStrings.jumpTo
|
||||||
|
color: buttonJumpTo.hovered ? JamiTheme.blueLinkColor : JamiTheme.chatviewUsernameColor
|
||||||
|
font.underline: buttonJumpTo.hovered
|
||||||
|
anchors.centerIn: parent
|
||||||
|
font.pointSize: JamiTheme.jumpToFontSize
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
182
src/app/mainview/components/Searchbar.qml
Normal file
182
src/app/mainview/components/Searchbar.qml
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
/*
|
||||||
|
* Copyright (C) 2023 Savoir-faire Linux Inc.
|
||||||
|
* Author: Nicolas Vengeon <nicolas.vengeon@savoirfairelinux.com>
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 3 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* 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.Layouts
|
||||||
|
import QtQuick.Controls
|
||||||
|
|
||||||
|
import net.jami.Adapters 1.1
|
||||||
|
import net.jami.Constants 1.1
|
||||||
|
|
||||||
|
import "../../commoncomponents"
|
||||||
|
|
||||||
|
RowLayout {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property real messagesResearchPanel: JamiTheme.detailsPageMinWidth
|
||||||
|
|
||||||
|
//TO DO: find a design to set dynamically the size of the searchbar
|
||||||
|
property real searchBarWidth: JamiTheme.searchbarSize
|
||||||
|
|
||||||
|
property string currentConversationId: CurrentConversation.id
|
||||||
|
property bool isOpened: false
|
||||||
|
|
||||||
|
function openSearchBar() {
|
||||||
|
searchBarOpened()
|
||||||
|
rectTextArea.isSearch = true
|
||||||
|
anim.start()
|
||||||
|
textArea.forceActiveFocus()
|
||||||
|
isOpened = true
|
||||||
|
}
|
||||||
|
|
||||||
|
function closeSearchbar() {
|
||||||
|
searchBarClosed()
|
||||||
|
rectTextArea.isSearch = false
|
||||||
|
anim.start()
|
||||||
|
isOpened = false
|
||||||
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: chatViewHeader
|
||||||
|
function onShowDetailsClicked() {
|
||||||
|
if (rectTextArea.isSearch)
|
||||||
|
closeSearchbar()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onCurrentConversationIdChanged: {
|
||||||
|
if (isOpened)
|
||||||
|
closeSearchbar()
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
PushButton {
|
||||||
|
id: startSearchMessages
|
||||||
|
|
||||||
|
source: JamiResources.search_svg
|
||||||
|
normalColor: JamiTheme.chatviewBgColor
|
||||||
|
imageColor: JamiTheme.chatviewButtonColor
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (rectTextArea.isSearch)
|
||||||
|
closeSearchbar()
|
||||||
|
else
|
||||||
|
openSearchBar()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
SequentialAnimation {
|
||||||
|
id: anim
|
||||||
|
|
||||||
|
PropertyAnimation {
|
||||||
|
target: rectTextArea; properties: "visible"
|
||||||
|
to: true
|
||||||
|
duration: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
ParallelAnimation {
|
||||||
|
|
||||||
|
NumberAnimation {
|
||||||
|
target: rectTextArea; properties: "opacity"
|
||||||
|
from: rectTextArea.isSearch ? 0 : 1
|
||||||
|
to: rectTextArea.isSearch ? 1 : 0
|
||||||
|
duration: 150
|
||||||
|
}
|
||||||
|
|
||||||
|
NumberAnimation {
|
||||||
|
target: rectTextArea; properties: "Layout.preferredWidth"
|
||||||
|
from: rectTextArea.isSearch ? 0 : root.searchBarWidth
|
||||||
|
to: rectTextArea.isSearch ? root.searchBarWidth : 0
|
||||||
|
duration: 150
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PropertyAnimation {
|
||||||
|
target: rectTextArea; properties: "visible"
|
||||||
|
to: rectTextArea.isSearch
|
||||||
|
duration: 0
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
Rectangle {
|
||||||
|
id: rectTextArea
|
||||||
|
|
||||||
|
visible: false
|
||||||
|
Layout.preferredHeight: startSearchMessages.height
|
||||||
|
Layout.alignment: Qt.AlignVCenter
|
||||||
|
color: "transparent"
|
||||||
|
border.color: JamiTheme.chatviewTextColor
|
||||||
|
radius: 10
|
||||||
|
border.width: 2
|
||||||
|
|
||||||
|
property bool isSearch: false
|
||||||
|
property int textAreaWidth: 200
|
||||||
|
property alias searchBarWidth: root.searchBarWidth
|
||||||
|
|
||||||
|
onSearchBarWidthChanged: {
|
||||||
|
Layout.preferredWidth = root.searchBarWidth
|
||||||
|
}
|
||||||
|
|
||||||
|
TextField {
|
||||||
|
id: textArea
|
||||||
|
|
||||||
|
background.visible: false
|
||||||
|
anchors.right: clearTextButton.left
|
||||||
|
anchors.left: rectTextArea.left
|
||||||
|
color: JamiTheme.chatviewTextColor
|
||||||
|
placeholderText: JamiStrings.search
|
||||||
|
placeholderTextColor: JamiTheme.chatviewTextColor
|
||||||
|
|
||||||
|
onTextChanged: {
|
||||||
|
MessagesAdapter.searchbarPrompt = text
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
PushButton {
|
||||||
|
id: clearTextButton
|
||||||
|
|
||||||
|
anchors.verticalCenter: rectTextArea.verticalCenter
|
||||||
|
anchors.right: rectTextArea.right
|
||||||
|
anchors.margins: 5
|
||||||
|
preferredSize: 21
|
||||||
|
|
||||||
|
radius: rectTextArea.radius
|
||||||
|
visible: textArea.text.length
|
||||||
|
opacity: visible ? 1 : 0
|
||||||
|
normalColor: "transparent"
|
||||||
|
imageColor: JamiTheme.chatviewButtonColor
|
||||||
|
source: JamiResources.ic_clear_24dp_svg
|
||||||
|
toolTipText: JamiStrings.clearText
|
||||||
|
|
||||||
|
property string convId: CurrentConversation.id
|
||||||
|
onConvIdChanged: {
|
||||||
|
textArea.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
textArea.clear()
|
||||||
|
textArea.forceActiveFocus()
|
||||||
|
}
|
||||||
|
|
||||||
|
Behavior on opacity {
|
||||||
|
NumberAnimation { duration: 500; easing.type: Easing.OutCubic }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -67,6 +67,8 @@ MessagesAdapter::MessagesAdapter(AppSettingsManager* settingsManager,
|
||||||
filteredMsgListModel_->setSourceModel(conversation.interactions.get());
|
filteredMsgListModel_->setSourceModel(conversation.interactions.get());
|
||||||
|
|
||||||
set_currentConvComposingList(conversationTypersUrlToName(conversation.typers));
|
set_currentConvComposingList(conversationTypersUrlToName(conversation.typers));
|
||||||
|
mediaInteractions_.reset(new MessageListModel(this));
|
||||||
|
set_mediaMessageListModel(QVariant::fromValue(mediaInteractions_.get()));
|
||||||
});
|
});
|
||||||
|
|
||||||
connect(previewEngine_, &PreviewEngine::infoReady, this, &MessagesAdapter::onPreviewInfoReady);
|
connect(previewEngine_, &PreviewEngine::infoReady, this, &MessagesAdapter::onPreviewInfoReady);
|
||||||
|
@ -82,6 +84,12 @@ MessagesAdapter::MessagesAdapter(AppSettingsManager* settingsManager,
|
||||||
connectConversationModel();
|
connectConversationModel();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
MessagesAdapter::isDocument(const interaction::Type& type)
|
||||||
|
{
|
||||||
|
return interaction::Type::DATA_TRANSFER == type;
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MessagesAdapter::loadMoreMessages()
|
MessagesAdapter::loadMoreMessages()
|
||||||
{
|
{
|
||||||
|
@ -575,25 +583,16 @@ MessagesAdapter::onComposingStatusChanged(const QString& convId,
|
||||||
|
|
||||||
void
|
void
|
||||||
MessagesAdapter::onMessagesFoundProcessed(const QString& accountId,
|
MessagesAdapter::onMessagesFoundProcessed(const QString& accountId,
|
||||||
const VectorMapStringString& messageIds,
|
const QMap<QString, interaction::Info>& messageInformation)
|
||||||
const QVector<interaction::Info>& messageInformations)
|
|
||||||
{
|
{
|
||||||
if (lrcInstance_->get_currentAccountId() != accountId) {
|
if (lrcInstance_->get_currentAccountId() != accountId) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
bool isSearchInProgress = messageIds.length();
|
|
||||||
|
bool isSearchInProgress = messageInformation.size();
|
||||||
if (isSearchInProgress) {
|
if (isSearchInProgress) {
|
||||||
int index = -1;
|
for (auto it = messageInformation.begin(); it != messageInformation.end(); it++) {
|
||||||
Q_FOREACH (const MapStringString& msg, messageIds) {
|
mediaInteractions_->insert(qMakePair(it.key(), it.value()));
|
||||||
index++;
|
|
||||||
try {
|
|
||||||
std::pair<QString, interaction::Info> message(msg["id"],
|
|
||||||
messageInformations.at(index));
|
|
||||||
mediaInteractions_->insert(message);
|
|
||||||
} catch (...) {
|
|
||||||
qWarning() << "error in onMessagesFoundProcessed, message insertion on index: "
|
|
||||||
<< index;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
set_mediaMessageListModel(QVariant::fromValue(mediaInteractions_.get()));
|
set_mediaMessageListModel(QVariant::fromValue(mediaInteractions_.get()));
|
||||||
|
@ -729,17 +728,24 @@ MessagesAdapter::getFormattedDay(const quint64 timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MessagesAdapter::getConvMedias()
|
MessagesAdapter::startSearch(QString& text, bool isMedia)
|
||||||
{
|
{
|
||||||
|
mediaInteractions_.reset(new MessageListModel(this));
|
||||||
|
set_mediaMessageListModel(QVariant::fromValue(mediaInteractions_.get()));
|
||||||
|
|
||||||
|
if (text.isEmpty() && !isMedia)
|
||||||
|
return;
|
||||||
|
|
||||||
auto accountId = lrcInstance_->get_currentAccountId();
|
auto accountId = lrcInstance_->get_currentAccountId();
|
||||||
auto convId = lrcInstance_->get_selectedConvUid();
|
auto convId = lrcInstance_->get_selectedConvUid();
|
||||||
|
|
||||||
mediaInteractions_.reset(new MessageListModel(this));
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
lrcInstance_->getCurrentConversationModel()->getConvMediasInfos(accountId, convId);
|
lrcInstance_->getCurrentConversationModel()->getConvMediasInfos(accountId,
|
||||||
|
convId,
|
||||||
|
text,
|
||||||
|
isMedia);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
qDebug() << "Exception during getConvMedia:";
|
qDebug() << "Exception during startSearch()";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -60,6 +60,7 @@ class MessagesAdapter final : public QmlAdapterBase
|
||||||
QML_PROPERTY(QString, editId)
|
QML_PROPERTY(QString, editId)
|
||||||
QML_RO_PROPERTY(QList<QString>, currentConvComposingList)
|
QML_RO_PROPERTY(QList<QString>, currentConvComposingList)
|
||||||
QML_PROPERTY(QVariant, mediaMessageListModel)
|
QML_PROPERTY(QVariant, mediaMessageListModel)
|
||||||
|
QML_PROPERTY(QString, searchbarPrompt)
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit MessagesAdapter(AppSettingsManager* settingsManager,
|
explicit MessagesAdapter(AppSettingsManager* settingsManager,
|
||||||
|
@ -70,6 +71,7 @@ public:
|
||||||
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void newInteraction(const QString& id, int type);
|
void newInteraction(const QString& id, int type);
|
||||||
|
void newMessageBarPlaceholderText(QString& placeholderText);
|
||||||
void newFilePasted(QString filePath);
|
void newFilePasted(QString filePath);
|
||||||
void newTextPasted();
|
void newTextPasted();
|
||||||
void previewInformationToQML(QString messageId, QStringList previewInformation);
|
void previewInformationToQML(QString messageId, QStringList previewInformation);
|
||||||
|
@ -77,6 +79,7 @@ Q_SIGNALS:
|
||||||
void timestampUpdated();
|
void timestampUpdated();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
Q_INVOKABLE bool isDocument(const interaction::Type& type);
|
||||||
Q_INVOKABLE void loadMoreMessages();
|
Q_INVOKABLE void loadMoreMessages();
|
||||||
Q_INVOKABLE void loadConversationUntil(const QString& to);
|
Q_INVOKABLE void loadConversationUntil(const QString& to);
|
||||||
Q_INVOKABLE void connectConversationModel();
|
Q_INVOKABLE void connectConversationModel();
|
||||||
|
@ -129,7 +132,7 @@ protected:
|
||||||
Q_INVOKABLE QVariantMap getTransferStats(const QString& messageId, int);
|
Q_INVOKABLE QVariantMap getTransferStats(const QString& messageId, int);
|
||||||
Q_INVOKABLE QVariant dataForInteraction(const QString& interactionId,
|
Q_INVOKABLE QVariant dataForInteraction(const QString& interactionId,
|
||||||
int role = Qt::DisplayRole) const;
|
int role = Qt::DisplayRole) const;
|
||||||
Q_INVOKABLE void getConvMedias();
|
Q_INVOKABLE void startSearch(QString& text, bool isMedia = false);
|
||||||
Q_INVOKABLE int getMessageIndexFromId(QString& id);
|
Q_INVOKABLE int getMessageIndexFromId(QString& id);
|
||||||
|
|
||||||
// Run corrsponding js functions, c++ to qml.
|
// Run corrsponding js functions, c++ to qml.
|
||||||
|
@ -150,8 +153,7 @@ private Q_SLOTS:
|
||||||
const QString& contactUri,
|
const QString& contactUri,
|
||||||
bool isComposing);
|
bool isComposing);
|
||||||
void onMessagesFoundProcessed(const QString& accountId,
|
void onMessagesFoundProcessed(const QString& accountId,
|
||||||
const VectorMapStringString& messageIds,
|
const QMap<QString, interaction::Info>& messageInformation);
|
||||||
const QVector<interaction::Info>& messageInformations);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QList<QString> conversationTypersUrlToName(const QSet<QString>& typersSet);
|
QList<QString> conversationTypersUrlToName(const QSet<QString>& typersSet);
|
||||||
|
|
|
@ -316,9 +316,12 @@ public:
|
||||||
api::datatransfer::Info& info) const;
|
api::datatransfer::Info& info) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Starts a search of all medias and files in a conversation
|
* Starts a search of all medias in a conversation
|
||||||
*/
|
*/
|
||||||
void getConvMediasInfos(const QString& accountId, const QString& conversationId);
|
void getConvMediasInfos(const QString& accountId,
|
||||||
|
const QString& conversationId,
|
||||||
|
const QString& text,
|
||||||
|
bool isMedia);
|
||||||
/**
|
/**
|
||||||
* @param convUid, uid of the conversation
|
* @param convUid, uid of the conversation
|
||||||
* @return the number of unread messages for the conversation
|
* @return the number of unread messages for the conversation
|
||||||
|
@ -612,12 +615,10 @@ Q_SIGNALS:
|
||||||
/**
|
/**
|
||||||
* Emitted once a message search has been done and processed
|
* Emitted once a message search has been done and processed
|
||||||
* @param accountId
|
* @param accountId
|
||||||
* @param messageIds ids of all the messages found by the search
|
* @param messageInformation message datas
|
||||||
* @param messageInformations message datas
|
|
||||||
*/
|
*/
|
||||||
void messagesFoundProcessed(const QString& accountId,
|
void messagesFoundProcessed(const QString& accountId,
|
||||||
const VectorMapStringString& messageIds,
|
const QMap<QString, interaction::Info>& messageInformation) const;
|
||||||
const QVector<interaction::Info>& messageInformations) const;
|
|
||||||
/**
|
/**
|
||||||
* Emitted once a conversation needs somebody to host the call
|
* Emitted once a conversation needs somebody to host the call
|
||||||
* @param callId
|
* @param callId
|
||||||
|
|
|
@ -243,7 +243,8 @@ public:
|
||||||
|
|
||||||
std::map<QString, std::mutex> interactionsLocks; ///< {convId, mutex}
|
std::map<QString, std::mutex> interactionsLocks; ///< {convId, mutex}
|
||||||
MapStringString transfIdToDbIntId;
|
MapStringString transfIdToDbIntId;
|
||||||
uint32_t currentMsgRequestId;
|
uint32_t mediaResearchRequestId;
|
||||||
|
uint32_t msgResearchRequestId;
|
||||||
|
|
||||||
public Q_SLOTS:
|
public Q_SLOTS:
|
||||||
/**
|
/**
|
||||||
|
@ -2540,29 +2541,34 @@ ConversationModelPimpl::slotMessagesFound(uint32_t requestId,
|
||||||
const QString& conversationId,
|
const QString& conversationId,
|
||||||
const VectorMapStringString& messageIds)
|
const VectorMapStringString& messageIds)
|
||||||
{
|
{
|
||||||
if (requestId != currentMsgRequestId) {
|
QMap<QString, interaction::Info> messageDetailedInformation;
|
||||||
return;
|
if (requestId == mediaResearchRequestId) {
|
||||||
}
|
Q_FOREACH (const MapStringString& msg, messageIds) {
|
||||||
QVector<interaction::Info> messageDetailedinformations;
|
auto intInfo = interaction::Info(msg, "");
|
||||||
Q_FOREACH (const MapStringString& msg, messageIds) {
|
if (intInfo.type == interaction::Type::DATA_TRANSFER) {
|
||||||
auto intInfo = interaction::Info(msg, "");
|
auto fileId = msg["fileId"];
|
||||||
if (intInfo.type == interaction::Type::DATA_TRANSFER) {
|
|
||||||
auto fileId = msg["fileId"];
|
|
||||||
|
|
||||||
QString path;
|
QString path;
|
||||||
qlonglong bytesProgress, totalSize;
|
qlonglong bytesProgress, totalSize;
|
||||||
linked.owner.dataTransferModel->fileTransferInfo(accountId,
|
linked.owner.dataTransferModel->fileTransferInfo(accountId,
|
||||||
conversationId,
|
conversationId,
|
||||||
fileId,
|
fileId,
|
||||||
path,
|
path,
|
||||||
totalSize,
|
totalSize,
|
||||||
bytesProgress);
|
bytesProgress);
|
||||||
intInfo.body = path;
|
intInfo.body = path;
|
||||||
|
}
|
||||||
|
messageDetailedInformation[msg["id"]] = intInfo;
|
||||||
|
}
|
||||||
|
} else if (requestId == msgResearchRequestId) {
|
||||||
|
Q_FOREACH (const MapStringString& msg, messageIds) {
|
||||||
|
auto intInfo = interaction::Info(msg, "");
|
||||||
|
if (intInfo.type == interaction::Type::TEXT) {
|
||||||
|
messageDetailedInformation[msg["id"]] = intInfo;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
messageDetailedinformations.append(intInfo);
|
|
||||||
}
|
}
|
||||||
|
Q_EMIT linked.messagesFoundProcessed(accountId, messageDetailedInformation);
|
||||||
Q_EMIT linked.messagesFoundProcessed(accountId, messageIds, messageDetailedinformations);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -4000,10 +4006,17 @@ ConversationModel::sendFile(const QString& convUid, const QString& path, const Q
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
ConversationModel::getConvMediasInfos(const QString& accountId, const QString& conversationId)
|
ConversationModel::getConvMediasInfos(const QString& accountId,
|
||||||
|
const QString& conversationId,
|
||||||
|
const QString& text,
|
||||||
|
bool isMedia)
|
||||||
{
|
{
|
||||||
pimpl_->currentMsgRequestId = ConfigurationManager::instance().searchConversation(
|
if (isMedia)
|
||||||
accountId, conversationId, "", "", "", "application/data-transfer+json", 0, 0, 0, 0);
|
pimpl_->mediaResearchRequestId = ConfigurationManager::instance().searchConversation(
|
||||||
|
accountId, conversationId, "", "", text, "application/data-transfer+json", 0, 0, 0, 0);
|
||||||
|
else
|
||||||
|
pimpl_->msgResearchRequestId = ConfigurationManager::instance().searchConversation(
|
||||||
|
accountId, conversationId, "", "", text, "text/plain", 0, 0, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
|
Loading…
Add table
Reference in a new issue